tests/auto/qtreeview/tst_qtreeview.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 
       
    44 #include <qabstractitemview.h>
       
    45 
       
    46 #include <QtTest/QtTest>
       
    47 #include <QtGui/QtGui>
       
    48 #include "../../shared/util.h"
       
    49 
       
    50 //TESTED_CLASS=
       
    51 //TESTED_FILES=
       
    52 
       
    53 Q_DECLARE_METATYPE(QModelIndex)
       
    54 #ifndef QT_NO_DRAGANDDROP
       
    55 Q_DECLARE_METATYPE(QAbstractItemView::DragDropMode)
       
    56 #endif
       
    57 Q_DECLARE_METATYPE(QAbstractItemView::EditTriggers)
       
    58 Q_DECLARE_METATYPE(QAbstractItemView::EditTrigger)
       
    59 
       
    60 static void initStandardTreeModel(QStandardItemModel *model)
       
    61 {
       
    62     QStandardItem *item;
       
    63     item = new QStandardItem(QLatin1String("Row 1 Item"));
       
    64     model->insertRow(0, item);
       
    65 
       
    66     item = new QStandardItem(QLatin1String("Row 2 Item"));
       
    67     item->setCheckable(true);
       
    68     model->insertRow(1, item);
       
    69 
       
    70     QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
       
    71     item->setChild(0, childItem);
       
    72 
       
    73     item = new QStandardItem(QLatin1String("Row 3 Item"));
       
    74     item->setIcon(QIcon());
       
    75     model->insertRow(2, item);
       
    76 }
       
    77 
       
    78 struct PublicView : public QTreeView
       
    79 {
       
    80     inline void executeDelayedItemsLayout()
       
    81     { QTreeView::executeDelayedItemsLayout(); }
       
    82 
       
    83     enum PublicCursorAction {
       
    84         MoveUp = QAbstractItemView::MoveUp,
       
    85         MoveDown = QAbstractItemView::MoveDown,
       
    86         MoveLeft = QAbstractItemView::MoveLeft,
       
    87         MoveRight = QAbstractItemView::MoveRight,
       
    88         MoveHome = QAbstractItemView::MoveHome,
       
    89         MoveEnd = QAbstractItemView::MoveEnd,
       
    90         MovePageUp = QAbstractItemView::MovePageUp,
       
    91         MovePageDown = QAbstractItemView::MovePageDown,
       
    92         MoveNext = QAbstractItemView::MoveNext,
       
    93         MovePrevious = QAbstractItemView::MovePrevious
       
    94     };
       
    95 
       
    96     inline QModelIndex moveCursor(PublicCursorAction ca, Qt::KeyboardModifiers kbm)
       
    97     { return QTreeView::moveCursor((CursorAction)ca, kbm); }
       
    98 
       
    99     inline void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
       
   100     {
       
   101         QTreeView::setSelection(rect, command);
       
   102     }
       
   103     inline int state()
       
   104     {
       
   105         return QTreeView::state();
       
   106     }
       
   107 
       
   108     inline int rowHeight(QModelIndex idx) { return QTreeView::rowHeight(idx); }
       
   109     inline int indexRowSizeHint(const QModelIndex &index) const { return QTreeView::indexRowSizeHint(index); }
       
   110 
       
   111     inline QModelIndexList selectedIndexes() const { return QTreeView::selectedIndexes(); }
       
   112 
       
   113     inline QStyleOptionViewItem viewOptions() const { return QTreeView::viewOptions(); }
       
   114     inline int sizeHintForColumn(int column) const { return QTreeView::sizeHintForColumn(column); }
       
   115 };
       
   116 
       
   117 class tst_QTreeView : public QObject
       
   118 {
       
   119     Q_OBJECT
       
   120 
       
   121 public:
       
   122     tst_QTreeView();
       
   123     virtual ~tst_QTreeView();
       
   124 
       
   125 
       
   126 public slots:
       
   127     void initTestCase();
       
   128     void cleanupTestCase();
       
   129     void init();
       
   130     void cleanup();
       
   131 
       
   132     void selectionOrderTest();
       
   133 
       
   134 private slots:
       
   135     void getSetCheck();
       
   136 
       
   137     // one test per QTreeView property
       
   138     void construction();
       
   139     void alternatingRowColors();
       
   140     void currentIndex_data();
       
   141     void currentIndex();
       
   142 #ifndef QT_NO_DRAGANDDROP
       
   143     void dragDropMode_data();
       
   144     void dragDropMode();
       
   145     void dragDropModeFromDragEnabledAndAcceptDrops_data();
       
   146     void dragDropModeFromDragEnabledAndAcceptDrops();
       
   147     void dragDropOverwriteMode();
       
   148 #endif
       
   149     void editTriggers_data();
       
   150     void editTriggers();
       
   151     void hasAutoScroll();
       
   152     void horizontalScrollMode();
       
   153     void iconSize();
       
   154     void indexAt();
       
   155     void indexWidget();
       
   156     void itemDelegate();
       
   157     void itemDelegateForColumnOrRow();
       
   158     void keyboardSearch();
       
   159     void setModel();
       
   160     void openPersistentEditor();
       
   161     void rootIndex();
       
   162 
       
   163     // specialized tests below
       
   164     void setHeader();
       
   165     void columnHidden();
       
   166     void rowHidden();
       
   167     void noDelegate();
       
   168     void noModel();
       
   169     void emptyModel();
       
   170     void removeRows();
       
   171     void removeCols();
       
   172     void expandAndCollapse_data();
       
   173     void expandAndCollapse();
       
   174     void expandAndCollapseAll();
       
   175     void expandWithNoChildren();
       
   176     void keyboardNavigation();
       
   177     void headerSections();
       
   178     void moveCursor_data();
       
   179     void moveCursor();
       
   180     void setSelection_data();
       
   181     void setSelection();
       
   182     void extendedSelection_data();
       
   183     void extendedSelection();
       
   184     void indexAbove();
       
   185     void indexBelow();
       
   186     void clicked();
       
   187     void mouseDoubleClick();
       
   188     void rowsAboutToBeRemoved();
       
   189     void headerSections_unhideSection();
       
   190     void columnAt();
       
   191     void scrollTo();
       
   192     void rowsAboutToBeRemoved_move();
       
   193     void resizeColumnToContents();
       
   194     void insertAfterSelect();
       
   195     void removeAfterSelect();
       
   196     void hiddenItems();
       
   197     void spanningItems();
       
   198     void rowSizeHint();
       
   199     void setSortingEnabled();
       
   200     void headerHidden();
       
   201 
       
   202     void selection();
       
   203     void removeAndInsertExpandedCol0();
       
   204     void selectionWithHiddenItems();
       
   205     void selectAll();
       
   206 
       
   207     void disabledButCheckable();
       
   208     void sortByColumn_data();
       
   209     void sortByColumn();
       
   210 
       
   211     void evilModel_data();
       
   212     void evilModel();
       
   213 
       
   214     void indexRowSizeHint();
       
   215     void addRowsWhileSectionsAreHidden();
       
   216     void filterProxyModelCrash();
       
   217     void styleOptionViewItem();
       
   218 
       
   219     // task-specific tests:
       
   220     void task174627_moveLeftToRoot();
       
   221     void task171902_expandWith1stColHidden();
       
   222     void task203696_hidingColumnsAndRowsn();
       
   223     void task211293_removeRootIndex();
       
   224     void task216717_updateChildren();
       
   225     void task220298_selectColumns();
       
   226     void task224091_appendColumns();
       
   227     void task225539_deleteModel();
       
   228     void task230123_setItemsExpandable();
       
   229     void task202039_closePersistentEditor();
       
   230     void task238873_avoidAutoReopening();
       
   231     void task244304_clickOnDecoration();
       
   232     void task246536_scrollbarsNotWorking();
       
   233     void task250683_wrongSectionSize();
       
   234     void task239271_addRowsWithFirstColumnHidden();
       
   235     void task254234_proxySort();
       
   236     void task248022_changeSelection();
       
   237     void task245654_changeModelAndExpandAll();
       
   238 };
       
   239 
       
   240 class QtTestModel: public QAbstractItemModel
       
   241 {
       
   242 public:
       
   243     QtTestModel(QObject *parent = 0): QAbstractItemModel(parent),
       
   244        fetched(false), rows(0), cols(0), levels(INT_MAX), wrongIndex(false) { init(); }
       
   245 
       
   246     QtTestModel(int _rows, int _cols, QObject *parent = 0): QAbstractItemModel(parent),
       
   247        rows(_rows), cols(_cols), levels(INT_MAX), wrongIndex(false) { init(); }
       
   248 
       
   249     void init() {
       
   250         decorationsEnabled = false;
       
   251     }
       
   252 
       
   253     inline qint32 level(const QModelIndex &index) const {
       
   254         return index.isValid() ? qint32(index.internalId()) : qint32(-1);
       
   255     }
       
   256 
       
   257     bool canFetchMore(const QModelIndex &) const {
       
   258         return !fetched;
       
   259     }
       
   260 
       
   261     void fetchMore(const QModelIndex &) {
       
   262         fetched = true;
       
   263     }
       
   264 
       
   265     bool hasChildren(const QModelIndex &parent = QModelIndex()) const {
       
   266         bool hasFetched = fetched;
       
   267         fetched = true;
       
   268         bool r = QAbstractItemModel::hasChildren(parent);
       
   269         fetched = hasFetched;
       
   270         return r;
       
   271     }
       
   272 
       
   273     int rowCount(const QModelIndex& parent = QModelIndex()) const {
       
   274         Q_ASSERT(fetched);
       
   275         if ((parent.column() > 0) || (level(parent) > levels))
       
   276             return 0;
       
   277         return rows;
       
   278     }
       
   279     int columnCount(const QModelIndex& parent = QModelIndex()) const {
       
   280         if ((parent.column() > 0) || (level(parent) > levels))
       
   281             return 0;
       
   282         return cols;
       
   283     }
       
   284 
       
   285     bool isEditable(const QModelIndex &index) const {
       
   286         if (index.isValid())
       
   287             return true;
       
   288         return false;
       
   289     }
       
   290 
       
   291     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
       
   292     {
       
   293         if (row < 0 || column < 0 || (level(parent) > levels) || column >= cols || row >= rows) {
       
   294             return QModelIndex();
       
   295         }
       
   296         QModelIndex i = createIndex(row, column, level(parent) + 1);
       
   297         parentHash[i] = parent;
       
   298         return i;
       
   299     }
       
   300 
       
   301     QModelIndex parent(const QModelIndex &index) const
       
   302     {
       
   303         if (!parentHash.contains(index))
       
   304             return QModelIndex();
       
   305         return parentHash[index];
       
   306     }
       
   307 
       
   308     QVariant data(const QModelIndex &idx, int role) const
       
   309     {
       
   310         if (!idx.isValid())
       
   311             return QVariant();
       
   312 
       
   313         if (role == Qt::DisplayRole) {
       
   314             if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) {
       
   315                 wrongIndex = true;
       
   316                 qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(),
       
   317                          idx.internalPointer());
       
   318             }
       
   319             if (idx.row() & 1)
       
   320                 return QString("[%1,%2,%3] - this item is extra wide").arg(idx.row()).arg(idx.column()).arg(level(idx));
       
   321             return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column()).arg(level(idx));
       
   322         }
       
   323         if (decorationsEnabled && role == Qt::DecorationRole) {
       
   324             QPixmap pm(16,16);
       
   325             pm.fill(QColor::fromHsv((idx.column() % 16)*8 + 64, 254, (idx.row() % 16)*8 + 32));
       
   326             return pm;
       
   327         }
       
   328         return QVariant();
       
   329     }
       
   330 
       
   331     void removeLastRow()
       
   332     {
       
   333         beginRemoveRows(QModelIndex(), rows - 1, rows - 1);
       
   334         --rows;
       
   335         endRemoveRows();
       
   336     }
       
   337 
       
   338     void removeAllRows()
       
   339     {
       
   340         beginRemoveRows(QModelIndex(), 0, rows - 1);
       
   341         rows = 0;
       
   342         endRemoveRows();
       
   343     }
       
   344 
       
   345     void removeLastColumn()
       
   346     {
       
   347         beginRemoveColumns(QModelIndex(), cols - 1, cols - 1);
       
   348         --cols;
       
   349         endRemoveColumns();
       
   350     }
       
   351 
       
   352     void removeAllColumns()
       
   353     {
       
   354         beginRemoveColumns(QModelIndex(), 0, cols - 1);
       
   355         cols = 0;
       
   356         endRemoveColumns();
       
   357     }
       
   358 
       
   359     void insertNewRow()
       
   360     {
       
   361         beginInsertRows(QModelIndex(), rows - 1, rows - 1);
       
   362         ++rows;
       
   363         endInsertRows();
       
   364     }
       
   365 
       
   366     void setDecorationsEnabled(bool enable)
       
   367     {
       
   368         decorationsEnabled = enable;
       
   369     }
       
   370 
       
   371     mutable bool fetched;
       
   372     bool decorationsEnabled;
       
   373     int rows, cols;
       
   374     int levels;
       
   375     mutable bool wrongIndex;
       
   376     mutable QMap<QModelIndex,QModelIndex> parentHash;
       
   377 };
       
   378 
       
   379 tst_QTreeView::tst_QTreeView()
       
   380 {
       
   381 }
       
   382 
       
   383 tst_QTreeView::~tst_QTreeView()
       
   384 {
       
   385 }
       
   386 
       
   387 void tst_QTreeView::initTestCase()
       
   388 {
       
   389 #ifdef Q_OS_WINCE //disable magic for WindowsCE
       
   390     qApp->setAutoMaximizeThreshold(-1);
       
   391 #endif
       
   392     qRegisterMetaType<QModelIndex>("QModelIndex");
       
   393 }
       
   394 
       
   395 void tst_QTreeView::cleanupTestCase()
       
   396 {
       
   397 }
       
   398 
       
   399 void tst_QTreeView::init()
       
   400 {
       
   401 }
       
   402 
       
   403 void tst_QTreeView::cleanup()
       
   404 {
       
   405 }
       
   406 
       
   407 // Testing get/set functions
       
   408 void tst_QTreeView::getSetCheck()
       
   409 {
       
   410     QTreeView obj1;
       
   411 
       
   412     // int QTreeView::indentation()
       
   413     // void QTreeView::setIndentation(int)
       
   414     QCOMPARE(obj1.indentation(), 20);
       
   415     obj1.setIndentation(0);
       
   416     QCOMPARE(obj1.indentation(), 0);
       
   417     obj1.setIndentation(INT_MIN);
       
   418     QCOMPARE(obj1.indentation(), INT_MIN);
       
   419     obj1.setIndentation(INT_MAX);
       
   420     QCOMPARE(obj1.indentation(), INT_MAX);
       
   421 
       
   422     // bool QTreeView::rootIsDecorated()
       
   423     // void QTreeView::setRootIsDecorated(bool)
       
   424     QCOMPARE(obj1.rootIsDecorated(), true);
       
   425     obj1.setRootIsDecorated(false);
       
   426     QCOMPARE(obj1.rootIsDecorated(), false);
       
   427     obj1.setRootIsDecorated(true);
       
   428     QCOMPARE(obj1.rootIsDecorated(), true);
       
   429 
       
   430     // bool QTreeView::uniformRowHeights()
       
   431     // void QTreeView::setUniformRowHeights(bool)
       
   432     QCOMPARE(obj1.uniformRowHeights(), false);
       
   433     obj1.setUniformRowHeights(false);
       
   434     QCOMPARE(obj1.uniformRowHeights(), false);
       
   435     obj1.setUniformRowHeights(true);
       
   436     QCOMPARE(obj1.uniformRowHeights(), true);
       
   437 
       
   438     // bool QTreeView::itemsExpandable()
       
   439     // void QTreeView::setItemsExpandable(bool)
       
   440     QCOMPARE(obj1.itemsExpandable(), true);
       
   441     obj1.setItemsExpandable(false);
       
   442     QCOMPARE(obj1.itemsExpandable(), false);
       
   443     obj1.setItemsExpandable(true);
       
   444     QCOMPARE(obj1.itemsExpandable(), true);
       
   445 
       
   446     // bool QTreeView::allColumnsShowFocus
       
   447     // void QTreeView::setAllColumnsShowFocus
       
   448     QCOMPARE(obj1.allColumnsShowFocus(), false);
       
   449     obj1.setAllColumnsShowFocus(false);
       
   450     QCOMPARE(obj1.allColumnsShowFocus(), false);
       
   451     obj1.setAllColumnsShowFocus(true);
       
   452     QCOMPARE(obj1.allColumnsShowFocus(), true);
       
   453 
       
   454     // bool QTreeView::isAnimated
       
   455     // void QTreeView::setAnimated
       
   456     QCOMPARE(obj1.isAnimated(), false);
       
   457     obj1.setAnimated(false);
       
   458     QCOMPARE(obj1.isAnimated(), false);
       
   459     obj1.setAnimated(true);
       
   460     QCOMPARE(obj1.isAnimated(), true);
       
   461 
       
   462     // bool QTreeView::setSortingEnabled
       
   463     // void QTreeView::isSortingEnabled
       
   464     QCOMPARE(obj1.isSortingEnabled(), false);
       
   465     obj1.setSortingEnabled(false);
       
   466     QCOMPARE(obj1.isSortingEnabled(), false);
       
   467     obj1.setSortingEnabled(true);
       
   468     QCOMPARE(obj1.isSortingEnabled(), true);
       
   469 }
       
   470 
       
   471 void tst_QTreeView::construction()
       
   472 {
       
   473     QTreeView view;
       
   474 
       
   475     // QAbstractItemView properties
       
   476     QVERIFY(!view.alternatingRowColors());
       
   477     QCOMPARE(view.currentIndex(), QModelIndex());
       
   478 #ifndef QT_NO_DRAGANDDROP
       
   479     QCOMPARE(view.dragDropMode(), QAbstractItemView::NoDragDrop);
       
   480     QVERIFY(!view.dragDropOverwriteMode());
       
   481     QVERIFY(!view.dragEnabled());
       
   482 #endif
       
   483     QCOMPARE(view.editTriggers(), QAbstractItemView::EditKeyPressed | QAbstractItemView::DoubleClicked);
       
   484     QVERIFY(view.hasAutoScroll());
       
   485     QCOMPARE(view.horizontalScrollMode(), QAbstractItemView::ScrollPerPixel);
       
   486     QCOMPARE(view.iconSize(), QSize());
       
   487     QCOMPARE(view.indexAt(QPoint()), QModelIndex());
       
   488     QVERIFY(!view.indexWidget(QModelIndex()));
       
   489     QVERIFY(qobject_cast<QStyledItemDelegate *>(view.itemDelegate()));
       
   490     QVERIFY(!view.itemDelegateForColumn(-1));
       
   491     QVERIFY(!view.itemDelegateForColumn(0));
       
   492     QVERIFY(!view.itemDelegateForColumn(1));
       
   493     QVERIFY(!view.itemDelegateForRow(-1));
       
   494     QVERIFY(!view.itemDelegateForRow(0));
       
   495     QVERIFY(!view.itemDelegateForRow(1));
       
   496     QVERIFY(!view.model());
       
   497     QCOMPARE(view.rootIndex(), QModelIndex());
       
   498     QCOMPARE(view.selectionBehavior(), QAbstractItemView::SelectRows);
       
   499     QCOMPARE(view.selectionMode(), QAbstractItemView::SingleSelection);
       
   500     QVERIFY(!view.selectionModel());
       
   501 #ifndef QT_NO_DRAGANDDROP
       
   502     QVERIFY(view.showDropIndicator());
       
   503 #endif
       
   504     QCOMPARE(view.QAbstractItemView::sizeHintForColumn(-1), -1); // <- protected in QTreeView
       
   505     QCOMPARE(view.QAbstractItemView::sizeHintForColumn(0), -1); // <- protected in QTreeView
       
   506     QCOMPARE(view.QAbstractItemView::sizeHintForColumn(1), -1); // <- protected in QTreeView
       
   507     QCOMPARE(view.sizeHintForIndex(QModelIndex()), QSize());
       
   508     QCOMPARE(view.sizeHintForRow(-1), -1);
       
   509     QCOMPARE(view.sizeHintForRow(0), -1);
       
   510     QCOMPARE(view.sizeHintForRow(1), -1);
       
   511     QVERIFY(!view.tabKeyNavigation());
       
   512     QCOMPARE(view.textElideMode(), Qt::ElideRight);
       
   513     QCOMPARE(view.verticalScrollMode(), QAbstractItemView::ScrollPerItem);
       
   514     QCOMPARE(view.visualRect(QModelIndex()), QRect());
       
   515 
       
   516     // QTreeView properties
       
   517     QVERIFY(!view.allColumnsShowFocus());
       
   518     QCOMPARE(view.autoExpandDelay(), -1);
       
   519     QCOMPARE(view.columnAt(-1), -1);
       
   520     QCOMPARE(view.columnAt(0), -1);
       
   521     QCOMPARE(view.columnAt(1), -1);
       
   522     QCOMPARE(view.columnViewportPosition(-1), -1);
       
   523     QCOMPARE(view.columnViewportPosition(0), -1);
       
   524     QCOMPARE(view.columnViewportPosition(1), -1);
       
   525     QCOMPARE(view.columnWidth(-1), 0);
       
   526     QCOMPARE(view.columnWidth(0), 0);
       
   527     QCOMPARE(view.columnWidth(1), 0);
       
   528     QVERIFY(view.header());
       
   529     QCOMPARE(view.indentation(), 20);
       
   530     QCOMPARE(view.indexAbove(QModelIndex()), QModelIndex());
       
   531     QCOMPARE(view.indexBelow(QModelIndex()), QModelIndex());
       
   532     QVERIFY(!view.isAnimated());
       
   533     QVERIFY(!view.isColumnHidden(-1));
       
   534     QVERIFY(!view.isColumnHidden(0));
       
   535     QVERIFY(!view.isColumnHidden(1));
       
   536     QVERIFY(!view.isExpanded(QModelIndex()));
       
   537     QVERIFY(!view.isRowHidden(-1, QModelIndex()));
       
   538     QVERIFY(!view.isRowHidden(0, QModelIndex()));
       
   539     QVERIFY(!view.isRowHidden(1, QModelIndex()));
       
   540     QVERIFY(!view.isFirstColumnSpanned(-1, QModelIndex()));
       
   541     QVERIFY(!view.isFirstColumnSpanned(0, QModelIndex()));
       
   542     QVERIFY(!view.isFirstColumnSpanned(1, QModelIndex()));
       
   543     QVERIFY(!view.isSortingEnabled());
       
   544     QVERIFY(view.itemsExpandable());
       
   545     QVERIFY(view.rootIsDecorated());
       
   546     QVERIFY(!view.uniformRowHeights());
       
   547     QCOMPARE(view.visualRect(QModelIndex()), QRect());
       
   548     QVERIFY(!view.wordWrap());
       
   549 }
       
   550 
       
   551 void tst_QTreeView::alternatingRowColors()
       
   552 {
       
   553     QTreeView view;
       
   554     QVERIFY(!view.alternatingRowColors());
       
   555     view.setAlternatingRowColors(true);
       
   556     QVERIFY(view.alternatingRowColors());
       
   557     view.setAlternatingRowColors(false);
       
   558     QVERIFY(!view.alternatingRowColors());
       
   559 
       
   560     // ### Test visual effect.
       
   561 }
       
   562 
       
   563 void tst_QTreeView::currentIndex_data()
       
   564 {
       
   565     QTest::addColumn<int>("row");
       
   566     QTest::addColumn<int>("column");
       
   567     QTest::addColumn<int>("indexRow");
       
   568     QTest::addColumn<int>("indexColumn");
       
   569     QTest::addColumn<int>("parentIndexRow");
       
   570     QTest::addColumn<int>("parentIndexColumn");
       
   571 
       
   572     QTest::newRow("-1, -1") << -1 << -1 << -1 << -1 << -1 << -1;
       
   573     QTest::newRow("-1, 0") << -1 << 0 << -1 << -1 << -1 << -1;
       
   574     QTest::newRow("0, -1") << 0 << -1 << -1 << -1 << -1 << -1;
       
   575     QTest::newRow("0, 0") << 0 << 0 << 0 << 0 << -1 << -1;
       
   576     QTest::newRow("0, 1") << 0 << 0 << 0 << 0 << -1 << -1;
       
   577     QTest::newRow("1, 0") << 1 << 0 << 1 << 0 << -1 << -1;
       
   578     QTest::newRow("1, 1") << 1 << 1 << -1 << -1 << -1 << -1;
       
   579     QTest::newRow("2, 0") << 2 << 0 << 2 << 0 << -1 << -1;
       
   580     QTest::newRow("2, 1") << 2 << 1 << -1 << -1 << -1 << -1;
       
   581     QTest::newRow("3, -1") << 3 << -1 << -1 << -1 << -1 << -1;
       
   582     QTest::newRow("3, 0") << 3 << 0 << -1 << -1 << -1 << -1;
       
   583     QTest::newRow("3, 1") << 3 << 1 << -1 << -1 << -1 << -1;
       
   584 }
       
   585 
       
   586 void tst_QTreeView::currentIndex()
       
   587 {
       
   588     QFETCH(int, row);
       
   589     QFETCH(int, column);
       
   590     QFETCH(int, indexRow);
       
   591     QFETCH(int, indexColumn);
       
   592     QFETCH(int, parentIndexRow);
       
   593     QFETCH(int, parentIndexColumn);
       
   594 
       
   595     QTreeView view;
       
   596     QStandardItemModel treeModel;
       
   597     initStandardTreeModel(&treeModel);
       
   598     view.setModel(&treeModel);
       
   599 
       
   600     QCOMPARE(view.currentIndex(), QModelIndex());
       
   601     view.setCurrentIndex(view.model()->index(row, column));
       
   602     QCOMPARE(view.currentIndex().row(), indexRow);
       
   603     QCOMPARE(view.currentIndex().column(), indexColumn);
       
   604     QCOMPARE(view.currentIndex().parent().row(), parentIndexRow);
       
   605     QCOMPARE(view.currentIndex().parent().column(), parentIndexColumn);
       
   606 
       
   607     // ### Test child and grandChild indexes.
       
   608 }
       
   609 
       
   610 #ifndef QT_NO_DRAGANDDROP
       
   611 
       
   612 void tst_QTreeView::dragDropMode_data()
       
   613 {
       
   614     QTest::addColumn<QAbstractItemView::DragDropMode>("dragDropMode");
       
   615     QTest::addColumn<bool>("acceptDrops");
       
   616     QTest::addColumn<bool>("dragEnabled");
       
   617     QTest::newRow("NoDragDrop") << QAbstractItemView::NoDragDrop << false << false;
       
   618     QTest::newRow("DragOnly") << QAbstractItemView::DragOnly << false << true;
       
   619     QTest::newRow("DropOnly") << QAbstractItemView::DropOnly << true << false;
       
   620     QTest::newRow("DragDrop") << QAbstractItemView::DragDrop << true << true;
       
   621     QTest::newRow("InternalMove") << QAbstractItemView::InternalMove << true << true;
       
   622 }
       
   623 
       
   624 void tst_QTreeView::dragDropMode()
       
   625 {
       
   626     QFETCH(QAbstractItemView::DragDropMode, dragDropMode);
       
   627     QFETCH(bool, acceptDrops);
       
   628     QFETCH(bool, dragEnabled);
       
   629 
       
   630     QTreeView view;
       
   631     QCOMPARE(view.dragDropMode(), QAbstractItemView::NoDragDrop);
       
   632     QVERIFY(!view.acceptDrops());
       
   633     QVERIFY(!view.dragEnabled());
       
   634 
       
   635     view.setDragDropMode(dragDropMode);
       
   636     QCOMPARE(view.dragDropMode(), dragDropMode);
       
   637     QCOMPARE(view.acceptDrops(), acceptDrops);
       
   638     QCOMPARE(view.dragEnabled(), dragEnabled);
       
   639 
       
   640     // ### Test effects of this mode
       
   641 }
       
   642 
       
   643 void tst_QTreeView::dragDropModeFromDragEnabledAndAcceptDrops_data()
       
   644 {
       
   645     QTest::addColumn<bool>("dragEnabled");
       
   646     QTest::addColumn<bool>("acceptDrops");
       
   647     QTest::addColumn<QAbstractItemView::DragDropMode>("dragDropMode");
       
   648     QTest::addColumn<QAbstractItemView::DragDropMode>("setBehavior");
       
   649 
       
   650     QTest::newRow("NoDragDrop -1") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DragDropMode(-1);
       
   651     QTest::newRow("NoDragDrop 0") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::NoDragDrop;
       
   652     QTest::newRow("NoDragDrop 1") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DragOnly;
       
   653     QTest::newRow("NoDragDrop 2") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DropOnly;
       
   654     QTest::newRow("NoDragDrop 3") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::DragDrop;
       
   655     QTest::newRow("NoDragDrop 4") << false << false << QAbstractItemView::NoDragDrop << QAbstractItemView::InternalMove;
       
   656     QTest::newRow("DragOnly -1") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DragDropMode(-1);
       
   657     QTest::newRow("DragOnly 0") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::NoDragDrop;
       
   658     QTest::newRow("DragOnly 1") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DragOnly;
       
   659     QTest::newRow("DragOnly 2") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DropOnly;
       
   660     QTest::newRow("DragOnly 3") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::DragDrop;
       
   661     QTest::newRow("DragOnly 4") << true << false << QAbstractItemView::DragOnly << QAbstractItemView::InternalMove;
       
   662     QTest::newRow("DropOnly -1") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DragDropMode(-1);
       
   663     QTest::newRow("DropOnly 0") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::NoDragDrop;
       
   664     QTest::newRow("DropOnly 1") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DragOnly;
       
   665     QTest::newRow("DropOnly 2") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DropOnly;
       
   666     QTest::newRow("DropOnly 3") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::DragDrop;
       
   667     QTest::newRow("DropOnly 4") << false << true << QAbstractItemView::DropOnly << QAbstractItemView::InternalMove;
       
   668     QTest::newRow("DragDrop -1") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragDropMode(-1);
       
   669     QTest::newRow("DragDrop 0") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragDropMode(-1);
       
   670     QTest::newRow("DragDrop 1") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::NoDragDrop;
       
   671     QTest::newRow("DragDrop 2") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragOnly;
       
   672     QTest::newRow("DragDrop 3") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DropOnly;
       
   673     QTest::newRow("DragDrop 4") << true << true << QAbstractItemView::DragDrop << QAbstractItemView::DragDrop;
       
   674     QTest::newRow("DragDrop 5") << true << true << QAbstractItemView::InternalMove << QAbstractItemView::InternalMove;
       
   675 }
       
   676 
       
   677 void tst_QTreeView::dragDropModeFromDragEnabledAndAcceptDrops()
       
   678 {
       
   679     QFETCH(bool, acceptDrops);
       
   680     QFETCH(bool, dragEnabled);
       
   681     QFETCH(QAbstractItemView::DragDropMode, dragDropMode);
       
   682     QFETCH(QAbstractItemView::DragDropMode, setBehavior);
       
   683 
       
   684     QTreeView view;
       
   685     QCOMPARE(view.dragDropMode(), QAbstractItemView::NoDragDrop);
       
   686 
       
   687     if (setBehavior != QAbstractItemView::DragDropMode(-1))
       
   688         view.setDragDropMode(setBehavior);
       
   689 
       
   690     view.setAcceptDrops(acceptDrops);
       
   691     view.setDragEnabled(dragEnabled);
       
   692     QCOMPARE(view.dragDropMode(), dragDropMode);
       
   693 
       
   694     // ### Test effects of this mode
       
   695 }
       
   696 
       
   697 void tst_QTreeView::dragDropOverwriteMode()
       
   698 {
       
   699     QTreeView view;
       
   700     QVERIFY(!view.dragDropOverwriteMode());
       
   701     view.setDragDropOverwriteMode(true);
       
   702     QVERIFY(view.dragDropOverwriteMode());
       
   703     view.setDragDropOverwriteMode(false);
       
   704     QVERIFY(!view.dragDropOverwriteMode());
       
   705 
       
   706     // ### This property changes the behavior of dropIndicatorPosition(),
       
   707     // which is protected and called only from within QListWidget and
       
   708     // QTableWidget, from their reimplementations of dropMimeData(). Hard to
       
   709     // test.
       
   710 }
       
   711 #endif
       
   712 
       
   713 void tst_QTreeView::editTriggers_data()
       
   714 {
       
   715     QTest::addColumn<QAbstractItemView::EditTriggers>("editTriggers");
       
   716     QTest::addColumn<QAbstractItemView::EditTrigger>("triggeredTrigger");
       
   717     QTest::addColumn<bool>("editorOpened");
       
   718 
       
   719     // NoEditTriggers
       
   720     QTest::newRow("NoEditTriggers 0") << QAbstractItemView::EditTriggers(QAbstractItemView::NoEditTriggers)
       
   721                                       << QAbstractItemView::NoEditTriggers << false;
       
   722     QTest::newRow("NoEditTriggers 1") << QAbstractItemView::EditTriggers(QAbstractItemView::NoEditTriggers)
       
   723                                       << QAbstractItemView::CurrentChanged << false;
       
   724     QTest::newRow("NoEditTriggers 2") << QAbstractItemView::EditTriggers(QAbstractItemView::NoEditTriggers)
       
   725                                       << QAbstractItemView::DoubleClicked << false;
       
   726     QTest::newRow("NoEditTriggers 3") << QAbstractItemView::EditTriggers(QAbstractItemView::NoEditTriggers)
       
   727                                       << QAbstractItemView::SelectedClicked << false;
       
   728     QTest::newRow("NoEditTriggers 4") << QAbstractItemView::EditTriggers(QAbstractItemView::NoEditTriggers)
       
   729                                       << QAbstractItemView::EditKeyPressed << false;
       
   730 
       
   731     // CurrentChanged
       
   732     QTest::newRow("CurrentChanged 0") << QAbstractItemView::EditTriggers(QAbstractItemView::CurrentChanged)
       
   733                                       << QAbstractItemView::NoEditTriggers << false;
       
   734     QTest::newRow("CurrentChanged 1") << QAbstractItemView::EditTriggers(QAbstractItemView::CurrentChanged)
       
   735                                       << QAbstractItemView::CurrentChanged << true;
       
   736     QTest::newRow("CurrentChanged 2") << QAbstractItemView::EditTriggers(QAbstractItemView::CurrentChanged)
       
   737                                       << QAbstractItemView::DoubleClicked << false;
       
   738     QTest::newRow("CurrentChanged 3") << QAbstractItemView::EditTriggers(QAbstractItemView::CurrentChanged)
       
   739                                       << QAbstractItemView::SelectedClicked << false;
       
   740     QTest::newRow("CurrentChanged 4") << QAbstractItemView::EditTriggers(QAbstractItemView::CurrentChanged)
       
   741                                       << QAbstractItemView::EditKeyPressed << false;
       
   742 
       
   743     // DoubleClicked
       
   744     QTest::newRow("DoubleClicked 0") << QAbstractItemView::EditTriggers(QAbstractItemView::DoubleClicked)
       
   745                                      << QAbstractItemView::NoEditTriggers << false;
       
   746     QTest::newRow("DoubleClicked 1") << QAbstractItemView::EditTriggers(QAbstractItemView::DoubleClicked)
       
   747                                      << QAbstractItemView::CurrentChanged << false;
       
   748     QTest::newRow("DoubleClicked 2") << QAbstractItemView::EditTriggers(QAbstractItemView::DoubleClicked)
       
   749                                      << QAbstractItemView::DoubleClicked << true;
       
   750     QTest::newRow("DoubleClicked 3") << QAbstractItemView::EditTriggers(QAbstractItemView::DoubleClicked)
       
   751                                      << QAbstractItemView::SelectedClicked << false;
       
   752     QTest::newRow("DoubleClicked 4") << QAbstractItemView::EditTriggers(QAbstractItemView::DoubleClicked)
       
   753                                      << QAbstractItemView::EditKeyPressed << false;
       
   754 
       
   755     // SelectedClicked
       
   756     QTest::newRow("SelectedClicked 0") << QAbstractItemView::EditTriggers(QAbstractItemView::SelectedClicked)
       
   757                                        << QAbstractItemView::NoEditTriggers << false;
       
   758     QTest::newRow("SelectedClicked 1") << QAbstractItemView::EditTriggers(QAbstractItemView::SelectedClicked)
       
   759                                        << QAbstractItemView::CurrentChanged << false;
       
   760     QTest::newRow("SelectedClicked 2") << QAbstractItemView::EditTriggers(QAbstractItemView::SelectedClicked)
       
   761                                        << QAbstractItemView::DoubleClicked << false;
       
   762     QTest::newRow("SelectedClicked 3") << QAbstractItemView::EditTriggers(QAbstractItemView::SelectedClicked)
       
   763                                        << QAbstractItemView::SelectedClicked << true;
       
   764     QTest::newRow("SelectedClicked 4") << QAbstractItemView::EditTriggers(QAbstractItemView::SelectedClicked)
       
   765                                        << QAbstractItemView::EditKeyPressed << false;
       
   766 
       
   767     // EditKeyPressed
       
   768     QTest::newRow("EditKeyPressed 0") << QAbstractItemView::EditTriggers(QAbstractItemView::EditKeyPressed)
       
   769                                       << QAbstractItemView::NoEditTriggers << false;
       
   770     QTest::newRow("EditKeyPressed 1") << QAbstractItemView::EditTriggers(QAbstractItemView::EditKeyPressed)
       
   771                                       << QAbstractItemView::CurrentChanged << false;
       
   772     QTest::newRow("EditKeyPressed 2") << QAbstractItemView::EditTriggers(QAbstractItemView::EditKeyPressed)
       
   773                                       << QAbstractItemView::DoubleClicked << false;
       
   774     QTest::newRow("EditKeyPressed 3") << QAbstractItemView::EditTriggers(QAbstractItemView::EditKeyPressed)
       
   775                                       << QAbstractItemView::SelectedClicked << false;
       
   776     QTest::newRow("EditKeyPressed 4") << QAbstractItemView::EditTriggers(QAbstractItemView::EditKeyPressed)
       
   777                                       << QAbstractItemView::EditKeyPressed << true;
       
   778 }
       
   779 
       
   780 void tst_QTreeView::editTriggers()
       
   781 {
       
   782     QFETCH(QAbstractItemView::EditTriggers, editTriggers);
       
   783     QFETCH(QAbstractItemView::EditTrigger, triggeredTrigger);
       
   784     QFETCH(bool, editorOpened);
       
   785 
       
   786     QTreeView view;
       
   787     QStandardItemModel treeModel;
       
   788     initStandardTreeModel(&treeModel);
       
   789     view.setModel(&treeModel);
       
   790     view.show();
       
   791 
       
   792     QCOMPARE(view.editTriggers(), QAbstractItemView::EditKeyPressed | QAbstractItemView::DoubleClicked);
       
   793 
       
   794     // Initialize the first index
       
   795     view.setCurrentIndex(view.model()->index(0, 0));
       
   796 
       
   797     // Verify that we don't have any editor initially
       
   798     QVERIFY(!qFindChild<QLineEdit *>(&view, QString()));
       
   799 
       
   800     // Set the triggers
       
   801     view.setEditTriggers(editTriggers);
       
   802 
       
   803     // Interact with the view
       
   804     switch (triggeredTrigger) {
       
   805     case QAbstractItemView::NoEditTriggers:
       
   806         // Do nothing, the editor shouldn't be there
       
   807         break;
       
   808     case QAbstractItemView::CurrentChanged:
       
   809         // Change the index to open an editor
       
   810         view.setCurrentIndex(view.model()->index(1, 0));
       
   811         break;
       
   812     case QAbstractItemView::DoubleClicked:
       
   813         // Doubleclick the center of the current cell
       
   814         QTest::mouseClick(view.viewport(), Qt::LeftButton, 0,
       
   815                           view.visualRect(view.model()->index(0, 0)).center());
       
   816         QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0,
       
   817                            view.visualRect(view.model()->index(0, 0)).center());
       
   818         break;
       
   819     case QAbstractItemView::SelectedClicked:
       
   820         // Click the center of the current cell
       
   821         view.selectionModel()->select(view.model()->index(0, 0), QItemSelectionModel::Select);
       
   822         QTest::mouseClick(view.viewport(), Qt::LeftButton, 0,
       
   823                           view.visualRect(view.model()->index(0, 0)).center());
       
   824         QTest::qWait(int(QApplication::doubleClickInterval() * 1.5));
       
   825         break;
       
   826     case QAbstractItemView::EditKeyPressed:
       
   827         view.setFocus();
       
   828 #ifdef Q_OS_MAC
       
   829         // Mac OS X uses Enter for editing
       
   830         QTest::keyPress(&view, Qt::Key_Enter);
       
   831 #else
       
   832         // All other platforms use F2
       
   833         QTest::keyPress(&view, Qt::Key_F2);
       
   834 #endif
       
   835         break;
       
   836     default:
       
   837         break;
       
   838     }
       
   839 
       
   840     // Check if we got an editor
       
   841     QTRY_COMPARE(qFindChild<QLineEdit *>(&view, QString()) != 0, editorOpened);
       
   842 }
       
   843 
       
   844 void tst_QTreeView::hasAutoScroll()
       
   845 {
       
   846     QTreeView view;
       
   847     QVERIFY(view.hasAutoScroll());
       
   848     view.setAutoScroll(false);
       
   849     QVERIFY(!view.hasAutoScroll());
       
   850     view.setAutoScroll(true);
       
   851     QVERIFY(view.hasAutoScroll());
       
   852 }
       
   853 
       
   854 void tst_QTreeView::horizontalScrollMode()
       
   855 {
       
   856     QStandardItemModel model;
       
   857     for (int i = 0; i < 100; ++i) {
       
   858         model.appendRow(QList<QStandardItem *>()
       
   859                         << new QStandardItem("An item that has very long text and should"
       
   860                                              " cause the horizontal scroll bar to appear.")
       
   861                         << new QStandardItem("An item that has very long text and should"
       
   862                                              " cause the horizontal scroll bar to appear."));
       
   863     }
       
   864 
       
   865     QTreeView view;
       
   866     view.setModel(&model);
       
   867     view.setFixedSize(100, 100);
       
   868     view.header()->resizeSection(0, 200);
       
   869     view.show();
       
   870 
       
   871     QCOMPARE(view.horizontalScrollMode(), QAbstractItemView::ScrollPerPixel);
       
   872     QCOMPARE(view.horizontalScrollBar()->minimum(), 0);
       
   873     QVERIFY(view.horizontalScrollBar()->maximum() > 2);
       
   874 
       
   875     view.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
       
   876     QCOMPARE(view.horizontalScrollMode(), QAbstractItemView::ScrollPerItem);
       
   877     QCOMPARE(view.horizontalScrollBar()->minimum(), 0);
       
   878     QCOMPARE(view.horizontalScrollBar()->maximum(), 1);
       
   879 
       
   880     view.setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
       
   881     QCOMPARE(view.horizontalScrollMode(), QAbstractItemView::ScrollPerPixel);
       
   882     QCOMPARE(view.horizontalScrollBar()->minimum(), 0);
       
   883     QVERIFY(view.horizontalScrollBar()->maximum() > 2);
       
   884 }
       
   885 
       
   886 class RepaintTreeView : public QTreeView
       
   887 {
       
   888 public:
       
   889     RepaintTreeView() : repainted(false) { }
       
   890     bool repainted;
       
   891 
       
   892 protected:
       
   893     void paintEvent(QPaintEvent *event)
       
   894     { repainted = true; QTreeView::paintEvent(event); }
       
   895 };
       
   896 
       
   897 void tst_QTreeView::iconSize()
       
   898 {
       
   899     RepaintTreeView view;
       
   900     QCOMPARE(view.iconSize(), QSize());
       
   901 
       
   902     QStandardItemModel treeModel;
       
   903     initStandardTreeModel(&treeModel);
       
   904     view.setModel(&treeModel);
       
   905     QCOMPARE(view.iconSize(), QSize());
       
   906     QVERIFY(!view.repainted);
       
   907 
       
   908     view.show();
       
   909     view.update();
       
   910     QTest::qWaitForWindowShown(&view);
       
   911     QTRY_VERIFY(view.repainted);
       
   912     QCOMPARE(view.iconSize(), QSize());
       
   913 
       
   914     view.repainted = false;
       
   915     view.setIconSize(QSize());
       
   916     QTRY_VERIFY(!view.repainted);
       
   917     QCOMPARE(view.iconSize(), QSize());
       
   918 
       
   919     view.setIconSize(QSize(10, 10));
       
   920     QTRY_VERIFY(view.repainted);
       
   921     QCOMPARE(view.iconSize(), QSize(10, 10));
       
   922 
       
   923     view.repainted = false;
       
   924     view.setIconSize(QSize(10000, 10000));
       
   925     QTRY_VERIFY(view.repainted);
       
   926     QCOMPARE(view.iconSize(), QSize(10000, 10000));
       
   927 }
       
   928 
       
   929 void tst_QTreeView::indexAt()
       
   930 {
       
   931     QtTestModel model;
       
   932     model.rows = model.cols = 5;
       
   933 
       
   934     QTreeView view;
       
   935     QCOMPARE(view.indexAt(QPoint()), QModelIndex());
       
   936     view.setModel(&model);
       
   937     QVERIFY(view.indexAt(QPoint()) != QModelIndex());
       
   938 
       
   939     QSize itemSize = view.visualRect(model.index(0, 0)).size();
       
   940     for (int i = 0; i < model.rowCount(); ++i) {
       
   941         QPoint pos(itemSize.width() / 2, (i * itemSize.height()) + (itemSize.height() / 2));
       
   942         QModelIndex index = view.indexAt(pos);
       
   943         QCOMPARE(index, model.index(i, 0));
       
   944     }
       
   945 
       
   946     /*
       
   947       // ### this is wrong; the widget _will_ affect the item size
       
   948     for (int j = 0; j < model.rowCount(); ++j)
       
   949         view.setIndexWidget(model.index(j, 0), new QPushButton);
       
   950     */
       
   951 
       
   952     for (int k = 0; k < model.rowCount(); ++k) {
       
   953         QPoint pos(itemSize.width() / 2, (k * itemSize.height()) + (itemSize.height() / 2));
       
   954         QModelIndex index = view.indexAt(pos);
       
   955         QCOMPARE(index, model.index(k, 0));
       
   956     }
       
   957 
       
   958     view.show();
       
   959     view.resize(600, 600);
       
   960     view.header()->setStretchLastSection(false);
       
   961     QCOMPARE(view.indexAt(QPoint(550, 20)), QModelIndex());
       
   962 }
       
   963 
       
   964 void tst_QTreeView::indexWidget()
       
   965 {
       
   966     QTreeView view;
       
   967     QStandardItemModel treeModel;
       
   968     initStandardTreeModel(&treeModel);
       
   969     view.setModel(&treeModel);
       
   970 
       
   971     QModelIndex index = view.model()->index(0, 0);
       
   972 
       
   973     QVERIFY(!view.indexWidget(QModelIndex()));
       
   974     QVERIFY(!view.indexWidget(index));
       
   975 
       
   976     QString text = QLatin1String("TestLabel");
       
   977 
       
   978     QWidget *label = new QLabel(text);
       
   979     view.setIndexWidget(QModelIndex(), label);
       
   980     QVERIFY(!view.indexWidget(QModelIndex()));
       
   981     QVERIFY(!label->parent());
       
   982     view.setIndexWidget(index, label);
       
   983     QCOMPARE(view.indexWidget(index), label);
       
   984     QCOMPARE(label->parentWidget(), view.viewport());
       
   985 
       
   986 
       
   987     QTextEdit *widget = new QTextEdit(text);
       
   988     widget->setFixedSize(200,100);
       
   989     view.setIndexWidget(index, widget);
       
   990     QCOMPARE(view.indexWidget(index), static_cast<QWidget *>(widget));
       
   991 
       
   992     QCOMPARE(widget->parentWidget(), view.viewport());
       
   993     QCOMPARE(widget->geometry(), view.visualRect(index).intersected(widget->geometry()));
       
   994     QCOMPARE(widget->toPlainText(), text);
       
   995 
       
   996     //now let's try to do that later when the widget is already shown
       
   997     view.show();
       
   998     index = view.model()->index(1, 0);
       
   999     QVERIFY(!view.indexWidget(index));
       
  1000 
       
  1001     widget = new QTextEdit(text);
       
  1002     widget->setFixedSize(200,100);
       
  1003     view.setIndexWidget(index, widget);
       
  1004     QCOMPARE(view.indexWidget(index), static_cast<QWidget *>(widget));
       
  1005 
       
  1006     QCOMPARE(widget->parentWidget(), view.viewport());
       
  1007     QCOMPARE(widget->geometry(), view.visualRect(index).intersect(widget->geometry()));
       
  1008     QCOMPARE(widget->toPlainText(), text);
       
  1009 }
       
  1010 
       
  1011 void tst_QTreeView::itemDelegate()
       
  1012 {
       
  1013     QPointer<QAbstractItemDelegate> oldDelegate;
       
  1014     QPointer<QItemDelegate> otherItemDelegate;
       
  1015 
       
  1016     {
       
  1017         QTreeView view;
       
  1018         QVERIFY(qobject_cast<QStyledItemDelegate *>(view.itemDelegate()));
       
  1019         QPointer<QAbstractItemDelegate> oldDelegate = view.itemDelegate();
       
  1020 
       
  1021         otherItemDelegate = new QItemDelegate;
       
  1022         view.setItemDelegate(otherItemDelegate);
       
  1023         QVERIFY(!otherItemDelegate->parent());
       
  1024         QVERIFY(oldDelegate);
       
  1025 
       
  1026         QCOMPARE(view.itemDelegate(), (QAbstractItemDelegate *)otherItemDelegate);
       
  1027 
       
  1028         view.setItemDelegate(0);
       
  1029         QVERIFY(!view.itemDelegate()); // <- view does its own drawing?
       
  1030         QVERIFY(otherItemDelegate);
       
  1031     }
       
  1032 
       
  1033     // This is strange. Why doesn't setItemDelegate() reparent the delegate?
       
  1034     QVERIFY(!oldDelegate);
       
  1035     QVERIFY(otherItemDelegate);
       
  1036 
       
  1037     delete otherItemDelegate;
       
  1038 }
       
  1039 
       
  1040 void tst_QTreeView::itemDelegateForColumnOrRow()
       
  1041 {
       
  1042     QTreeView view;
       
  1043     QAbstractItemDelegate *defaultDelegate = view.itemDelegate();
       
  1044     QVERIFY(defaultDelegate);
       
  1045 
       
  1046     QVERIFY(!view.itemDelegateForRow(0));
       
  1047     QVERIFY(!view.itemDelegateForColumn(0));
       
  1048     QCOMPARE(view.itemDelegate(QModelIndex()), defaultDelegate);
       
  1049 
       
  1050     QStandardItemModel model;
       
  1051     for (int i = 0; i < 100; ++i) {
       
  1052         model.appendRow(QList<QStandardItem *>()
       
  1053                         << new QStandardItem("An item that has very long text and should"
       
  1054                                              " cause the horizontal scroll bar to appear.")
       
  1055                         << new QStandardItem("An item that has very long text and should"
       
  1056                                              " cause the horizontal scroll bar to appear.")
       
  1057                         << new QStandardItem("An item that has very long text and should"
       
  1058                                              " cause the horizontal scroll bar to appear."));
       
  1059     }
       
  1060     view.setModel(&model);
       
  1061 
       
  1062     QVERIFY(!view.itemDelegateForRow(0));
       
  1063     QVERIFY(!view.itemDelegateForColumn(0));
       
  1064     QCOMPARE(view.itemDelegate(QModelIndex()), defaultDelegate);
       
  1065     QCOMPARE(view.itemDelegate(view.model()->index(0, 0)), defaultDelegate);
       
  1066 
       
  1067     QPointer<QAbstractItemDelegate> rowDelegate = new QItemDelegate;
       
  1068     view.setItemDelegateForRow(0, rowDelegate);
       
  1069     QVERIFY(!rowDelegate->parent());
       
  1070     QCOMPARE(view.itemDelegateForRow(0), (QAbstractItemDelegate *)rowDelegate);
       
  1071     QCOMPARE(view.itemDelegate(view.model()->index(0, 0)), (QAbstractItemDelegate *)rowDelegate);
       
  1072     QCOMPARE(view.itemDelegate(view.model()->index(0, 1)), (QAbstractItemDelegate *)rowDelegate);
       
  1073     QCOMPARE(view.itemDelegate(view.model()->index(1, 0)), defaultDelegate);
       
  1074     QCOMPARE(view.itemDelegate(view.model()->index(1, 1)), defaultDelegate);
       
  1075 
       
  1076     QPointer<QAbstractItemDelegate> columnDelegate = new QItemDelegate;
       
  1077     view.setItemDelegateForColumn(1, columnDelegate);
       
  1078     QVERIFY(!columnDelegate->parent());
       
  1079     QCOMPARE(view.itemDelegateForColumn(1), (QAbstractItemDelegate *)columnDelegate);
       
  1080     QCOMPARE(view.itemDelegate(view.model()->index(0, 0)), (QAbstractItemDelegate *)rowDelegate);
       
  1081     QCOMPARE(view.itemDelegate(view.model()->index(0, 1)), (QAbstractItemDelegate *)rowDelegate); // row wins
       
  1082     QCOMPARE(view.itemDelegate(view.model()->index(1, 0)), defaultDelegate);
       
  1083     QCOMPARE(view.itemDelegate(view.model()->index(1, 1)), (QAbstractItemDelegate *)columnDelegate);
       
  1084 
       
  1085     view.setItemDelegateForRow(0, 0);
       
  1086     QVERIFY(!view.itemDelegateForRow(0));
       
  1087     QVERIFY(rowDelegate); // <- wasn't deleted
       
  1088 
       
  1089     view.setItemDelegateForColumn(1, 0);
       
  1090     QVERIFY(!view.itemDelegateForColumn(1));
       
  1091     QVERIFY(columnDelegate); // <- wasn't deleted
       
  1092 
       
  1093     delete rowDelegate;
       
  1094     delete columnDelegate;
       
  1095 }
       
  1096 
       
  1097 void tst_QTreeView::keyboardSearch()
       
  1098 {
       
  1099     QTreeView view;
       
  1100     QStandardItemModel model;
       
  1101     model.appendRow(new QStandardItem("Andreas"));
       
  1102     model.appendRow(new QStandardItem("Baldrian"));
       
  1103     model.appendRow(new QStandardItem("Cecilie"));
       
  1104     view.setModel(&model);
       
  1105     view.show();
       
  1106 
       
  1107     // Nothing is selected
       
  1108     QVERIFY(!view.selectionModel()->hasSelection());
       
  1109     QVERIFY(!view.selectionModel()->isSelected(model.index(0, 0)));
       
  1110 
       
  1111     // First item is selected
       
  1112     view.keyboardSearch(QLatin1String("A"));
       
  1113     QTRY_VERIFY(view.selectionModel()->isSelected(model.index(0, 0)));
       
  1114 
       
  1115     // First item is still selected
       
  1116     view.keyboardSearch(QLatin1String("n"));
       
  1117     QVERIFY(view.selectionModel()->isSelected(model.index(0, 0)));
       
  1118 
       
  1119     // No "AnB" item - keep the same selection.
       
  1120     view.keyboardSearch(QLatin1String("B"));
       
  1121     QVERIFY(view.selectionModel()->isSelected(model.index(0, 0)));
       
  1122 
       
  1123     // Wait a bit.
       
  1124     QTest::qWait(QApplication::keyboardInputInterval() * 2);
       
  1125 
       
  1126     // The item that starts with B is selected.
       
  1127     view.keyboardSearch(QLatin1String("B"));
       
  1128     QVERIFY(view.selectionModel()->isSelected(model.index(1, 0)));
       
  1129 }
       
  1130 
       
  1131 void tst_QTreeView::setModel()
       
  1132 {
       
  1133     QTreeView view;
       
  1134     view.show();
       
  1135     QCOMPARE(view.model(), (QAbstractItemModel*)0);
       
  1136     QCOMPARE(view.selectionModel(), (QItemSelectionModel*)0);
       
  1137     QCOMPARE(view.header()->model(), (QAbstractItemModel*)0);
       
  1138     QCOMPARE(view.header()->selectionModel(), (QItemSelectionModel*)0);
       
  1139 
       
  1140     for (int x = 0; x < 2; ++x) {
       
  1141         QtTestModel *model = new QtTestModel(10, 8);
       
  1142         QAbstractItemModel *oldModel = view.model();
       
  1143         QSignalSpy modelDestroyedSpy(oldModel ? oldModel : model, SIGNAL(destroyed()));
       
  1144         // set the same model twice
       
  1145         for (int i = 0; i < 2; ++i) {
       
  1146             QItemSelectionModel *oldSelectionModel = view.selectionModel();
       
  1147             QItemSelectionModel *dummy = new QItemSelectionModel(model);
       
  1148             QSignalSpy selectionModelDestroyedSpy(
       
  1149                 oldSelectionModel ? oldSelectionModel : dummy, SIGNAL(destroyed()));
       
  1150             view.setModel(model);
       
  1151 //                QCOMPARE(selectionModelDestroyedSpy.count(), (x == 0 || i == 1) ? 0 : 1);
       
  1152             QCOMPARE(view.model(), (QAbstractItemModel *)model);
       
  1153             QCOMPARE(view.header()->model(), (QAbstractItemModel *)model);
       
  1154             QCOMPARE(view.selectionModel() != oldSelectionModel, (i == 0));
       
  1155         }
       
  1156         QTRY_COMPARE(modelDestroyedSpy.count(), 0);
       
  1157 
       
  1158         view.setModel(0);
       
  1159         QCOMPARE(view.model(), (QAbstractItemModel*)0);
       
  1160         // ### shouldn't selectionModel also be 0 now?
       
  1161 //        QCOMPARE(view.selectionModel(), (QItemSelectionModel*)0);
       
  1162         delete model;
       
  1163     }
       
  1164 }
       
  1165 
       
  1166 void tst_QTreeView::openPersistentEditor()
       
  1167 {
       
  1168     QTreeView view;
       
  1169     QStandardItemModel treeModel;
       
  1170     initStandardTreeModel(&treeModel);
       
  1171     view.setModel(&treeModel);
       
  1172     view.show();
       
  1173 
       
  1174     QVERIFY(!qFindChild<QLineEdit *>(view.viewport()));
       
  1175     view.openPersistentEditor(view.model()->index(0, 0));
       
  1176     QVERIFY(qFindChild<QLineEdit *>(view.viewport()));
       
  1177 
       
  1178     view.closePersistentEditor(view.model()->index(0, 0));
       
  1179     QVERIFY(!qFindChild<QLineEdit *>(view.viewport())->isVisible());
       
  1180 
       
  1181     qApp->sendPostedEvents(0, QEvent::DeferredDelete);
       
  1182     QVERIFY(!qFindChild<QLineEdit *>(view.viewport()));
       
  1183 }
       
  1184 
       
  1185 void tst_QTreeView::rootIndex()
       
  1186 {
       
  1187     QTreeView view;
       
  1188     QCOMPARE(view.rootIndex(), QModelIndex());
       
  1189     QStandardItemModel treeModel;
       
  1190     initStandardTreeModel(&treeModel);
       
  1191     view.setModel(&treeModel);
       
  1192     QCOMPARE(view.rootIndex(), QModelIndex());
       
  1193 
       
  1194     view.setRootIndex(view.model()->index(1, 0));
       
  1195 
       
  1196     QCOMPARE(view.model()->data(view.model()->index(0, view.header()->visualIndex(0), view.rootIndex()), Qt::DisplayRole)
       
  1197              .toString(), QString("Row 2 Child Item"));
       
  1198 }
       
  1199 
       
  1200 void tst_QTreeView::setHeader()
       
  1201 {
       
  1202     QTreeView view;
       
  1203     QVERIFY(view.header() != 0);
       
  1204     QCOMPARE(view.header()->orientation(), Qt::Horizontal);
       
  1205     QCOMPARE(view.header()->parent(), (QObject *)&view);
       
  1206     for (int x = 0; x < 2; ++x) {
       
  1207         QSignalSpy destroyedSpy(view.header(), SIGNAL(destroyed()));
       
  1208         Qt::Orientation orient = x ? Qt::Vertical : Qt::Horizontal;
       
  1209         QHeaderView *head = new QHeaderView(orient);
       
  1210         view.setHeader(head);
       
  1211         QCOMPARE(destroyedSpy.count(), 1);
       
  1212         QCOMPARE(head->parent(), (QObject *)&view);
       
  1213         QCOMPARE(view.header(), head);
       
  1214         view.setHeader(head);
       
  1215         QCOMPARE(view.header(), head);
       
  1216         // Itemviews in Qt < 4.2 have asserts for this. Qt >= 4.2 should handle this gracefully
       
  1217         view.setHeader((QHeaderView *)0);
       
  1218         QCOMPARE(view.header(), head);
       
  1219     }
       
  1220 }
       
  1221 
       
  1222 void tst_QTreeView::columnHidden()
       
  1223 {
       
  1224     QTreeView view;
       
  1225     QtTestModel model(10, 8);
       
  1226     view.setModel(&model);
       
  1227     view.show();
       
  1228     for (int c = 0; c < model.columnCount(); ++c)
       
  1229         QCOMPARE(view.isColumnHidden(c), false);
       
  1230     // hide even columns
       
  1231     for (int c = 0; c < model.columnCount(); c+=2)
       
  1232         view.setColumnHidden(c, true);
       
  1233     for (int c = 0; c < model.columnCount(); ++c)
       
  1234         QCOMPARE(view.isColumnHidden(c), (c & 1) == 0);
       
  1235     view.update();
       
  1236     // hide odd columns too
       
  1237     for (int c = 1; c < model.columnCount(); c+=2)
       
  1238         view.setColumnHidden(c, true);
       
  1239     for (int c = 0; c < model.columnCount(); ++c)
       
  1240         QCOMPARE(view.isColumnHidden(c), true);
       
  1241     view.update();
       
  1242 }
       
  1243 
       
  1244 void tst_QTreeView::rowHidden()
       
  1245 {
       
  1246     QtTestModel model(4, 6);
       
  1247     model.levels = 3;
       
  1248     QTreeView view;
       
  1249     view.resize(500,500);
       
  1250     view.setModel(&model);
       
  1251     view.show();
       
  1252 
       
  1253     QCOMPARE(view.isRowHidden(-1, QModelIndex()), false);
       
  1254     QCOMPARE(view.isRowHidden(999999, QModelIndex()), false);
       
  1255     view.setRowHidden(-1, QModelIndex(), true);
       
  1256     view.setRowHidden(999999, QModelIndex(), true);
       
  1257     QCOMPARE(view.isRowHidden(-1, QModelIndex()), false);
       
  1258     QCOMPARE(view.isRowHidden(999999, QModelIndex()), false);
       
  1259 
       
  1260     view.setRowHidden(0, QModelIndex(), true);
       
  1261     QCOMPARE(view.isRowHidden(0, QModelIndex()), true);
       
  1262     view.setRowHidden(0, QModelIndex(), false);
       
  1263     QCOMPARE(view.isRowHidden(0, QModelIndex()), false);
       
  1264 
       
  1265     QStack<QModelIndex> parents;
       
  1266     parents.push(QModelIndex());
       
  1267     while (!parents.isEmpty()) {
       
  1268         QModelIndex p = parents.pop();
       
  1269         if (model.canFetchMore(p))
       
  1270             model.fetchMore(p);
       
  1271         int rows = model.rowCount(p);
       
  1272         // hide all
       
  1273         for (int r = 0; r < rows; ++r) {
       
  1274             view.setRowHidden(r, p, true);
       
  1275             QCOMPARE(view.isRowHidden(r, p), true);
       
  1276         }
       
  1277         // hide none
       
  1278         for (int r = 0; r < rows; ++r) {
       
  1279             view.setRowHidden(r, p, false);
       
  1280             QCOMPARE(view.isRowHidden(r, p), false);
       
  1281         }
       
  1282         // hide only even rows
       
  1283         for (int r = 0; r < rows; ++r) {
       
  1284             bool hide = (r & 1) == 0;
       
  1285             view.setRowHidden(r, p, hide);
       
  1286             QCOMPARE(view.isRowHidden(r, p), hide);
       
  1287         }
       
  1288         for (int r = 0; r < rows; ++r)
       
  1289             parents.push(model.index(r, 0, p));
       
  1290     }
       
  1291 
       
  1292     parents.push(QModelIndex());
       
  1293     while (!parents.isEmpty()) {
       
  1294         QModelIndex p = parents.pop();
       
  1295         // all even rows should still be hidden
       
  1296         for (int r = 0; r < model.rowCount(p); ++r)
       
  1297             QCOMPARE(view.isRowHidden(r, p), (r & 1) == 0);
       
  1298         if (model.rowCount(p) > 0) {
       
  1299             for (int r = 0; r < model.rowCount(p); ++r)
       
  1300                 parents.push(model.index(r, 0, p));
       
  1301         }
       
  1302     }
       
  1303 }
       
  1304 
       
  1305 void tst_QTreeView::noDelegate()
       
  1306 {
       
  1307     QtTestModel model(10, 7);
       
  1308     QTreeView view;
       
  1309     view.setModel(&model);
       
  1310     view.setItemDelegate(0);
       
  1311     QCOMPARE(view.itemDelegate(), (QAbstractItemDelegate *)0);
       
  1312 }
       
  1313 
       
  1314 void tst_QTreeView::noModel()
       
  1315 {
       
  1316     QTreeView view;
       
  1317     view.show();
       
  1318     view.setRowHidden(0, QModelIndex(), true);
       
  1319 }
       
  1320 
       
  1321 void tst_QTreeView::emptyModel()
       
  1322 {
       
  1323     QtTestModel model;
       
  1324     QTreeView view;
       
  1325     view.setModel(&model);
       
  1326     view.show();
       
  1327     QVERIFY(!model.wrongIndex);
       
  1328 }
       
  1329 
       
  1330 void tst_QTreeView::removeRows()
       
  1331 {
       
  1332     QtTestModel model(7, 10);
       
  1333 
       
  1334     QTreeView view;
       
  1335 
       
  1336     view.setModel(&model);
       
  1337     view.show();
       
  1338 
       
  1339     model.removeLastRow();
       
  1340     QVERIFY(!model.wrongIndex);
       
  1341 
       
  1342     model.removeAllRows();
       
  1343     QVERIFY(!model.wrongIndex);
       
  1344 }
       
  1345 
       
  1346 void tst_QTreeView::removeCols()
       
  1347 {
       
  1348     QtTestModel model(5, 8);
       
  1349 
       
  1350     QTreeView view;
       
  1351     view.setModel(&model);
       
  1352     view.show();
       
  1353     model.fetched = true;
       
  1354     model.removeLastColumn();
       
  1355     QVERIFY(!model.wrongIndex);
       
  1356     QCOMPARE(view.header()->count(), model.cols);
       
  1357 
       
  1358     model.removeAllColumns();
       
  1359     QVERIFY(!model.wrongIndex);
       
  1360     QCOMPARE(view.header()->count(), model.cols);
       
  1361 }
       
  1362 
       
  1363 void tst_QTreeView::expandAndCollapse_data()
       
  1364 {
       
  1365     QTest::addColumn<bool>("animationEnabled");
       
  1366     QTest::newRow("normal") << false;
       
  1367     QTest::newRow("animated") << true;
       
  1368 
       
  1369 }
       
  1370 
       
  1371 void tst_QTreeView::expandAndCollapse()
       
  1372 {
       
  1373     QFETCH(bool, animationEnabled);
       
  1374 
       
  1375     QtTestModel model(10, 9);
       
  1376 
       
  1377     QTreeView view;
       
  1378     view.setUniformRowHeights(true);
       
  1379     view.setModel(&model);
       
  1380     view.setAnimated(animationEnabled);
       
  1381     view.show();
       
  1382 
       
  1383     QModelIndex a = model.index(0, 0, QModelIndex());
       
  1384     QModelIndex b = model.index(0, 0, a);
       
  1385 
       
  1386     QSignalSpy expandedSpy(&view, SIGNAL(expanded(const QModelIndex&)));
       
  1387     QSignalSpy collapsedSpy(&view, SIGNAL(collapsed(const QModelIndex&)));
       
  1388     QVariantList args;
       
  1389 
       
  1390     for (int y = 0; y < 2; ++y) {
       
  1391         view.setVisible(y == 0);
       
  1392         for (int x = 0; x < 2; ++x) {
       
  1393             view.setItemsExpandable(x == 0);
       
  1394 
       
  1395             // Test bad args
       
  1396             view.expand(QModelIndex());
       
  1397             QCOMPARE(view.isExpanded(QModelIndex()), false);
       
  1398             view.collapse(QModelIndex());
       
  1399             QCOMPARE(expandedSpy.count(), 0);
       
  1400             QCOMPARE(collapsedSpy.count(), 0);
       
  1401 
       
  1402             // expand a first level item
       
  1403             QVERIFY(!view.isExpanded(a));
       
  1404             view.expand(a);
       
  1405             QVERIFY(view.isExpanded(a));
       
  1406             QCOMPARE(expandedSpy.count(), 1);
       
  1407             QCOMPARE(collapsedSpy.count(), 0);
       
  1408             args = expandedSpy.takeFirst();
       
  1409             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a);
       
  1410 
       
  1411             view.expand(a);
       
  1412             QVERIFY(view.isExpanded(a));
       
  1413             QCOMPARE(expandedSpy.count(), 0);
       
  1414             QCOMPARE(collapsedSpy.count(), 0);
       
  1415 
       
  1416             // expand a second level item
       
  1417             QVERIFY(!view.isExpanded(b));
       
  1418             view.expand(b);
       
  1419             QVERIFY(view.isExpanded(a));
       
  1420             QVERIFY(view.isExpanded(b));
       
  1421             QCOMPARE(expandedSpy.count(), 1);
       
  1422             QCOMPARE(collapsedSpy.count(), 0);
       
  1423             args = expandedSpy.takeFirst();
       
  1424             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), b);
       
  1425 
       
  1426             view.expand(b);
       
  1427             QVERIFY(view.isExpanded(b));
       
  1428             QCOMPARE(expandedSpy.count(), 0);
       
  1429             QCOMPARE(collapsedSpy.count(), 0);
       
  1430 
       
  1431             // collapse the first level item
       
  1432             view.collapse(a);
       
  1433             QVERIFY(!view.isExpanded(a));
       
  1434             QVERIFY(view.isExpanded(b));
       
  1435             QCOMPARE(expandedSpy.count(), 0);
       
  1436             QCOMPARE(collapsedSpy.count(), 1);
       
  1437             args = collapsedSpy.takeFirst();
       
  1438             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a);
       
  1439 
       
  1440             view.collapse(a);
       
  1441             QVERIFY(!view.isExpanded(a));
       
  1442             QCOMPARE(expandedSpy.count(), 0);
       
  1443             QCOMPARE(collapsedSpy.count(), 0);
       
  1444 
       
  1445             // expand the first level item again
       
  1446             view.expand(a);
       
  1447             QVERIFY(view.isExpanded(a));
       
  1448             QVERIFY(view.isExpanded(b));
       
  1449             QCOMPARE(expandedSpy.count(), 1);
       
  1450             QCOMPARE(collapsedSpy.count(), 0);
       
  1451             args = expandedSpy.takeFirst();
       
  1452             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a);
       
  1453 
       
  1454             // collapse the second level item
       
  1455             view.collapse(b);
       
  1456             QVERIFY(view.isExpanded(a));
       
  1457             QVERIFY(!view.isExpanded(b));
       
  1458             QCOMPARE(expandedSpy.count(), 0);
       
  1459             QCOMPARE(collapsedSpy.count(), 1);
       
  1460             args = collapsedSpy.takeFirst();
       
  1461             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), b);
       
  1462 
       
  1463             // collapse the first level item
       
  1464             view.collapse(a);
       
  1465             QVERIFY(!view.isExpanded(a));
       
  1466             QVERIFY(!view.isExpanded(b));
       
  1467             QCOMPARE(expandedSpy.count(), 0);
       
  1468             QCOMPARE(collapsedSpy.count(), 1);
       
  1469             args = collapsedSpy.takeFirst();
       
  1470             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a);
       
  1471 
       
  1472             // expand and remove row
       
  1473             QPersistentModelIndex c = model.index(9, 0, b);
       
  1474             view.expand(a);
       
  1475             view.expand(b);
       
  1476             model.removeLastRow(); // remove c
       
  1477             QVERIFY(view.isExpanded(a));
       
  1478             QVERIFY(view.isExpanded(b));
       
  1479             QVERIFY(!view.isExpanded(c));
       
  1480             QCOMPARE(expandedSpy.count(), 2);
       
  1481             QCOMPARE(collapsedSpy.count(), 0);
       
  1482             args = expandedSpy.takeFirst();
       
  1483             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a);
       
  1484             args = expandedSpy.takeFirst();
       
  1485             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), b);
       
  1486 
       
  1487             view.collapse(a);
       
  1488             view.collapse(b);
       
  1489             QVERIFY(!view.isExpanded(a));
       
  1490             QVERIFY(!view.isExpanded(b));
       
  1491             QVERIFY(!view.isExpanded(c));
       
  1492             QCOMPARE(expandedSpy.count(), 0);
       
  1493             QCOMPARE(collapsedSpy.count(), 2);
       
  1494             args = collapsedSpy.takeFirst();
       
  1495             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a);
       
  1496             args = collapsedSpy.takeFirst();
       
  1497             QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), b);
       
  1498         }
       
  1499     }
       
  1500 }
       
  1501 
       
  1502 void tst_QTreeView::expandAndCollapseAll()
       
  1503 {
       
  1504     QtTestModel model(3, 2);
       
  1505     model.levels = 2;
       
  1506     QTreeView view;
       
  1507     view.setUniformRowHeights(true);
       
  1508     view.setModel(&model);
       
  1509 
       
  1510     QSignalSpy expandedSpy(&view, SIGNAL(expanded(const QModelIndex&)));
       
  1511     QSignalSpy collapsedSpy(&view, SIGNAL(collapsed(const QModelIndex&)));
       
  1512 
       
  1513     view.expandAll();
       
  1514     view.show();
       
  1515 
       
  1516     QCOMPARE(collapsedSpy.count(), 0);
       
  1517 
       
  1518     QStack<QModelIndex> parents;
       
  1519     parents.push(QModelIndex());
       
  1520     int count = 0;
       
  1521     while (!parents.isEmpty()) {
       
  1522         QModelIndex p = parents.pop();
       
  1523         int rows = model.rowCount(p);
       
  1524         for (int r = 0; r < rows; ++r)
       
  1525             QVERIFY(view.isExpanded(model.index(r, 0, p)));
       
  1526         count += rows;
       
  1527         for (int r = 0; r < rows; ++r)
       
  1528             parents.push(model.index(r, 0, p));
       
  1529     }
       
  1530 // ### why is expanded() signal not emitted?
       
  1531 //    QCOMPARE(expandedSpy.count(), count);
       
  1532 
       
  1533     view.collapseAll();
       
  1534 
       
  1535     QCOMPARE(expandedSpy.count(), 0);
       
  1536 
       
  1537     parents.push(QModelIndex());
       
  1538     count = 0;
       
  1539     while (!parents.isEmpty()) {
       
  1540         QModelIndex p = parents.pop();
       
  1541         int rows = model.rowCount(p);
       
  1542         for (int r = 0; r < rows; ++r)
       
  1543             QVERIFY(!view.isExpanded(model.index(r, 0, p)));
       
  1544         count += rows;
       
  1545         for (int r = 0; r < rows; ++r)
       
  1546             parents.push(model.index(r, 0, p));
       
  1547     }
       
  1548 // ### why is collapsed() signal not emitted?
       
  1549 //    QCOMPARE(collapsedSpy.count(), count);
       
  1550 }
       
  1551 
       
  1552 void tst_QTreeView::expandWithNoChildren()
       
  1553 {
       
  1554     QTreeView tree;
       
  1555     QStandardItemModel model(1,1);
       
  1556     tree.setModel(&model);
       
  1557     tree.setAnimated(true);
       
  1558     tree.doItemsLayout();
       
  1559     //this test should not output warnings
       
  1560     tree.expand(model.index(0,0));
       
  1561 }
       
  1562 
       
  1563 
       
  1564 
       
  1565 void tst_QTreeView::keyboardNavigation()
       
  1566 {
       
  1567     const int rows = 10;
       
  1568     const int columns = 7;
       
  1569 
       
  1570     QtTestModel model(rows, columns);
       
  1571 
       
  1572     QTreeView view;
       
  1573     view.setModel(&model);
       
  1574     view.show();
       
  1575 
       
  1576     QVector<Qt::Key> keymoves;
       
  1577     keymoves << Qt::Key_Down << Qt::Key_Right << Qt::Key_Right << Qt::Key_Right
       
  1578              << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down
       
  1579              << Qt::Key_Right << Qt::Key_Right << Qt::Key_Right
       
  1580              << Qt::Key_Left << Qt::Key_Up << Qt::Key_Left << Qt::Key_Left
       
  1581              << Qt::Key_Up << Qt::Key_Down << Qt::Key_Up << Qt::Key_Up
       
  1582              << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up
       
  1583              << Qt::Key_Left << Qt::Key_Left << Qt::Key_Up << Qt::Key_Down;
       
  1584 
       
  1585     int row    = 0;
       
  1586     int column = 0;
       
  1587     QModelIndex index = model.index(row, column, QModelIndex());
       
  1588     view.setCurrentIndex(index);
       
  1589     QCOMPARE(view.currentIndex(), index);
       
  1590 
       
  1591     for (int i = 0; i < keymoves.size(); ++i) {
       
  1592         Qt::Key key = keymoves.at(i);
       
  1593         QTest::keyClick(&view, key);
       
  1594 
       
  1595         switch (key) {
       
  1596         case Qt::Key_Up:
       
  1597             if (row > 0) {
       
  1598                 index = index.sibling(row - 1, column);
       
  1599                 row -= 1;
       
  1600             } else if (index.parent() != QModelIndex()) {
       
  1601                 index = index.parent();
       
  1602                 row = index.row();
       
  1603             }
       
  1604             break;
       
  1605         case Qt::Key_Down:
       
  1606             if (view.isExpanded(index)) {
       
  1607                 row = 0;
       
  1608                 index = index.child(row, column);
       
  1609             } else {
       
  1610                 row = qMin(rows - 1, row + 1);
       
  1611                 index = index.sibling(row, column);
       
  1612             }
       
  1613             break;
       
  1614         case Qt::Key_Left: {
       
  1615             QScrollBar *b = view.horizontalScrollBar();
       
  1616             if (b->value() == b->minimum())
       
  1617                 QVERIFY(!view.isExpanded(index));
       
  1618             // windows style right will walk to the parent
       
  1619             if (view.currentIndex() != index) {
       
  1620                 QCOMPARE(view.currentIndex(), index.parent());
       
  1621                 index = view.currentIndex();
       
  1622                 row = index.row();
       
  1623                 column = index.column();
       
  1624             }
       
  1625             break;
       
  1626         }
       
  1627         case Qt::Key_Right:
       
  1628             QVERIFY(view.isExpanded(index));
       
  1629             // windows style right will walk to the first child
       
  1630             if (view.currentIndex() != index) {
       
  1631                 QCOMPARE(view.currentIndex().parent(), index);
       
  1632                 row = view.currentIndex().row();
       
  1633                 column = view.currentIndex().column();
       
  1634                 index = view.currentIndex();
       
  1635             }
       
  1636             break;
       
  1637         default:
       
  1638             QVERIFY(false);
       
  1639         }
       
  1640 
       
  1641         QCOMPARE(view.currentIndex().row(), row);
       
  1642         QCOMPARE(view.currentIndex().column(), column);
       
  1643         QCOMPARE(view.currentIndex(), index);
       
  1644     }
       
  1645 }
       
  1646 
       
  1647 class Dmodel : public QtTestModel
       
  1648 {
       
  1649 public:
       
  1650     Dmodel() : QtTestModel(10, 10){}
       
  1651 
       
  1652     int columnCount(const QModelIndex &parent) const
       
  1653     {
       
  1654         if (parent.row() == 5)
       
  1655             return 1;
       
  1656         return QtTestModel::columnCount(parent);
       
  1657     }
       
  1658 };
       
  1659 
       
  1660 void tst_QTreeView::headerSections()
       
  1661 {
       
  1662     Dmodel model;
       
  1663 
       
  1664     QTreeView view;
       
  1665     QHeaderView *header = view.header();
       
  1666 
       
  1667     view.setModel(&model);
       
  1668     QModelIndex index = model.index(5, 0);
       
  1669     view.setRootIndex(index);
       
  1670     QCOMPARE(model.columnCount(QModelIndex()), 10);
       
  1671     QCOMPARE(model.columnCount(index), 1);
       
  1672     QCOMPARE(header->count(), model.columnCount(index));
       
  1673 }
       
  1674 
       
  1675 void tst_QTreeView::moveCursor_data()
       
  1676 {
       
  1677     QTest::addColumn<bool>("uniformRowHeights");
       
  1678     QTest::addColumn<bool>("scrollPerPixel");
       
  1679     QTest::newRow("uniformRowHeights = false, scrollPerPixel = false")
       
  1680         << false << false;
       
  1681     QTest::newRow("uniformRowHeights = true, scrollPerPixel = false")
       
  1682         << true << false;
       
  1683     QTest::newRow("uniformRowHeights = false, scrollPerPixel = true")
       
  1684         << false << true;
       
  1685     QTest::newRow("uniformRowHeights = true, scrollPerPixel = true")
       
  1686         << true << true;
       
  1687 }
       
  1688 
       
  1689 void tst_QTreeView::moveCursor()
       
  1690 {
       
  1691     QFETCH(bool, uniformRowHeights);
       
  1692     QFETCH(bool, scrollPerPixel);
       
  1693     QtTestModel model(8, 6);
       
  1694 
       
  1695     PublicView view;
       
  1696     view.setUniformRowHeights(uniformRowHeights);
       
  1697     view.setModel(&model);
       
  1698     view.setRowHidden(0, QModelIndex(), true);
       
  1699     view.setVerticalScrollMode(scrollPerPixel ?
       
  1700             QAbstractItemView::ScrollPerPixel :
       
  1701             QAbstractItemView::ScrollPerItem);
       
  1702     QVERIFY(view.isRowHidden(0, QModelIndex()));
       
  1703     view.setColumnHidden(0, true);
       
  1704     QVERIFY(view.isColumnHidden(0));
       
  1705     view.show();
       
  1706     qApp->setActiveWindow(&view);
       
  1707 
       
  1708     //here the first visible index should be selected
       
  1709     //because the view got the focus
       
  1710     QModelIndex expected = model.index(1, 1, QModelIndex());
       
  1711     QCOMPARE(view.currentIndex(), expected);
       
  1712 
       
  1713     //then pressing down should go to the next line
       
  1714     QModelIndex actual = view.moveCursor(PublicView::MoveDown, Qt::NoModifier);
       
  1715     expected = model.index(2, 1, QModelIndex());
       
  1716     QCOMPARE(actual, expected);
       
  1717 
       
  1718     view.setRowHidden(0, QModelIndex(), false);
       
  1719     view.setColumnHidden(0, false);
       
  1720 
       
  1721     // PageUp was broken with uniform row heights turned on
       
  1722     view.setCurrentIndex(model.index(1, 0));
       
  1723     actual = view.moveCursor(PublicView::MovePageUp, Qt::NoModifier);
       
  1724     expected = model.index(0, 0, QModelIndex());
       
  1725     QCOMPARE(actual, expected);
       
  1726 
       
  1727     //let's try another column
       
  1728     view.setCurrentIndex(model.index(1, 1));
       
  1729     view.setSelectionBehavior(QAbstractItemView::SelectItems);
       
  1730     QTest::keyClick(view.viewport(), Qt::Key_Up);
       
  1731     expected = model.index(0, 1, QModelIndex());
       
  1732     QCOMPARE(view.currentIndex(), expected);
       
  1733     QTest::keyClick(view.viewport(), Qt::Key_Down);
       
  1734     expected = model.index(1, 1, QModelIndex());
       
  1735     QCOMPARE(view.currentIndex(), expected);
       
  1736     QTest::keyClick(view.viewport(), Qt::Key_Up);
       
  1737     expected = model.index(0, 1, QModelIndex());
       
  1738     QCOMPARE(view.currentIndex(), expected);
       
  1739     view.setColumnHidden(0, true);
       
  1740     QTest::keyClick(view.viewport(), Qt::Key_Left);
       
  1741     expected = model.index(0, 1, QModelIndex()); //it shouldn't have changed
       
  1742     QCOMPARE(view.currentIndex(), expected);
       
  1743     view.setColumnHidden(0, false);
       
  1744     QTest::keyClick(view.viewport(), Qt::Key_Left);
       
  1745     expected = model.index(0, 0, QModelIndex());
       
  1746     QCOMPARE(view.currentIndex(), expected);
       
  1747 }
       
  1748 
       
  1749 class TestDelegate : public QItemDelegate
       
  1750 {
       
  1751 public:
       
  1752     TestDelegate(QObject *parent) : QItemDelegate(parent) {}
       
  1753     QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return QSize(200, 50); }
       
  1754 };
       
  1755 
       
  1756 typedef QList<QPoint> PointList;
       
  1757 Q_DECLARE_METATYPE(PointList)
       
  1758 
       
  1759 void tst_QTreeView::setSelection_data()
       
  1760 {
       
  1761     QTest::addColumn<QRect>("selectionRect");
       
  1762     QTest::addColumn<int>("selectionMode");
       
  1763     QTest::addColumn<int>("selectionCommand");
       
  1764     QTest::addColumn<PointList>("expectedItems");
       
  1765     QTest::addColumn<int>("verticalOffset");
       
  1766 
       
  1767     QTest::newRow("(0,0,50,20),rows") << QRect(0,0,50,20)
       
  1768                                  << int(QAbstractItemView::SingleSelection)
       
  1769                                  << int(QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows)
       
  1770                                  << (PointList()
       
  1771                                     << QPoint(0,0) << QPoint(1,0) << QPoint(2,0) << QPoint(3,0) << QPoint(4,0)
       
  1772                                     )
       
  1773                                  << 0;
       
  1774 
       
  1775     QTest::newRow("(0,0,50,90),rows") << QRect(0,0,50,90)
       
  1776                                  << int(QAbstractItemView::ExtendedSelection)
       
  1777                                  << int(QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows)
       
  1778                                  << (PointList()
       
  1779                                     << QPoint(0,0) << QPoint(1,0) << QPoint(2,0) << QPoint(3,0) << QPoint(4,0)
       
  1780                                     << QPoint(0,1) << QPoint(1,1) << QPoint(2,1) << QPoint(3,1) << QPoint(4,1)
       
  1781                                     )
       
  1782                                  << 0;
       
  1783 
       
  1784     QTest::newRow("(50,0,0,90),rows,invalid rect") << QRect(QPoint(50, 0), QPoint(0, 90))
       
  1785                                  << int(QAbstractItemView::ExtendedSelection)
       
  1786                                  << int(QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows)
       
  1787                                  << (PointList()
       
  1788                                     << QPoint(0,0) << QPoint(1,0) << QPoint(2,0) << QPoint(3,0) << QPoint(4,0)
       
  1789                                     << QPoint(0,1) << QPoint(1,1) << QPoint(2,1) << QPoint(3,1) << QPoint(4,1)
       
  1790                                     )
       
  1791                                  << 0;
       
  1792 
       
  1793     QTest::newRow("(0,-20,20,50),rows") << QRect(0,-20,20,50)
       
  1794                                  << int(QAbstractItemView::ExtendedSelection)
       
  1795                                  << int(QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows)
       
  1796                                  << (PointList()
       
  1797                                     << QPoint(0,0) << QPoint(1,0) << QPoint(2,0) << QPoint(3,0) << QPoint(4,0)
       
  1798                                     << QPoint(0,1) << QPoint(1,1) << QPoint(2,1) << QPoint(3,1) << QPoint(4,1)
       
  1799                                     )
       
  1800                                  << 1;
       
  1801     QTest::newRow("(0,-50,20,90),rows") << QRect(0,-50,20,90)
       
  1802                                  << int(QAbstractItemView::ExtendedSelection)
       
  1803                                  << int(QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows)
       
  1804                                  << (PointList()
       
  1805                                     << QPoint(0,0) << QPoint(1,0) << QPoint(2,0) << QPoint(3,0) << QPoint(4,0)
       
  1806                                     << QPoint(0,1) << QPoint(1,1) << QPoint(2,1) << QPoint(3,1) << QPoint(4,1)
       
  1807                                     )
       
  1808                                  << 1;
       
  1809 
       
  1810 }
       
  1811 
       
  1812 void tst_QTreeView::setSelection()
       
  1813 {
       
  1814     QFETCH(QRect, selectionRect);
       
  1815     QFETCH(int, selectionMode);
       
  1816     QFETCH(int, selectionCommand);
       
  1817     QFETCH(PointList, expectedItems);
       
  1818     QFETCH(int, verticalOffset);
       
  1819 
       
  1820     QtTestModel model(10, 5);
       
  1821     model.levels = 1;
       
  1822     model.setDecorationsEnabled(true);
       
  1823     PublicView view;
       
  1824     view.resize(400, 300);
       
  1825     view.show();
       
  1826     view.setRootIsDecorated(false);
       
  1827     view.setItemDelegate(new TestDelegate(&view));
       
  1828     view.setSelectionMode(QAbstractItemView::SelectionMode(selectionMode));
       
  1829     view.setModel(&model);
       
  1830     view.setUniformRowHeights(true);
       
  1831     view.setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
       
  1832     view.scrollTo(model.index(verticalOffset, 0), QAbstractItemView::PositionAtTop);
       
  1833     view.setSelection(selectionRect, QItemSelectionModel::SelectionFlags(selectionCommand));
       
  1834     QItemSelectionModel *selectionModel = view.selectionModel();
       
  1835     QVERIFY(selectionModel);
       
  1836 
       
  1837     QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
       
  1838     QCOMPARE(selectedIndexes.count(), expectedItems.count());
       
  1839     for (int i = 0; i < selectedIndexes.count(); ++i) {
       
  1840         QModelIndex idx = selectedIndexes.at(i);
       
  1841         QVERIFY(expectedItems.contains(QPoint(idx.column(), idx.row())));
       
  1842     }
       
  1843 }
       
  1844 
       
  1845 void tst_QTreeView::indexAbove()
       
  1846 {
       
  1847     QtTestModel model(6, 7);
       
  1848     model.levels = 2;
       
  1849     QTreeView view;
       
  1850 
       
  1851     QCOMPARE(view.indexAbove(QModelIndex()), QModelIndex());
       
  1852     view.setModel(&model);
       
  1853     QCOMPARE(view.indexAbove(QModelIndex()), QModelIndex());
       
  1854 
       
  1855     QStack<QModelIndex> parents;
       
  1856     parents.push(QModelIndex());
       
  1857     while (!parents.isEmpty()) {
       
  1858         QModelIndex p = parents.pop();
       
  1859         if (model.canFetchMore(p))
       
  1860             model.fetchMore(p);
       
  1861         int rows = model.rowCount(p);
       
  1862         for (int r = rows - 1; r > 0; --r) {
       
  1863             QModelIndex idx = model.index(r, 0, p);
       
  1864             QModelIndex expected = model.index(r - 1, 0, p);
       
  1865             QCOMPARE(view.indexAbove(idx), expected);
       
  1866         }
       
  1867         // hide even rows
       
  1868         for (int r = 0; r < rows; r+=2)
       
  1869             view.setRowHidden(r, p, true);
       
  1870         for (int r = rows - 1; r > 0; r-=2) {
       
  1871             QModelIndex idx = model.index(r, 0, p);
       
  1872             QModelIndex expected = model.index(r - 2, 0, p);
       
  1873             QCOMPARE(view.indexAbove(idx), expected);
       
  1874         }
       
  1875 //        for (int r = 0; r < rows; ++r)
       
  1876 //            parents.push(model.index(r, 0, p));
       
  1877     }
       
  1878 }
       
  1879 
       
  1880 void tst_QTreeView::indexBelow()
       
  1881 {
       
  1882     QtTestModel model(2, 1);
       
  1883 
       
  1884     QTreeView view;
       
  1885     view.setModel(&model);
       
  1886     view.show();
       
  1887 
       
  1888     QModelIndex i = model.index(0, 0, view.rootIndex());
       
  1889     QVERIFY(i.isValid());
       
  1890     QCOMPARE(i.row(), 0);
       
  1891 
       
  1892     i = view.indexBelow(i);
       
  1893     QVERIFY(i.isValid());
       
  1894     QCOMPARE(i.row(), 1);
       
  1895     i = view.indexBelow(i);
       
  1896     QVERIFY(!i.isValid());
       
  1897 }
       
  1898 
       
  1899 void tst_QTreeView::clicked()
       
  1900 {
       
  1901     QtTestModel model(10, 2);
       
  1902 
       
  1903     QTreeView view;
       
  1904     view.setModel(&model);
       
  1905     view.show();
       
  1906 
       
  1907     QModelIndex firstIndex = model.index(0, 0, QModelIndex());
       
  1908     QVERIFY(firstIndex.isValid());
       
  1909     int itemHeight = view.visualRect(firstIndex).height();
       
  1910     int itemOffset = view.visualRect(firstIndex).width() / 2;
       
  1911     view.resize(200, itemHeight * (model.rows + 2));
       
  1912 
       
  1913     for (int i = 0; i < model.rowCount(); ++i) {
       
  1914         QPoint p(itemOffset, 1 + itemHeight * i);
       
  1915         QModelIndex index = view.indexAt(p);
       
  1916         if (!index.isValid())
       
  1917             continue;
       
  1918         QSignalSpy spy(&view, SIGNAL(clicked(const QModelIndex&)));
       
  1919         QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  1920         QTRY_COMPARE(spy.count(), 1);
       
  1921     }
       
  1922 }
       
  1923 
       
  1924 void tst_QTreeView::mouseDoubleClick()
       
  1925 {
       
  1926     // Test double clicks outside the viewport.
       
  1927     // (Should be a no-op and should not expand any item.)
       
  1928 
       
  1929     QStandardItemModel model(20, 2);
       
  1930     for (int i = 0; i < model.rowCount(); i++) {
       
  1931         QModelIndex index = model.index(i, 0, QModelIndex());
       
  1932         model.insertRows(0, 20, index);
       
  1933         model.insertColumns(0,2,index);
       
  1934         for (int i1 = 0; i1 <  model.rowCount(index); i1++) {
       
  1935             QModelIndex index2 = model.index(i1, 0, index);
       
  1936         }
       
  1937     }
       
  1938 
       
  1939     QTreeView view;
       
  1940     view.setModel(&model);
       
  1941 
       
  1942     // make sure the viewport height is smaller than the contents height.
       
  1943     view.resize(200,200);
       
  1944     view.move(0,0);
       
  1945     view.show();
       
  1946     QModelIndex index = model.index(0, 0, QModelIndex());
       
  1947     view.setCurrentIndex(index);
       
  1948 
       
  1949     view.setExpanded(model.index(0,0, QModelIndex()), true);
       
  1950     view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
       
  1951     view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
       
  1952 
       
  1953     // Make sure all items are collapsed
       
  1954     for (int i = 0; i < model.rowCount(QModelIndex()); i++) {
       
  1955         view.setExpanded(model.index(i,0, QModelIndex()), false);
       
  1956     }
       
  1957 
       
  1958     int maximum = view.verticalScrollBar()->maximum();
       
  1959 
       
  1960     // Doubleclick in the bottom right corner, in the unused area between the vertical and horizontal scrollbar.
       
  1961     int vsw = view.verticalScrollBar()->width();
       
  1962     int hsh = view.horizontalScrollBar()->height();
       
  1963     QTest::mouseDClick(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() - vsw + 1, view.height() - hsh + 1));
       
  1964     // Should not have expanded, thus maximum() should have the same value.
       
  1965     QCOMPARE(maximum, view.verticalScrollBar()->maximum());
       
  1966 
       
  1967     view.setExpandsOnDoubleClick(false);
       
  1968     QTest::mouseDClick(&view, Qt::LeftButton, Qt::NoModifier, view.visualRect(index).center());
       
  1969     QVERIFY(!view.isExpanded(index));
       
  1970 }
       
  1971 
       
  1972 void tst_QTreeView::rowsAboutToBeRemoved()
       
  1973 {
       
  1974     QStandardItemModel model(3, 1);
       
  1975     for (int i = 0; i < model.rowCount(); i++) {
       
  1976         QModelIndex index = model.index(i, 0, QModelIndex());
       
  1977         model.setData(index, QString("%1").arg(i));
       
  1978         model.insertRows(0, 4, index);
       
  1979         model.insertColumns(0,1,index);
       
  1980         for (int i1 = 0; i1 <  model.rowCount(index); i1++) {
       
  1981             QModelIndex index2 = model.index(i1, 0, index);
       
  1982             model.setData(index2, QString("%1%2").arg(i).arg(i1));
       
  1983         }
       
  1984     }
       
  1985 
       
  1986     PublicView view;
       
  1987     view.setModel(&model);
       
  1988     view.show();
       
  1989     QModelIndex index = model.index(0,0, QModelIndex());
       
  1990     view.setCurrentIndex(index);
       
  1991     view.setExpanded(model.index(0,0, QModelIndex()), true);
       
  1992 
       
  1993     for (int i = 0; i < model.rowCount(QModelIndex()); i++) {
       
  1994         view.setExpanded(model.index(i,0, QModelIndex()), true);
       
  1995     }
       
  1996 
       
  1997     QSignalSpy spy1(&model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
       
  1998 
       
  1999     model.removeRows(1,1);
       
  2000     QCOMPARE(view.state(), 0);
       
  2001     // Should not be 5 (or any other number for that sake :)
       
  2002     QCOMPARE(spy1.count(), 1);
       
  2003 
       
  2004 }
       
  2005 
       
  2006 void tst_QTreeView::headerSections_unhideSection()
       
  2007 {
       
  2008     QtTestModel model(10, 7);
       
  2009 
       
  2010     QTreeView view;
       
  2011 
       
  2012     view.setModel(&model);
       
  2013     view.show();
       
  2014     int size = view.header()->sectionSize(0);
       
  2015     view.setColumnHidden(0, true);
       
  2016 
       
  2017     // should go back to old size
       
  2018     view.setColumnHidden(0, false);
       
  2019     QCOMPARE(size, view.header()->sectionSize(0));
       
  2020 }
       
  2021 
       
  2022 void tst_QTreeView::columnAt()
       
  2023 {
       
  2024     QtTestModel model;
       
  2025     model.rows = model.cols = 10;
       
  2026     QTreeView view;
       
  2027     view.resize(500,500);
       
  2028     view.setModel(&model);
       
  2029 
       
  2030     QCOMPARE(view.columnAt(0), 0);
       
  2031     // really this is testing the header... so not much more should be needed if the header is working...
       
  2032 }
       
  2033 
       
  2034 void tst_QTreeView::scrollTo()
       
  2035 {
       
  2036 #define CHECK_VISIBLE(ROW,COL) QVERIFY(QRect(QPoint(),view.viewport()->size()).contains(\
       
  2037                     view.visualRect(model.index((ROW),(COL),QModelIndex()))))
       
  2038 
       
  2039     QtTestModel model;
       
  2040     model.rows = model.cols = 100;
       
  2041     QTreeView view;
       
  2042     view.setUniformRowHeights(true);
       
  2043     view.scrollTo(QModelIndex(), QTreeView::PositionAtTop);
       
  2044     view.setModel(&model);
       
  2045 
       
  2046     // ### check the scrollbar values an make sure it actually scrolls to the item
       
  2047     // ### check for bot item based and pixel based scrolling
       
  2048     // ### create a data function for this test
       
  2049 
       
  2050     view.scrollTo(QModelIndex());
       
  2051     view.scrollTo(model.index(0,0,QModelIndex()));
       
  2052     view.scrollTo(model.index(0,0,QModelIndex()), QTreeView::PositionAtTop);
       
  2053     view.scrollTo(model.index(0,0,QModelIndex()), QTreeView::PositionAtBottom);
       
  2054 
       
  2055     //
       
  2056 
       
  2057     view.show();
       
  2058     view.setVerticalScrollMode(QAbstractItemView::ScrollPerItem); //some styles change that in Polish
       
  2059 
       
  2060     view.resize(300, 200);
       
  2061     //view.verticalScrollBar()->setValue(0);
       
  2062 
       
  2063     view.scrollTo(model.index(0,0,QModelIndex()));
       
  2064     CHECK_VISIBLE(0,0);
       
  2065     QCOMPARE(view.verticalScrollBar()->value(), 0);
       
  2066 
       
  2067     view.header()->resizeSection(0, 5); // now we only see the branches
       
  2068     view.scrollTo(model.index(5, 0, QModelIndex()), QTreeView::PositionAtTop);
       
  2069     QCOMPARE(view.verticalScrollBar()->value(), 5);
       
  2070 
       
  2071     view.scrollTo(model.index(60, 60, QModelIndex()));
       
  2072 
       
  2073     CHECK_VISIBLE(60,60);
       
  2074     view.scrollTo(model.index(60, 30, QModelIndex()));
       
  2075     CHECK_VISIBLE(60,30);
       
  2076     view.scrollTo(model.index(30, 30, QModelIndex()));
       
  2077     CHECK_VISIBLE(30,30);
       
  2078 
       
  2079     // TODO force it to move to the left and then the right
       
  2080 }
       
  2081 
       
  2082 void tst_QTreeView::rowsAboutToBeRemoved_move()
       
  2083 {
       
  2084     QStandardItemModel model(3,1);
       
  2085     QTreeView view;
       
  2086     view.setModel(&model);
       
  2087     QModelIndex indexThatWantsToLiveButWillDieDieITellYou;
       
  2088     QModelIndex parent = model.index(2, 0 );
       
  2089     view.expand(parent);
       
  2090     for (int i = 0; i < 6; ++i) {
       
  2091         model.insertRows(0, 1, parent);
       
  2092         model.insertColumns(0, 1, parent);
       
  2093         QModelIndex index = model.index(0, 0, parent);
       
  2094         view.expand(index);
       
  2095         if ( i == 3 )
       
  2096             indexThatWantsToLiveButWillDieDieITellYou = index;
       
  2097         model.setData(index, i);
       
  2098         parent = index;
       
  2099     }
       
  2100     view.resize(600,800);
       
  2101     view.show();
       
  2102     view.doItemsLayout();
       
  2103     static_cast<PublicView *>(&view)->executeDelayedItemsLayout();
       
  2104     parent = indexThatWantsToLiveButWillDieDieITellYou.parent();
       
  2105     QCOMPARE(view.isExpanded(indexThatWantsToLiveButWillDieDieITellYou), true);
       
  2106     QCOMPARE(parent.isValid(), true);
       
  2107     QCOMPARE(parent.parent().isValid(), true);
       
  2108     view.expand(parent);
       
  2109     QCOMPARE(view.isExpanded(parent), true);
       
  2110     QCOMPARE(view.isExpanded(indexThatWantsToLiveButWillDieDieITellYou), true);
       
  2111     model.removeRow(0, indexThatWantsToLiveButWillDieDieITellYou);
       
  2112     QCOMPARE(view.isExpanded(parent), true);
       
  2113     QCOMPARE(view.isExpanded(indexThatWantsToLiveButWillDieDieITellYou), true);
       
  2114 }
       
  2115 
       
  2116 void tst_QTreeView::resizeColumnToContents()
       
  2117 {
       
  2118     QStandardItemModel model(50,2);
       
  2119     for (int r = 0; r < model.rowCount(); ++r) {
       
  2120         for (int c = 0; c < model.columnCount(); ++c) {
       
  2121             QModelIndex idx = model.index(r, c);
       
  2122             model.setData(idx, QString::fromAscii("%1,%2").arg(r).arg(c) );
       
  2123             model.insertColumns(0, 2, idx);
       
  2124             model.insertRows(0, 6, idx);
       
  2125             for (int i = 0; i < 6; ++i) {
       
  2126                 for (int j = 0; j < 2 ; ++j) {
       
  2127                     model.setData(model.index(i, j, idx), QString::fromAscii("child%1%2").arg(i).arg(j));
       
  2128                 }
       
  2129             }
       
  2130         }
       
  2131     }
       
  2132     QTreeView view;
       
  2133     view.setModel(&model);
       
  2134     view.show();
       
  2135     qApp->processEvents(); //must have this, or else it will not scroll
       
  2136     view.scrollToBottom();
       
  2137     view.resizeColumnToContents(0);
       
  2138     int oldColumnSize = view.header()->sectionSize(0);
       
  2139     view.setRootIndex(model.index(0, 0));
       
  2140     view.resizeColumnToContents(0);        //Earlier, this gave an assert
       
  2141     QVERIFY(view.header()->sectionSize(0) > oldColumnSize);
       
  2142 }
       
  2143 
       
  2144 void tst_QTreeView::insertAfterSelect()
       
  2145 {
       
  2146     QtTestModel model;
       
  2147     model.rows = model.cols = 10;
       
  2148     QTreeView view;
       
  2149     view.setModel(&model);
       
  2150     view.show();
       
  2151     QModelIndex firstIndex = model.index(0, 0, QModelIndex());
       
  2152     QVERIFY(firstIndex.isValid());
       
  2153     int itemOffset = view.visualRect(firstIndex).width() / 2;
       
  2154     QPoint p(itemOffset, 1);
       
  2155     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  2156     QVERIFY(view.selectionModel()->isSelected(firstIndex));
       
  2157     model.insertNewRow();
       
  2158     QVERIFY(view.selectionModel()->isSelected(firstIndex)); // Should still be selected
       
  2159 }
       
  2160 
       
  2161 void tst_QTreeView::removeAfterSelect()
       
  2162 {
       
  2163     QtTestModel model;
       
  2164     model.rows = model.cols = 10;
       
  2165     QTreeView view;
       
  2166     view.setModel(&model);
       
  2167     view.show();
       
  2168     QModelIndex firstIndex = model.index(0, 0, QModelIndex());
       
  2169     QVERIFY(firstIndex.isValid());
       
  2170     int itemOffset = view.visualRect(firstIndex).width() / 2;
       
  2171     QPoint p(itemOffset, 1);
       
  2172     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  2173     QVERIFY(view.selectionModel()->isSelected(firstIndex));
       
  2174     model.removeLastRow();
       
  2175     QVERIFY(view.selectionModel()->isSelected(firstIndex)); // Should still be selected
       
  2176 }
       
  2177 
       
  2178 void tst_QTreeView::hiddenItems()
       
  2179 {
       
  2180     QtTestModel model;
       
  2181     model.rows = model.cols = 10;
       
  2182     QTreeView view;
       
  2183     view.setModel(&model);
       
  2184     view.show();
       
  2185 
       
  2186     QModelIndex firstIndex = model.index(1, 0, QModelIndex());
       
  2187     QVERIFY(firstIndex.isValid());
       
  2188     if (model.canFetchMore(firstIndex))
       
  2189         model.fetchMore(firstIndex);
       
  2190     for (int i=0; i < model.rowCount(firstIndex); i++)
       
  2191         view.setRowHidden(i , firstIndex, true );
       
  2192 
       
  2193     int itemOffset = view.visualRect(firstIndex).width() / 2;
       
  2194     int itemHeight = view.visualRect(firstIndex).height();
       
  2195     QPoint p(itemOffset, itemHeight + 1);
       
  2196     view.setExpanded(firstIndex, false);
       
  2197     QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  2198     QCOMPARE(view.isExpanded(firstIndex), false);
       
  2199 
       
  2200     p.setX( 5 );
       
  2201     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  2202     QCOMPARE(view.isExpanded(firstIndex), false);
       
  2203 }
       
  2204 
       
  2205 void tst_QTreeView::spanningItems()
       
  2206 {
       
  2207     QtTestModel model;
       
  2208     model.rows = model.cols = 10;
       
  2209     PublicView view;
       
  2210     view.setModel(&model);
       
  2211     view.show();
       
  2212 
       
  2213     int itemWidth = view.header()->sectionSize(0);
       
  2214     int itemHeight = view.visualRect(model.index(0, 0, QModelIndex())).height();
       
  2215 
       
  2216     // every second row is spanning
       
  2217     for (int i = 1; i < model.rowCount(QModelIndex()); i += 2)
       
  2218         view.setFirstColumnSpanned(i , QModelIndex(), true);
       
  2219 
       
  2220     // non-spanning item
       
  2221     QPoint p(itemWidth / 2, itemHeight / 2); // column 0, row 0
       
  2222     view.setCurrentIndex(QModelIndex());
       
  2223     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  2224     QCOMPARE(view.currentIndex(), model.index(0, 0, QModelIndex()));
       
  2225     QCOMPARE(view.header()->sectionSize(0) - view.indentation(),
       
  2226              view.visualRect(model.index(0, 0, QModelIndex())).width());
       
  2227 
       
  2228     // spanning item
       
  2229     p.setX(itemWidth + (itemWidth / 2)); // column 1
       
  2230     p.setY(itemHeight + (itemHeight / 2)); // row 1
       
  2231     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  2232     QCOMPARE(view.currentIndex(), model.index(1, 0, QModelIndex()));
       
  2233     QCOMPARE(view.header()->length() - view.indentation(),
       
  2234              view.visualRect(model.index(1, 0, QModelIndex())).width());
       
  2235 
       
  2236     // size hint
       
  2237     // every second row is un-spanned
       
  2238     QStyleOptionViewItem option = view.viewOptions();
       
  2239     int w = view.header()->sectionSizeHint(0);
       
  2240     for (int i = 0; i < model.rowCount(QModelIndex()); ++i) {
       
  2241         if (!view.isFirstColumnSpanned(i, QModelIndex())) {
       
  2242             QModelIndex index = model.index(i, 0, QModelIndex());
       
  2243             w = qMax(w, view.itemDelegate(index)->sizeHint(option, index).width() + view.indentation());
       
  2244         }
       
  2245     }
       
  2246     QCOMPARE(view.sizeHintForColumn(0), w);
       
  2247 }
       
  2248 
       
  2249 void tst_QTreeView::selectionOrderTest()
       
  2250 {
       
  2251     QVERIFY(((QItemSelectionModel*)sender())->currentIndex().row() != -1);
       
  2252 }
       
  2253 
       
  2254 void tst_QTreeView::selection()
       
  2255 {
       
  2256     QTreeView treeView;
       
  2257     QStandardItemModel m(10, 2);
       
  2258     for (int i = 0;i < 10; ++i)
       
  2259         m.setData(m.index(i, 0), i);
       
  2260     treeView.setModel(&m);
       
  2261 
       
  2262     treeView.setSelectionBehavior(QAbstractItemView::SelectRows);
       
  2263     treeView.setSelectionMode(QAbstractItemView::ExtendedSelection);
       
  2264 
       
  2265     connect(treeView.selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
       
  2266             this, SLOT(selectionOrderTest()));
       
  2267 
       
  2268     treeView.show();
       
  2269 
       
  2270     QTest::mousePress(treeView.viewport(), Qt::LeftButton, 0, treeView.visualRect(m.index(1, 0)).center());
       
  2271     QTest::keyPress(treeView.viewport(), Qt::Key_Down);
       
  2272 }
       
  2273 
       
  2274 //From task 151686 QTreeView ExtendedSelection selects hidden rows
       
  2275 void tst_QTreeView::selectionWithHiddenItems()
       
  2276 {
       
  2277     QStandardItemModel model;
       
  2278     for (int i = 0; i < model.rowCount(); ++i)
       
  2279         model.setData(model.index(i,0), QString("row %1").arg(i));
       
  2280 
       
  2281     QStandardItem item0("row 0");
       
  2282     QStandardItem item1("row 1");
       
  2283     QStandardItem item2("row 2");
       
  2284     QStandardItem item3("row 3");
       
  2285     model.appendColumn( QList<QStandardItem*>() << &item0 << &item1 << &item2 << &item3);
       
  2286 
       
  2287     QStandardItem child("child");
       
  2288     item1.appendRow( &child);
       
  2289 
       
  2290     QTreeView view;
       
  2291     view.setModel(&model);
       
  2292     view.setSelectionMode(QAbstractItemView::ExtendedSelection);
       
  2293     view.show();
       
  2294     qApp->processEvents();
       
  2295 
       
  2296     //child should not be selected as it is hidden (its parent is not expanded)
       
  2297     view.selectAll();
       
  2298     QCOMPARE(view.selectionModel()->selection().count(), 1); //one range
       
  2299     QCOMPARE(view.selectionModel()->selectedRows().count(), 4);
       
  2300     view.expandAll();
       
  2301     QVERIFY(view.isExpanded(item1.index()));
       
  2302     QCOMPARE(view.selectionModel()->selection().count(), 1);
       
  2303     QCOMPARE(view.selectionModel()->selectedRows().count(), 4);
       
  2304     QVERIFY( !view.selectionModel()->isSelected(model.indexFromItem(&child)));
       
  2305     view.clearSelection();
       
  2306     QVERIFY(view.isExpanded(item1.index()));
       
  2307 
       
  2308     //child should be selected as it is visible (its parent is expanded)
       
  2309     view.selectAll();
       
  2310     QCOMPARE(view.selectionModel()->selection().count(), 2);
       
  2311     QCOMPARE(view.selectionModel()->selectedRows().count(), 5); //everything is selected
       
  2312     view.clearSelection();
       
  2313 
       
  2314     //we hide the node with a child (there should then be 3 items selected in 2 ranges)
       
  2315     view.setRowHidden(1, QModelIndex(), true);
       
  2316     QVERIFY(view.isExpanded(item1.index()));
       
  2317     qApp->processEvents();
       
  2318     view.selectAll();
       
  2319     QCOMPARE(view.selectionModel()->selection().count(), 2);
       
  2320     QCOMPARE(view.selectionModel()->selectedRows().count(), 3);
       
  2321     QVERIFY( !view.selectionModel()->isSelected(model.indexFromItem(&item1)));
       
  2322     QVERIFY( !view.selectionModel()->isSelected(model.indexFromItem(&child)));
       
  2323 
       
  2324     view.setRowHidden(1, QModelIndex(), false);
       
  2325     QVERIFY(view.isExpanded(item1.index()));
       
  2326     view.clearSelection();
       
  2327 
       
  2328     //we hide a node without children (there should then be 4 items selected in 3 ranges)
       
  2329     view.setRowHidden(2, QModelIndex(), true);
       
  2330     qApp->processEvents();
       
  2331     QVERIFY(view.isExpanded(item1.index()));
       
  2332     view.selectAll();
       
  2333     QVERIFY(view.isExpanded(item1.index()));
       
  2334     QCOMPARE(view.selectionModel()->selection().count(), 3);
       
  2335     QCOMPARE(view.selectionModel()->selectedRows().count(), 4);
       
  2336     QVERIFY( !view.selectionModel()->isSelected(model.indexFromItem(&item2)));
       
  2337     view.setRowHidden(2, QModelIndex(), false);
       
  2338     QVERIFY(view.isExpanded(item1.index()));
       
  2339     view.clearSelection();
       
  2340 }
       
  2341 
       
  2342 void tst_QTreeView::selectAll()
       
  2343 {
       
  2344     QStandardItemModel model(4,4);
       
  2345     PublicView view2;
       
  2346     view2.setModel(&model);
       
  2347     view2.setSelectionMode(QAbstractItemView::ExtendedSelection);
       
  2348     view2.selectAll();  // Should work with an empty model
       
  2349     //everything should be selected since we are in ExtendedSelection mode
       
  2350     QCOMPARE(view2.selectedIndexes().count(), model.rowCount() * model.columnCount());
       
  2351 
       
  2352     for (int i = 0; i < model.rowCount(); ++i)
       
  2353         model.setData(model.index(i,0), QString("row %1").arg(i));
       
  2354     PublicView view;
       
  2355     view.setModel(&model);
       
  2356     int selectedCount = view.selectedIndexes().count();
       
  2357     view.selectAll();
       
  2358     QCOMPARE(view.selectedIndexes().count(), selectedCount);
       
  2359 }
       
  2360 
       
  2361 void tst_QTreeView::extendedSelection_data()
       
  2362 {
       
  2363     QTest::addColumn<QPoint>("mousePressPos");
       
  2364     QTest::addColumn<int>("selectedCount");
       
  2365 
       
  2366     QTest::newRow("select") << QPoint(10, 10) << 2;
       
  2367     QTest::newRow("unselect") << QPoint(10, 150) << 0;
       
  2368 }
       
  2369 
       
  2370 void tst_QTreeView::extendedSelection()
       
  2371 {
       
  2372     QFETCH(QPoint, mousePressPos);
       
  2373     QFETCH(int, selectedCount);
       
  2374 
       
  2375     QStandardItemModel model(5, 2);
       
  2376     QTreeView view;
       
  2377     view.resize(qMax(mousePressPos.x() * 2, 200), qMax(mousePressPos.y() * 2, 200));
       
  2378     view.setModel(&model);
       
  2379     view.setSelectionMode(QAbstractItemView::ExtendedSelection);
       
  2380     view.show();
       
  2381     QTest::mousePress(view.viewport(), Qt::LeftButton, 0, mousePressPos);
       
  2382     QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedCount);
       
  2383 }
       
  2384 
       
  2385 void tst_QTreeView::rowSizeHint()
       
  2386 {
       
  2387     //tests whether the correct visible columns are taken into account when
       
  2388     //calculating the height of a line
       
  2389     QStandardItemModel model(1,3);
       
  2390     model.setData( model.index(0,0), QSize(20,40), Qt::SizeHintRole);
       
  2391     model.setData( model.index(0,1), QSize(20,10), Qt::SizeHintRole);
       
  2392     model.setData( model.index(0,2), QSize(20,10), Qt::SizeHintRole);
       
  2393     QTreeView view;
       
  2394     view.setModel(&model);
       
  2395 
       
  2396     view.header()->moveSection(1, 0); //the 2nd column goes to the 1st place
       
  2397 
       
  2398     view.show();
       
  2399 
       
  2400     //it must be 40 since the tallest item that defines the height of a line
       
  2401     QCOMPARE( view.visualRect(model.index(0,0)).height(), 40);
       
  2402     QCOMPARE( view.visualRect(model.index(0,1)).height(), 40);
       
  2403     QCOMPARE( view.visualRect(model.index(0,2)).height(), 40);
       
  2404 }
       
  2405 
       
  2406 
       
  2407 //From task 155449 (QTreeWidget has a large width for the first section when sorting
       
  2408 //is turned on before items are added)
       
  2409 void tst_QTreeView::setSortingEnabled()
       
  2410 {
       
  2411     //1st the treeview is a top-level
       
  2412     {
       
  2413         QTreeView view;
       
  2414         QStandardItemModel model(1,1);
       
  2415         view.setModel(&model);
       
  2416         const int size = view.header()->sectionSize(0);
       
  2417         view.setSortingEnabled(true);
       
  2418         model.setColumnCount(3);
       
  2419         //we test that changing the column count doesn't change the 1st column size
       
  2420         QCOMPARE(view.header()->sectionSize(0), size);
       
  2421     }
       
  2422 
       
  2423     //then it is no more a top-level
       
  2424     {
       
  2425         QMainWindow win;
       
  2426         QTreeView view;
       
  2427         QStandardItemModel model(1,1);
       
  2428         view.setModel(&model);
       
  2429         win.setCentralWidget(&view);
       
  2430         const int size = view.header()->sectionSize(0);
       
  2431         view.setSortingEnabled(true);
       
  2432         model.setColumnCount(3);
       
  2433         //we test that changing the column count doesn't change the 1st column size
       
  2434         QCOMPARE(view.header()->sectionSize(0), size);
       
  2435     }
       
  2436 }
       
  2437 
       
  2438 void tst_QTreeView::headerHidden()
       
  2439 {
       
  2440     QTreeView view;
       
  2441     QStandardItemModel model;
       
  2442     view.setModel(&model);
       
  2443     QCOMPARE(view.isHeaderHidden(), false);
       
  2444     QCOMPARE(view.header()->isHidden(), false);
       
  2445     view.setHeaderHidden(true);
       
  2446     QCOMPARE(view.isHeaderHidden(), true);
       
  2447     QCOMPARE(view.header()->isHidden(), true);
       
  2448 }
       
  2449 
       
  2450 // From Task 145199 (crash when column 0 having at least one expanded item is removed and then
       
  2451 // inserted). The test passes simply if it doesn't crash, hence there are no calls
       
  2452 // to QCOMPARE() or QVERIFY().
       
  2453 void tst_QTreeView::removeAndInsertExpandedCol0()
       
  2454 {
       
  2455     QTreeView view;
       
  2456     QStandardItemModel model;
       
  2457     view.setModel(&model);
       
  2458 
       
  2459     model.setColumnCount(1);
       
  2460 
       
  2461     QStandardItem *item0 = new QStandardItem(QString("item 0"));
       
  2462     model.invisibleRootItem()->appendRow(item0);
       
  2463     view.expand(item0->index());
       
  2464     QStandardItem *item1 = new QStandardItem(QString("item 1"));
       
  2465     item0->appendRow(item1);
       
  2466 
       
  2467     model.removeColumns(0, 1);
       
  2468     model.insertColumns(0, 1);
       
  2469 
       
  2470     view.show();
       
  2471     qApp->processEvents();
       
  2472 }
       
  2473 
       
  2474 void tst_QTreeView::disabledButCheckable()
       
  2475 {
       
  2476     QTreeView view;
       
  2477     QStandardItemModel model;
       
  2478     QStandardItem *item;
       
  2479     item = new QStandardItem(QLatin1String("Row 1 Item"));
       
  2480     model.insertRow(0, item);
       
  2481 
       
  2482     item = new QStandardItem(QLatin1String("Row 2 Item"));
       
  2483     item->setCheckable(true);
       
  2484     item->setEnabled(false);
       
  2485     model.insertRow(1, item);
       
  2486 
       
  2487     view.setModel(&model);
       
  2488     view.setCurrentIndex(model.index(1,0));
       
  2489     QCOMPARE(item->checkState(), Qt::Unchecked);
       
  2490     view.show();
       
  2491 
       
  2492     QTest::keyClick(&view, Qt::Key_Space);
       
  2493     QCOMPARE(item->checkState(), Qt::Unchecked);
       
  2494 }
       
  2495 
       
  2496 void tst_QTreeView::sortByColumn_data()
       
  2497 {
       
  2498     QTest::addColumn<bool>("sortingEnabled");
       
  2499     QTest::newRow("sorting enabled") << true;
       
  2500     QTest::newRow("sorting disabled") << false;
       
  2501 }
       
  2502 
       
  2503 // Checks sorting and that sortByColumn also sets the sortIndicator
       
  2504 void tst_QTreeView::sortByColumn()
       
  2505 {
       
  2506     QFETCH(bool, sortingEnabled);
       
  2507     QTreeView view;
       
  2508     QStandardItemModel model(4,2);
       
  2509     model.setItem(0,0,new QStandardItem("b"));
       
  2510     model.setItem(1,0,new QStandardItem("d"));
       
  2511     model.setItem(2,0,new QStandardItem("c"));
       
  2512     model.setItem(3,0,new QStandardItem("a"));
       
  2513     model.setItem(0,1,new QStandardItem("e"));
       
  2514     model.setItem(1,1,new QStandardItem("g"));
       
  2515     model.setItem(2,1,new QStandardItem("h"));
       
  2516     model.setItem(3,1,new QStandardItem("f"));
       
  2517 
       
  2518     view.setSortingEnabled(sortingEnabled);
       
  2519     view.setModel(&model);
       
  2520     view.sortByColumn(1);
       
  2521     QCOMPARE(view.header()->sortIndicatorSection(), 1);
       
  2522     QCOMPARE(view.model()->data(view.model()->index(0,1)).toString(), QString::fromLatin1("h"));
       
  2523     QCOMPARE(view.model()->data(view.model()->index(1,1)).toString(), QString::fromLatin1("g"));
       
  2524     view.sortByColumn(0, Qt::AscendingOrder);
       
  2525     QCOMPARE(view.header()->sortIndicatorSection(), 0);
       
  2526     QCOMPARE(view.model()->data(view.model()->index(0,0)).toString(), QString::fromLatin1("a"));
       
  2527     QCOMPARE(view.model()->data(view.model()->index(1,0)).toString(), QString::fromLatin1("b"));
       
  2528 }
       
  2529 
       
  2530 /*
       
  2531     This is a model that every time kill() is called it will completely change
       
  2532     all of its nodes for new nodes.  It then asserts if you later use a dead node.
       
  2533  */
       
  2534 class EvilModel: public QAbstractItemModel
       
  2535 {
       
  2536 
       
  2537 public:
       
  2538     class Node {
       
  2539     public:
       
  2540         Node(Node *p = 0, int level = 0) : parent(p), isDead(false) {
       
  2541             populate(level);
       
  2542         }
       
  2543         ~Node()
       
  2544         {
       
  2545             qDeleteAll(children.begin(), children.end());
       
  2546             qDeleteAll(deadChildren.begin(), deadChildren.end());
       
  2547         }
       
  2548 
       
  2549         void populate(int level = 0) {
       
  2550             if (level < 4)
       
  2551                 for (int i = 0; i < 5; ++i)
       
  2552                     children.append(new Node(this, level + 1));
       
  2553         }
       
  2554         void kill() {
       
  2555             for (int i = children.count() -1; i >= 0; --i) {
       
  2556                 children.at(i)->kill();
       
  2557                 if (parent == 0) {
       
  2558                     deadChildren.append(children.at(i));
       
  2559                     children.removeAt(i);
       
  2560                 }
       
  2561             }
       
  2562             if (parent == 0) {
       
  2563                 Q_ASSERT(children.isEmpty());
       
  2564                 populate();
       
  2565             } else {
       
  2566                 isDead = true;
       
  2567             }
       
  2568         }
       
  2569 
       
  2570         QList<Node*> children;
       
  2571         QList<Node*> deadChildren;
       
  2572         Node *parent;
       
  2573         bool isDead;
       
  2574     };
       
  2575 
       
  2576     Node *root;
       
  2577 
       
  2578     EvilModel(QObject *parent = 0): QAbstractItemModel(parent), root(new Node)
       
  2579     {
       
  2580     }
       
  2581     ~EvilModel()
       
  2582     {
       
  2583         delete root;
       
  2584     }
       
  2585 
       
  2586     void change()
       
  2587     {
       
  2588         emit layoutAboutToBeChanged();
       
  2589         QModelIndexList oldList = persistentIndexList();
       
  2590         QList<QStack<int> > oldListPath;
       
  2591         for (int i = 0; i < oldList.count(); ++i) {
       
  2592             QModelIndex idx = oldList.at(i);
       
  2593             QStack<int> path;
       
  2594             while (idx.isValid()) {
       
  2595                 path.push(idx.row());
       
  2596                 idx = idx.parent();
       
  2597             }
       
  2598             oldListPath.append(path);
       
  2599         }
       
  2600         root->kill();
       
  2601 
       
  2602         QModelIndexList newList;
       
  2603         for (int i = 0; i < oldListPath.count(); ++i) {
       
  2604             QStack<int> path = oldListPath[i];
       
  2605             QModelIndex idx;
       
  2606             while(!path.isEmpty()) {
       
  2607                 idx = index(path.pop(), 0, idx);
       
  2608             }
       
  2609             newList.append(idx);
       
  2610         }
       
  2611 
       
  2612         changePersistentIndexList(oldList, newList);
       
  2613         emit layoutChanged();
       
  2614     }
       
  2615 
       
  2616     int rowCount(const QModelIndex& parent = QModelIndex()) const {
       
  2617         Node *parentNode = root;
       
  2618         if (parent.isValid()) {
       
  2619             parentNode = static_cast<Node*>(parent.internalPointer());
       
  2620             Q_ASSERT(!parentNode->isDead);
       
  2621         }
       
  2622         return parentNode->children.count();
       
  2623     }
       
  2624     int columnCount(const QModelIndex& parent = QModelIndex()) const {
       
  2625         if (parent.column() > 0)
       
  2626             return 0;
       
  2627         return 1;
       
  2628     }
       
  2629 
       
  2630     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
       
  2631     {
       
  2632         Node *grandparentNode = static_cast<Node*>(parent.internalPointer());
       
  2633         Node *parentNode = root;
       
  2634         if (parent.isValid()) {
       
  2635             Q_ASSERT(!grandparentNode->isDead);
       
  2636             parentNode = grandparentNode->children[parent.row()];
       
  2637             Q_ASSERT(!parentNode->isDead);
       
  2638         }
       
  2639         return createIndex(row, column, parentNode);
       
  2640     }
       
  2641 
       
  2642     QModelIndex parent(const QModelIndex &index) const
       
  2643     {
       
  2644         Node *parent = static_cast<Node*>(index.internalPointer());
       
  2645         Node *grandparent = parent->parent;
       
  2646         if (!grandparent)
       
  2647             return QModelIndex();
       
  2648         return createIndex(grandparent->children.indexOf(parent), 0, grandparent);
       
  2649     }
       
  2650 
       
  2651     QVariant data(const QModelIndex &idx, int role) const
       
  2652     {
       
  2653         if (idx.isValid() && role == Qt::DisplayRole) {
       
  2654             Node *parentNode = root;
       
  2655             if (idx.isValid()) {
       
  2656                 parentNode = static_cast<Node*>(idx.internalPointer());
       
  2657                 Q_ASSERT(!parentNode->isDead);
       
  2658             }
       
  2659             return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column())
       
  2660                 .arg(parentNode->isDead ? "dead" : "alive");
       
  2661         }
       
  2662         return QVariant();
       
  2663     }
       
  2664 };
       
  2665 
       
  2666 void tst_QTreeView::evilModel_data()
       
  2667 {
       
  2668     QTest::addColumn<bool>("visible");
       
  2669     QTest::newRow("visible") << false;
       
  2670 }
       
  2671 
       
  2672 void tst_QTreeView::evilModel()
       
  2673 {
       
  2674     QFETCH(bool, visible);
       
  2675     // init
       
  2676     PublicView view;
       
  2677     EvilModel model;
       
  2678     view.setModel(&model);
       
  2679     view.setVisible(visible);
       
  2680     QPersistentModelIndex firstLevel = model.index(0, 0);
       
  2681     QPersistentModelIndex secondLevel = model.index(1, 0, firstLevel);
       
  2682     QPersistentModelIndex thirdLevel = model.index(2, 0, secondLevel);
       
  2683     view.setExpanded(firstLevel, true);
       
  2684     view.setExpanded(secondLevel, true);
       
  2685     view.setExpanded(thirdLevel, true);
       
  2686     model.change();
       
  2687 
       
  2688     // tests
       
  2689     view.setRowHidden(0, firstLevel, true);
       
  2690     model.change();
       
  2691 
       
  2692     return;
       
  2693     view.setFirstColumnSpanned(1, QModelIndex(), true);
       
  2694     model.change();
       
  2695 
       
  2696     view.expand(secondLevel);
       
  2697     model.change();
       
  2698 
       
  2699     view.collapse(secondLevel);
       
  2700     model.change();
       
  2701 
       
  2702     view.isExpanded(secondLevel);
       
  2703     view.setCurrentIndex(firstLevel);
       
  2704     model.change();
       
  2705 
       
  2706     view.keyboardSearch("foo");
       
  2707     model.change();
       
  2708 
       
  2709     view.visualRect(secondLevel);
       
  2710     model.change();
       
  2711 
       
  2712     view.scrollTo(thirdLevel);
       
  2713     model.change();
       
  2714 
       
  2715     view.repaint();
       
  2716     model.change();
       
  2717 
       
  2718     QTest::mouseDClick(view.viewport(), Qt::LeftButton);
       
  2719     model.change();
       
  2720 
       
  2721     view.indexAt(QPoint(10, 10));
       
  2722     model.change();
       
  2723 
       
  2724     view.indexAbove(model.index(2, 0));
       
  2725     model.change();
       
  2726 
       
  2727     view.indexBelow(model.index(1, 0));
       
  2728     model.change();
       
  2729 
       
  2730     QRect rect(0, 0, 10, 10);
       
  2731     view.setSelection(rect, QItemSelectionModel::Select);
       
  2732     model.change();
       
  2733 
       
  2734     view.moveCursor(PublicView::MoveDown, Qt::NoModifier);
       
  2735     model.change();
       
  2736 
       
  2737     view.resizeColumnToContents(1);
       
  2738     model.change();
       
  2739 
       
  2740     view.QAbstractItemView::sizeHintForColumn(1);
       
  2741     model.change();
       
  2742 
       
  2743     view.rowHeight(secondLevel);
       
  2744     model.change();
       
  2745 
       
  2746     view.setRootIsDecorated(true);
       
  2747     model.change();
       
  2748 
       
  2749     view.setItemsExpandable(false);
       
  2750     model.change();
       
  2751 
       
  2752     view.columnViewportPosition(0);
       
  2753     model.change();
       
  2754 
       
  2755     view.columnWidth(0);
       
  2756     model.change();
       
  2757 
       
  2758     view.setColumnWidth(0, 30);
       
  2759     model.change();
       
  2760 
       
  2761     view.columnAt(15);
       
  2762     model.change();
       
  2763 
       
  2764     view.isColumnHidden(1);
       
  2765     model.change();
       
  2766 
       
  2767     view.setColumnHidden(2, true);
       
  2768     model.change();
       
  2769 
       
  2770     view.isHeaderHidden();
       
  2771     model.change();
       
  2772 
       
  2773     view.setHeaderHidden(true);
       
  2774     model.change();
       
  2775 
       
  2776     view.isRowHidden(2, secondLevel);
       
  2777     model.change();
       
  2778 
       
  2779     view.setRowHidden(3, secondLevel, true);
       
  2780     model.change();
       
  2781 
       
  2782     view.isFirstColumnSpanned(3, thirdLevel);
       
  2783     model.change();
       
  2784 
       
  2785     view.setSortingEnabled(true);
       
  2786     model.change();
       
  2787 
       
  2788     view.isSortingEnabled();
       
  2789     model.change();
       
  2790 
       
  2791     view.setAnimated(true);
       
  2792     model.change();
       
  2793 
       
  2794     view.isAnimated();
       
  2795     model.change();
       
  2796 
       
  2797     view.setAllColumnsShowFocus(true);
       
  2798     model.change();
       
  2799 
       
  2800     view.allColumnsShowFocus();
       
  2801     model.change();
       
  2802 
       
  2803     view.doItemsLayout();
       
  2804     model.change();
       
  2805 
       
  2806     view.reset();
       
  2807     model.change();
       
  2808 
       
  2809     view.sortByColumn(1, Qt::AscendingOrder);
       
  2810     model.change();
       
  2811 
       
  2812     view.dataChanged(secondLevel, secondLevel);
       
  2813     model.change();
       
  2814 
       
  2815     view.hideColumn(1);
       
  2816     model.change();
       
  2817 
       
  2818     view.showColumn(1);
       
  2819     model.change();
       
  2820 
       
  2821     view.resizeColumnToContents(1);
       
  2822     model.change();
       
  2823 
       
  2824     view.sortByColumn(1);
       
  2825     model.change();
       
  2826 
       
  2827     view.selectAll();
       
  2828     model.change();
       
  2829 
       
  2830     view.expandAll();
       
  2831     model.change();
       
  2832 
       
  2833     view.collapseAll();
       
  2834     model.change();
       
  2835 
       
  2836     view.expandToDepth(3);
       
  2837     model.change();
       
  2838 
       
  2839     view.setRootIndex(secondLevel);
       
  2840 }
       
  2841 
       
  2842 void tst_QTreeView::indexRowSizeHint()
       
  2843 {
       
  2844     QStandardItemModel model(10, 1);
       
  2845     PublicView view;
       
  2846 
       
  2847     view.setModel(&model);
       
  2848 
       
  2849     QModelIndex index = model.index(5, 0);
       
  2850     QPushButton *w = new QPushButton("Test");
       
  2851     view.setIndexWidget(index, w);
       
  2852 
       
  2853     view.show();
       
  2854 
       
  2855     QCOMPARE(view.indexRowSizeHint(index), w->sizeHint().height());
       
  2856 }
       
  2857 
       
  2858 void tst_QTreeView::filterProxyModelCrash()
       
  2859 {
       
  2860     QStandardItemModel model;
       
  2861     QList<QStandardItem *> items;
       
  2862     for (int i = 0; i < 100; i++)
       
  2863         items << new QStandardItem(QString::fromLatin1("item %1").arg(i));
       
  2864     model.appendColumn(items);
       
  2865 
       
  2866     QSortFilterProxyModel proxy;
       
  2867     proxy.setSourceModel(&model);
       
  2868 
       
  2869     QTreeView view;
       
  2870     view.setModel(&proxy);
       
  2871     view.show();
       
  2872     QTest::qWait(30);
       
  2873     proxy.invalidate();
       
  2874     view.verticalScrollBar()->setValue(15);
       
  2875     QTest::qWait(20);
       
  2876 
       
  2877     proxy.invalidate();
       
  2878     view.repaint(); //used to crash
       
  2879 }
       
  2880 
       
  2881 void tst_QTreeView::styleOptionViewItem()
       
  2882 {
       
  2883     class MyDelegate : public QStyledItemDelegate
       
  2884     {
       
  2885         public:
       
  2886             void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
       
  2887             {
       
  2888                 QVERIFY(qstyleoption_cast<const QStyleOptionViewItemV4 *>(&option));
       
  2889                 QStyleOptionViewItemV4 opt(option);
       
  2890                 initStyleOption(&opt, index);
       
  2891 
       
  2892                 QVERIFY(!opt.text.isEmpty());
       
  2893                 QCOMPARE(opt.index, index);
       
  2894                 QCOMPARE(!(opt.features & QStyleOptionViewItemV2::Alternate), !(index.row() % 2));
       
  2895                 QCOMPARE(!(opt.features & QStyleOptionViewItemV2::HasCheckIndicator), !opt.text.contains("Checkable"));
       
  2896 
       
  2897                 if (opt.text.contains("Beginning"))
       
  2898                     QCOMPARE(opt.viewItemPosition, QStyleOptionViewItemV4::Beginning);
       
  2899 
       
  2900                 if (opt.text.contains("Middle"))
       
  2901                     QCOMPARE(opt.viewItemPosition, QStyleOptionViewItemV4::Middle);
       
  2902 
       
  2903                 if (opt.text.contains("End"))
       
  2904                     QCOMPARE(opt.viewItemPosition, QStyleOptionViewItemV4::End);
       
  2905 
       
  2906                 if (opt.text.contains("OnlyOne"))
       
  2907                     QCOMPARE(opt.viewItemPosition, QStyleOptionViewItemV4::OnlyOne);
       
  2908 
       
  2909                 if (opt.text.contains("Checked"))
       
  2910                     QCOMPARE(opt.checkState, Qt::Checked);
       
  2911                 else
       
  2912                     QCOMPARE(opt.checkState, Qt::Unchecked);
       
  2913 
       
  2914                 QVERIFY(!opt.text.contains("Assert"));
       
  2915 
       
  2916                 QStyledItemDelegate::paint(painter, option, index);
       
  2917                 count++;
       
  2918             }
       
  2919             mutable int count;
       
  2920     };
       
  2921 
       
  2922     QTreeView view;
       
  2923     QStandardItemModel model;
       
  2924     view.setModel(&model);
       
  2925     MyDelegate delegate;
       
  2926     view.setItemDelegate(&delegate);
       
  2927     model.appendRow(QList<QStandardItem*>()
       
  2928         << new QStandardItem("Beginning") <<  new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") );
       
  2929     model.appendRow(QList<QStandardItem*>()
       
  2930         << new QStandardItem("Beginning") <<  new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") );
       
  2931     model.appendRow(QList<QStandardItem*>()
       
  2932         << new QStandardItem("OnlyOne") <<  new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") );
       
  2933     QStandardItem *checkable = new QStandardItem("Checkable");
       
  2934     checkable->setCheckable(true);
       
  2935     QStandardItem *checked = new QStandardItem("Checkable Checked");
       
  2936     checkable->setCheckable(true);
       
  2937     checked->setCheckState(Qt::Checked);
       
  2938     model.appendRow(QList<QStandardItem*>()
       
  2939         << new QStandardItem("Beginning") <<  checkable << checked << new QStandardItem("End") );
       
  2940 
       
  2941     view.setFirstColumnSpanned(2, QModelIndex(), true);
       
  2942     view.setAlternatingRowColors(true);
       
  2943 
       
  2944     delegate.count = 0;
       
  2945     view.showMaximized();
       
  2946     QTRY_VERIFY(delegate.count >= 13);
       
  2947 }
       
  2948 
       
  2949 class task174627_TreeView : public QTreeView
       
  2950 {
       
  2951     Q_OBJECT
       
  2952 protected slots:
       
  2953     void currentChanged(const QModelIndex &current, const QModelIndex &)
       
  2954     { emit currentChanged(current); }
       
  2955 signals:
       
  2956     void currentChanged(const QModelIndex &);
       
  2957 };
       
  2958 
       
  2959 void tst_QTreeView::task174627_moveLeftToRoot()
       
  2960 {
       
  2961     QStandardItemModel model;
       
  2962     QStandardItem *item1 = new QStandardItem(QString("item 1"));
       
  2963     model.invisibleRootItem()->appendRow(item1);
       
  2964     QStandardItem *item2 = new QStandardItem(QString("item 2"));
       
  2965     item1->appendRow(item2);
       
  2966 
       
  2967     task174627_TreeView view;
       
  2968     view.setModel(&model);
       
  2969     view.setRootIndex(item1->index());
       
  2970     view.setCurrentIndex(item2->index());
       
  2971 
       
  2972     QSignalSpy spy(&view, SIGNAL(currentChanged(QModelIndex)));
       
  2973     QTest::keyClick(&view, Qt::Key_Left);
       
  2974     QCOMPARE(spy.count(), 0);
       
  2975 }
       
  2976 
       
  2977 void tst_QTreeView::task171902_expandWith1stColHidden()
       
  2978 {
       
  2979     //the task was: if the first column of a treeview is hidden, the expanded state is not correctly restored
       
  2980     QStandardItemModel model;
       
  2981     QStandardItem root("root"), root2("root"),
       
  2982         subitem("subitem"), subitem2("subitem"),
       
  2983         subsubitem("subsubitem"), subsubitem2("subsubitem");
       
  2984 
       
  2985     model.appendRow( QList<QStandardItem *>() << &root << &root2);
       
  2986     root.appendRow( QList<QStandardItem *>() << &subitem << &subitem2);
       
  2987     subitem.appendRow( QList<QStandardItem *>() << &subsubitem << &subsubitem2);
       
  2988 
       
  2989     QTreeView view;
       
  2990     view.setModel(&model);
       
  2991 
       
  2992     view.setColumnHidden(0, true);
       
  2993     view.expandAll();
       
  2994     view.collapse(root.index());
       
  2995     view.expand(root.index());
       
  2996 
       
  2997     QCOMPARE(view.isExpanded(root.index()), true);
       
  2998     QCOMPARE(view.isExpanded(subitem.index()), true);
       
  2999 
       
  3000 }
       
  3001 
       
  3002 void tst_QTreeView::task203696_hidingColumnsAndRowsn()
       
  3003 {
       
  3004     QTreeView view;
       
  3005     QStandardItemModel *model = new QStandardItemModel(0, 3, &view);
       
  3006     for (int i = 0; i < 3; ++i)
       
  3007     {
       
  3008         model->insertRow(model->rowCount());
       
  3009         for (int j = 0; j < model->columnCount(); ++j)
       
  3010             model->setData(model->index(i, j), QString("row %1 col %2").arg(i).arg(j));
       
  3011     }
       
  3012     view.setModel(model);
       
  3013     view.show();
       
  3014     view.setColumnHidden(0, true);
       
  3015     view.setRowHidden(0, QModelIndex(), true);
       
  3016     QCOMPARE(view.indexAt(QPoint(0, 0)), model->index(1, 1));
       
  3017 }
       
  3018 
       
  3019 
       
  3020 void tst_QTreeView::addRowsWhileSectionsAreHidden()
       
  3021 {
       
  3022     QTreeView view;
       
  3023     for (int pass = 1; pass <= 2; ++pass) {
       
  3024         QStandardItemModel *model = new QStandardItemModel(6, pass, &view);
       
  3025         view.setModel(model);
       
  3026         view.show();
       
  3027 
       
  3028         int i;
       
  3029         for (i = 0; i < 3; ++i)
       
  3030         {
       
  3031             model->insertRow(model->rowCount());
       
  3032             for (int j = 0; j < model->columnCount(); ++j) {
       
  3033                 model->setData(model->index(i, j), QString("row %1 col %2").arg(i).arg(j));
       
  3034             }
       
  3035         }
       
  3036         int col;
       
  3037         for (col = 0; col < pass; ++col)
       
  3038             view.setColumnHidden(col, true);
       
  3039         for (i = 3; i < 6; ++i)
       
  3040         {
       
  3041             model->insertRow(model->rowCount());
       
  3042             for (int j = 0; j < model->columnCount(); ++j) {
       
  3043                 model->setData(model->index(i, j), QString("row %1 col %2").arg(i).arg(j));
       
  3044             }
       
  3045         }
       
  3046         for (col = 0; col < pass; ++col)
       
  3047             view.setColumnHidden(col, false);
       
  3048         QTest::qWait(250);
       
  3049 
       
  3050         for (i = 0; i < 6; ++i) {
       
  3051             QRect rect = view.visualRect(model->index(i, 0));
       
  3052             QCOMPARE(rect.isValid(), true);
       
  3053         }
       
  3054 
       
  3055         delete model;
       
  3056     }
       
  3057 }
       
  3058 
       
  3059 void tst_QTreeView::task216717_updateChildren()
       
  3060 {
       
  3061     class Tree : public QTreeWidget {
       
  3062         protected:
       
  3063             void paintEvent(QPaintEvent *e)
       
  3064             {
       
  3065                 QTreeWidget::paintEvent(e);
       
  3066                 refreshed=true;
       
  3067             }
       
  3068         public:
       
  3069             bool refreshed;
       
  3070     } tree;
       
  3071     tree.show();
       
  3072     QTest::qWaitForWindowShown(&tree);
       
  3073     tree.refreshed = false;
       
  3074     QTreeWidgetItem *parent = new QTreeWidgetItem(QStringList() << "parent");
       
  3075     tree.addTopLevelItem(parent);
       
  3076     QTest::qWait(10);
       
  3077     QTRY_VERIFY(tree.refreshed);
       
  3078     tree.refreshed = false;
       
  3079     parent->addChild(new QTreeWidgetItem(QStringList() << "child"));
       
  3080     QTest::qWait(10);
       
  3081     QTRY_VERIFY(tree.refreshed);
       
  3082 
       
  3083 }
       
  3084 
       
  3085 void tst_QTreeView::task220298_selectColumns()
       
  3086 {
       
  3087     //this is a very simple 3x3 model where the internalId of the index are different for each cell
       
  3088     class Model : public QAbstractTableModel
       
  3089     { public:
       
  3090             virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const
       
  3091             { return parent.isValid() ? 0 : 3; }
       
  3092             virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const
       
  3093             { return parent.isValid() ? 0 : 3; }
       
  3094 
       
  3095             virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const
       
  3096             {
       
  3097                 if(role == Qt::DisplayRole)
       
  3098                     return QVariant(QString("%1-%2").arg(index.column()).arg(index.row()));
       
  3099                 return QVariant();
       
  3100             }
       
  3101 
       
  3102             virtual QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const
       
  3103             {
       
  3104                 return hasIndex(row, column, parent) ? createIndex(row, column, column*10+row) : QModelIndex();
       
  3105             }
       
  3106     };
       
  3107 
       
  3108     class TreeView : public QTreeView { public: QModelIndexList selectedIndexes () const { return QTreeView::selectedIndexes(); } } view;
       
  3109     Model model;
       
  3110     view.setModel(&model);
       
  3111     view.show();
       
  3112     QTest::qWait(50);
       
  3113     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0,
       
  3114                       view.visualRect(view.model()->index(1, 1)).center());
       
  3115     QTest::qWait(50);
       
  3116     QVERIFY(view.selectedIndexes().contains(view.model()->index(1, 2)));
       
  3117     QVERIFY(view.selectedIndexes().contains(view.model()->index(1, 1)));
       
  3118     QVERIFY(view.selectedIndexes().contains(view.model()->index(1, 0)));
       
  3119 }
       
  3120 
       
  3121 
       
  3122 void tst_QTreeView::task224091_appendColumns()
       
  3123 {
       
  3124     QStandardItemModel *model = new QStandardItemModel();
       
  3125     QTreeView *treeView = new QTreeView();
       
  3126     treeView->setModel(model);
       
  3127     treeView->show();
       
  3128     treeView->resize(50,50);
       
  3129 
       
  3130     QTest::qWaitForWindowShown(treeView);
       
  3131     qApp->processEvents();
       
  3132 
       
  3133     QList<QStandardItem *> projlist;
       
  3134     for (int k = 0; k < 10; ++k)
       
  3135         projlist.append(new QStandardItem(QString("Top Level %0").arg(k)));
       
  3136     model->appendColumn(projlist);
       
  3137     model->invisibleRootItem()->appendRow(new QStandardItem("end"));
       
  3138 
       
  3139     QTest::qWait(50);
       
  3140     qApp->processEvents();
       
  3141 
       
  3142     QTRY_VERIFY(treeView->verticalScrollBar()->isVisible());
       
  3143 
       
  3144     delete treeView;
       
  3145     delete model;
       
  3146 }
       
  3147 
       
  3148 void tst_QTreeView::task211293_removeRootIndex()
       
  3149 {
       
  3150     QTreeView view;
       
  3151     QStandardItemModel model;
       
  3152     QStandardItem *A1 = new QStandardItem("A1");
       
  3153     QStandardItem *B11 = new QStandardItem("B1.1");
       
  3154     QStandardItem *C111 = new QStandardItem("C1.1.1");
       
  3155     QStandardItem *C112 = new QStandardItem("C1.1.2");
       
  3156     QStandardItem *C113 = new QStandardItem("C1.1.3");
       
  3157     QStandardItem *D1131 = new QStandardItem("D1.1.3.1");
       
  3158     QStandardItem *E11311 = new QStandardItem("E1.1.3.1.1");
       
  3159     QStandardItem *E11312 = new QStandardItem("E1.1.3.1.2");
       
  3160     QStandardItem *E11313 = new QStandardItem("E1.1.3.1.3");
       
  3161     QStandardItem *E11314 = new QStandardItem("E1.1.3.1.4");
       
  3162     QStandardItem *D1132 = new QStandardItem("D1.1.3.2");
       
  3163     QStandardItem *E11321 = new QStandardItem("E1.1.3.2.1");
       
  3164     D1132->appendRow(E11321);
       
  3165     D1131->appendRow(E11311);
       
  3166     D1131->appendRow(E11312);
       
  3167     D1131->appendRow(E11313);
       
  3168     D1131->appendRow(E11314);
       
  3169     C113->appendRow(D1131);
       
  3170     C113->appendRow(D1132);
       
  3171     B11->appendRow(C111);
       
  3172     B11->appendRow(C112);
       
  3173     B11->appendRow(C113);
       
  3174     A1->appendRow(B11);
       
  3175     model.appendRow(A1);
       
  3176     view.setModel(&model);
       
  3177     view.setRootIndex(model.indexFromItem(B11));
       
  3178     view.setExpanded(model.indexFromItem(B11), true);
       
  3179     view.setCurrentIndex(model.indexFromItem(E11314));
       
  3180     view.setExpanded(model.indexFromItem(E11314), true);
       
  3181     view.show();
       
  3182     qApp->processEvents();
       
  3183     model.removeRows(0, 1);
       
  3184     qApp->processEvents();
       
  3185 }
       
  3186 
       
  3187 void tst_QTreeView::task225539_deleteModel()
       
  3188 {
       
  3189     QTreeView treeView;
       
  3190     treeView.show();
       
  3191     QStandardItemModel *model = new QStandardItemModel(&treeView);
       
  3192 
       
  3193     QStandardItem* parentItem = model->invisibleRootItem();
       
  3194     QStandardItem* item = new QStandardItem(QString("item"));
       
  3195     parentItem->appendRow(item);
       
  3196 
       
  3197     treeView.setModel(model);
       
  3198 
       
  3199     QCOMPARE(item->index(), treeView.indexAt(QPoint()));
       
  3200 
       
  3201     delete model;
       
  3202 
       
  3203     QVERIFY(!treeView.indexAt(QPoint()).isValid());
       
  3204 }
       
  3205 
       
  3206 void tst_QTreeView::task230123_setItemsExpandable()
       
  3207 {
       
  3208     //let's check that we prevent the expansion inside a treeview
       
  3209     //when the property is set.
       
  3210     QTreeWidget tree;
       
  3211 
       
  3212     QTreeWidgetItem root;
       
  3213     QTreeWidgetItem child;
       
  3214     root.addChild(&child);
       
  3215     tree.addTopLevelItem(&root);
       
  3216 
       
  3217     tree.setCurrentItem(&root);
       
  3218 
       
  3219     tree.setItemsExpandable(false);
       
  3220 
       
  3221     QTest::keyClick(&tree, Qt::Key_Plus);
       
  3222     QVERIFY(!root.isExpanded());
       
  3223 
       
  3224     QTest::keyClick(&tree, Qt::Key_Right);
       
  3225     QVERIFY(!root.isExpanded());
       
  3226 
       
  3227     tree.setItemsExpandable(true);
       
  3228 
       
  3229     QTest::keyClick(&tree, Qt::Key_Plus);
       
  3230     QVERIFY(root.isExpanded());
       
  3231 
       
  3232     QTest::keyClick(&tree, Qt::Key_Minus);
       
  3233     QVERIFY(!root.isExpanded());
       
  3234 
       
  3235     QTest::keyClick(&tree, Qt::Key_Right);
       
  3236     QVERIFY(root.isExpanded());
       
  3237 
       
  3238     QTest::keyClick(&tree, Qt::Key_Left);
       
  3239     QVERIFY(!root.isExpanded());
       
  3240 
       
  3241     QTest::keyClick(&tree, Qt::Key_Right);
       
  3242     QVERIFY(root.isExpanded());
       
  3243 
       
  3244     const bool navToChild = tree.style()->styleHint(QStyle::SH_ItemView_ArrowKeysNavigateIntoChildren, 0, &tree);
       
  3245     QTest::keyClick(&tree, Qt::Key_Right);
       
  3246     QCOMPARE(tree.currentItem(), navToChild ? &child : &root);
       
  3247 
       
  3248     QTest::keyClick(&tree, Qt::Key_Right);
       
  3249     //it should not be expanded: it has no leaf
       
  3250     QCOMPARE(child.isExpanded(), false);
       
  3251 
       
  3252     QTest::keyClick(&tree, Qt::Key_Left);
       
  3253     QCOMPARE(tree.currentItem(), &root);
       
  3254 
       
  3255     QTest::keyClick(&tree, Qt::Key_Left);
       
  3256     QVERIFY(!root.isExpanded());
       
  3257 
       
  3258 
       
  3259 }
       
  3260 
       
  3261 void tst_QTreeView::task202039_closePersistentEditor()
       
  3262 {
       
  3263     QStandardItemModel model(1,1);
       
  3264     QTreeView view;
       
  3265     view.setModel(&model);
       
  3266 
       
  3267     QModelIndex current = model.index(0,0);
       
  3268     QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.visualRect(current).center());
       
  3269     QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, view.visualRect(current).center());
       
  3270     QCOMPARE(view.currentIndex(), current);
       
  3271     QVERIFY(view.indexWidget(current));
       
  3272 
       
  3273     view.closePersistentEditor(current);
       
  3274     QVERIFY(view.indexWidget(current) == 0);
       
  3275 
       
  3276     //here was the bug: closing the persistent editor would not reset the state
       
  3277     //and it was impossible to go into editinon again
       
  3278     QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.visualRect(current).center());
       
  3279     QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, view.visualRect(current).center());
       
  3280     QCOMPARE(view.currentIndex(), current);
       
  3281     QVERIFY(view.indexWidget(current));
       
  3282 }
       
  3283 
       
  3284 void tst_QTreeView::task238873_avoidAutoReopening()
       
  3285 {
       
  3286     QStandardItemModel model;
       
  3287 
       
  3288     QStandardItem item0("row 0");
       
  3289     QStandardItem item1("row 1");
       
  3290     QStandardItem item2("row 2");
       
  3291     QStandardItem item3("row 3");
       
  3292     model.appendColumn( QList<QStandardItem*>() << &item0 << &item1 << &item2 << &item3);
       
  3293 
       
  3294     QStandardItem child("child");
       
  3295     item1.appendRow( &child);
       
  3296 
       
  3297     QTreeView view;
       
  3298     view.setModel(&model);
       
  3299     view.show();
       
  3300     view.expandAll();
       
  3301     QTest::qWait(100);
       
  3302 
       
  3303     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.visualRect(child.index()).center());
       
  3304     QTest::qWait(20);
       
  3305     QCOMPARE(view.currentIndex(), child.index());
       
  3306 
       
  3307     view.setExpanded(item1.index(), false);
       
  3308 
       
  3309     QTest::qWait(500); //enough to trigger the delayedAutoScroll timer
       
  3310     QVERIFY(!view.isExpanded(item1.index()));
       
  3311 }
       
  3312 
       
  3313 void tst_QTreeView::task244304_clickOnDecoration()
       
  3314 {
       
  3315     QTreeView view;
       
  3316     QStandardItemModel model;
       
  3317     QStandardItem item0("row 0");
       
  3318     QStandardItem item00("row 0");
       
  3319     item0.appendRow(&item00);
       
  3320     QStandardItem item1("row 1");
       
  3321     model.appendColumn(QList<QStandardItem*>() << &item0 << &item1);
       
  3322     view.setModel(&model);
       
  3323 
       
  3324     QVERIFY(!view.currentIndex().isValid());
       
  3325     QRect rect = view.visualRect(item0.index());
       
  3326     //we click on the decoration
       
  3327     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, rect.topLeft()+QPoint(-rect.left()/2,rect.height()/2));
       
  3328     QVERIFY(!view.currentIndex().isValid());
       
  3329     QVERIFY(view.isExpanded(item0.index()));
       
  3330 
       
  3331     rect = view.visualRect(item1.index());
       
  3332     //the item has no decoration, it should get selected
       
  3333     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, rect.topLeft()+QPoint(-rect.left()/2,rect.height()/2));
       
  3334     QCOMPARE(view.currentIndex(), item1.index());
       
  3335 }
       
  3336 
       
  3337 void tst_QTreeView::task246536_scrollbarsNotWorking()
       
  3338 {
       
  3339     struct MyObject : public QObject
       
  3340     {
       
  3341         MyObject() : count(0)
       
  3342         {
       
  3343         }
       
  3344 
       
  3345         bool eventFilter(QObject*, QEvent *e)
       
  3346         {
       
  3347             if (e->type() == QEvent::Paint)
       
  3348                 count++;
       
  3349 
       
  3350             return false;
       
  3351         }
       
  3352 
       
  3353         int count;
       
  3354     };
       
  3355     QTreeView tree;
       
  3356     MyObject o;
       
  3357     tree.viewport()->installEventFilter(&o);
       
  3358     QStandardItemModel model;
       
  3359     tree.setModel(&model);
       
  3360     tree.show();
       
  3361     QTest::qWaitForWindowShown(&tree);
       
  3362     QList<QStandardItem *> items;
       
  3363     for(int i=0; i<100; ++i){
       
  3364         items << new QStandardItem(QString::fromLatin1("item %1").arg(i));
       
  3365     }
       
  3366     model.invisibleRootItem()->appendColumn(items);
       
  3367     QTest::qWait(100);
       
  3368     o.count = 0;
       
  3369     tree.verticalScrollBar()->setValue(50);
       
  3370     QTest::qWait(100);
       
  3371     QTRY_VERIFY(o.count > 0);
       
  3372 }
       
  3373 
       
  3374 void tst_QTreeView::task250683_wrongSectionSize()
       
  3375 {
       
  3376     QDirModel model;
       
  3377     QTreeView treeView;
       
  3378     treeView.header()->setResizeMode(QHeaderView::ResizeToContents);
       
  3379     treeView.setModel(&model);
       
  3380     treeView.setColumnHidden(2, true);
       
  3381     treeView.setColumnHidden(3, true);
       
  3382 
       
  3383     treeView.show();
       
  3384     QTest::qWait(100);
       
  3385 
       
  3386     QCOMPARE(treeView.header()->sectionSize(0) + treeView.header()->sectionSize(1), treeView.viewport()->width());
       
  3387 }
       
  3388 
       
  3389 void tst_QTreeView::task239271_addRowsWithFirstColumnHidden()
       
  3390 {
       
  3391     class MyDelegate : public QStyledItemDelegate
       
  3392     {
       
  3393     public:
       
  3394         void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
       
  3395         {
       
  3396             paintedIndexes << index;
       
  3397             QStyledItemDelegate::paint(painter, option, index);
       
  3398         }
       
  3399 
       
  3400         mutable QSet<QModelIndex> paintedIndexes;
       
  3401     };
       
  3402 
       
  3403     QTreeView view;
       
  3404     QStandardItemModel model;
       
  3405     view.setModel(&model);
       
  3406     MyDelegate delegate;
       
  3407     view.setItemDelegate(&delegate);
       
  3408     QStandardItem root0("root0"), root1("root1");
       
  3409     model.invisibleRootItem()->appendRow(QList<QStandardItem*>() << &root0 << &root1);
       
  3410     QStandardItem sub0("sub0"), sub00("sub00");
       
  3411     root0.appendRow(QList<QStandardItem*>() << &sub0 << &sub00);
       
  3412     view.expand(root0.index());
       
  3413 
       
  3414     view.hideColumn(0);
       
  3415     view.show();
       
  3416     QTest::qWaitForWindowShown(&view);
       
  3417     delegate.paintedIndexes.clear();
       
  3418     QStandardItem sub1("sub1"), sub11("sub11");
       
  3419     root0.appendRow(QList<QStandardItem*>() << &sub1 << &sub11);
       
  3420 
       
  3421     QTest::qWait(20);
       
  3422     //items in the 2nd column should have been painted
       
  3423     QTRY_VERIFY(!delegate.paintedIndexes.isEmpty());
       
  3424     QVERIFY(delegate.paintedIndexes.contains(sub00.index()));
       
  3425     QVERIFY(delegate.paintedIndexes.contains(sub11.index()));
       
  3426 }
       
  3427 
       
  3428 void tst_QTreeView::task254234_proxySort()
       
  3429 {
       
  3430     //based on tst_QTreeView::sortByColumn
       
  3431     // it used not to work when setting the source of a proxy after enabling sorting
       
  3432     QTreeView view;
       
  3433     QStandardItemModel model(4,2);
       
  3434     model.setItem(0,0,new QStandardItem("b"));
       
  3435     model.setItem(1,0,new QStandardItem("d"));
       
  3436     model.setItem(2,0,new QStandardItem("c"));
       
  3437     model.setItem(3,0,new QStandardItem("a"));
       
  3438     model.setItem(0,1,new QStandardItem("e"));
       
  3439     model.setItem(1,1,new QStandardItem("g"));
       
  3440     model.setItem(2,1,new QStandardItem("h"));
       
  3441     model.setItem(3,1,new QStandardItem("f"));
       
  3442 
       
  3443     view.sortByColumn(1);
       
  3444     view.setSortingEnabled(true);
       
  3445 
       
  3446     QSortFilterProxyModel proxy;
       
  3447     proxy.setDynamicSortFilter(true);
       
  3448     view.setModel(&proxy);
       
  3449     proxy.setSourceModel(&model);
       
  3450     QCOMPARE(view.header()->sortIndicatorSection(), 1);
       
  3451     QCOMPARE(view.model()->data(view.model()->index(0,1)).toString(), QString::fromLatin1("h"));
       
  3452     QCOMPARE(view.model()->data(view.model()->index(1,1)).toString(), QString::fromLatin1("g"));
       
  3453 }
       
  3454 
       
  3455 class TreeView : public QTreeView
       
  3456 {
       
  3457     Q_OBJECT
       
  3458 public slots:
       
  3459     void handleSelectionChanged()
       
  3460     {
       
  3461         //let's select the last item
       
  3462         QModelIndex idx = model()->index(0, 0);
       
  3463         selectionModel()->select(QItemSelection(idx, idx), QItemSelectionModel::Select);
       
  3464         disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(handleSelectionChanged()));
       
  3465     }
       
  3466 };
       
  3467 
       
  3468 void tst_QTreeView::task248022_changeSelection()
       
  3469 {
       
  3470     //we check that changing the selection between the mouse press and the mouse release
       
  3471     //works correctly
       
  3472     TreeView view;
       
  3473     QStringList list = QStringList() << "1" << "2";
       
  3474     QStringListModel model(list);
       
  3475     view.setSelectionMode(QAbstractItemView::ExtendedSelection);
       
  3476     view.setModel(&model);
       
  3477     view.connect(view.selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(handleSelectionChanged()));
       
  3478     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.visualRect(model.index(1)).center());
       
  3479     QCOMPARE(view.selectionModel()->selectedIndexes().count(), list.count());
       
  3480 }
       
  3481 
       
  3482 void tst_QTreeView::task245654_changeModelAndExpandAll()
       
  3483 {
       
  3484     QTreeView view;
       
  3485     QStandardItemModel *model = new QStandardItemModel;
       
  3486     QStandardItem *top = new QStandardItem("top");
       
  3487     QStandardItem *sub = new QStandardItem("sub");
       
  3488     top->appendRow(sub);
       
  3489     model->appendRow(top);
       
  3490     view.setModel(model);
       
  3491     view.expandAll();
       
  3492     QApplication::processEvents();
       
  3493     QVERIFY(view.isExpanded(top->index()));
       
  3494 
       
  3495     //now let's try to delete the model
       
  3496     //then repopulate and expand again
       
  3497     delete model;
       
  3498     model = new QStandardItemModel;
       
  3499     top = new QStandardItem("top");
       
  3500     sub = new QStandardItem("sub");
       
  3501     top->appendRow(sub);
       
  3502     model->appendRow(top);
       
  3503     view.setModel(model);
       
  3504     view.expandAll();
       
  3505     QApplication::processEvents();
       
  3506     QVERIFY(view.isExpanded(top->index()));
       
  3507 
       
  3508 }
       
  3509 
       
  3510 
       
  3511 
       
  3512 QTEST_MAIN(tst_QTreeView)
       
  3513 #include "tst_qtreeview.moc"