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
43
#include <QtTest/QtTest>
44
45
#include <q3datetimeedit.h>
46
#include <qapplication.h>
47
#include <qcombobox.h>
48
#include <qdialog.h>
49
#include <qlineedit.h>
50
#include <q3listbox.h>
51
#include <q3table.h>
52
#include <qlayout.h>
53
54
#include "../../shared/util.h"
55
56
#define WAITS 1
57
#ifdef WAITS
58
#endif
59
60
Q_DECLARE_METATYPE(QPoint)
61
62
//TESTED_FILES=
63
64
QT_FORWARD_DECLARE_CLASS(Q3Table)
65
66
class tst_Q3Table : public QObject
67
{
68
    Q_OBJECT
69
public:
70
    tst_Q3Table();
71
72
public slots:
73
    void initTestCase();
74
    void cleanupTestCase();
75
    void init();
76
    void cleanup();
77
private slots:
78
    void setNumRowsColsItems();
79
    void setNumRowsColsWidgets();
80
81
    void selection();
82
    void selectComboTableItem_data();
83
    void selectComboTableItem();
84
    void pageUpDownNavigation_data();
85
    void pageUpDownNavigation();
86
    void simpleKeyboardNavigation();
87
    void setRowStretchable();
88
    void setColumnStretchable();
89
    void selectRow_data();
90
    void selectRow();
91
    void selectColumn_data();
92
    void selectColumn();
93
    void removeSelection_selectionChanged();
94
    void cellNavigation();
95
    void cellNavigationWhileEditing();
96
    void removeRow_data();
97
    void removeRow();
98
    void swapRowMemoryLeak();
99
    void insertRows_data();
100
    void insertRows();
101
    void editCheck();
102
    void setCellWidgetFocus();
103
    void selectionWithMouse_data();
104
    void selectionWithMouse();
105
    void valueChanged();
106
    void numSelections(); // Task specific, moreNumSelections() should cover all bases
107
    void dateTimeEdit();
108
    void onValueChanged(int, int);
109
    void moreNumSelections_data();
110
    void moreNumSelections();
111
    void headerSwapIconset();
112
    void propagateEscapeKey();
113
public slots:
114
    void selectionWasChanged();
115
private:
116
    void setupTableItems();
117
    Q3Table *testWidget;
118
    bool isValueChanged, receivedSelectionChanged;
119
};
120
121
Q_DECLARE_METATYPE(Q3Table::SelectionMode);
122
123
#if 0
124
/* XPM */
125
static const char *fileopen[] = {
126
"    16    13        5            1",
127
". c #040404",
128
"# c #808304",
129
"a c None",
130
"b c #f3f704",
131
"c c #f3f7f3",
132
"aaaaaaaaa...aaaa",
133
"aaaaaaaa.aaa.a.a",
134
"aaaaaaaaaaaaa..a",
135
"a...aaaaaaaa...a",
136
".bcb.......aaaaa",
137
".cbcbcbcbc.aaaaa",
138
".bcbcbcbcb.aaaaa",
139
".cbcb...........",
140
".bcb.#########.a",
141
".cb.#########.aa",
142
".b.#########.aaa",
143
"..#########.aaaa",
144
"...........aaaaa"
145
};
146
#endif
147
148
tst_Q3Table::tst_Q3Table()
149
    : isValueChanged( false )
150
{
151
}
152
153
void tst_Q3Table::initTestCase()
154
{
155
}
156
157
void tst_Q3Table::cleanupTestCase()
158
{
159
}
160
161
void tst_Q3Table::init()
162
{
163
    // Reset the table
164
    testWidget = new Q3Table(4,4,0,"testWidget");
165
    testWidget->show();
166
#ifdef Q_WS_X11
167
    qt_x11_wait_for_window_manager( testWidget );
168
#endif
169
}
170
171
void tst_Q3Table::cleanup()
172
{
173
    testWidget->hide();
174
    delete testWidget;
175
    testWidget = 0;
176
}
177
178
/*
179
    Function that will popuplate the testWidget with a variety of Q3TableItems
180
*/
181
182
void tst_Q3Table::setupTableItems()
183
{
184
    QStringList list;
185
    list << "A" << "B";
186
    Q3ComboTableItem *cbi = new Q3ComboTableItem(testWidget, list);
187
    testWidget->setItem(1, 1, cbi);
188
    Q3ComboTableItem *ecbi = new Q3ComboTableItem(testWidget, list, TRUE);
189
    testWidget->setItem(1, 2, ecbi);
190
    Q3CheckTableItem *chi = new Q3CheckTableItem(testWidget, "Check");
191
    testWidget->setItem(2, 2, chi);
192
    Q3TableItem *ne = new Q3TableItem(testWidget, Q3TableItem::Never, "Never");
193
    testWidget->setItem(0, 0, ne);
194
    Q3TableItem *ot = new Q3TableItem(testWidget, Q3TableItem::OnTyping, "On Typing");
195
    testWidget->setItem(0, 1, ot);
196
    Q3TableItem *wc = new Q3TableItem(testWidget, Q3TableItem::WhenCurrent, "When Current");
197
    testWidget->setItem(0, 2, wc);
198
    Q3TableItem *al = new Q3TableItem(testWidget, Q3TableItem::Always, "Always");
199
    testWidget->setItem(0, 3, al);
200
}
201
202
#define CELL_TEXT(r, c) QString::number( r ) + "/" + QString::number( c )
203
204
void tst_Q3Table::setNumRowsColsItems()
205
{
206
    Q3Table *t = new Q3Table( 0, "test_table" );
207
208
    const int initial_num_rows = 4;
209
    const int initial_num_cols = 4;
210
211
    const int larger_num_rows = 8;
212
    const int larger_num_cols = 8;
213
214
    const int smaller_num_rows = 3;
215
    const int smaller_num_cols = 3;
216
217
    t->setNumRows( initial_num_cols );
218
    t->setNumCols( initial_num_cols );
219
220
    QCOMPARE( t->numRows(), initial_num_rows );
221
    QCOMPARE( t->numCols(), initial_num_cols );
222
223
    int r, c;
224
    for ( r = 0; r < initial_num_rows; ++r ) {
225
	for ( c = 0; c < initial_num_cols; ++c ) {
226
	    t->setText( r, c, CELL_TEXT( r, c ) );
227
	}
228
    }
229
230
    for ( r = 0; r < initial_num_rows; ++r ) {
231
	for ( c = 0; c < initial_num_cols; ++c ) {
232
	    QCOMPARE( t->text( r, c ), CELL_TEXT( r, c ) );
233
	}
234
    }
235
236
    t->setNumRows( larger_num_rows );
237
238
    for ( r = 0; r < larger_num_rows; ++r ) {
239
	for ( c = 0; c < initial_num_cols; ++c ) {
240
	    if ( r < initial_num_rows && c < initial_num_cols ) {
241
		QCOMPARE( t->text( r, c ), CELL_TEXT( r, c ) );
242
	    } else {
243
		QCOMPARE( t->text( r, c ), QString() );
244
	    }
245
	}
246
    }
247
248
    t->setNumCols( larger_num_cols );
249
250
    for ( r = 0; r < larger_num_rows; ++r ) {
251
	for ( c = 0; c < larger_num_cols; ++c ) {
252
	    if ( r < initial_num_rows && c < initial_num_cols ) {
253
		QCOMPARE( t->text( r, c ), CELL_TEXT( r, c ) );
254
	    } else {
255
		QCOMPARE( t->text( r, c ), QString() );
256
	    }
257
	}
258
    }
259
260
    t->setNumRows( smaller_num_rows );
261
262
    for ( r = 0; r < smaller_num_rows; ++r ) {
263
	for ( c = 0; c < initial_num_cols; ++c ) {
264
	    QCOMPARE( t->text( r, c ), CELL_TEXT( r, c ) );
265
	}
266
    }
267
268
    t->setNumCols( smaller_num_cols );
269
270
    for ( r = 0; r < smaller_num_rows; ++r ) {
271
	for ( c = 0; c < smaller_num_cols; ++c ) {
272
	    QCOMPARE( t->text( r, c ), CELL_TEXT( r, c ) );
273
	}
274
    }
275
276
    delete t;
277
}
278
279
void tst_Q3Table::setNumRowsColsWidgets()
280
{
281
    Q3Table *t = new Q3Table( 0, "test_table" );
282
283
    const int initial_num_rows = 4;
284
    const int initial_num_cols = 4;
285
286
    const int larger_num_rows = 8;
287
    const int larger_num_cols = 8;
288
289
    const int smaller_num_rows = 3;
290
    const int smaller_num_cols = 3;
291
292
    t->setNumRows( initial_num_cols );
293
    t->setNumCols( initial_num_cols );
294
295
    QCOMPARE( t->numRows(), initial_num_rows );
296
    QCOMPARE( t->numCols(), initial_num_cols );
297
298
    int r, c;
299
300
    for ( r = 0; r < initial_num_rows; ++r ) {
301
	for ( c = 0; c < initial_num_cols; ++c ) {
302
	    t->setCellWidget( r, c, new QWidget( t, CELL_TEXT( r, c ) ) );
303
	}
304
    }
305
306
    for ( r = 0; r < initial_num_rows; ++r ) {
307
	for ( c = 0; c < initial_num_cols; ++c ) {
308
	    QCOMPARE( QString( t->cellWidget( r, c )->name() ), CELL_TEXT( r, c ) );
309
	}
310
    }
311
312
    t->setNumRows( larger_num_rows );
313
314
    for ( r = 0; r < larger_num_rows; ++r ) {
315
	for ( c = 0; c < initial_num_cols; ++c ) {
316
	    if ( r < initial_num_rows && c < initial_num_cols ) {
317
		QCOMPARE( QString( t->cellWidget( r, c )->name() ), CELL_TEXT( r, c ) );
318
	    } else {
319
		QCOMPARE( t->cellWidget( r, c ), (QWidget*)0 );
320
	    }
321
	}
322
    }
323
324
    t->setNumCols( larger_num_cols );
325
326
    for ( r = 0; r < larger_num_rows; ++r ) {
327
	for ( c = 0; c < larger_num_cols; ++c ) {
328
	    if ( r < initial_num_rows && c < initial_num_cols ) {
329
		QCOMPARE( QString( t->cellWidget( r, c )->name() ), CELL_TEXT( r, c ) );
330
	    } else {
331
		QCOMPARE( t->cellWidget( r, c ), (QWidget*)0 );
332
	    }
333
	}
334
    }
335
336
    t->setNumRows( smaller_num_rows );
337
338
    for ( r = 0; r < smaller_num_rows; ++r ) {
339
	for ( c = 0; c < initial_num_cols; ++c ) {
340
	    QCOMPARE( QString( t->cellWidget( r, c )->name() ), CELL_TEXT( r, c ) );
341
	}
342
    }
343
344
    t->setNumCols( smaller_num_cols );
345
346
    for ( r = 0; r < smaller_num_rows; ++r ) {
347
	for ( c = 0; c < smaller_num_cols; ++c ) {
348
	    QCOMPARE( QString( t->cellWidget( r, c )->name() ), CELL_TEXT( r, c ) );
349
	}
350
    }
351
352
    delete t;
353
}
354
355
356
void tst_Q3Table::selection()
357
{
358
    Q3Table *t = new Q3Table( 20, 20, 0, "test_table" );
359
360
    t->selectCells( 0, 0, 50, 50 );
361
362
    Q3TableSelection sel( 60, 60, 100, 100 );
363
    t->addSelection( sel );
364
365
    t->show();
366
    QCOMPARE( t->numSelections(), 2 );
367
    delete t;
368
}
369
370
void tst_Q3Table::selectComboTableItem_data()
371
{
372
    QTest::addColumn<bool>("editable");
373
374
    QTest::newRow( "editable" ) << TRUE;
375
    QTest::newRow( "non-editable" ) << FALSE;
376
377
}
378
379
class MyTable : public Q3Table
380
{
381
    // Conveience subclass used to be able to call isEditing()
382
public:
383
    MyTable(int rows,int cols,QWidget *parent = 0,const char *name = 0)
384
	: Q3Table(rows,cols,parent,name) {}
385
    bool isEditing() {
386
	return Q3Table::isEditing();
387
    }
388
};
389
390
void tst_Q3Table::selectComboTableItem()
391
{
392
#if 0
393
    MyTable table(4,4,0,"subclassTestWidget");
394
    // Test for task #25026
395
    QFETCH( bool, editable );
396
397
    QStringList strings;
398
    strings << "One" << "Two" << "Three" << "Four";
399
    QComboTableItem *cbi = new QComboTableItem(testWidget,strings,editable);
400
    table.setItem(0,0,cbi);
401
    table.hide();
402
    table.show();
403
    QComboBox *cb;
404
    if ( !editable )
405
	cb = (QComboBox*)table.viewport()->child("qt_editor_cb","QComboBox");
406
    else
407
	cb = (QComboBox*)table.cellWidget(0,0);
408
    QVERIFY( cb );
409
    QCOMPARE(table.text(0,0),QString("One"));
410
    QTest::mouseClick(cb,QtTestCase::LeftButton,QtTestCase::NoButton,QPoint(cb->width()-7,cb->height()-5));
411
    QVERIFY(cb->listBox()->isVisible());
412
    QTest::mouseClick(cb->listBox()->viewport(),QtTestCase::LeftButton,QtTestCase::NoButton,QPoint(5,cb->listBox()->height()-5));
413
    QCOMPARE(table.text(0,0),QString("Four"));
414
415
    // Ensure the edit is accepted
416
    QTest::mouseClick(table.viewport(),QtTestCase::LeftButton,QtTestCase::NoButton,QPoint(table.width()-10,table.height()-10));
417
    QVERIFY(!table.isEditing());
418
    QCOMPARE(table.text(0,0),QString("Four"));
419
420
    // Now check that Escape will revert any changes
421
    QTest::mouseClick(cb,QtTestCase::LeftButton,QtTestCase::NoButton,QPoint(cb->width()-7,cb->height()-5));
422
    QVERIFY(cb->listBox()->isVisible());
423
    QTest::mouseClick(cb->listBox()->viewport(),QtTestCase::LeftButton,QtTestCase::NoButton,QPoint(5,5));
424
    QCOMPARE(cb->currentText(),QString("One"));
425
    QTest::keyClick(cb,Qt::Key_Escape);
426
    QVERIFY(!table.isEditing());
427
    QCOMPARE(table.text(0,0),QString("Four"));
428
#else
429
    QSKIP("This test will fail at the moment since the way qtestlib iss handling mouse events is broken",SkipAll);
430
#endif
431
}
432
433
void tst_Q3Table::pageUpDownNavigation_data()
434
{
435
    QTest::addColumn<Q3Table::SelectionMode>("selectionMode");
436
    QTest::addColumn<bool>("activeSelection");
437
    QTest::addColumn<int>("pgUpTopRow");
438
    QTest::addColumn<int>("pgUpBottomRow");
439
    QTest::addColumn<int>("pgUpLeftCol");
440
    QTest::addColumn<int>("pgUpRightCol");
441
    QTest::addColumn<int>("pgDownTopRow");
442
    QTest::addColumn<int>("pgDownBottomRow");
443
    QTest::addColumn<int>("pgDownLeftCol");
444
    QTest::addColumn<int>("pgDownRightCol");
445
446
    QTest::newRow("NoSelection") << Q3Table::NoSelection << FALSE << -1 << -1 << -1 << -1 << -1 << -1 << -1 << -1;
447
    QTest::newRow("SingleSelection") << Q3Table::Single << FALSE << -1 << -1 << -1 << -1 << -1 << -1 << -1 << -1;
448
    QTest::newRow("MultiSelection") << Q3Table::Multi << FALSE << -1 << -1 << -1 << -1 << -1 << -1 << -1 << -1;
449
    QTest::newRow("SingleRowSelection") << Q3Table::SingleRow << TRUE << 0 << 0 << 0 << 3 << 3 << 3 << 0 << 3;
450
    QTest::newRow("MultiRowSelection") << Q3Table::MultiRow << TRUE << 0 << 0 << 0 << 3 << 3 << 3 << 0 << 3;
451
}
452
453
void tst_Q3Table::pageUpDownNavigation()
454
{
455
    setupTableItems();
456
457
    // Test for task #25842
458
    QFETCH(Q3Table::SelectionMode,selectionMode);
459
    QFETCH(bool,activeSelection);
460
    QFETCH(int,pgUpTopRow);
461
    QFETCH(int,pgUpBottomRow);
462
    QFETCH(int,pgUpLeftCol);
463
    QFETCH(int,pgUpRightCol);
464
    QFETCH(int,pgDownTopRow);
465
    QFETCH(int,pgDownBottomRow);
466
    QFETCH(int,pgDownLeftCol);
467
    QFETCH(int,pgDownRightCol);
468
469
    // Needed to force the table to have "no selection"
470
    testWidget->setCurrentCell(-1,-1);
471
472
    testWidget->setSelectionMode(selectionMode);
473
#ifdef WAITS
474
    QTest::qWait(50);
475
#endif
476
    QTest::keyClick(testWidget->viewport(),Qt::Key_PageUp);
477
#ifdef WAITS
478
    QTest::qWait(50);
479
#endif
480
    Q3TableSelection ts = testWidget->selection(testWidget->currentSelection());
481
    QVERIFY(ts.isActive() == activeSelection);
482
    if (activeSelection) {
483
	QVERIFY(ts.topRow() == pgUpTopRow);
484
	QVERIFY(ts.bottomRow() == pgUpBottomRow);
485
	QVERIFY(ts.leftCol() == pgUpLeftCol);
486
	QVERIFY(ts.rightCol() == pgUpRightCol);
487
    }
488
    QTest::keyClick(testWidget->viewport(),Qt::Key_PageDown);
489
#ifdef WAITS
490
    QTest::qWait(50);
491
#endif
492
    ts = testWidget->selection(testWidget->currentSelection());
493
    QVERIFY(ts.isActive() == activeSelection);
494
    if (activeSelection) {
495
	QVERIFY(ts.topRow() == pgDownTopRow);
496
	QVERIFY(ts.bottomRow() == pgDownBottomRow);
497
	QVERIFY(ts.leftCol() == pgDownLeftCol);
498
	QVERIFY(ts.rightCol() == pgDownRightCol);
499
    }
500
}
501
502
void tst_Q3Table::simpleKeyboardNavigation()
503
{
504
    QApplication::setActiveWindow(testWidget);
505
    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(testWidget));
506
    QWidget *w;
507
508
    // Test for task #24726
509
#ifdef WAITS
510
    QTest::qWait(50);
511
#endif
512
    QTest::mouseClick(testWidget->viewport(),
513
               Qt::LeftButton, Qt::NoModifier,
514
               QPoint(testWidget->columnPos(0) + 3, testWidget->rowPos(0) + 3));
515
#ifdef WAITS
516
    QTest::qWait(50);
517
#endif
518
519
    QCOMPARE(testWidget->currentColumn(), 0);
520
    QCOMPARE(testWidget->currentRow(), 0);
521
522
    QTest::keyClick(testWidget->viewport(), Qt::Key_T);
523
524
    // After the first keyevent, the table starts editing the item
525
    w = testWidget->cellWidget(0, 0);
526
    QVERIFY(w);
527
528
#ifdef WAITS
529
    QTest::qWait(50);
530
#endif
531
532
    QTest::keyClick(w, Qt::Key_E);
533
534
#ifdef WAITS
535
    QTest::qWait(50);
536
#endif
537
538
    QTest::keyClick(w, Qt::Key_C);
539
540
#ifdef WAITS
541
    QTest::qWait(50);
542
#endif
543
544
    QTest::keyClick(w, Qt::Key_H);
545
546
#ifdef WAITS
547
    QTest::qWait(50);
548
#endif
549
550
#ifdef Q_WS_MAC // Mac lineedits grab Up and Down
551
    QTest::keyClick(w, Qt::Key_Return);
552
#else
553
    QTest::keyClick(testWidget->viewport(), Qt::Key_Down);
554
#endif
555
556
#ifdef WAITS
557
    QTest::qWait(50);
558
#endif
559
560
    QCOMPARE(testWidget->text(0,0), QString("tech"));
561
    QCOMPARE(testWidget->currentColumn(), 0);
562
    QCOMPARE(testWidget->currentRow(), 1);
563
564
    QTest::keyClick(testWidget->viewport(), Qt::Key_A);
565
    w = testWidget->cellWidget(0, 1);
566
567
#ifdef WAITS
568
    QTest::qWait(50);
569
#endif
570
571
    QTest::keyClick(w, Qt::Key_B);
572
573
#ifdef WAITS
574
    QTest::qWait(50);
575
#endif
576
577
    QTest::keyClick(w, Qt::Key_C);
578
579
#ifdef WAITS
580
    QTest::qWait(50);
581
#endif
582
583
#ifdef Q_WS_MAC // Mac lineedits grab Up and Down
584
    QTest::keyClick(w, Qt::Key_Return);
585
    QTest::keyClick(testWidget->viewport(), Qt::Key_Up);
586
    QTest::keyClick(testWidget->viewport(), Qt::Key_Up);
587
#else
588
    QTest::keyClick(w, Qt::Key_Up);
589
#endif
590
591
#ifdef WAITS
592
    QTest::qWait(50);
593
#endif
594
595
    QCOMPARE(testWidget->text(1,0), QString("abc"));
596
    QCOMPARE(testWidget->currentColumn(), 0);
597
    QCOMPARE(testWidget->currentRow(), 0);
598
    w = testWidget->cellWidget(0, 0);
599
600
    QTest::keyClick(w, Qt::Key_D);
601
602
#ifdef WAITS
603
    QTest::qWait(50);
604
#endif
605
606
    QTest::keyClick(w, Qt::Key_E);
607
608
#ifdef WAITS
609
    QTest::qWait(50);
610
#endif
611
612
    QTest::keyClick(w, Qt::Key_F);
613
614
#ifdef WAITS
615
    QTest::qWait(50);
616
#endif
617
618
#ifdef Q_WS_MAC // Mac lineedits grab Up and Down
619
    QTest::keyClick(w, Qt::Key_Return);
620
#else
621
    QTest::keyClick(w, Qt::Key_Down);
622
#endif
623
624
#ifdef WAITS
625
    QTest::qWait(50);
626
#endif
627
628
    QCOMPARE(testWidget->text(0,0), QString("def"));
629
    QCOMPARE(testWidget->currentColumn(), 0);
630
    QCOMPARE(testWidget->currentRow(), 1);
631
}
632
633
void tst_Q3Table::setRowStretchable()
634
{
635
#if 1
636
    QSKIP("This test currently fails on all versions", SkipAll);
637
#endif
638
    // Part of test for task 24471
639
    // Only tests TRUE case, need FALSE case written
640
    // Also needs to test the case where the user tries to resize it
641
    testWidget->setRowStretchable(0,TRUE);
642
    testWidget->show();
643
    int height = testWidget->rowHeight(0);
644
    testWidget->setRowHeight(0,height * 2);
645
    QCOMPARE(height,testWidget->rowHeight(0));
646
}
647
648
void tst_Q3Table::setColumnStretchable()
649
{
650
#if 1
651
    QSKIP("This test currently fails on all versions", SkipAll);
652
#endif
653
    // Part of test for task 24471
654
    // Only tests TRUE case, need FALSE case written
655
    // Also needs to test the case where the user tries to resize it
656
    testWidget->setColumnStretchable(0,TRUE);
657
    testWidget->show();
658
    int width = testWidget->columnWidth(0);
659
    testWidget->setColumnWidth(0,width * 2);
660
    QCOMPARE(width,testWidget->columnWidth(0));
661
}
662
663
void tst_Q3Table::selectRow_data()
664
{
665
    QTest::addColumn<Q3Table::SelectionMode>("selectionMode");
666
    QTest::addColumn<bool>("activeSelection");
667
    QTest::addColumn<int>("topRow");
668
    QTest::addColumn<int>("bottomRow");
669
    QTest::addColumn<int>("leftCol");
670
    QTest::addColumn<int>("rightCol");
671
672
    QTest::newRow("NoSelection") << Q3Table::NoSelection << TRUE << 1 << 1 << 0 << 3;
673
    QTest::newRow("SingleSelection") << Q3Table::Single << TRUE << 1 << 1 << 0 << 3;
674
    QTest::newRow("MultiSelection") << Q3Table::Multi << TRUE << 1 << 1 << 0 << 3;
675
    QTest::newRow("SingleRowSelection") << Q3Table::SingleRow << TRUE << 1 << 1 << 0 << 3;
676
    QTest::newRow("MultiRowSelection") << Q3Table::MultiRow << TRUE << 1 << 1 << 0 << 3;
677
}
678
679
void tst_Q3Table::selectRow()
680
{
681
    QFETCH(Q3Table::SelectionMode,selectionMode);
682
    QFETCH(bool,activeSelection);
683
    QFETCH(int,topRow);
684
    QFETCH(int,bottomRow);
685
    QFETCH(int,leftCol);
686
    QFETCH(int,rightCol);
687
688
    testWidget->clearSelection();
689
    testWidget->setSelectionMode(selectionMode);
690
    testWidget->selectRow(1);
691
692
    int current = testWidget->currentSelection();
693
    QVERIFY(current != -1);
694
    Q3TableSelection ts = testWidget->selection(current);
695
696
    QCOMPARE(ts.isActive(), activeSelection);
697
698
    if (activeSelection) {
699
        QCOMPARE(ts.topRow(), topRow);
700
	QCOMPARE(ts.bottomRow(), bottomRow);
701
	QCOMPARE(ts.leftCol(), leftCol);
702
	QCOMPARE(ts.rightCol(), rightCol);
703
    }
704
705
    // make sure selection is cleared
706
    testWidget->clearSelection();
707
    current = testWidget->currentSelection();
708
    QVERIFY(current == -1);
709
710
    testWidget->selectRow(1);
711
    QEXPECT_FAIL("SingleRowSelection", "This currently fails in all versions", Abort);
712
    QVERIFY(testWidget->numSelections() > 0); // selectRow in SingleRowSelection doesn't select anything (see qtable.cpp)
713
    current = testWidget->currentSelection();
714
    QVERIFY(current != -1);
715
    ts = testWidget->selection(current);
716
717
    QCOMPARE(ts.isActive(), activeSelection);
718
719
    if (activeSelection) {
720
	QCOMPARE(ts.topRow(), topRow);
721
	QCOMPARE(ts.bottomRow(), bottomRow);
722
	QCOMPARE(ts.leftCol(), leftCol);
723
	QCOMPARE(ts.rightCol(), rightCol);
724
    }
725
}
726
727
void tst_Q3Table::selectColumn_data()
728
{
729
    QTest::addColumn<Q3Table::SelectionMode>("selectionMode");
730
    QTest::addColumn<bool>("activeSelection");
731
    QTest::addColumn<int>("topRow");
732
    QTest::addColumn<int>("bottomRow");
733
    QTest::addColumn<int>("leftCol");
734
    QTest::addColumn<int>("rightCol");
735
736
    QTest::newRow("NoSelection") << Q3Table::NoSelection << TRUE << 0 << 3 << 1 << 1;
737
    QTest::newRow("SingleSelection") << Q3Table::Single << TRUE << 0 << 3 << 1 << 1;
738
    QTest::newRow("MultiSelection") << Q3Table::Multi << TRUE << 0 << 3 << 1 << 1;
739
    QTest::newRow("SingleRowSelection") << Q3Table::SingleRow << TRUE << 0 << 3 << 1 << 1;
740
    QTest::newRow("MultiRowSelection") << Q3Table::MultiRow << TRUE << 0 << 3 << 1 << 1;
741
}
742
743
void tst_Q3Table::selectColumn()
744
{
745
    QFETCH(Q3Table::SelectionMode,selectionMode);
746
    QFETCH(bool,activeSelection);
747
    QFETCH(int,topRow);
748
    QFETCH(int,bottomRow);
749
    QFETCH(int,leftCol);
750
    QFETCH(int,rightCol);
751
752
    testWidget->setSelectionMode(selectionMode);
753
    testWidget->selectColumn(1);
754
    Q3TableSelection ts = testWidget->selection(testWidget->currentSelection());
755
    QCOMPARE(ts.isActive(), activeSelection);
756
757
    if (activeSelection) {
758
	QCOMPARE(ts.topRow(), topRow);
759
	QCOMPARE(ts.bottomRow(), bottomRow);
760
	QCOMPARE(ts.leftCol(), leftCol);
761
	QCOMPARE(ts.rightCol(), rightCol);
762
    }
763
764
    testWidget->clearSelection();
765
    ts = testWidget->selection(testWidget->currentSelection());
766
    QVERIFY(!ts.isActive());
767
768
    testWidget->selectColumn(1);
769
    ts = testWidget->selection(testWidget->currentSelection());
770
    QCOMPARE(ts.isActive(), activeSelection);
771
    if (activeSelection) {
772
        QCOMPARE(ts.topRow(), topRow);
773
	QCOMPARE(ts.bottomRow(), bottomRow);
774
	QCOMPARE(ts.leftCol(), leftCol);
775
	QCOMPARE(ts.rightCol(), rightCol);
776
    }
777
}
778
779
void tst_Q3Table::cellNavigation()
780
{
781
#if 0
782
    setupTableItems();
783
#endif
784
785
    testWidget->setCurrentCell(0, 0);
786
787
    // Check tab key first
788
    QCOMPARE(testWidget->currentRow(), 0);
789
    QCOMPARE(testWidget->currentColumn(), 0);
790
    QTest::keyClick(testWidget->viewport(), Qt::Key_Tab);
791
#ifdef WAITS
792
    QTest::qWait(50);
793
#endif
794
    QCOMPARE(testWidget->currentRow(), 0);
795
    QCOMPARE(testWidget->currentColumn(), 1);
796
    QTest::keyClick(testWidget->viewport(), Qt::Key_Tab);
797
#ifdef WAITS
798
    QTest::qWait(50);
799
#endif
800
    QCOMPARE(testWidget->currentRow(), 0);
801
    QCOMPARE(testWidget->currentColumn(), 2);
802
    QTest::keyClick(testWidget->viewport(), Qt::Key_Tab);
803
#ifdef WAITS
804
    QTest::qWait(50);
805
#endif
806
807
    // One more, and it should stay where it is
808
    QTest::keyClick(testWidget->viewport(), Qt::Key_Tab);
809
    QCOMPARE(testWidget->currentRow(), 0);
810
    QCOMPARE(testWidget->currentColumn(), 3);
811
812
    testWidget->setCurrentCell(3,3);
813
814
    // Now check backtab key
815
    QCOMPARE(testWidget->currentRow(), 3);
816
    QCOMPARE(testWidget->currentColumn(), 3);
817
    QTest::keyClick(testWidget->viewport(), Qt::Key_BackTab);
818
#ifdef WAITS
819
    QTest::qWait(50);
820
#endif
821
    QCOMPARE(testWidget->currentRow(), 3);
822
    QCOMPARE(testWidget->currentColumn(), 2);
823
    QTest::keyClick(testWidget->viewport(), Qt::Key_BackTab);
824
#ifdef WAITS
825
    QTest::qWait(50);
826
#endif
827
    QCOMPARE(testWidget->currentRow(), 3);
828
    QCOMPARE(testWidget->currentColumn(), 1);
829
    QTest::keyClick(testWidget->viewport(), Qt::Key_BackTab);
830
#ifdef WAITS
831
    QTest::qWait(50);
832
#endif
833
834
    // One more, and it should stay where it is
835
    QTest::keyClick(testWidget->viewport(), Qt::Key_BackTab);
836
    QCOMPARE(testWidget->currentRow(), 3);
837
    QCOMPARE(testWidget->currentColumn(), 0);
838
#ifdef WAITS
839
    QTest::qWait(50);
840
#endif
841
842
    testWidget->setCurrentCell(0, 0);
843
844
    // Now check enter key
845
    for (int row = 0; row < 3; ++row) {
846
        QCOMPARE(testWidget->currentRow(), row);
847
        QCOMPARE(testWidget->currentColumn(), 0);
848
        QTest::keyClick(testWidget->viewport(), Qt::Key_Enter);
849
#ifdef WAITS
850
        QTest::qWait(50);
851
#endif
852
    }
853
    // One more, and it should go to back
854
    QTest::keyClick(testWidget->viewport(), Qt::Key_Enter);
855
    QCOMPARE(testWidget->currentRow(), 0);
856
    QCOMPARE(testWidget->currentColumn(), 1);
857
}
858
859
void tst_Q3Table::cellNavigationWhileEditing()
860
{
861
    // This is basically the cellNavigation() test
862
    // with the current cell being edited before
863
    // navigation.
864
#if 0
865
    setupTableItems();
866
867
    int a, b;
868
    QPoint contentPos;
869
    // Check tab key first
870
    for (a = 0;a < 4;a++) {
871
	for (b = 0;b < 4;b++) {
872
	    QCOMPARE(testWidget->currentRow(),a);
873
	    QCOMPARE(testWidget->currentColumn(),b);
874
	    contentPos = QPoint(testWidget->columnPos(b) + 3, testWidget->rowPos(a) + 3);
875
	    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
876
		testWidget->contentsToViewport(contentPos));
877
	    if(a == 0 && b == 2) // On typing item
878
		QTest::keyClick(testWidget->viewport(), Qt::Key_A);
879
	    QTest::keyClick(testWidget->viewport(),Qt::Key_Tab);
880
	}
881
    }
882
    // One more should put it at the beginning again
883
    QTest::keyClick(testWidget->viewport(),Qt::Key_Tab);
884
    QCOMPARE(testWidget->currentRow(),0);
885
    QCOMPARE(testWidget->currentColumn(),0);
886
887
    testWidget->setCurrentCell(3,3);
888
    // Now check backtab key
889
    for (a = 3;a > -1;a--) {
890
	for (b = 3;b > -1;b--) {
891
	    QCOMPARE(testWidget->currentRow(),a);
892
	    QCOMPARE(testWidget->currentColumn(),b);
893
	    contentPos = QPoint(testWidget->columnPos(b) + 3, testWidget->rowPos(a) + 3);
894
	    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
895
		testWidget->contentsToViewport(contentPos));
896
	    if(a == 0 && b == 2) // On typing item
897
		QTest::keyClick(testWidget->viewport(), Qt::Key_A);
898
	    QTest::keyClick(testWidget->viewport(),Qt::Key_BackTab);
899
	}
900
    }
901
    // One more should put it at the end again
902
    QTest::keyClick(testWidget->viewport(),Qt::Key_BackTab);
903
    QCOMPARE(testWidget->currentRow(),3);
904
    QCOMPARE(testWidget->currentColumn(),3);
905
906
    testWidget->setCurrentCell(0,0);
907
    // Now check enter key
908
    for (a = 0;a < 4;a++) {
909
	for (b = 0;b < 4;b++) {
910
	    QCOMPARE(testWidget->currentColumn(),a);
911
	    QCOMPARE(testWidget->currentRow(),b);
912
	    contentPos = QPoint(testWidget->columnPos(a) + 3, testWidget->rowPos(b) + 3);
913
	    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
914
		testWidget->contentsToViewport(contentPos));
915
	    if(a == 0 && b == 2) // On typing item
916
		QTest::keyClick(testWidget->viewport(), Qt::Key_A);
917
	    QTest::keyClick(testWidget->viewport(),Qt::Key_Enter);
918
	}
919
    }
920
    // One more should put it at the beginning again
921
    QTest::keyClick(testWidget->viewport(),Qt::Key_Enter);
922
    QCOMPARE(testWidget->currentRow(),0);
923
    QCOMPARE(testWidget->currentColumn(),0);
924
925
    // Reset it back to the top
926
    contentPos = QPoint(testWidget->columnPos(0) + 3, testWidget->rowPos(0) + 3);
927
    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
928
	testWidget->contentsToViewport(contentPos));
929
930
    // Now check down key
931
    for (a = 0;a < 4;a++) {
932
	for (b = 0;b < 4;b++) {
933
	    QCOMPARE(testWidget->currentRow(),a);
934
	    QCOMPARE(testWidget->currentColumn(),b);
935
	    contentPos = QPoint(testWidget->columnPos(b) + 3, testWidget->rowPos(a) + 3);
936
	    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
937
		testWidget->contentsToViewport(contentPos));
938
	    if(a == 0 && b == 2) // On typing item
939
		QTest::keyClick(testWidget->viewport(), Qt::Key_A);
940
	    QTest::keyClick(testWidget->viewport(),Qt::Key_Down);
941
	    if (a == 3) {
942
		// Check it hasn't moved from the bottom even
943
		// after clicking down
944
		QCOMPARE(testWidget->currentRow(),a);
945
		QCOMPARE(testWidget->currentColumn(),b);
946
		// Put it in correct place for next check
947
		QTest::keyClick(testWidget->viewport(),Qt::Key_Home);
948
		QTest::keyClick(testWidget->viewport(),Qt::Key_Right);
949
	    }
950
	}
951
    }
952
953
    // Start at the bottom now
954
    contentPos = QPoint(testWidget->columnPos(0) + 3, testWidget->rowPos(3) + 3);
955
    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
956
	testWidget->contentsToViewport(contentPos));
957
958
    // Now check up key
959
    for (a = 3;a > -1;a--) {
960
	for (b = 3;b > -1;b--) {
961
	    QCOMPARE(testWidget->currentRow(),a);
962
	    QCOMPARE(testWidget->currentColumn(),b);
963
	    contentPos = QPoint(testWidget->columnPos(b) + 3, testWidget->rowPos(a) + 3);
964
	    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
965
		testWidget->contentsToViewport(contentPos));
966
	    if(a == 0 && b == 2) // On typing item
967
		QTest::keyClick(testWidget->viewport(), Qt::Key_A);
968
	    QTest::keyClick(testWidget->viewport(),Qt::Key_Up);
969
	    if (a == 0) {
970
		// Check it hasn't moved from the bottom even
971
		// after clicking down
972
		QCOMPARE(testWidget->currentRow(),a);
973
		QCOMPARE(testWidget->currentColumn(),b);
974
		// Put it in correct place for next check
975
		QTest::keyClick(testWidget->viewport(),Qt::Key_End);
976
		QTest::keyClick(testWidget->viewport(),Qt::Key_Right);
977
	    }
978
	}
979
    }
980
981
    // Reset it back to the top
982
    contentPos = QPoint(testWidget->columnPos(0) + 3, testWidget->rowPos(0) + 3);
983
    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
984
	testWidget->contentsToViewport(contentPos));
985
986
    // Now check right key
987
    for (a = 0;a < 4;a++) {
988
	for (b = 0;b < 4;b++) {
989
	    QCOMPARE(testWidget->currentRow(),a);
990
	    QCOMPARE(testWidget->currentColumn(),b);
991
	    contentPos = QPoint(testWidget->columnPos(b) + 3, testWidget->rowPos(a) + 3);
992
	    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
993
		testWidget->contentsToViewport(contentPos));
994
	    if(a == 0 && b == 2) // On typing item
995
		QTest::keyClick(testWidget->viewport(), Qt::Key_A);
996
	    QTest::keyClick(testWidget->viewport(),Qt::Key_Right);
997
	    if (b == 3) {
998
		// Check it hasn't moved from the bottom even
999
		// after clicking down
1000
		QCOMPARE(testWidget->currentRow(),a);
1001
		QCOMPARE(testWidget->currentColumn(),b);
1002
		// Put it in correct place for next check
1003
		QTest::keyClick(testWidget->viewport(),Qt::Key_Home);
1004
		QTest::keyClick(testWidget->viewport(),Qt::Key_Down);
1005
	    }
1006
	}
1007
    }
1008
1009
    // Start it at the far left
1010
    contentPos = QPoint(testWidget->columnPos(3) + 3, testWidget->rowPos(0) + 3);
1011
    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
1012
	testWidget->contentsToViewport(contentPos));
1013
1014
    // Now check up key
1015
    for (a = 3;a > -1;a--) {
1016
	for (b = 3;b > -1;b--) {
1017
	    QCOMPARE(testWidget->currentRow(),a);
1018
	    QCOMPARE(testWidget->currentColumn(),b);
1019
	    contentPos = QPoint(testWidget->columnPos(b) + 3, testWidget->rowPos(a) + 3);
1020
	    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoButton,
1021
		testWidget->contentsToViewport(contentPos));
1022
	    if(a == 0 && b == 2) // On typing item
1023
		QTest::keyClick(testWidget->viewport(), Qt::Key_A);
1024
	    QTest::keyClick(testWidget->viewport(),Qt::Key_Left);
1025
	    if (b == 0) {
1026
		// Check it hasn't moved from the bottom even
1027
		// after clicking down
1028
		QCOMPARE(testWidget->currentRow(),a);
1029
		QCOMPARE(testWidget->currentColumn(),b);
1030
		// Put it in correct place for next check
1031
		QTest::keyClick(testWidget->viewport(),Qt::Key_End);
1032
		QTest::keyClick(testWidget->viewport(),Qt::Key_Down);
1033
	    }
1034
	}
1035
    }
1036
#else
1037
    QSKIP( "This test currently fails on all versions", SkipAll);
1038
#endif
1039
}
1040
1041
void tst_Q3Table::removeRow_data()
1042
{
1043
    QTest::addColumn<Q3Table::SelectionMode>("selectionMode");
1044
1045
    QTest::newRow("NoSelection") << Q3Table::NoSelection;
1046
    QTest::newRow("SingleSelection") << Q3Table::Single;
1047
    QTest::newRow("MultiSelection") << Q3Table::Multi;
1048
    QTest::newRow("SingleRowSelection") << Q3Table::SingleRow;
1049
    QTest::newRow("MultiRowSelection") << Q3Table::MultiRow;
1050
}
1051
1052
1053
void tst_Q3Table::removeRow()
1054
{
1055
    QFETCH(Q3Table::SelectionMode, selectionMode);
1056
1057
#if 1
1058
    if(selectionMode == Q3Table::SingleRow
1059
       || selectionMode == Q3Table::MultiRow)
1060
	QSKIP("removeRow() is expected to fail in SingleRow/MultiRow selection modes in all versions", SkipAll);
1061
#endif
1062
    // This tests task 26419
1063
1064
1065
    setupTableItems();
1066
    testWidget->setSelectionMode(selectionMode);
1067
    for(int a = 3;a > -1;a--) {
1068
	QPoint contentPos(testWidget->columnPos(0) + 3, testWidget->rowPos(a) + 3);
1069
	QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoModifier,
1070
	    testWidget->contentsToViewport(contentPos));
1071
#ifdef WAITS
1072
    QTest::qWait(50);
1073
#endif
1074
	if (selectionMode != Q3Table::NoSelection) {
1075
	    Q3TableSelection ts = testWidget->selection(testWidget->currentSelection());
1076
	    QVERIFY(ts.isActive());
1077
	    QVERIFY(ts.topRow() == a);
1078
	    QVERIFY(ts.bottomRow() == a);
1079
	}
1080
	testWidget->removeRow(a);
1081
	// a is actually now the number of rows because the row sections are
1082
	// zero-based
1083
	QVERIFY(testWidget->numRows() == a);
1084
	QVERIFY(!testWidget->selection(testWidget->currentSelection()).isActive());
1085
    }
1086
}
1087
1088
1089
class SwapRowMemoryLeakTableItem : public Q3TableItem
1090
{
1091
public:
1092
    SwapRowMemoryLeakTableItem(Q3Table * table, const QString & text, bool * deletionFlag)
1093
	: Q3TableItem(table, OnTyping, text)
1094
    {
1095
	this->deletionFlag = deletionFlag;
1096
    }
1097
1098
    ~SwapRowMemoryLeakTableItem()
1099
    {
1100
	*deletionFlag = TRUE;
1101
    }
1102
1103
private:
1104
    bool * deletionFlag;
1105
};
1106
1107
1108
void tst_Q3Table::swapRowMemoryLeak()
1109
{
1110
    //Although this should fail due to code in Q3Table::swapRows() it dose not becuse it is saved
1111
    //in ~Q3Table
1112
    Q3Table * quickTable = new Q3Table(2, 1);
1113
1114
1115
    bool i1deletionFlag = FALSE;
1116
    SwapRowMemoryLeakTableItem * i1 = new SwapRowMemoryLeakTableItem(quickTable,"item 1", &i1deletionFlag);
1117
    quickTable->setItem(0, 0, i1);
1118
    bool i2deletionFlag = FALSE;
1119
    SwapRowMemoryLeakTableItem * i2 = new SwapRowMemoryLeakTableItem(quickTable,"item 2", &i2deletionFlag);
1120
    quickTable->setItem(1, 0, i2);
1121
1122
    quickTable->swapRows(0, 1);
1123
1124
   // quickTable->removeRow(0);
1125
1126
    delete quickTable;
1127
1128
    QVERIFY(i1deletionFlag);
1129
    QVERIFY(i2deletionFlag);
1130
}
1131
1132
void tst_Q3Table::insertRows_data()
1133
{
1134
    QTest::addColumn<int>("rowToInsertAt");
1135
    QTest::addColumn<int>("numberOfRowsToInsert");
1136
1137
    QTest::newRow("firstRowOneRow") << 1 << 1;
1138
    QTest::newRow("secondRowTenRows") << 2 << 10;
1139
    QTest::newRow("thirdRowNoRows") << 3 << 0;
1140
    QTest::newRow("zerothRowNegativeRows") << 0 << -1;
1141
}
1142
1143
void tst_Q3Table::insertRows()
1144
{
1145
    QFETCH(int, rowToInsertAt);
1146
    QFETCH(int, numberOfRowsToInsert);
1147
1148
    int i = 0;
1149
    for (i = 0;i < 4;i++)
1150
        testWidget->setText(i, 0, QString("Item %0,0").arg(i));
1151
1152
    testWidget->insertRows(rowToInsertAt, numberOfRowsToInsert);
1153
    if(numberOfRowsToInsert <= 0) {
1154
	QVERIFY(testWidget->numRows() == 4);
1155
    } else {
1156
	QVERIFY(testWidget->numRows() == 4 + numberOfRowsToInsert);
1157
    }
1158
1159
    int rowNumber = 0;
1160
    for (i = 0;i < rowToInsertAt;i++) {
1161
	QCOMPARE(testWidget->text(i, 0), QString("Item %0,0").arg(rowNumber));
1162
	rowNumber++;
1163
    }
1164
1165
    if (numberOfRowsToInsert > 0) {
1166
	for (i = rowToInsertAt;i < rowToInsertAt + numberOfRowsToInsert;i++)
1167
	    QCOMPARE(testWidget->text(i, 0), QString());
1168
1169
	for (i = rowToInsertAt + numberOfRowsToInsert;i < 4 + numberOfRowsToInsert;i++) {
1170
	    QCOMPARE(testWidget->text(i, 0), QString("Item %0,0").arg(rowNumber));
1171
	    rowNumber++;
1172
	}
1173
    }
1174
}
1175
1176
class EditCheckQ3Table : public Q3Table
1177
{
1178
public:
1179
    int endEditCount;
1180
    int beginEditCount;
1181
1182
    EditCheckQ3Table(int r, int c, QWidget *parent = 0, const char *name = 0)
1183
        : Q3Table(r, c, parent, name)
1184
    {
1185
	endEditCount = beginEditCount = 0;
1186
    }
1187
protected:
1188
    void endEdit(int row, int col, bool accept, bool replace)
1189
    {
1190
	endEditCount++;
1191
	Q3Table::endEdit(row, col, accept, replace);
1192
    }
1193
    QWidget * beginEdit(int row, int col, bool replace)
1194
    {
1195
	beginEditCount++;
1196
	return Q3Table::beginEdit(row, col, replace);
1197
    }
1198
};
1199
1200
void tst_Q3Table::editCheck()
1201
{
1202
    // Test for task 28086
1203
#if 1
1204
    QSKIP("This test currently fails on all versions", SkipAll);
1205
#endif
1206
1207
    EditCheckQ3Table table(10, 10, 0);
1208
    table.show();
1209
    QApplication::setActiveWindow(&table);
1210
    QTest::qWaitForWindowShown(&table);
1211
    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&table));
1212
    table.setCurrentCell(0, 0);
1213
#ifdef WAITS
1214
    QTest::qWait(50);
1215
#endif
1216
    QTest::keyClick(table.viewport(), Qt::Key_T);
1217
#ifdef WAITS
1218
    QTest::qWait(50);
1219
#endif
1220
    // After the first keyevent, the table starts editing the item
1221
    QLineEdit *le = qFindChild<QLineEdit *>(testWidget->viewport(), "qt_lineeditor");
1222
#ifdef WAITS
1223
    QTest::qWait(50);
1224
#endif
1225
    QTest::keyClick(le, Qt::Key_Enter);
1226
    le = 0;
1227
#ifdef WAITS
1228
    QTest::qWait(50);
1229
#endif
1230
    QCOMPARE(table.beginEditCount, 1);
1231
    QEXPECT_FAIL("", "this fails because endEdit is called for the old current item when we set a new one", Abort);
1232
    QCOMPARE(table.endEditCount, 1);
1233
}
1234
1235
void tst_Q3Table::setCellWidgetFocus()
1236
{
1237
#define CELLWIDGET_CHEAT 1
1238
    // Test for task 27683
1239
    int numRows = testWidget->numRows();
1240
    int numCols = testWidget->numCols();
1241
    testWidget->setNumRows(1);
1242
    testWidget->setNumCols(1);
1243
#if CELLWIDGET_CHEAT
1244
    qApp->processEvents();
1245
#endif
1246
    QLineEdit *lineedit = new QLineEdit(testWidget);
1247
    testWidget->setCellWidget(0, 0, lineedit);
1248
    testWidget->show();
1249
    qApp->setActiveWindow(testWidget);
1250
    lineedit->setFocus();
1251
    QVERIFY(lineedit->hasFocus());
1252
    testWidget->setNumRows(numRows);
1253
    testWidget->setNumCols(numCols);
1254
}
1255
1256
void tst_Q3Table::selectionWithMouse_data()
1257
{
1258
    QTest::addColumn<QPoint>("clickPos");
1259
    QTest::addColumn<Q3Table::SelectionMode>("selectionMode");
1260
    QTest::addColumn<int>("numSelections");
1261
    QTest::addColumn<bool>("activeSelection");
1262
    QTest::addColumn<int>("topRow");
1263
    QTest::addColumn<int>("bottomRow");
1264
    QTest::addColumn<int>("leftCol");
1265
    QTest::addColumn<int>("rightCol");
1266
1267
    QTest::newRow("NoSelection") << QPoint(20, 15) << Q3Table::NoSelection << 0 << FALSE << -1 << -1 << -1 << -1;
1268
    QTest::newRow("SingleSelection") << QPoint(20, 15) << Q3Table::Single << 1 << TRUE << 0 << 0 << 0 << 0;
1269
    QTest::newRow("MultiSelection") << QPoint(20, 15) << Q3Table::Multi << 1 << TRUE << 0 << 0 << 0 << 0;
1270
    QTest::newRow("SingleRowSelection") << QPoint(20, 15) << Q3Table::SingleRow << 1 << TRUE << 0 << 0 << 0 << 3;
1271
    QTest::newRow("MultiRowSelection") << QPoint(20, 15) << Q3Table::MultiRow << 1 << TRUE << 0 << 0 << 0 << 3;
1272
}
1273
1274
void tst_Q3Table::selectionWithMouse()
1275
{
1276
    QFETCH(QPoint, clickPos);
1277
    QFETCH(Q3Table::SelectionMode, selectionMode);
1278
    QFETCH(int, numSelections);
1279
    QFETCH(bool, activeSelection);
1280
    QFETCH(int, topRow);
1281
    QFETCH(int, bottomRow);
1282
    QFETCH(int, leftCol);
1283
    QFETCH(int, rightCol);
1284
1285
    testWidget->setSelectionMode((Q3Table::SelectionMode)selectionMode);
1286
#ifdef WAITS
1287
    QTest::qWait(50);
1288
#endif
1289
    QTest::mouseClick(testWidget->viewport(), Qt::LeftButton, Qt::NoModifier, clickPos);
1290
#ifdef WAITS
1291
    QTest::qWait(50);
1292
#endif
1293
    QVERIFY(testWidget->numSelections() == numSelections);
1294
    Q3TableSelection ts = testWidget->selection(testWidget->currentSelection());
1295
    QVERIFY(ts.isActive() == activeSelection);
1296
    if (activeSelection) {
1297
	QVERIFY(ts.topRow() == topRow);
1298
	QVERIFY(ts.bottomRow() == bottomRow);
1299
	QVERIFY(ts.leftCol() == leftCol);
1300
	QVERIFY(ts.rightCol() == rightCol);
1301
    }
1302
}
1303
1304
class TimeTableItem : public Q3TableItem
1305
{
1306
public:
1307
    TimeTableItem(Q3Table *parent=0)
1308
	: Q3TableItem(parent, Q3TableItem::OnTyping, ""),
1309
	  editorWasTimeEdit(false)
1310
    { setReplaceable(false); }
1311
1312
    QWidget* createEditor() const
1313
    {
1314
        return new Q3TimeEdit(table()->viewport(), "time_edit");
1315
    }
1316
1317
    void setContentFromEditor(QWidget* widget)
1318
    {
1319
        Q3TimeEdit *time_edit = ::qobject_cast<Q3TimeEdit*>(widget);
1320
	if (!time_edit) {
1321
	    editorWasTimeEdit = false;
1322
	    Q3TableItem::setContentFromEditor(widget);
1323
	    return;
1324
	}
1325
	editorWasTimeEdit = true;
1326
        QTime res = time_edit->time();
1327
        setText(QString::number(QTime().secsTo(res)));
1328
    }
1329
1330
    bool editorWasTimeEdit;
1331
};
1332
1333
void tst_Q3Table::onValueChanged(int, int)
1334
{
1335
    isValueChanged = true;
1336
}
1337
1338
void tst_Q3Table::valueChanged()
1339
{
1340
    // task 27496
1341
    isValueChanged = false;
1342
    TimeTableItem *ti = new TimeTableItem(testWidget);
1343
    testWidget->setItem(0, 0, ti);
1344
    connect(testWidget,SIGNAL(valueChanged(int,int)),this,SLOT(onValueChanged(int,int)));
1345
    testWidget->show();
1346
    QApplication::setActiveWindow(testWidget);
1347
    QTest::qWaitForWindowShown(testWidget);
1348
    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(testWidget));
1349
#ifdef WAITS
1350
    QTest::qWait(50);
1351
#endif
1352
    QTest::keyClick(testWidget->viewport(), Qt::Key_1);
1353
#ifdef WAITS
1354
    QTest::qWait(50);
1355
#endif
1356
    QTRY_VERIFY(qApp->focusWidget());
1357
    QTest::keyClick(qApp->focusWidget(), Qt::Key_Enter);
1358
#ifdef WAITS
1359
    QTest::qWait(50);
1360
#endif
1361
    QVERIFY(ti->editorWasTimeEdit);
1362
    disconnect(testWidget,SIGNAL(valueChanged(int,int)),this,SLOT(onValueChanged(int,int)));
1363
}
1364
1365
void tst_Q3Table::numSelections()
1366
{
1367
    // task 28017
1368
    int numRows = testWidget->numRows();
1369
    int numCols = testWidget->numCols();
1370
    testWidget->setNumRows(10);
1371
    testWidget->setNumCols(10);
1372
    for (int i=0;i<10;++i)
1373
	for (int j=0;j<10;++j)
1374
	    testWidget->setItem(i,j,new Q3TableItem(testWidget,Q3TableItem::OnTyping,"Item"));
1375
    QCOMPARE(testWidget->numSelections(),0);
1376
    testWidget->clearSelection();
1377
    QCOMPARE(testWidget->numSelections(),0);
1378
    testWidget->selectRow(2);
1379
    QCOMPARE(testWidget->numSelections(),1);
1380
    testWidget->selectRow(4);
1381
    QCOMPARE(testWidget->numSelections(),2);
1382
    testWidget->selectRow(5);
1383
    QCOMPARE(testWidget->numSelections(),3);
1384
    testWidget->clearSelection();
1385
    QCOMPARE(testWidget->numSelections(),0);
1386
    testWidget->setNumRows(numRows);
1387
    testWidget->setNumCols(numCols);
1388
}
1389
1390
void tst_Q3Table::dateTimeEdit()
1391
{
1392
    // task 29002
1393
    TimeTableItem *ti = new TimeTableItem(testWidget);
1394
    testWidget->setItem(0, 0, ti);
1395
    testWidget->show();
1396
    QApplication::setActiveWindow(testWidget);
1397
    QTest::qWaitForWindowShown(testWidget);
1398
    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(testWidget));
1399
#ifdef WAITS
1400
    QTest::qWait(50);
1401
#endif
1402
    QTest::keyClick(testWidget->viewport(), Qt::Key_1);
1403
#ifdef WAITS
1404
    QTest::qWait(50);
1405
#endif
1406
    QTRY_VERIFY(qApp->focusWidget());
1407
    QTest::keyClick(qApp->focusWidget(), Qt::Key_Enter);
1408
#ifdef WAITS
1409
    QTest::qWait(50);
1410
#endif
1411
    QVERIFY(ti->editorWasTimeEdit);
1412
}
1413
1414
void tst_Q3Table::moreNumSelections_data()
1415
{
1416
    QTest::addColumn<Q3Table::SelectionMode>("selectionMode");
1417
    QTest::addColumn<int>("numSelectionsBeforeAnyRowClicked");
1418
    QTest::addColumn<int>("numSelectionsAfter1stRowClicked");
1419
    QTest::addColumn<int>("numSelectionsAfter3rdRowClicked");
1420
    QTest::addColumn<int>("numSelectionsAfter3rdRowClickedAgain");
1421
1422
    QTest::newRow("NoSelection") << Q3Table::NoSelection << 0 << 0 << 0 << 0;
1423
    QTest::newRow("SingleSelection") << Q3Table::Single << 0 << 1 << 1 << 1;
1424
    QTest::newRow("MultiSelection") << Q3Table::Multi << 0 << 1 << 2 << 2;
1425
    // in row selection modes the current item is always selected
1426
    QTest::newRow("SingleRowSelection") << Q3Table::SingleRow << 1 << 1 << 1 << 1;
1427
    QTest::newRow("MultiRowSelection") << Q3Table::MultiRow << 1 << 1 << 2 << 2;
1428
}
1429
1430
void tst_Q3Table::moreNumSelections()
1431
{
1432
#if 0
1433
    QFETCH(Q3Table::SelectionMode, selectionMode);
1434
    QFETCH(int, numSelectionsBeforeAnyRowClicked);
1435
    QFETCH(int, numSelectionsAfter1stRowClicked);
1436
    QFETCH(int, numSelectionsAfter3rdRowClicked);
1437
    QFETCH(int, numSelectionsAfter3rdRowClickedAgain);
1438
1439
    if((Q3Table::SelectionMode)selectionMode == Q3Table::Multi ||
1440
       (Q3Table::SelectionMode)selectionMode == Q3Table::MultiRow) {
1441
	QSKIP("numSelections() currently fails on all versions", SkipAll);
1442
    }
1443
1444
    testWidget->setSelectionMode((Q3Table::SelectionMode)selectionMode);
1445
    QCOMPARE(testWidget->numSelections(), numSelectionsBeforeAnyRowClicked);
1446
#ifdef WAITS
1447
    QTest::qWait(50);
1448
#endif
1449
1450
    QTest::mouseClick(testWidget->verticalHeader(), QtTestCase::LeftButton, QtTestCase::NoButton,
1451
	       QPoint(5, testWidget->verticalHeader()->sectionPos(0)+2));
1452
#ifdef WAITS
1453
    QTest::qWait(50);
1454
#endif
1455
    QCOMPARE(testWidget->numSelections(), numSelectionsAfter1stRowClicked);
1456
1457
    QTest::mouseClick(testWidget->verticalHeader(), QtTestCase::LeftButton, QtTestCase::NoButton,
1458
	       QPoint(5, testWidget->verticalHeader()->sectionPos(2)+2));
1459
#ifdef WAITS
1460
    QTest::qWait(50);
1461
#endif
1462
    QEXPECT_FAIL("MultiSelection", "Will not fix this for 3.x", Abort);
1463
    QEXPECT_FAIL("MultiRowSelection", "Will not fix this for 3.x", Abort);
1464
    QCOMPARE(testWidget->numSelections(), numSelectionsAfter3rdRowClicked);
1465
1466
    QTest::mouseClick(testWidget->verticalHeader(), QtTestCase::LeftButton, QtTestCase::NoButton,
1467
	       QPoint(5, testWidget->verticalHeader()->sectionPos(2)+2));
1468
#ifdef WAITS
1469
    QTest::qWait(50);
1470
#endif
1471
    QCOMPARE(testWidget->numSelections(), numSelectionsAfter3rdRowClickedAgain);
1472
#else
1473
    QSKIP( "This test is expected to fail on >= 3.2", SkipAll);
1474
#endif
1475
}
1476
1477
void tst_Q3Table::headerSwapIconset()
1478
{
1479
#if 0
1480
    QIconSet is0, is1;
1481
    QString hl0, hl1;
1482
    if (testWidget->horizontalHeader()->iconSet(0))
1483
	is0 = *testWidget->horizontalHeader()->iconSet(0);
1484
    hl0 = testWidget->horizontalHeader()->label(0);
1485
    if (testWidget->horizontalHeader()->iconSet(1))
1486
	is1 = *testWidget->horizontalHeader()->iconSet(1);
1487
    hl1 = testWidget->horizontalHeader()->label(1);
1488
1489
    testWidget->show();
1490
    testWidget->horizontalHeader()->setLabel(1, QPixmap(fileopen), "Test");
1491
    testWidget->swapColumns(0, 1, true);
1492
    QVERIFY(!testWidget->horizontalHeader()->iconSet(1)
1493
	   || testWidget->horizontalHeader()->iconSet(1)->isNull());
1494
1495
    testWidget->horizontalHeader()->setLabel(0, is0, hl0);
1496
    testWidget->horizontalHeader()->setLabel(1, is1, hl1);
1497
#else
1498
    QSKIP( "This test fails in Qt 4", SkipAll);
1499
#endif
1500
}
1501
1502
1503
class EscapeKeyDialog : public QDialog
1504
{
1505
public:
1506
    EscapeKeyDialog() : QDialog(0), recievedEscape(false) {}
1507
    bool recievedEscape;
1508
protected:
1509
    void keyPressEvent(QKeyEvent *e)
1510
    {
1511
	if (e->key() == Qt::Key_Escape)
1512
	    recievedEscape = TRUE;
1513
	QDialog::keyPressEvent(e);
1514
    }
1515
};
1516
1517
void tst_Q3Table::propagateEscapeKey()
1518
{
1519
#if 0
1520
    EscapeKeyDialog ekd;
1521
    Q3Table *table = new Q3Table(5, 5, &ekd);
1522
    ekd.show();
1523
#ifdef Q_WS_X11
1524
    qt_x11_wait_for_window_manager(&ekd);
1525
#endif
1526
    table->setCurrentCell(0,0);
1527
#ifdef WAITS
1528
    QTest::qWait(50);
1529
#endif
1530
    QTest::keyClick(table->viewport(), Qt::Key_A);
1531
#ifdef WAITS
1532
    QTest::qWait(50);
1533
#endif
1534
    QTest::keyClick(table->viewport(), Qt::Key_Escape);
1535
#ifdef WAITS
1536
    QTest::qWait(50);
1537
#endif
1538
    QVERIFY(!ekd.recievedEscape);
1539
    QVERIFY(table->text(0,0).isEmpty());
1540
    QTest::keyClick(table->viewport(), Qt::Key_Escape);
1541
#ifdef WAITS
1542
    QTest::qWait(50);
1543
#endif
1544
    QVERIFY(ekd.recievedEscape);
1545
#else
1546
    QSKIP("This test fails for all versions of Qt", SkipAll);
1547
#endif
1548
}
1549
1550
void tst_Q3Table::removeSelection_selectionChanged()
1551
{
1552
    int numRows = testWidget->numRows();
1553
    int numCols = testWidget->numCols();
1554
    testWidget->setNumRows(3);
1555
    testWidget->setNumCols(3);
1556
    Q3TableSelection sel(1, 1, 2, 2);
1557
    testWidget->addSelection(sel);
1558
    QObject::connect(testWidget, SIGNAL(selectionChanged()),
1559
		     this, SLOT(selectionWasChanged()));
1560
    receivedSelectionChanged = false;
1561
    testWidget->removeSelection(sel);
1562
    qApp->processEvents();
1563
    QVERIFY(receivedSelectionChanged);
1564
    testWidget->setNumRows(numRows);
1565
    testWidget->setNumCols(numCols);
1566
    QObject::disconnect(testWidget, SIGNAL(selectionChanged()),
1567
			this, SLOT(selectionWasChanged()));
1568
}
1569
1570
void tst_Q3Table::selectionWasChanged()
1571
{
1572
    receivedSelectionChanged = true;
1573
}
1574
1575
QTEST_MAIN(tst_Q3Table)
1576
#include "tst_q3table.moc"