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

« back to all changes in this revision

Viewing changes to tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the test suite of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
 
 
43
#include <QtTest/QtTest>
 
44
 
 
45
#include <qabstractitemview.h>
 
46
#include <qstandarditemmodel.h>
 
47
#include <qapplication.h>
 
48
#include <qlistview.h>
 
49
#include <qlistwidget.h>
 
50
#include <qtableview.h>
 
51
#include <qtablewidget.h>
 
52
#include <qtreeview.h>
 
53
#include <qtreewidget.h>
 
54
#include <qheaderview.h>
 
55
#include <qspinbox.h>
 
56
#include <qitemdelegate.h>
 
57
#include <qpushbutton.h>
 
58
#include <qscrollbar.h>
 
59
#include <qboxlayout.h>
 
60
#include <qlineedit.h>
 
61
 
 
62
// Will try to wait for the condition while allowing event processing
 
63
// for a maximum of 5 seconds.
 
64
#define TRY_COMPARE(expr, expected) \
 
65
    do { \
 
66
        const int step = 50; \
 
67
        for (int q = 0; q < 5000 && ((expr) != (expected)); q+=step) { \
 
68
            QTest::qWait(step); \
 
69
        } \
 
70
        QCOMPARE(expr, expected); \
 
71
    } while(0)
 
72
 
 
73
static inline void setFrameless(QWidget *w)
 
74
{
 
75
    Qt::WindowFlags flags = w->windowFlags();
 
76
    flags |= Qt::FramelessWindowHint;
 
77
    flags &= ~(Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
 
78
    w->setWindowFlags(flags);
 
79
}
 
80
 
 
81
class TestView : public QAbstractItemView
 
82
{
 
83
    Q_OBJECT
 
84
public:
 
85
    inline void tst_dataChanged(const QModelIndex &tl, const QModelIndex &br)
 
86
        { dataChanged(tl, br); }
 
87
    inline void tst_setHorizontalStepsPerItem(int steps)
 
88
        { setHorizontalStepsPerItem(steps); }
 
89
    inline int tst_horizontalStepsPerItem() const
 
90
        { return horizontalStepsPerItem(); }
 
91
    inline void tst_setVerticalStepsPerItem(int steps)
 
92
        { setVerticalStepsPerItem(steps); }
 
93
    inline int tst_verticalStepsPerItem() const
 
94
        { return verticalStepsPerItem(); }
 
95
 
 
96
    inline void tst_rowsInserted(const QModelIndex &parent, int start, int end)
 
97
        { rowsInserted(parent, start, end); }
 
98
    inline void tst_rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
 
99
        { rowsAboutToBeRemoved(parent, start, end); }
 
100
    inline void tst_selectionChanged(const QItemSelection &selected,
 
101
                                     const QItemSelection &deselected)
 
102
        { selectionChanged(selected, deselected); }
 
103
    inline void tst_currentChanged(const QModelIndex &current, const QModelIndex &previous)
 
104
        { currentChanged(current, previous); }
 
105
    inline void tst_updateEditorData()
 
106
        { updateEditorData(); }
 
107
    inline void tst_updateEditorGeometries()
 
108
        { updateEditorGeometries(); }
 
109
    inline void tst_updateGeometries()
 
110
        { updateGeometries(); }
 
111
    inline void tst_verticalScrollbarAction(int action)
 
112
        { verticalScrollbarAction(action); }
 
113
    inline void tst_horizontalScrollbarAction(int action)
 
114
        { horizontalScrollbarAction(action); }
 
115
    inline void tst_verticalScrollbarValueChanged(int value)
 
116
        { verticalScrollbarValueChanged(value); }
 
117
    inline void tst_horizontalScrollbarValueChanged(int value)
 
118
        { horizontalScrollbarValueChanged(value); }
 
119
    inline void tst_closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
 
120
        { closeEditor(editor, hint); }
 
121
    inline void tst_commitData(QWidget *editor)
 
122
        { commitData(editor); }
 
123
    inline void tst_editorDestroyed(QObject *editor)
 
124
        { editorDestroyed(editor); }
 
125
    enum tst_CursorAction {
 
126
        MoveUp = QAbstractItemView::MoveUp,
 
127
        MoveDown = QAbstractItemView::MoveDown,
 
128
        MoveLeft = QAbstractItemView::MoveLeft,
 
129
        MoveRight = QAbstractItemView::MoveRight,
 
130
        MoveHome = QAbstractItemView::MoveHome,
 
131
        MoveEnd = QAbstractItemView::MoveEnd,
 
132
        MovePageUp = QAbstractItemView::MovePageUp,
 
133
        MovePageDown = QAbstractItemView::MovePageDown,
 
134
        MoveNext = QAbstractItemView::MoveNext,
 
135
        MovePrevious = QAbstractItemView::MovePrevious
 
136
    };
 
137
    inline QModelIndex tst_moveCursor(tst_CursorAction cursorAction,
 
138
                                      Qt::KeyboardModifiers modifiers)
 
139
        { return moveCursor(QAbstractItemView::CursorAction(cursorAction), modifiers); }
 
140
    inline int tst_horizontalOffset() const
 
141
        { return horizontalOffset(); }
 
142
    inline int tst_verticalOffset() const
 
143
        { return verticalOffset(); }
 
144
    inline bool tst_isIndexHidden(const QModelIndex &index) const
 
145
        { return isIndexHidden(index); }
 
146
    inline void tst_setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
 
147
        { setSelection(rect, command); }
 
148
    inline QRegion tst_visualRegionForSelection(const QItemSelection &selection) const
 
149
        { return visualRegionForSelection(selection); }
 
150
    inline QModelIndexList tst_selectedIndexes() const
 
151
        { return selectedIndexes(); }
 
152
    inline bool tst_edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
 
153
        { return edit(index, trigger, event); }
 
154
    inline QItemSelectionModel::SelectionFlags tst_selectionCommand(const QModelIndex &index,
 
155
                                                                    const QEvent *event = 0) const
 
156
        { return selectionCommand(index, event); }
 
157
#ifndef QT_NO_DRAGANDDROP
 
158
    inline void tst_startDrag(Qt::DropActions supportedActions)
 
159
        { startDrag(supportedActions); }
 
160
#endif
 
161
    inline QStyleOptionViewItem tst_viewOptions() const
 
162
        { return viewOptions(); }
 
163
    enum tst_State {
 
164
        NoState = QAbstractItemView::NoState,
 
165
        DraggingState = QAbstractItemView::DraggingState,
 
166
        DragSelectingState = QAbstractItemView::DragSelectingState,
 
167
        EditingState = QAbstractItemView::EditingState,
 
168
        ExpandingState = QAbstractItemView::ExpandingState,
 
169
        CollapsingState = QAbstractItemView::CollapsingState
 
170
    };
 
171
    inline tst_State tst_state() const
 
172
        { return (tst_State)state(); }
 
173
    inline void tst_setState(tst_State state)
 
174
        { setState(QAbstractItemView::State(state)); }
 
175
    inline void tst_startAutoScroll()
 
176
        { startAutoScroll(); }
 
177
    inline void tst_stopAutoScroll()
 
178
        { stopAutoScroll(); }
 
179
    inline void tst_doAutoScroll()
 
180
        { doAutoScroll(); }
 
181
};
 
182
 
 
183
class tst_QAbstractItemView : public QObject
 
184
{
 
185
    Q_OBJECT
 
186
 
 
187
public:
 
188
 
 
189
    tst_QAbstractItemView();
 
190
    virtual ~tst_QAbstractItemView();
 
191
    void basic_tests(TestView *view);
 
192
 
 
193
public slots:
 
194
    void initTestCase();
 
195
    void cleanupTestCase();
 
196
 
 
197
private slots:
 
198
    void getSetCheck();
 
199
    void emptyModels_data();
 
200
    void emptyModels();
 
201
    void setModel_data();
 
202
    void setModel();
 
203
    void noModel();
 
204
    void dragSelect();
 
205
    void rowDelegate();
 
206
    void columnDelegate();
 
207
    void selectAll();
 
208
    void ctrlA();
 
209
    void persistentEditorFocus();
 
210
    void setItemDelegate();
 
211
    void setItemDelegate_data();
 
212
        // The dragAndDrop() test doesn't work, and is thus disabled on Mac and Windows
 
213
        // for the following reasons:
 
214
        //   Mac: use of GetCurrentEventButtonState() in QDragManager::drag()
 
215
        //   Win: unknown reason
 
216
#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
 
217
#if 0
 
218
    void dragAndDrop();
 
219
    void dragAndDropOnChild();
 
220
#endif
 
221
#endif
 
222
    void noFallbackToRoot();
 
223
    void setCurrentIndex_data();
 
224
    void setCurrentIndex();
 
225
 
 
226
    void task221955_selectedEditor();
 
227
    void task250754_fontChange();
 
228
    void task200665_itemEntered();
 
229
    void task257481_emptyEditor();
 
230
    void shiftArrowSelectionAfterScrolling();
 
231
    void shiftSelectionAfterRubberbandSelection();
 
232
    void ctrlRubberbandSelection();
 
233
    void QTBUG6407_extendedSelection();
 
234
    void QTBUG6753_selectOnSelection();
 
235
    void testDelegateDestroyEditor();
 
236
    void testClickedSignal();
 
237
    void testChangeEditorState();
 
238
};
 
239
 
 
240
class MyAbstractItemDelegate : public QAbstractItemDelegate
 
241
{
 
242
public:
 
243
    MyAbstractItemDelegate() : QAbstractItemDelegate() { calledVirtualDtor = false; }
 
244
    void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const {}
 
245
    QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return QSize(); }
 
246
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
 
247
    {
 
248
        openedEditor = new QWidget(parent);
 
249
        return openedEditor;
 
250
    }
 
251
    void destroyEditor(QWidget *editor, const QModelIndex &) const
 
252
    {
 
253
        calledVirtualDtor = true;
 
254
        editor->deleteLater();
 
255
    }
 
256
 
 
257
    mutable bool calledVirtualDtor;
 
258
    mutable QWidget *openedEditor;
 
259
};
 
260
 
 
261
// Testing get/set functions
 
262
void tst_QAbstractItemView::getSetCheck()
 
263
{
 
264
    QListView view;
 
265
    TestView *obj1 = reinterpret_cast<TestView*>(&view);
 
266
    // QAbstractItemDelegate * QAbstractItemView::itemDelegate()
 
267
    // void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *)
 
268
    MyAbstractItemDelegate *var1 = new MyAbstractItemDelegate;
 
269
    obj1->setItemDelegate(var1);
 
270
    QCOMPARE((QAbstractItemDelegate*)var1, obj1->itemDelegate());
 
271
    obj1->setItemDelegate((QAbstractItemDelegate *)0);
 
272
    QCOMPARE((QAbstractItemDelegate *)0, obj1->itemDelegate());
 
273
    delete var1;
 
274
 
 
275
    // EditTriggers QAbstractItemView::editTriggers()
 
276
    // void QAbstractItemView::setEditTriggers(EditTriggers)
 
277
    obj1->setEditTriggers(QAbstractItemView::EditTriggers(QAbstractItemView::NoEditTriggers));
 
278
    QCOMPARE(QAbstractItemView::EditTriggers(QAbstractItemView::NoEditTriggers), obj1->editTriggers());
 
279
    obj1->setEditTriggers(QAbstractItemView::EditTriggers(QAbstractItemView::CurrentChanged));
 
280
    QCOMPARE(QAbstractItemView::EditTriggers(QAbstractItemView::CurrentChanged), obj1->editTriggers());
 
281
    obj1->setEditTriggers(QAbstractItemView::EditTriggers(QAbstractItemView::DoubleClicked));
 
282
    QCOMPARE(QAbstractItemView::EditTriggers(QAbstractItemView::DoubleClicked), obj1->editTriggers());
 
283
    obj1->setEditTriggers(QAbstractItemView::EditTriggers(QAbstractItemView::SelectedClicked));
 
284
    QCOMPARE(QAbstractItemView::EditTriggers(QAbstractItemView::SelectedClicked), obj1->editTriggers());
 
285
    obj1->setEditTriggers(QAbstractItemView::EditTriggers(QAbstractItemView::EditKeyPressed));
 
286
    QCOMPARE(QAbstractItemView::EditTriggers(QAbstractItemView::EditKeyPressed), obj1->editTriggers());
 
287
    obj1->setEditTriggers(QAbstractItemView::EditTriggers(QAbstractItemView::AnyKeyPressed));
 
288
    QCOMPARE(QAbstractItemView::EditTriggers(QAbstractItemView::AnyKeyPressed), obj1->editTriggers());
 
289
    obj1->setEditTriggers(QAbstractItemView::EditTriggers(QAbstractItemView::AllEditTriggers));
 
290
    QCOMPARE(QAbstractItemView::EditTriggers(QAbstractItemView::AllEditTriggers), obj1->editTriggers());
 
291
 
 
292
    // bool QAbstractItemView::tabKeyNavigation()
 
293
    // void QAbstractItemView::setTabKeyNavigation(bool)
 
294
    obj1->setTabKeyNavigation(false);
 
295
    QCOMPARE(false, obj1->tabKeyNavigation());
 
296
    obj1->setTabKeyNavigation(true);
 
297
    QCOMPARE(true, obj1->tabKeyNavigation());
 
298
 
 
299
    // bool QAbstractItemView::dragEnabled()
 
300
    // void QAbstractItemView::setDragEnabled(bool)
 
301
#ifndef QT_NO_DRAGANDDROP
 
302
    obj1->setDragEnabled(false);
 
303
    QCOMPARE(false, obj1->dragEnabled());
 
304
    obj1->setDragEnabled(true);
 
305
    QCOMPARE(true, obj1->dragEnabled());
 
306
#endif
 
307
    // bool QAbstractItemView::alternatingRowColors()
 
308
    // void QAbstractItemView::setAlternatingRowColors(bool)
 
309
    obj1->setAlternatingRowColors(false);
 
310
    QCOMPARE(false, obj1->alternatingRowColors());
 
311
    obj1->setAlternatingRowColors(true);
 
312
    QCOMPARE(true, obj1->alternatingRowColors());
 
313
 
 
314
    // State QAbstractItemView::state()
 
315
    // void QAbstractItemView::setState(State)
 
316
    obj1->tst_setState(TestView::tst_State(TestView::NoState));
 
317
    QCOMPARE(TestView::tst_State(TestView::NoState), obj1->tst_state());
 
318
    obj1->tst_setState(TestView::tst_State(TestView::DraggingState));
 
319
    QCOMPARE(TestView::tst_State(TestView::DraggingState), obj1->tst_state());
 
320
    obj1->tst_setState(TestView::tst_State(TestView::DragSelectingState));
 
321
    QCOMPARE(TestView::tst_State(TestView::DragSelectingState), obj1->tst_state());
 
322
    obj1->tst_setState(TestView::tst_State(TestView::EditingState));
 
323
    QCOMPARE(TestView::tst_State(TestView::EditingState), obj1->tst_state());
 
324
    obj1->tst_setState(TestView::tst_State(TestView::ExpandingState));
 
325
    QCOMPARE(TestView::tst_State(TestView::ExpandingState), obj1->tst_state());
 
326
    obj1->tst_setState(TestView::tst_State(TestView::CollapsingState));
 
327
    QCOMPARE(TestView::tst_State(TestView::CollapsingState), obj1->tst_state());
 
328
 
 
329
    // QWidget QAbstractScrollArea::viewport()
 
330
    // void setViewport(QWidget*)
 
331
    QWidget *vp = new QWidget;
 
332
    obj1->setViewport(vp);
 
333
    QCOMPARE(vp, obj1->viewport());
 
334
 
 
335
    QCOMPARE(16, obj1->autoScrollMargin());
 
336
    obj1->setAutoScrollMargin(20);
 
337
    QCOMPARE(20, obj1->autoScrollMargin());
 
338
    obj1->setAutoScrollMargin(16);
 
339
    QCOMPARE(16, obj1->autoScrollMargin());
 
340
}
 
341
 
 
342
tst_QAbstractItemView::tst_QAbstractItemView()
 
343
{
 
344
}
 
345
 
 
346
tst_QAbstractItemView::~tst_QAbstractItemView()
 
347
{
 
348
}
 
349
 
 
350
void tst_QAbstractItemView::initTestCase()
 
351
{
 
352
#ifdef Q_OS_WINCE_WM
 
353
    qApp->setAutoMaximizeThreshold(-1);
 
354
#endif
 
355
}
 
356
 
 
357
void tst_QAbstractItemView::cleanupTestCase()
 
358
{
 
359
}
 
360
 
 
361
void tst_QAbstractItemView::emptyModels_data()
 
362
{
 
363
    QTest::addColumn<QString>("viewType");
 
364
 
 
365
    QTest::newRow("QListView") << "QListView";
 
366
    QTest::newRow("QTableView") << "QTableView";
 
367
    QTest::newRow("QTreeView") << "QTreeView";
 
368
    QTest::newRow("QHeaderView") << "QHeaderView";
 
369
}
 
370
 
 
371
void tst_QAbstractItemView::emptyModels()
 
372
{
 
373
    QFETCH(QString, viewType);
 
374
 
 
375
    TestView *view = 0;
 
376
    if (viewType == "QListView")
 
377
        view = reinterpret_cast<TestView*>(new QListView());
 
378
    else if (viewType == "QTableView")
 
379
        view = reinterpret_cast<TestView*>(new QTableView());
 
380
    else if (viewType == "QTreeView")
 
381
        view = reinterpret_cast<TestView*>(new QTreeView());
 
382
    else if (viewType == "QHeaderView")
 
383
        view = reinterpret_cast<TestView*>(new QHeaderView(Qt::Vertical));
 
384
    else
 
385
        QVERIFY(0);
 
386
    view->show();
 
387
 
 
388
    QVERIFY(!view->model());
 
389
    QVERIFY(!view->selectionModel());
 
390
    //QVERIFY(view->itemDelegate() != 0);
 
391
 
 
392
    basic_tests(view);
 
393
    delete view;
 
394
}
 
395
 
 
396
void tst_QAbstractItemView::setModel_data()
 
397
{
 
398
    QTest::addColumn<QString>("viewType");
 
399
 
 
400
    QTest::newRow("QListView") << "QListView";
 
401
    QTest::newRow("QTableView") << "QTableView";
 
402
    QTest::newRow("QTreeView") << "QTreeView";
 
403
    QTest::newRow("QHeaderView") << "QHeaderView";
 
404
}
 
405
 
 
406
void tst_QAbstractItemView::setModel()
 
407
{
 
408
    QFETCH(QString, viewType);
 
409
    TestView *view = 0;
 
410
    if (viewType == "QListView")
 
411
        view = reinterpret_cast<TestView*>(new QListView());
 
412
    else if (viewType == "QTableView")
 
413
        view = reinterpret_cast<TestView*>(new QTableView());
 
414
    else if (viewType == "QTreeView")
 
415
        view = reinterpret_cast<TestView*>(new QTreeView());
 
416
    else if (viewType == "QHeaderView")
 
417
        view = reinterpret_cast<TestView*>(new QHeaderView(Qt::Vertical));
 
418
    else
 
419
        QVERIFY(0);
 
420
    view->show();
 
421
 
 
422
    QStandardItemModel model(20,20);
 
423
    view->setModel(0);
 
424
    view->setModel(&model);
 
425
    basic_tests(view);
 
426
    delete view;
 
427
}
 
428
 
 
429
void tst_QAbstractItemView::basic_tests(TestView *view)
 
430
{
 
431
    // setSelectionModel
 
432
    // Will assert as it should
 
433
    //view->setSelectionModel(0);
 
434
    // setItemDelegate
 
435
    //view->setItemDelegate(0);
 
436
    // Will asswert as it should
 
437
 
 
438
    // setSelectionMode
 
439
    view->setSelectionMode(QAbstractItemView::SingleSelection);
 
440
    QCOMPARE(view->selectionMode(), QAbstractItemView::SingleSelection);
 
441
    view->setSelectionMode(QAbstractItemView::ContiguousSelection);
 
442
    QCOMPARE(view->selectionMode(), QAbstractItemView::ContiguousSelection);
 
443
    view->setSelectionMode(QAbstractItemView::ExtendedSelection);
 
444
    QCOMPARE(view->selectionMode(), QAbstractItemView::ExtendedSelection);
 
445
    view->setSelectionMode(QAbstractItemView::MultiSelection);
 
446
    QCOMPARE(view->selectionMode(), QAbstractItemView::MultiSelection);
 
447
    view->setSelectionMode(QAbstractItemView::NoSelection);
 
448
    QCOMPARE(view->selectionMode(), QAbstractItemView::NoSelection);
 
449
 
 
450
    // setSelectionBehavior
 
451
    view->setSelectionBehavior(QAbstractItemView::SelectItems);
 
452
    QCOMPARE(view->selectionBehavior(), QAbstractItemView::SelectItems);
 
453
    view->setSelectionBehavior(QAbstractItemView::SelectRows);
 
454
    QCOMPARE(view->selectionBehavior(), QAbstractItemView::SelectRows);
 
455
    view->setSelectionBehavior(QAbstractItemView::SelectColumns);
 
456
    QCOMPARE(view->selectionBehavior(), QAbstractItemView::SelectColumns);
 
457
 
 
458
    // setEditTriggers
 
459
    view->setEditTriggers(QAbstractItemView::EditKeyPressed);
 
460
    QCOMPARE(view->editTriggers(), QAbstractItemView::EditKeyPressed);
 
461
    view->setEditTriggers(QAbstractItemView::NoEditTriggers);
 
462
    QCOMPARE(view->editTriggers(), QAbstractItemView::NoEditTriggers);
 
463
    view->setEditTriggers(QAbstractItemView::CurrentChanged);
 
464
    QCOMPARE(view->editTriggers(), QAbstractItemView::CurrentChanged);
 
465
    view->setEditTriggers(QAbstractItemView::DoubleClicked);
 
466
    QCOMPARE(view->editTriggers(), QAbstractItemView::DoubleClicked);
 
467
    view->setEditTriggers(QAbstractItemView::SelectedClicked);
 
468
    QCOMPARE(view->editTriggers(), QAbstractItemView::SelectedClicked);
 
469
    view->setEditTriggers(QAbstractItemView::AnyKeyPressed);
 
470
    QCOMPARE(view->editTriggers(), QAbstractItemView::AnyKeyPressed);
 
471
    view->setEditTriggers(QAbstractItemView::AllEditTriggers);
 
472
    QCOMPARE(view->editTriggers(), QAbstractItemView::AllEditTriggers);
 
473
 
 
474
    // setAutoScroll
 
475
    view->setAutoScroll(false);
 
476
    QCOMPARE(view->hasAutoScroll(), false);
 
477
    view->setAutoScroll(true);
 
478
    QCOMPARE(view->hasAutoScroll(), true);
 
479
 
 
480
    // setTabKeyNavigation
 
481
    view->setTabKeyNavigation(false);
 
482
    QCOMPARE(view->tabKeyNavigation(), false);
 
483
    view->setTabKeyNavigation(true);
 
484
    QCOMPARE(view->tabKeyNavigation(), true);
 
485
 
 
486
#ifndef QT_NO_DRAGANDDROP
 
487
    // setDropIndicatorShown
 
488
    view->setDropIndicatorShown(false);
 
489
    QCOMPARE(view->showDropIndicator(), false);
 
490
    view->setDropIndicatorShown(true);
 
491
    QCOMPARE(view->showDropIndicator(), true);
 
492
 
 
493
    // setDragEnabled
 
494
    view->setDragEnabled(false);
 
495
    QCOMPARE(view->dragEnabled(), false);
 
496
    view->setDragEnabled(true);
 
497
    QCOMPARE(view->dragEnabled(), true);
 
498
#endif
 
499
 
 
500
    // setAlternatingRowColors
 
501
    view->setAlternatingRowColors(false);
 
502
    QCOMPARE(view->alternatingRowColors(), false);
 
503
    view->setAlternatingRowColors(true);
 
504
    QCOMPARE(view->alternatingRowColors(), true);
 
505
 
 
506
    // setIconSize
 
507
    view->setIconSize(QSize(16, 16));
 
508
    QCOMPARE(view->iconSize(), QSize(16, 16));
 
509
    view->setIconSize(QSize(32, 32));
 
510
    QCOMPARE(view->iconSize(), QSize(32, 32));
 
511
    // Should this happen?
 
512
    view->setIconSize(QSize(-1, -1));
 
513
    QCOMPARE(view->iconSize(), QSize(-1, -1));
 
514
 
 
515
    QCOMPARE(view->currentIndex(), QModelIndex());
 
516
    QCOMPARE(view->rootIndex(), QModelIndex());
 
517
 
 
518
    view->keyboardSearch("");
 
519
    view->keyboardSearch("foo");
 
520
    view->keyboardSearch("1");
 
521
 
 
522
    QCOMPARE(view->visualRect(QModelIndex()), QRect());
 
523
 
 
524
    view->scrollTo(QModelIndex());
 
525
 
 
526
    QCOMPARE(view->sizeHintForIndex(QModelIndex()), QSize());
 
527
    QCOMPARE(view->indexAt(QPoint(-1, -1)), QModelIndex());
 
528
 
 
529
    if (!view->model()){
 
530
        QCOMPARE(view->indexAt(QPoint(10, 10)), QModelIndex());
 
531
        QCOMPARE(view->sizeHintForRow(0), -1);
 
532
        QCOMPARE(view->sizeHintForColumn(0), -1);
 
533
    }else if (view->itemDelegate()){
 
534
        view->sizeHintForRow(0);
 
535
        view->sizeHintForColumn(0);
 
536
    }
 
537
    view->openPersistentEditor(QModelIndex());
 
538
    view->closePersistentEditor(QModelIndex());
 
539
 
 
540
    view->reset();
 
541
    view->setRootIndex(QModelIndex());
 
542
    view->doItemsLayout();
 
543
    view->selectAll();
 
544
    view->edit(QModelIndex());
 
545
    view->clearSelection();
 
546
    view->setCurrentIndex(QModelIndex());
 
547
 
 
548
    // protected methods
 
549
    view->tst_dataChanged(QModelIndex(), QModelIndex());
 
550
    view->tst_rowsInserted(QModelIndex(), -1, -1);
 
551
    view->tst_rowsAboutToBeRemoved(QModelIndex(), -1, -1);
 
552
    view->tst_selectionChanged(QItemSelection(), QItemSelection());
 
553
    if (view->model()){
 
554
        view->tst_currentChanged(QModelIndex(), QModelIndex());
 
555
        view->tst_currentChanged(QModelIndex(), view->model()->index(0,0));
 
556
    }
 
557
    view->tst_updateEditorData();
 
558
    view->tst_updateEditorGeometries();
 
559
    view->tst_updateGeometries();
 
560
    view->tst_verticalScrollbarAction(QAbstractSlider::SliderSingleStepAdd);
 
561
    view->tst_horizontalScrollbarAction(QAbstractSlider::SliderSingleStepAdd);
 
562
    view->tst_verticalScrollbarValueChanged(10);
 
563
    view->tst_horizontalScrollbarValueChanged(10);
 
564
    view->tst_closeEditor(0, QAbstractItemDelegate::NoHint);
 
565
    view->tst_commitData(0);
 
566
    view->tst_editorDestroyed(0);
 
567
 
 
568
    view->tst_setHorizontalStepsPerItem(2);
 
569
    view->tst_horizontalStepsPerItem();
 
570
    view->tst_setVerticalStepsPerItem(2);
 
571
    view->tst_verticalStepsPerItem();
 
572
 
 
573
    // Will assert as it should
 
574
    // view->setIndexWidget(QModelIndex(), 0);
 
575
 
 
576
    view->tst_moveCursor(TestView::MoveUp, Qt::NoModifier);
 
577
    view->tst_horizontalOffset();
 
578
    view->tst_verticalOffset();
 
579
 
 
580
//    view->tst_isIndexHidden(QModelIndex()); // will (correctly) assert
 
581
    if(view->model())
 
582
        view->tst_isIndexHidden(view->model()->index(0,0));
 
583
 
 
584
    view->tst_setSelection(QRect(0, 0, 10, 10), QItemSelectionModel::ClearAndSelect);
 
585
    view->tst_setSelection(QRect(-1, -1, -1, -1), QItemSelectionModel::ClearAndSelect);
 
586
    view->tst_visualRegionForSelection(QItemSelection());
 
587
    view->tst_selectedIndexes();
 
588
 
 
589
    view->tst_edit(QModelIndex(), QAbstractItemView::NoEditTriggers, 0);
 
590
 
 
591
    view->tst_selectionCommand(QModelIndex(), 0);
 
592
 
 
593
#ifndef QT_NO_DRAGANDDROP
 
594
    if (!view->model())
 
595
        view->tst_startDrag(Qt::CopyAction);
 
596
 
 
597
    view->tst_viewOptions();
 
598
 
 
599
    view->tst_setState(TestView::NoState);
 
600
    QVERIFY(view->tst_state()==TestView::NoState);
 
601
    view->tst_setState(TestView::DraggingState);
 
602
    QVERIFY(view->tst_state()==TestView::DraggingState);
 
603
    view->tst_setState(TestView::DragSelectingState);
 
604
    QVERIFY(view->tst_state()==TestView::DragSelectingState);
 
605
    view->tst_setState(TestView::EditingState);
 
606
    QVERIFY(view->tst_state()==TestView::EditingState);
 
607
    view->tst_setState(TestView::ExpandingState);
 
608
    QVERIFY(view->tst_state()==TestView::ExpandingState);
 
609
    view->tst_setState(TestView::CollapsingState);
 
610
    QVERIFY(view->tst_state()==TestView::CollapsingState);
 
611
#endif
 
612
 
 
613
    view->tst_startAutoScroll();
 
614
    view->tst_stopAutoScroll();
 
615
    view->tst_doAutoScroll();
 
616
 
 
617
    // testing mouseFoo and key functions
 
618
//     QTest::mousePress(view, Qt::LeftButton, Qt::NoModifier, QPoint(0,0));
 
619
//     mouseMove(view, Qt::LeftButton, Qt::NoModifier, QPoint(10,10));
 
620
//     QTest::mouseRelease(view, Qt::LeftButton, Qt::NoModifier, QPoint(10,10));
 
621
//     QTest::mouseClick(view, Qt::LeftButton, Qt::NoModifier, QPoint(10,10));
 
622
//     mouseDClick(view, Qt::LeftButton, Qt::NoModifier, QPoint(10,10));
 
623
//     QTest::keyClick(view, Qt::Key_A);
 
624
}
 
625
 
 
626
void tst_QAbstractItemView::noModel()
 
627
{
 
628
    // From task #85415
 
629
 
 
630
    QStandardItemModel model(20,20);
 
631
    QTreeView view;
 
632
    setFrameless(&view);
 
633
 
 
634
    view.setModel(&model);
 
635
    // Make the viewport smaller than the contents, so that we can scroll
 
636
    view.resize(100,100);
 
637
    view.show();
 
638
 
 
639
    // make sure that the scrollbars are not at value 0
 
640
    view.scrollTo(view.model()->index(10,10));
 
641
    QApplication::processEvents();
 
642
 
 
643
    view.setModel(0);
 
644
    // Due to the model is removed, this will generate a valueChanged signal on both scrollbars. (value to 0)
 
645
    QApplication::processEvents();
 
646
    QCOMPARE(view.model(), (QAbstractItemModel*)0);
 
647
}
 
648
 
 
649
void tst_QAbstractItemView::dragSelect()
 
650
{
 
651
    // From task #86108
 
652
 
 
653
    QStandardItemModel model(64,64);
 
654
 
 
655
    QTableView view;
 
656
    view.setModel(&model);
 
657
    view.setVisible(true);
 
658
 
 
659
    const int delay = 2;
 
660
    for (int i = 0; i < 2; ++i) {
 
661
        bool tracking = (i == 1);
 
662
        view.setMouseTracking(false);
 
663
        QTest::mouseMove(&view, QPoint(0, 0), delay);
 
664
        view.setMouseTracking(tracking);
 
665
        QTest::mouseMove(&view, QPoint(50, 50), delay);
 
666
        QVERIFY(view.selectionModel()->selectedIndexes().isEmpty());
 
667
    }
 
668
}
 
669
 
 
670
void tst_QAbstractItemView::rowDelegate()
 
671
{
 
672
    QStandardItemModel model(4,4);
 
673
    MyAbstractItemDelegate delegate;
 
674
 
 
675
    QTableView view;
 
676
    view.setModel(&model);
 
677
    view.setItemDelegateForRow(3, &delegate);
 
678
    view.show();
 
679
 
 
680
    QModelIndex index = model.index(3, 0);
 
681
    view.openPersistentEditor(index);
 
682
    QWidget *w = view.indexWidget(index);
 
683
    QVERIFY(w);
 
684
    QCOMPARE(w->metaObject()->className(), "QWidget");
 
685
}
 
686
 
 
687
void tst_QAbstractItemView::columnDelegate()
 
688
{
 
689
    QStandardItemModel model(4,4);
 
690
    MyAbstractItemDelegate delegate;
 
691
 
 
692
    QTableView view;
 
693
    view.setModel(&model);
 
694
    view.setItemDelegateForColumn(3, &delegate);
 
695
    view.show();
 
696
 
 
697
    QModelIndex index = model.index(0, 3);
 
698
    view.openPersistentEditor(index);
 
699
    QWidget *w = view.indexWidget(index);
 
700
    QVERIFY(w);
 
701
    QCOMPARE(w->metaObject()->className(), "QWidget");
 
702
}
 
703
 
 
704
void tst_QAbstractItemView::selectAll()
 
705
{
 
706
    QStandardItemModel model(4,4);
 
707
    QTableView view;
 
708
    view.setModel(&model);
 
709
 
 
710
    TestView *tst_view = (TestView*)&view;
 
711
 
 
712
    QCOMPARE(tst_view->tst_selectedIndexes().count(), 0);
 
713
    view.selectAll();
 
714
    QCOMPARE(tst_view->tst_selectedIndexes().count(), 4*4);
 
715
}
 
716
 
 
717
void tst_QAbstractItemView::ctrlA()
 
718
{
 
719
    QStandardItemModel model(4,4);
 
720
    QTableView view;
 
721
    view.setModel(&model);
 
722
 
 
723
    TestView *tst_view = (TestView*)&view;
 
724
 
 
725
    QCOMPARE(tst_view->tst_selectedIndexes().count(), 0);
 
726
    QTest::keyClick(&view, Qt::Key_A, Qt::ControlModifier);
 
727
    QCOMPARE(tst_view->tst_selectedIndexes().count(), 4*4);
 
728
}
 
729
 
 
730
void tst_QAbstractItemView::persistentEditorFocus()
 
731
{
 
732
    // one row, three columns
 
733
    QStandardItemModel model(1, 3);
 
734
    for(int i = 0; i < model.columnCount(); ++i)
 
735
        model.setData(model.index(0, i), i);
 
736
    QTableView view;
 
737
    view.setModel(&model);
 
738
 
 
739
    view.openPersistentEditor(model.index(0, 1));
 
740
    view.openPersistentEditor(model.index(0, 2));
 
741
 
 
742
    //these are spinboxes because we put numbers inside
 
743
    QList<QSpinBox*> list = qFindChildren<QSpinBox*>(view.viewport());
 
744
    QCOMPARE(list.count(), 2); //these should be the 2 editors
 
745
 
 
746
    view.setCurrentIndex(model.index(0, 0));
 
747
    QCOMPARE(view.currentIndex(), model.index(0, 0));
 
748
    view.show();
 
749
    QTRY_VERIFY(view.isVisible());
 
750
 
 
751
    for (int i = 0; i < list.count(); ++i) {
 
752
        TRY_COMPARE(list.at(i)->isVisible(), true);
 
753
        QPoint p = QPoint(5, 5);
 
754
        QMouseEvent mouseEvent(QEvent::MouseButtonPress, p, Qt::LeftButton,
 
755
                               Qt::LeftButton, Qt::NoModifier);
 
756
        qApp->sendEvent(list.at(i), &mouseEvent);
 
757
        if (!qApp->focusWidget())
 
758
            QSKIP("Some window managers don't handle focus that well");
 
759
        QTRY_COMPARE(qApp->focusWidget(), static_cast<QWidget *>(list.at(i)));
 
760
    }
 
761
}
 
762
 
 
763
 
 
764
#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
 
765
 
 
766
#if 0
 
767
 
 
768
static void sendMouseMove(QWidget *widget, QPoint pos = QPoint())
 
769
{
 
770
    if (pos.isNull())
 
771
        pos = widget->rect().center();
 
772
    QMouseEvent event(QEvent::MouseMove, pos, widget->mapToGlobal(pos), Qt::NoButton, 0, 0);
 
773
    QCursor::setPos(widget->mapToGlobal(pos));
 
774
    qApp->processEvents();
 
775
    QVERIFY(QTest::qWaitForWindowExposed(widget));
 
776
    QApplication::sendEvent(widget, &event);
 
777
}
 
778
 
 
779
static void sendMousePress(
 
780
    QWidget *widget, QPoint pos = QPoint(), Qt::MouseButton button = Qt::LeftButton)
 
781
{
 
782
    if (pos.isNull())
 
783
         pos = widget->rect().center();
 
784
    QMouseEvent event(QEvent::MouseButtonPress, pos, widget->mapToGlobal(pos), button, 0, 0);
 
785
    QApplication::sendEvent(widget, &event);
 
786
}
 
787
 
 
788
static void sendMouseRelease(
 
789
    QWidget *widget, QPoint pos = QPoint(), Qt::MouseButton button = Qt::LeftButton)
 
790
{
 
791
    if (pos.isNull())
 
792
         pos = widget->rect().center();
 
793
    QMouseEvent event(QEvent::MouseButtonRelease, pos, widget->mapToGlobal(pos), button, 0, 0);
 
794
    QApplication::sendEvent(widget, &event);
 
795
}
 
796
 
 
797
class DnDTestModel : public QStandardItemModel
 
798
{
 
799
    Q_OBJECT
 
800
    bool dropMimeData(const QMimeData *md, Qt::DropAction action, int r, int c, const QModelIndex &p)
 
801
    {
 
802
        dropAction_result = action;
 
803
        QStandardItemModel::dropMimeData(md, action, r, c, p);
 
804
        return true;
 
805
    }
 
806
    Qt::DropActions supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; }
 
807
 
 
808
    Qt::DropAction dropAction_result;
 
809
public:
 
810
    DnDTestModel() : QStandardItemModel(20, 20), dropAction_result(Qt::IgnoreAction) {
 
811
        for (int i = 0; i < rowCount(); ++i)
 
812
            setData(index(i, 0), QString("%1").arg(i));
 
813
    }
 
814
    Qt::DropAction dropAction() const { return dropAction_result; }
 
815
};
 
816
 
 
817
class DnDTestView : public QTreeView
 
818
{
 
819
    Q_OBJECT
 
820
 
 
821
    QPoint dropPoint;
 
822
    Qt::DropAction dropAction;
 
823
 
 
824
    void dragEnterEvent(QDragEnterEvent *event)
 
825
    {
 
826
        QAbstractItemView::dragEnterEvent(event);
 
827
    }
 
828
 
 
829
    void dropEvent(QDropEvent *event)
 
830
    {
 
831
        event->setDropAction(dropAction);
 
832
        QTreeView::dropEvent(event);
 
833
    }
 
834
 
 
835
    void timerEvent(QTimerEvent *event)
 
836
    {
 
837
        killTimer(event->timerId());
 
838
        sendMouseMove(this, dropPoint);
 
839
        sendMouseRelease(this);
 
840
    }
 
841
 
 
842
    void mousePressEvent(QMouseEvent *e)
 
843
    {
 
844
        QTreeView::mousePressEvent(e);
 
845
 
 
846
        startTimer(0);
 
847
        setState(DraggingState);
 
848
        startDrag(dropAction);
 
849
    }
 
850
 
 
851
public:
 
852
    DnDTestView(Qt::DropAction dropAction, QAbstractItemModel *model)
 
853
        : dropAction(dropAction)
 
854
    {
 
855
        header()->hide();
 
856
        setModel(model);
 
857
        setDragDropMode(QAbstractItemView::DragDrop);
 
858
        setAcceptDrops(true);
 
859
        setDragEnabled(true);
 
860
    }
 
861
 
 
862
    void dragAndDrop(QPoint drag, QPoint drop)
 
863
    {
 
864
        dropPoint = drop;
 
865
        setCurrentIndex(indexAt(drag));
 
866
        sendMousePress(viewport(), drag);
 
867
    }
 
868
};
 
869
 
 
870
class DnDTestWidget : public QWidget
 
871
{
 
872
    Q_OBJECT
 
873
 
 
874
    Qt::DropAction dropAction_request;
 
875
    Qt::DropAction dropAction_result;
 
876
    QWidget *dropTarget;
 
877
 
 
878
    void timerEvent(QTimerEvent *event)
 
879
    {
 
880
        killTimer(event->timerId());
 
881
        sendMouseMove(dropTarget);
 
882
        sendMouseRelease(dropTarget);
 
883
    }
 
884
 
 
885
    void mousePressEvent(QMouseEvent *)
 
886
    {
 
887
        QDrag *drag = new QDrag(this);
 
888
        QMimeData *mimeData = new QMimeData;
 
889
        mimeData->setData("application/x-qabstractitemmodeldatalist", QByteArray(""));
 
890
        drag->setMimeData(mimeData);
 
891
        startTimer(0);
 
892
        dropAction_result = drag->start(dropAction_request);
 
893
    }
 
894
 
 
895
public:
 
896
    Qt::DropAction dropAction() const { return dropAction_result; }
 
897
 
 
898
    void dragAndDrop(QWidget *dropTarget, Qt::DropAction dropAction)
 
899
    {
 
900
        this->dropTarget = dropTarget;
 
901
        dropAction_request = dropAction;
 
902
        sendMousePress(this);
 
903
    }
 
904
};
 
905
 
 
906
void tst_QAbstractItemView::dragAndDrop()
 
907
{
 
908
    // From Task 137729
 
909
 
 
910
 
 
911
    const int attempts = 10;
 
912
    int successes = 0;
 
913
    for (int i = 0; i < attempts; ++i) {
 
914
        Qt::DropAction dropAction = Qt::MoveAction;
 
915
 
 
916
        DnDTestModel model;
 
917
        DnDTestView view(dropAction, &model);
 
918
        DnDTestWidget widget;
 
919
 
 
920
        const int size = 200;
 
921
        widget.setFixedSize(size, size);
 
922
        view.setFixedSize(size, size);
 
923
 
 
924
        widget.move(0, 0);
 
925
        view.move(int(size * 1.5), int(size * 1.5));
 
926
 
 
927
        widget.show();
 
928
        view.show();
 
929
        QVERIFY(QTest::qWaitForWindowExposed(&widget));
 
930
        QVERIFY(QTest::qWaitForWindowExposed(&view));
 
931
 
 
932
        widget.dragAndDrop(&view, dropAction);
 
933
        if (model.dropAction() == dropAction
 
934
            && widget.dropAction() == dropAction)
 
935
            ++successes;
 
936
    }
 
937
 
 
938
    if (successes < attempts) {
 
939
        QString msg = QString("# successes (%1) < # attempts (%2)").arg(successes).arg(attempts);
 
940
        QWARN(msg.toLatin1());
 
941
    }
 
942
    QVERIFY(successes > 0); // allow for some "event unstability" (i.e. unless
 
943
                            // successes == 0, QAbstractItemView is probably ok!)
 
944
}
 
945
 
 
946
void tst_QAbstractItemView::dragAndDropOnChild()
 
947
{
 
948
 
 
949
    const int attempts = 10;
 
950
    int successes = 0;
 
951
    for (int i = 0; i < attempts; ++i) {
 
952
        Qt::DropAction dropAction = Qt::MoveAction;
 
953
 
 
954
        DnDTestModel model;
 
955
        QModelIndex parent = model.index(0, 0);
 
956
        model.insertRow(0, parent);
 
957
        model.insertColumn(0, parent);
 
958
        QModelIndex child = model.index(0, 0, parent);
 
959
        model.setData(child, "child");
 
960
        QCOMPARE(model.rowCount(parent), 1);
 
961
        DnDTestView view(dropAction, &model);
 
962
        view.setExpanded(parent, true);
 
963
        view.setDragDropMode(QAbstractItemView::InternalMove);
 
964
 
 
965
        const int size = 200;
 
966
        view.setFixedSize(size, size);
 
967
        view.move(int(size * 1.5), int(size * 1.5));
 
968
        view.show();
 
969
        QVERIFY(QTest::qWaitForWindowExposed(&view));
 
970
 
 
971
        view.dragAndDrop(view.visualRect(parent).center(),
 
972
                         view.visualRect(child).center());
 
973
        if (model.dropAction() == dropAction)
 
974
            ++successes;
 
975
    }
 
976
 
 
977
    QVERIFY(successes == 0);
 
978
}
 
979
 
 
980
#endif // 0
 
981
#endif // !Q_OS_MAC && !Q_OS_WIN
 
982
 
 
983
class TestModel : public QStandardItemModel
 
984
{
 
985
public:
 
986
    TestModel(int rows, int columns) : QStandardItemModel(rows, columns)
 
987
    {
 
988
        setData_count = 0;
 
989
    }
 
990
 
 
991
    virtual bool setData(const QModelIndex &/*index*/, const QVariant &/*value*/, int /*role = Qt::EditRole*/)
 
992
    {
 
993
        ++setData_count;
 
994
        return true;
 
995
    }
 
996
 
 
997
    int setData_count;
 
998
};
 
999
 
 
1000
typedef QList<int> IntList;
 
1001
 
 
1002
void tst_QAbstractItemView::setItemDelegate_data()
 
1003
{
 
1004
    // default is rows, a -1 will switch to columns
 
1005
    QTest::addColumn<IntList>("rowsOrColumnsWithDelegate");
 
1006
    QTest::addColumn<QPoint>("cellToEdit");
 
1007
    QTest::newRow("4 columndelegates")
 
1008
                << (IntList() << -1 << 0 << 1 << 2 << 3)
 
1009
                << QPoint(0, 0);
 
1010
    QTest::newRow("2 identical rowdelegates on the same row")
 
1011
                << (IntList() << 0 << 0)
 
1012
                << QPoint(0, 0);
 
1013
    QTest::newRow("2 identical columndelegates on the same column")
 
1014
                << (IntList() << -1 << 2 << 2)
 
1015
                << QPoint(2, 0);
 
1016
    QTest::newRow("2 duplicate delegates, 1 row and 1 column")
 
1017
                << (IntList() << 0 << -1 << 2)
 
1018
                << QPoint(2, 0);
 
1019
    QTest::newRow("4 duplicate delegates, 2 row and 2 column")
 
1020
                << (IntList() << 0 << 0 << -1 << 2 << 2)
 
1021
                << QPoint(2, 0);
 
1022
 
 
1023
}
 
1024
 
 
1025
void tst_QAbstractItemView::setItemDelegate()
 
1026
{
 
1027
    QFETCH(IntList, rowsOrColumnsWithDelegate);
 
1028
    QFETCH(QPoint, cellToEdit);
 
1029
    QTableView v;
 
1030
    QItemDelegate *delegate = new QItemDelegate(&v);
 
1031
    TestModel model(5, 5);
 
1032
    v.setModel(&model);
 
1033
 
 
1034
    bool row = true;
 
1035
    foreach (int rc, rowsOrColumnsWithDelegate) {
 
1036
        if (rc == -1) {
 
1037
            row = !row;
 
1038
        } else {
 
1039
            if (row) {
 
1040
                v.setItemDelegateForRow(rc, delegate);
 
1041
            } else {
 
1042
                v.setItemDelegateForColumn(rc, delegate);
 
1043
            }
 
1044
        }
 
1045
    }
 
1046
    v.show();
 
1047
#ifdef Q_WS_X11
 
1048
    QCursor::setPos(v.geometry().center());
 
1049
    QApplication::syncX();
 
1050
#endif
 
1051
    QApplication::setActiveWindow(&v);
 
1052
    QVERIFY(QTest::qWaitForWindowActive(&v));
 
1053
 
 
1054
    QModelIndex index = model.index(cellToEdit.y(), cellToEdit.x());
 
1055
    v.edit(index);
 
1056
 
 
1057
    // This will close the editor
 
1058
    TRY_COMPARE(QApplication::focusWidget() == 0, false);
 
1059
    QWidget *editor = QApplication::focusWidget();
 
1060
    QVERIFY(editor);
 
1061
    editor->hide();
 
1062
    delete editor;
 
1063
    QCOMPARE(model.setData_count, 1);
 
1064
    delete delegate;
 
1065
}
 
1066
 
 
1067
void tst_QAbstractItemView::noFallbackToRoot()
 
1068
{
 
1069
    QStandardItemModel model(0, 1);
 
1070
    for (int i = 0; i < 5; ++i)
 
1071
        model.appendRow(new QStandardItem("top" + QString::number(i)));
 
1072
    QStandardItem *par1 = model.item(1);
 
1073
    for (int j = 0; j < 15; ++j)
 
1074
        par1->appendRow(new QStandardItem("sub" + QString::number(j)));
 
1075
    QStandardItem *par2 = par1->child(2);
 
1076
    for (int k = 0; k < 10; ++k)
 
1077
        par2->appendRow(new QStandardItem("bot" + QString::number(k)));
 
1078
    QStandardItem *it1 = par2->child(5);
 
1079
 
 
1080
    QModelIndex parent1 = model.indexFromItem(par1);
 
1081
    QModelIndex parent2 = model.indexFromItem(par2);
 
1082
    QModelIndex item1 = model.indexFromItem(it1);
 
1083
 
 
1084
    QTreeView v;
 
1085
    v.setModel(&model);
 
1086
    v.setRootIndex(parent1);
 
1087
    v.setCurrentIndex(item1);
 
1088
    QCOMPARE(v.currentIndex(), item1);
 
1089
    QVERIFY(model.removeRows(0, 10, parent2));
 
1090
    QCOMPARE(v.currentIndex(), parent2);
 
1091
    QVERIFY(model.removeRows(0, 15, parent1));
 
1092
    QCOMPARE(v.currentIndex(), QModelIndex());
 
1093
}
 
1094
 
 
1095
void tst_QAbstractItemView::setCurrentIndex_data()
 
1096
{
 
1097
    QTest::addColumn<QString>("viewType");
 
1098
    QTest::addColumn<int>("itemFlags");
 
1099
    QTest::addColumn<bool>("result");
 
1100
 
 
1101
    QStringList widgets;
 
1102
    widgets << "QListView" << "QTreeView" << "QHeaderView" << "QTableView";
 
1103
 
 
1104
    foreach(QString widget, widgets) {
 
1105
        QTest::newRow((widget+QLatin1String(": no flags")).toLocal8Bit().constData())
 
1106
            << widget << (int)0 << false;
 
1107
        QTest::newRow((widget+QLatin1String(": checkable")).toLocal8Bit().constData())
 
1108
            << widget << (int)Qt::ItemIsUserCheckable << false;
 
1109
        QTest::newRow((widget+QLatin1String(": selectable")).toLocal8Bit().constData())
 
1110
            << widget << (int)Qt::ItemIsSelectable << false;
 
1111
        QTest::newRow((widget+QLatin1String(": enabled")).toLocal8Bit().constData())
 
1112
            << widget << (int)Qt::ItemIsEnabled << true;
 
1113
        QTest::newRow((widget+QLatin1String(": enabled|selectable")).toLocal8Bit().constData())
 
1114
            << widget << (int)(Qt::ItemIsSelectable|Qt::ItemIsEnabled) << true;
 
1115
    }
 
1116
}
 
1117
 
 
1118
void tst_QAbstractItemView::setCurrentIndex()
 
1119
{
 
1120
    QFETCH(QString, viewType);
 
1121
    QFETCH(int, itemFlags);
 
1122
    QFETCH(bool, result);
 
1123
 
 
1124
    TestView *view = 0;
 
1125
    if (viewType == "QListView")
 
1126
        view = reinterpret_cast<TestView*>(new QListView());
 
1127
    else if (viewType == "QTableView")
 
1128
        view = reinterpret_cast<TestView*>(new QTableView());
 
1129
    else if (viewType == "QTreeView")
 
1130
        view = reinterpret_cast<TestView*>(new QTreeView());
 
1131
    else if (viewType == "QHeaderView")
 
1132
        view = reinterpret_cast<TestView*>(new QHeaderView(Qt::Vertical));
 
1133
    else
 
1134
        QVERIFY(0);
 
1135
    view->show();
 
1136
 
 
1137
    QStandardItemModel *model = new QStandardItemModel(view);
 
1138
    QStandardItem *item = new QStandardItem("first item");
 
1139
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
 
1140
    model->appendRow(item);
 
1141
 
 
1142
    item = new QStandardItem("test item");
 
1143
    item->setFlags(Qt::ItemFlags(itemFlags));
 
1144
    model->appendRow(item);
 
1145
 
 
1146
    view->setModel(model);
 
1147
 
 
1148
    view->setCurrentIndex(model->index(0,0));
 
1149
    QVERIFY(view->currentIndex() == model->index(0,0));
 
1150
    view->setCurrentIndex(model->index(1,0));
 
1151
    QVERIFY(view->currentIndex() == model->index(result ? 1 : 0,0));
 
1152
 
 
1153
    delete view;
 
1154
}
 
1155
 
 
1156
void tst_QAbstractItemView::task221955_selectedEditor()
 
1157
{
 
1158
    QPushButton *button;
 
1159
 
 
1160
    QTreeWidget tree;
 
1161
    tree.setColumnCount(2);
 
1162
 
 
1163
    tree.addTopLevelItem(new QTreeWidgetItem(QStringList() << "Foo" <<"1"));
 
1164
    tree.addTopLevelItem(new QTreeWidgetItem(QStringList() << "Bar" <<"2"));
 
1165
    tree.addTopLevelItem(new QTreeWidgetItem(QStringList() << "Baz" <<"3"));
 
1166
 
 
1167
    QTreeWidgetItem *dummy = new QTreeWidgetItem();
 
1168
    tree.addTopLevelItem(dummy);
 
1169
    tree.setItemWidget(dummy, 0, button = new QPushButton("More..."));
 
1170
    button->setAutoFillBackground(true);  // as recommended in doc
 
1171
 
 
1172
    tree.show();
 
1173
    tree.setFocus();
 
1174
    tree.setCurrentIndex(tree.model()->index(1,0));
 
1175
    QTest::qWait(100);
 
1176
    QApplication::setActiveWindow(&tree);
 
1177
 
 
1178
    QVERIFY(! tree.selectionModel()->selectedIndexes().contains(tree.model()->index(3,0)));
 
1179
 
 
1180
    //We set the focus to the button, the index need to be selected
 
1181
    button->setFocus();
 
1182
    QTest::qWait(100);
 
1183
    QVERIFY(tree.selectionModel()->selectedIndexes().contains(tree.model()->index(3,0)));
 
1184
 
 
1185
    tree.setCurrentIndex(tree.model()->index(1,0));
 
1186
    QVERIFY(! tree.selectionModel()->selectedIndexes().contains(tree.model()->index(3,0)));
 
1187
 
 
1188
    //Same thing but with the flag NoSelection,   nothing can be selected.
 
1189
    tree.setFocus();
 
1190
    tree.setSelectionMode(QAbstractItemView::NoSelection);
 
1191
    tree.clearSelection();
 
1192
    QVERIFY(tree.selectionModel()->selectedIndexes().isEmpty());
 
1193
    QTest::qWait(10);
 
1194
    button->setFocus();
 
1195
    QTest::qWait(50);
 
1196
    QVERIFY(tree.selectionModel()->selectedIndexes().isEmpty());
 
1197
}
 
1198
 
 
1199
void tst_QAbstractItemView::task250754_fontChange()
 
1200
{
 
1201
    QString app_css = qApp->styleSheet();
 
1202
    qApp->setStyleSheet("/*  */");
 
1203
 
 
1204
    QWidget w;
 
1205
    QTreeView tree(&w);
 
1206
    QVBoxLayout *vLayout = new QVBoxLayout(&w);
 
1207
    vLayout->addWidget(&tree);
 
1208
 
 
1209
    QStandardItemModel *m = new QStandardItemModel(this);
 
1210
    for (int i=0; i<5; ++i) {
 
1211
        QStandardItem *item = new QStandardItem(QString("Item number %1").arg(i));
 
1212
        for (int j=0; j<5; ++j) {
 
1213
            QStandardItem *child = new QStandardItem(QString("Child Item number %1").arg(j));
 
1214
            item->setChild(j, 0, child);
 
1215
        }
 
1216
        m->setItem(i, 0, item);
 
1217
    }
 
1218
    tree.setModel(m);
 
1219
 
 
1220
    w.show();
 
1221
    w.resize(150,240);
 
1222
    QTest::qWait(30);
 
1223
    QFont font = tree.font();
 
1224
    font.setPixelSize(10);
 
1225
    tree.setFont(font);
 
1226
    QTRY_VERIFY(!tree.verticalScrollBar()->isVisible());
 
1227
 
 
1228
    font.setPixelSize(60);
 
1229
    tree.setFont(font);
 
1230
    //now with the huge items, the scrollbar must be visible
 
1231
    QTRY_VERIFY(tree.verticalScrollBar()->isVisible());
 
1232
 
 
1233
    qApp->setStyleSheet(app_css);
 
1234
}
 
1235
 
 
1236
void tst_QAbstractItemView::task200665_itemEntered()
 
1237
{
 
1238
#ifdef Q_OS_WINCE_WM
 
1239
    QSKIP("On Windows Mobile the mouse tracking is unavailable at the moment");
 
1240
#endif
 
1241
    //we test that view will emit entered
 
1242
    //when the scrollbar move but not the mouse itself
 
1243
    QStandardItemModel model(1000,1);
 
1244
    QListView view;
 
1245
    view.setModel(&model);
 
1246
    view.show();
 
1247
    QTest::qWait(200);
 
1248
    QRect rect = view.visualRect(model.index(0,0));
 
1249
    QCursor::setPos( view.viewport()->mapToGlobal(rect.center()) );
 
1250
    QSignalSpy spy(&view, SIGNAL(entered(QModelIndex)));
 
1251
    view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum());
 
1252
 
 
1253
    QCOMPARE(spy.count(), 1);
 
1254
}
 
1255
 
 
1256
void tst_QAbstractItemView::task257481_emptyEditor()
 
1257
{
 
1258
    QIcon icon = qApp->style()->standardIcon(QStyle::SP_ComputerIcon);
 
1259
 
 
1260
    QStandardItemModel model;
 
1261
 
 
1262
    model.appendRow( new QStandardItem(icon, QString()) );
 
1263
    model.appendRow( new QStandardItem(icon, "Editor works") );
 
1264
    model.appendRow( new QStandardItem( QString() ) );
 
1265
 
 
1266
    QTreeView treeView;
 
1267
    treeView.setRootIsDecorated(false);
 
1268
    treeView.setModel(&model);
 
1269
    treeView.show();
 
1270
 
 
1271
    treeView.edit(model.index(0,0));
 
1272
    QList<QLineEdit *> lineEditors = qFindChildren<QLineEdit *>(treeView.viewport());
 
1273
    QCOMPARE(lineEditors.count(), 1);
 
1274
    QVERIFY(!lineEditors.first()->size().isEmpty());
 
1275
 
 
1276
    QTest::qWait(30);
 
1277
 
 
1278
    treeView.edit(model.index(1,0));
 
1279
    lineEditors = qFindChildren<QLineEdit *>(treeView.viewport());
 
1280
    QCOMPARE(lineEditors.count(), 1);
 
1281
    QVERIFY(!lineEditors.first()->size().isEmpty());
 
1282
 
 
1283
    QTest::qWait(30);
 
1284
 
 
1285
    treeView.edit(model.index(2,0));
 
1286
    lineEditors = qFindChildren<QLineEdit *>(treeView.viewport());
 
1287
    QCOMPARE(lineEditors.count(), 1);
 
1288
    QVERIFY(!lineEditors.first()->size().isEmpty());
 
1289
}
 
1290
 
 
1291
void tst_QAbstractItemView::shiftArrowSelectionAfterScrolling()
 
1292
{
 
1293
    QStandardItemModel model;
 
1294
    for (int i=0; i<10; ++i) {
 
1295
        QStandardItem *item = new QStandardItem(QString("%1").arg(i));
 
1296
        model.setItem(i, 0, item);
 
1297
    }
 
1298
 
 
1299
    QListView view;
 
1300
    view.setFixedSize(150, 250);
 
1301
    view.setFlow(QListView::LeftToRight);
 
1302
    view.setGridSize(QSize(100, 100));
 
1303
    view.setSelectionMode(QListView::ExtendedSelection);
 
1304
    view.setViewMode(QListView::IconMode);
 
1305
    view.setModel(&model);
 
1306
    view.show();
 
1307
    QTest::qWait(30);
 
1308
 
 
1309
    QModelIndex index0 = model.index(0, 0);
 
1310
    QModelIndex index1 = model.index(1, 0);
 
1311
    QModelIndex index9 = model.index(9, 0);
 
1312
 
 
1313
    view.selectionModel()->setCurrentIndex(index0, QItemSelectionModel::NoUpdate);
 
1314
    QCOMPARE(view.currentIndex(), index0);
 
1315
 
 
1316
    view.scrollTo(index9);
 
1317
    QTest::keyClick(&view, Qt::Key_Down, Qt::ShiftModifier);
 
1318
 
 
1319
    QCOMPARE(view.currentIndex(), index1);
 
1320
    QModelIndexList selected = view.selectionModel()->selectedIndexes();
 
1321
    QCOMPARE(selected.count(), 2);
 
1322
    QVERIFY(selected.contains(index0));
 
1323
    QVERIFY(selected.contains(index1));
 
1324
}
 
1325
 
 
1326
void tst_QAbstractItemView::shiftSelectionAfterRubberbandSelection()
 
1327
{
 
1328
    QStandardItemModel model;
 
1329
    for (int i=0; i<3; ++i) {
 
1330
        QStandardItem *item = new QStandardItem(QString("%1").arg(i));
 
1331
        model.setItem(i, 0, item);
 
1332
    }
 
1333
 
 
1334
    QListView view;
 
1335
    view.setFixedSize(150, 450);
 
1336
    view.setFlow(QListView::LeftToRight);
 
1337
    view.setGridSize(QSize(100, 100));
 
1338
    view.setSelectionMode(QListView::ExtendedSelection);
 
1339
    view.setViewMode(QListView::IconMode);
 
1340
    view.setModel(&model);
 
1341
    view.show();
 
1342
    QTest::qWait(30);
 
1343
 
 
1344
    QModelIndex index0 = model.index(0, 0);
 
1345
    QModelIndex index1 = model.index(1, 0);
 
1346
    QModelIndex index2 = model.index(2, 0);
 
1347
 
 
1348
    view.setCurrentIndex(index0);
 
1349
    QCOMPARE(view.currentIndex(), index0);
 
1350
 
 
1351
    // Determine the points where the rubberband selection starts and ends
 
1352
    QPoint pressPos = view.visualRect(index1).bottomRight() + QPoint(1, 1);
 
1353
    QPoint releasePos = view.visualRect(index1).center();
 
1354
    QVERIFY(!view.indexAt(pressPos).isValid());
 
1355
    QCOMPARE(view.indexAt(releasePos), index1);
 
1356
 
 
1357
    // Select item 1 using a rubberband selection
 
1358
    // The mouse move event has to be created manually because the QTest framework does not
 
1359
    // contain a function for mouse moves with buttons pressed
 
1360
    QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, pressPos);
 
1361
    QMouseEvent moveEvent(QEvent::MouseMove, releasePos, Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
 
1362
    bool moveEventReceived = qApp->notify(view.viewport(), &moveEvent);
 
1363
    QVERIFY(moveEventReceived);
 
1364
    QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, releasePos);
 
1365
    QCOMPARE(view.currentIndex(), index1);
 
1366
 
 
1367
    // Shift-click item 2
 
1368
    QPoint item2Pos = view.visualRect(index2).center();
 
1369
    QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, item2Pos);
 
1370
    QCOMPARE(view.currentIndex(), index2);
 
1371
 
 
1372
    // Verify that the selection worked OK
 
1373
    QModelIndexList selected = view.selectionModel()->selectedIndexes();
 
1374
    QCOMPARE(selected.count(), 2);
 
1375
    QVERIFY(selected.contains(index1));
 
1376
    QVERIFY(selected.contains(index2));
 
1377
 
 
1378
    // Select item 0 to revert the selection
 
1379
    view.setCurrentIndex(index0);
 
1380
    QCOMPARE(view.currentIndex(), index0);
 
1381
 
 
1382
    // Repeat the same steps as above, but with a Shift-Arrow selection
 
1383
    QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, pressPos);
 
1384
    QMouseEvent moveEvent2(QEvent::MouseMove, releasePos, Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
 
1385
    moveEventReceived = qApp->notify(view.viewport(), &moveEvent2);
 
1386
    QVERIFY(moveEventReceived);
 
1387
    QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, releasePos);
 
1388
    QCOMPARE(view.currentIndex(), index1);
 
1389
 
 
1390
    // Press Shift-Down
 
1391
    QTest::keyClick(&view, Qt::Key_Down, Qt::ShiftModifier);
 
1392
    QCOMPARE(view.currentIndex(), index2);
 
1393
 
 
1394
    // Verify that the selection worked OK
 
1395
    selected = view.selectionModel()->selectedIndexes();
 
1396
    QCOMPARE(selected.count(), 2);
 
1397
    QVERIFY(selected.contains(index1));
 
1398
    QVERIFY(selected.contains(index2));
 
1399
}
 
1400
 
 
1401
void tst_QAbstractItemView::ctrlRubberbandSelection()
 
1402
{
 
1403
    QStandardItemModel model;
 
1404
    for (int i=0; i<3; ++i) {
 
1405
        QStandardItem *item = new QStandardItem(QString("%1").arg(i));
 
1406
        model.setItem(i, 0, item);
 
1407
    }
 
1408
 
 
1409
    QListView view;
 
1410
    view.setFixedSize(150, 450);
 
1411
    view.setFlow(QListView::LeftToRight);
 
1412
    view.setGridSize(QSize(100, 100));
 
1413
    view.setSelectionMode(QListView::ExtendedSelection);
 
1414
    view.setViewMode(QListView::IconMode);
 
1415
    view.setModel(&model);
 
1416
    view.show();
 
1417
    QTest::qWait(30);
 
1418
 
 
1419
    QModelIndex index1 = model.index(1, 0);
 
1420
    QModelIndex index2 = model.index(2, 0);
 
1421
 
 
1422
    // Select item 1
 
1423
    view.setCurrentIndex(index1);
 
1424
    QModelIndexList selected = view.selectionModel()->selectedIndexes();
 
1425
    QCOMPARE(selected.count(), 1);
 
1426
    QVERIFY(selected.contains(index1));
 
1427
 
 
1428
    // Now press control and draw a rubberband around items 1 and 2.
 
1429
    // The mouse move event has to be created manually because the QTest framework does not
 
1430
    // contain a function for mouse moves with buttons pressed.
 
1431
    QPoint pressPos = view.visualRect(index1).topLeft() - QPoint(1, 1);
 
1432
    QPoint releasePos = view.visualRect(index2).bottomRight() + QPoint(1, 1);
 
1433
    QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::ControlModifier, pressPos);
 
1434
    QMouseEvent moveEvent(QEvent::MouseMove, releasePos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
 
1435
    bool moveEventReceived = qApp->notify(view.viewport(), &moveEvent);
 
1436
    QVERIFY(moveEventReceived);
 
1437
    QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::ControlModifier, releasePos);
 
1438
 
 
1439
    // Verify that item 2 is selected now
 
1440
    selected = view.selectionModel()->selectedIndexes();
 
1441
    QCOMPARE(selected.count(), 1);
 
1442
    QVERIFY(selected.contains(index2));
 
1443
}
 
1444
 
 
1445
void tst_QAbstractItemView::QTBUG6407_extendedSelection()
 
1446
{
 
1447
    QListWidget view;
 
1448
    view.setSelectionMode(QAbstractItemView::ExtendedSelection);
 
1449
    for(int i = 0; i < 50; ++i)
 
1450
        view.addItem(QString::number(i));
 
1451
 
 
1452
    QFont font = view.font();
 
1453
    font.setPixelSize(10);
 
1454
    view.setFont(font);
 
1455
    view.resize(200,240);
 
1456
 
 
1457
    view.show();
 
1458
    QApplication::setActiveWindow(&view);
 
1459
    QVERIFY(QTest::qWaitForWindowActive(&view));
 
1460
    QCOMPARE(static_cast<QWidget *>(&view), QApplication::activeWindow());
 
1461
 
 
1462
    view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum());
 
1463
    QTest::qWait(20);
 
1464
 
 
1465
    QModelIndex index49 = view.model()->index(49,0);
 
1466
    QPoint p = view.visualRect(index49).center();
 
1467
    QVERIFY(view.viewport()->rect().contains(p));
 
1468
    QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p);
 
1469
    QCOMPARE(view.currentIndex(), index49);
 
1470
    QCOMPARE(view.selectedItems().count(), 1);
 
1471
 
 
1472
    QModelIndex index47 = view.model()->index(47,0);
 
1473
    p = view.visualRect(index47).center();
 
1474
    QVERIFY(view.viewport()->rect().contains(p));
 
1475
    QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, p);
 
1476
    QCOMPARE(view.currentIndex(), index47);
 
1477
    QCOMPARE(view.selectedItems().count(), 3); //49, 48, 47;
 
1478
 
 
1479
    QModelIndex index44 = view.model()->index(44,0);
 
1480
    p = view.visualRect(index44).center();
 
1481
    QVERIFY(view.viewport()->rect().contains(p));
 
1482
    QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, p);
 
1483
    QCOMPARE(view.currentIndex(), index44);
 
1484
    QCOMPARE(view.selectedItems().count(), 6); //49 .. 44;
 
1485
 
 
1486
}
 
1487
 
 
1488
void tst_QAbstractItemView::QTBUG6753_selectOnSelection()
 
1489
{
 
1490
    QTableWidget table(5, 5);
 
1491
    for (int i = 0; i < table.rowCount(); ++i)
 
1492
        for (int j = 0; j < table.columnCount(); ++j)
 
1493
            table.setItem(i, j, new QTableWidgetItem("choo-be-doo-wah"));
 
1494
 
 
1495
    table.show();
 
1496
    table.setSelectionMode(QAbstractItemView::ExtendedSelection);
 
1497
    table.selectAll();
 
1498
    QVERIFY(QTest::qWaitForWindowExposed(&table));
 
1499
    QModelIndex item = table.model()->index(1,1);
 
1500
    QRect itemRect = table.visualRect(item);
 
1501
    QTest::mouseMove(table.viewport(), itemRect.center());
 
1502
    QTest::mouseClick(table.viewport(), Qt::LeftButton, Qt::NoModifier, itemRect.center());
 
1503
    QTest::qWait(20);
 
1504
 
 
1505
    QCOMPARE(table.selectedItems().count(), 1);
 
1506
    QCOMPARE(table.selectedItems().first(), table.item(item.row(), item.column()));
 
1507
}
 
1508
 
 
1509
void tst_QAbstractItemView::testDelegateDestroyEditor()
 
1510
{
 
1511
    QTableWidget table(5, 5);
 
1512
    MyAbstractItemDelegate delegate;
 
1513
    table.setItemDelegate(&delegate);
 
1514
    table.edit(table.model()->index(1, 1));
 
1515
    TestView *tv = reinterpret_cast<TestView*>(&table);
 
1516
    QVERIFY(!delegate.calledVirtualDtor);
 
1517
    tv->tst_closeEditor(delegate.openedEditor, QAbstractItemDelegate::NoHint);
 
1518
    QVERIFY(delegate.calledVirtualDtor);
 
1519
}
 
1520
 
 
1521
void tst_QAbstractItemView::testClickedSignal()
 
1522
{
 
1523
    QTableWidget view(5, 5);
 
1524
 
 
1525
    view.show();
 
1526
    QApplication::setActiveWindow(&view);
 
1527
    QVERIFY(QTest::qWaitForWindowActive(&view));
 
1528
    QCOMPARE(static_cast<QWidget *>(&view), QApplication::activeWindow());
 
1529
 
 
1530
    QModelIndex index49 = view.model()->index(49,0);
 
1531
    QPoint p = view.visualRect(index49).center();
 
1532
    QVERIFY(view.viewport()->rect().contains(p));
 
1533
 
 
1534
    QSignalSpy clickedSpy(&view, SIGNAL(clicked(QModelIndex)));
 
1535
 
 
1536
    QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p);
 
1537
    QCOMPARE(clickedSpy.count(), 1);
 
1538
 
 
1539
    QTest::mouseClick(view.viewport(), Qt::RightButton, 0, p);
 
1540
    // We expect that right-clicks do not cause the clicked() signal to
 
1541
    // be emitted.
 
1542
    QCOMPARE(clickedSpy.count(), 1);
 
1543
 
 
1544
}
 
1545
 
 
1546
class StateChangeDelegate : public QItemDelegate {
 
1547
  Q_OBJECT
 
1548
 
 
1549
public:
 
1550
  explicit StateChangeDelegate(QObject* parent = 0) :
 
1551
    QItemDelegate(parent)
 
1552
  {}
 
1553
 
 
1554
  void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE {
 
1555
      Q_UNUSED(index);
 
1556
      static bool w = true;
 
1557
      editor->setEnabled(w);
 
1558
      w = !w;
 
1559
  }
 
1560
};
 
1561
 
 
1562
class StateChangeModel : public QStandardItemModel {
 
1563
  Q_OBJECT
 
1564
 
 
1565
public:
 
1566
  explicit StateChangeModel(QObject *parent = 0) :
 
1567
    QStandardItemModel(parent)
 
1568
  {}
 
1569
 
 
1570
  void emitDataChanged() {
 
1571
    emit dataChanged(index(0, 0), index(0, 1));
 
1572
  }
 
1573
};
 
1574
 
 
1575
 
 
1576
void tst_QAbstractItemView::testChangeEditorState()
 
1577
{
 
1578
    // Test for QTBUG-25370
 
1579
    StateChangeModel model;
 
1580
    {
 
1581
      QStandardItem* item = new QStandardItem("a");
 
1582
      model.setItem(0, 0, item);
 
1583
    }
 
1584
    {
 
1585
      QStandardItem* item = new QStandardItem("b");
 
1586
      model.setItem(0, 1, item);
 
1587
    }
 
1588
 
 
1589
    QTableView view;
 
1590
    view.setEditTriggers(QAbstractItemView::CurrentChanged);
 
1591
    view.setItemDelegate(new StateChangeDelegate);
 
1592
    view.setModel(&model);
 
1593
    view.show();
 
1594
    QApplication::setActiveWindow(&view);
 
1595
    QVERIFY(QTest::qWaitForWindowActive(&view));
 
1596
    QCOMPARE(static_cast<QWidget *>(&view), QApplication::activeWindow());
 
1597
 
 
1598
    model.emitDataChanged();
 
1599
    // No segfault - the test passes.
 
1600
}
 
1601
 
 
1602
QTEST_MAIN(tst_QAbstractItemView)
 
1603
#include "tst_qabstractitemview.moc"