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