2011-04-27 10:05:43 +00:00
/****************************************************************************
* *
2016-01-15 12:36:27 +00:00
* * Copyright ( C ) 2016 The Qt Company Ltd .
* * Contact : https : //www.qt.io/licensing/
2011-04-27 10:05:43 +00:00
* *
* * This file is part of the test suite of the Qt Toolkit .
* *
2016-01-15 12:36:27 +00:00
* * $ QT_BEGIN_LICENSE : GPL - EXCEPT $
2012-09-19 12:28:29 +00:00
* * Commercial License Usage
* * Licensees holding valid commercial Qt licenses may use this file in
* * accordance with the commercial license agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
2015-01-28 08:44:43 +00:00
* * a written agreement between you and The Qt Company . For licensing terms
2016-01-15 12:36:27 +00:00
* * and conditions see https : //www.qt.io/terms-conditions. For further
* * information use the contact form at https : //www.qt.io/contact-us.
2012-09-19 12:28:29 +00:00
* *
2016-01-15 12:36:27 +00:00
* * GNU General Public License Usage
* * Alternatively , this file may be used under the terms of the GNU
* * General Public License version 3 as published by the Free Software
* * Foundation with exceptions as appearing in the file LICENSE . GPL3 - EXCEPT
* * included in the packaging of this file . Please review the following
* * information to ensure the GNU General Public License requirements will
* * be met : https : //www.gnu.org/licenses/gpl-3.0.html.
2011-04-27 10:05:43 +00:00
* *
* * $ QT_END_LICENSE $
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-01-23 15:04:16 +00:00
# include "../../../../shared/fakedirmodel.h"
2011-04-27 10:05:43 +00:00
# include <qabstractitemview.h>
# include <QtTest/QtTest>
# include <QtGui/QtGui>
2011-09-16 12:07:05 +00:00
# include <QtWidgets/QtWidgets>
2016-07-28 16:51:53 +00:00
# include <private/qtreeview_p.h>
2011-04-27 10:05:43 +00:00
2017-10-30 12:45:18 +00:00
# include <QtTest/private/qtesthelpers_p.h>
using namespace QTestPrivate ;
2018-04-13 07:01:43 +00:00
# if QT_CONFIG(draganddrop)
2011-04-27 10:05:43 +00:00
Q_DECLARE_METATYPE ( QAbstractItemView : : DragDropMode )
# endif
Q_DECLARE_METATYPE ( QAbstractItemView : : EditTriggers )
Q_DECLARE_METATYPE ( QAbstractItemView : : EditTrigger )
static void initStandardTreeModel ( QStandardItemModel * model )
{
QStandardItem * item ;
item = new QStandardItem ( QLatin1String ( " Row 1 Item " ) ) ;
model - > insertRow ( 0 , item ) ;
item = new QStandardItem ( QLatin1String ( " Row 2 Item " ) ) ;
item - > setCheckable ( true ) ;
model - > insertRow ( 1 , item ) ;
QStandardItem * childItem = new QStandardItem ( QLatin1String ( " Row 2 Child Item " ) ) ;
item - > setChild ( 0 , childItem ) ;
item = new QStandardItem ( QLatin1String ( " Row 3 Item " ) ) ;
item - > setIcon ( QIcon ( ) ) ;
model - > insertRow ( 2 , item ) ;
}
class tst_QTreeView : public QObject
{
Q_OBJECT
public slots :
void selectionOrderTest ( ) ;
private slots :
2018-11-21 20:02:07 +00:00
void initTestCase ( ) { QApplication : : setKeyboardInputInterval ( 100 ) ; }
2011-04-27 10:05:43 +00:00
void getSetCheck ( ) ;
// one test per QTreeView property
void construction ( ) ;
void alternatingRowColors ( ) ;
void currentIndex_data ( ) ;
void currentIndex ( ) ;
2018-04-13 07:01:43 +00:00
# if QT_CONFIG(draganddrop)
2011-04-27 10:05:43 +00:00
void dragDropMode_data ( ) ;
void dragDropMode ( ) ;
void dragDropModeFromDragEnabledAndAcceptDrops_data ( ) ;
void dragDropModeFromDragEnabledAndAcceptDrops ( ) ;
void dragDropOverwriteMode ( ) ;
# endif
void editTriggers_data ( ) ;
void editTriggers ( ) ;
void hasAutoScroll ( ) ;
void horizontalScrollMode ( ) ;
void iconSize ( ) ;
void indexAt ( ) ;
void indexWidget ( ) ;
void itemDelegate ( ) ;
void itemDelegateForColumnOrRow ( ) ;
void keyboardSearch ( ) ;
2012-08-22 14:18:11 +00:00
void keyboardSearchMultiColumn ( ) ;
2011-04-27 10:05:43 +00:00
void setModel ( ) ;
void openPersistentEditor ( ) ;
void rootIndex ( ) ;
// specialized tests below
void setHeader ( ) ;
void columnHidden ( ) ;
void rowHidden ( ) ;
void noDelegate ( ) ;
void noModel ( ) ;
void emptyModel ( ) ;
void removeRows ( ) ;
void removeCols ( ) ;
2012-11-23 14:24:48 +00:00
void limitedExpand ( ) ;
2011-04-27 10:05:43 +00:00
void expandAndCollapse_data ( ) ;
void expandAndCollapse ( ) ;
void expandAndCollapseAll ( ) ;
void expandWithNoChildren ( ) ;
2018-09-26 13:39:35 +00:00
# if QT_CONFIG(animation)
2012-08-29 12:24:40 +00:00
void quickExpandCollapse ( ) ;
# endif
2011-04-27 10:05:43 +00:00
void keyboardNavigation ( ) ;
void headerSections ( ) ;
void moveCursor_data ( ) ;
void moveCursor ( ) ;
void setSelection_data ( ) ;
void setSelection ( ) ;
void extendedSelection_data ( ) ;
void extendedSelection ( ) ;
void indexAbove ( ) ;
void indexBelow ( ) ;
void clicked ( ) ;
void mouseDoubleClick ( ) ;
void rowsAboutToBeRemoved ( ) ;
void headerSections_unhideSection ( ) ;
void columnAt ( ) ;
void scrollTo ( ) ;
void rowsAboutToBeRemoved_move ( ) ;
void resizeColumnToContents ( ) ;
void insertAfterSelect ( ) ;
void removeAfterSelect ( ) ;
void hiddenItems ( ) ;
void spanningItems ( ) ;
void rowSizeHint ( ) ;
2016-02-18 15:15:44 +00:00
void setSortingEnabledTopLevel ( ) ;
void setSortingEnabledChild ( ) ;
2011-04-27 10:05:43 +00:00
void headerHidden ( ) ;
2014-09-10 14:09:55 +00:00
void indentation ( ) ;
2011-04-27 10:05:43 +00:00
void selection ( ) ;
void removeAndInsertExpandedCol0 ( ) ;
void selectionWithHiddenItems ( ) ;
void selectAll ( ) ;
void disabledButCheckable ( ) ;
void sortByColumn_data ( ) ;
void sortByColumn ( ) ;
void evilModel_data ( ) ;
void evilModel ( ) ;
void indexRowSizeHint ( ) ;
void addRowsWhileSectionsAreHidden ( ) ;
void filterProxyModelCrash ( ) ;
2012-04-17 17:45:20 +00:00
void renderToPixmap_data ( ) ;
void renderToPixmap ( ) ;
2011-04-27 10:05:43 +00:00
void styleOptionViewItem ( ) ;
void keyboardNavigationWithDisabled ( ) ;
2018-03-01 10:04:00 +00:00
void saveRestoreState ( ) ;
2011-04-27 10:05:43 +00:00
2017-05-08 07:29:17 +00:00
void statusTip_data ( ) ;
void statusTip ( ) ;
2016-11-23 10:09:47 +00:00
void fetchMoreOnScroll ( ) ;
2017-05-08 07:29:17 +00:00
2011-04-27 10:05:43 +00:00
// task-specific tests:
void task174627_moveLeftToRoot ( ) ;
void task171902_expandWith1stColHidden ( ) ;
void task203696_hidingColumnsAndRowsn ( ) ;
void task211293_removeRootIndex ( ) ;
void task216717_updateChildren ( ) ;
void task220298_selectColumns ( ) ;
void task224091_appendColumns ( ) ;
void task225539_deleteModel ( ) ;
void task230123_setItemsExpandable ( ) ;
void task202039_closePersistentEditor ( ) ;
void task238873_avoidAutoReopening ( ) ;
void task244304_clickOnDecoration ( ) ;
void task246536_scrollbarsNotWorking ( ) ;
void task250683_wrongSectionSize ( ) ;
void task239271_addRowsWithFirstColumnHidden ( ) ;
void task254234_proxySort ( ) ;
void task248022_changeSelection ( ) ;
void task245654_changeModelAndExpandAll ( ) ;
void doubleClickedWithSpans ( ) ;
void taskQTBUG_6450_selectAllWith1stColumnHidden ( ) ;
void taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint ( ) ;
void taskQTBUG_11466_keyboardNavigationRegression ( ) ;
void taskQTBUG_13567_removeLastItemRegression ( ) ;
2012-05-25 13:41:03 +00:00
void taskQTBUG_25333_adjustViewOptionsForIndex ( ) ;
2012-08-13 09:53:05 +00:00
void taskQTBUG_18539_emitLayoutChanged ( ) ;
2012-11-06 20:08:10 +00:00
void taskQTBUG_8176_emitOnExpandAll ( ) ;
2014-05-05 08:59:56 +00:00
void taskQTBUG_37813_crash ( ) ;
2015-05-27 10:27:19 +00:00
void taskQTBUG_45697_crash ( ) ;
2012-11-07 18:06:01 +00:00
void taskQTBUG_7232_AllowUserToControlSingleStep ( ) ;
2017-11-12 12:33:25 +00:00
void taskQTBUG_8376 ( ) ;
2013-08-26 18:26:07 +00:00
void testInitialFocus ( ) ;
2011-04-27 10:05:43 +00:00
} ;
class QtTestModel : public QAbstractItemModel
{
public :
QtTestModel ( QObject * parent = 0 ) : QAbstractItemModel ( parent ) ,
fetched ( false ) , rows ( 0 ) , cols ( 0 ) , levels ( INT_MAX ) , wrongIndex ( false ) { init ( ) ; }
QtTestModel ( int _rows , int _cols , QObject * parent = 0 ) : QAbstractItemModel ( parent ) ,
fetched ( false ) , rows ( _rows ) , cols ( _cols ) , levels ( INT_MAX ) , wrongIndex ( false ) { init ( ) ; }
2017-10-27 07:20:29 +00:00
void init ( )
{
2011-04-27 10:05:43 +00:00
decorationsEnabled = false ;
2017-05-08 07:29:17 +00:00
statusTipsEnabled = false ;
2011-04-27 10:05:43 +00:00
}
2017-10-27 07:20:29 +00:00
inline qint32 level ( const QModelIndex & index ) const
{
2011-04-27 10:05:43 +00:00
return index . isValid ( ) ? qint32 ( index . internalId ( ) ) : qint32 ( - 1 ) ;
}
2017-10-27 06:51:05 +00:00
bool canFetchMore ( const QModelIndex & ) const override { return ! fetched ; }
2011-04-27 10:05:43 +00:00
2017-10-27 06:51:05 +00:00
void fetchMore ( const QModelIndex & ) override { fetched = true ; }
2011-04-27 10:05:43 +00:00
2017-10-27 06:51:05 +00:00
bool hasChildren ( const QModelIndex & parent = QModelIndex ( ) ) const override
{
2011-04-27 10:05:43 +00:00
bool hasFetched = fetched ;
fetched = true ;
bool r = QAbstractItemModel : : hasChildren ( parent ) ;
fetched = hasFetched ;
return r ;
}
2017-10-27 06:51:05 +00:00
int rowCount ( const QModelIndex & parent = QModelIndex ( ) ) const override
{
2011-05-09 07:14:39 +00:00
if ( ! fetched )
qFatal ( " %s: rowCount should not be called before fetching " , Q_FUNC_INFO ) ;
2011-04-27 10:05:43 +00:00
if ( ( parent . column ( ) > 0 ) | | ( level ( parent ) > levels ) )
return 0 ;
return rows ;
}
2017-10-27 06:51:05 +00:00
int columnCount ( const QModelIndex & parent = QModelIndex ( ) ) const override
{
2011-04-27 10:05:43 +00:00
if ( ( parent . column ( ) > 0 ) | | ( level ( parent ) > levels ) )
return 0 ;
return cols ;
}
2017-10-27 07:20:29 +00:00
bool isEditable ( const QModelIndex & index ) const
{
2011-04-27 10:05:43 +00:00
if ( index . isValid ( ) )
return true ;
return false ;
}
2017-10-27 06:51:05 +00:00
QModelIndex index ( int row , int column , const QModelIndex & parent = QModelIndex ( ) ) const override
2011-04-27 10:05:43 +00:00
{
if ( row < 0 | | column < 0 | | ( level ( parent ) > levels ) | | column > = cols | | row > = rows ) {
return QModelIndex ( ) ;
}
QModelIndex i = createIndex ( row , column , level ( parent ) + 1 ) ;
parentHash [ i ] = parent ;
return i ;
}
2017-10-27 06:51:05 +00:00
QModelIndex parent ( const QModelIndex & index ) const override
2011-04-27 10:05:43 +00:00
{
if ( ! parentHash . contains ( index ) )
return QModelIndex ( ) ;
return parentHash [ index ] ;
}
2017-10-27 06:51:05 +00:00
QVariant data ( const QModelIndex & idx , int role ) const override
2011-04-27 10:05:43 +00:00
{
if ( ! idx . isValid ( ) )
return QVariant ( ) ;
if ( role = = Qt : : DisplayRole ) {
if ( idx . row ( ) < 0 | | idx . column ( ) < 0 | | idx . column ( ) > = cols | | idx . row ( ) > = rows ) {
wrongIndex = true ;
qWarning ( " Invalid modelIndex [%d,%d,%p] " , idx . row ( ) , idx . column ( ) ,
idx . internalPointer ( ) ) ;
}
2015-10-16 07:38:51 +00:00
QString result = QLatin1Char ( ' [ ' ) + QString : : number ( idx . row ( ) ) + QLatin1Char ( ' , ' )
+ QString : : number ( idx . column ( ) ) + QLatin1Char ( ' , ' ) + QString : : number ( level ( idx ) )
+ QLatin1Char ( ' ] ' ) ;
2011-04-27 10:05:43 +00:00
if ( idx . row ( ) & 1 )
2015-10-16 07:38:51 +00:00
result + = QLatin1String ( " - this item is extra wide " ) ;
return result ;
2011-04-27 10:05:43 +00:00
}
if ( decorationsEnabled & & role = = Qt : : DecorationRole ) {
QPixmap pm ( 16 , 16 ) ;
pm . fill ( QColor : : fromHsv ( ( idx . column ( ) % 16 ) * 8 + 64 , 254 , ( idx . row ( ) % 16 ) * 8 + 32 ) ) ;
return pm ;
}
2017-05-08 07:29:17 +00:00
if ( statusTipsEnabled & & role = = Qt : : StatusTipRole )
return QString ( " [%1,%2,%3] -- Status " ) . arg ( idx . row ( ) ) . arg ( idx . column ( ) ) . arg ( level ( idx ) ) ;
return QVariant ( ) ;
}
QVariant headerData ( int section , Qt : : Orientation orientation ,
int role = Qt : : DisplayRole ) const override
{
Q_UNUSED ( orientation ) ;
if ( section < 0 | | section > = columnCount ( ) )
return QVariant ( ) ;
if ( statusTipsEnabled & & role = = Qt : : StatusTipRole )
return QString ( " Header %1 -- Status " ) . arg ( section ) ;
2011-04-27 10:05:43 +00:00
return QVariant ( ) ;
}
2017-12-17 18:56:35 +00:00
void simulateMoveRows ( )
{
beginMoveRows ( QModelIndex ( ) , 0 , 0 , QModelIndex ( ) , 2 ) ;
endMoveRows ( ) ;
}
2011-04-27 10:05:43 +00:00
void removeLastRow ( )
{
beginRemoveRows ( QModelIndex ( ) , rows - 1 , rows - 1 ) ;
- - rows ;
endRemoveRows ( ) ;
}
void removeAllRows ( )
{
beginRemoveRows ( QModelIndex ( ) , 0 , rows - 1 ) ;
rows = 0 ;
endRemoveRows ( ) ;
}
void removeLastColumn ( )
{
beginRemoveColumns ( QModelIndex ( ) , cols - 1 , cols - 1 ) ;
- - cols ;
endRemoveColumns ( ) ;
}
void removeAllColumns ( )
{
beginRemoveColumns ( QModelIndex ( ) , 0 , cols - 1 ) ;
cols = 0 ;
endRemoveColumns ( ) ;
}
void insertNewRow ( )
{
beginInsertRows ( QModelIndex ( ) , rows - 1 , rows - 1 ) ;
+ + rows ;
endInsertRows ( ) ;
}
void setDecorationsEnabled ( bool enable )
{
decorationsEnabled = enable ;
}
mutable bool fetched ;
bool decorationsEnabled ;
2017-05-08 07:29:17 +00:00
bool statusTipsEnabled ;
2011-04-27 10:05:43 +00:00
int rows , cols ;
int levels ;
mutable bool wrongIndex ;
mutable QMap < QModelIndex , QModelIndex > parentHash ;
} ;
// Testing get/set functions
void tst_QTreeView : : getSetCheck ( )
{
QTreeView obj1 ;
// int QTreeView::indentation()
// void QTreeView::setIndentation(int)
2014-09-10 14:09:55 +00:00
const int styledIndentation = obj1 . style ( ) - > pixelMetric ( QStyle : : PM_TreeViewIndentation , 0 , & obj1 ) ;
QCOMPARE ( obj1 . indentation ( ) , styledIndentation ) ;
2011-04-27 10:05:43 +00:00
obj1 . setIndentation ( 0 ) ;
QCOMPARE ( obj1 . indentation ( ) , 0 ) ;
obj1 . setIndentation ( INT_MIN ) ;
QCOMPARE ( obj1 . indentation ( ) , INT_MIN ) ;
obj1 . setIndentation ( INT_MAX ) ;
QCOMPARE ( obj1 . indentation ( ) , INT_MAX ) ;
// bool QTreeView::rootIsDecorated()
// void QTreeView::setRootIsDecorated(bool)
QCOMPARE ( obj1 . rootIsDecorated ( ) , true ) ;
obj1 . setRootIsDecorated ( false ) ;
QCOMPARE ( obj1 . rootIsDecorated ( ) , false ) ;
obj1 . setRootIsDecorated ( true ) ;
QCOMPARE ( obj1 . rootIsDecorated ( ) , true ) ;
// bool QTreeView::uniformRowHeights()
// void QTreeView::setUniformRowHeights(bool)
QCOMPARE ( obj1 . uniformRowHeights ( ) , false ) ;
obj1 . setUniformRowHeights ( false ) ;
QCOMPARE ( obj1 . uniformRowHeights ( ) , false ) ;
obj1 . setUniformRowHeights ( true ) ;
QCOMPARE ( obj1 . uniformRowHeights ( ) , true ) ;
// bool QTreeView::itemsExpandable()
// void QTreeView::setItemsExpandable(bool)
QCOMPARE ( obj1 . itemsExpandable ( ) , true ) ;
obj1 . setItemsExpandable ( false ) ;
QCOMPARE ( obj1 . itemsExpandable ( ) , false ) ;
obj1 . setItemsExpandable ( true ) ;
QCOMPARE ( obj1 . itemsExpandable ( ) , true ) ;
// bool QTreeView::allColumnsShowFocus
// void QTreeView::setAllColumnsShowFocus
QCOMPARE ( obj1 . allColumnsShowFocus ( ) , false ) ;
obj1 . setAllColumnsShowFocus ( false ) ;
QCOMPARE ( obj1 . allColumnsShowFocus ( ) , false ) ;
obj1 . setAllColumnsShowFocus ( true ) ;
QCOMPARE ( obj1 . allColumnsShowFocus ( ) , true ) ;
// bool QTreeView::isAnimated
// void QTreeView::setAnimated
QCOMPARE ( obj1 . isAnimated ( ) , false ) ;
obj1 . setAnimated ( false ) ;
QCOMPARE ( obj1 . isAnimated ( ) , false ) ;
obj1 . setAnimated ( true ) ;
QCOMPARE ( obj1 . isAnimated ( ) , true ) ;
// bool QTreeView::setSortingEnabled
// void QTreeView::isSortingEnabled
QCOMPARE ( obj1 . isSortingEnabled ( ) , false ) ;
obj1 . setSortingEnabled ( false ) ;
QCOMPARE ( obj1 . isSortingEnabled ( ) , false ) ;
obj1 . setSortingEnabled ( true ) ;
QCOMPARE ( obj1 . isSortingEnabled ( ) , true ) ;
}
void tst_QTreeView : : construction ( )
{
QTreeView view ;
// QAbstractItemView properties
QVERIFY ( ! view . alternatingRowColors ( ) ) ;
QCOMPARE ( view . currentIndex ( ) , QModelIndex ( ) ) ;
2018-04-13 07:01:43 +00:00
# if QT_CONFIG(draganddrop)
2011-04-27 10:05:43 +00:00
QCOMPARE ( view . dragDropMode ( ) , QAbstractItemView : : NoDragDrop ) ;
QVERIFY ( ! view . dragDropOverwriteMode ( ) ) ;
QVERIFY ( ! view . dragEnabled ( ) ) ;
# endif
QCOMPARE ( view . editTriggers ( ) , QAbstractItemView : : EditKeyPressed | QAbstractItemView : : DoubleClicked ) ;
QVERIFY ( view . hasAutoScroll ( ) ) ;
QCOMPARE ( view . horizontalScrollMode ( ) , QAbstractItemView : : ScrollPerPixel ) ;
QCOMPARE ( view . iconSize ( ) , QSize ( ) ) ;
QCOMPARE ( view . indexAt ( QPoint ( ) ) , QModelIndex ( ) ) ;
QVERIFY ( ! view . indexWidget ( QModelIndex ( ) ) ) ;
QVERIFY ( qobject_cast < QStyledItemDelegate * > ( view . itemDelegate ( ) ) ) ;
QVERIFY ( ! view . itemDelegateForColumn ( - 1 ) ) ;
QVERIFY ( ! view . itemDelegateForColumn ( 0 ) ) ;
QVERIFY ( ! view . itemDelegateForColumn ( 1 ) ) ;
QVERIFY ( ! view . itemDelegateForRow ( - 1 ) ) ;
QVERIFY ( ! view . itemDelegateForRow ( 0 ) ) ;
QVERIFY ( ! view . itemDelegateForRow ( 1 ) ) ;
QVERIFY ( ! view . model ( ) ) ;
QCOMPARE ( view . rootIndex ( ) , QModelIndex ( ) ) ;
QCOMPARE ( view . selectionBehavior ( ) , QAbstractItemView : : SelectRows ) ;
QCOMPARE ( view . selectionMode ( ) , QAbstractItemView : : SingleSelection ) ;
QVERIFY ( ! view . selectionModel ( ) ) ;
2018-04-13 07:01:43 +00:00
# if QT_CONFIG(draganddrop)
2011-04-27 10:05:43 +00:00
QVERIFY ( view . showDropIndicator ( ) ) ;
# endif
QCOMPARE ( view . QAbstractItemView : : sizeHintForColumn ( - 1 ) , - 1 ) ; // <- protected in QTreeView
QCOMPARE ( view . QAbstractItemView : : sizeHintForColumn ( 0 ) , - 1 ) ; // <- protected in QTreeView
QCOMPARE ( view . QAbstractItemView : : sizeHintForColumn ( 1 ) , - 1 ) ; // <- protected in QTreeView
QCOMPARE ( view . sizeHintForIndex ( QModelIndex ( ) ) , QSize ( ) ) ;
QCOMPARE ( view . sizeHintForRow ( - 1 ) , - 1 ) ;
QCOMPARE ( view . sizeHintForRow ( 0 ) , - 1 ) ;
QCOMPARE ( view . sizeHintForRow ( 1 ) , - 1 ) ;
QVERIFY ( ! view . tabKeyNavigation ( ) ) ;
QCOMPARE ( view . textElideMode ( ) , Qt : : ElideRight ) ;
2016-02-06 00:41:20 +00:00
QCOMPARE ( static_cast < int > ( view . verticalScrollMode ( ) ) , view . style ( ) - > styleHint ( QStyle : : SH_ItemView_ScrollMode , 0 , & view ) ) ;
2011-04-27 10:05:43 +00:00
QCOMPARE ( view . visualRect ( QModelIndex ( ) ) , QRect ( ) ) ;
// QTreeView properties
QVERIFY ( ! view . allColumnsShowFocus ( ) ) ;
QCOMPARE ( view . autoExpandDelay ( ) , - 1 ) ;
QCOMPARE ( view . columnAt ( - 1 ) , - 1 ) ;
QCOMPARE ( view . columnAt ( 0 ) , - 1 ) ;
QCOMPARE ( view . columnAt ( 1 ) , - 1 ) ;
QCOMPARE ( view . columnViewportPosition ( - 1 ) , - 1 ) ;
QCOMPARE ( view . columnViewportPosition ( 0 ) , - 1 ) ;
QCOMPARE ( view . columnViewportPosition ( 1 ) , - 1 ) ;
QCOMPARE ( view . columnWidth ( - 1 ) , 0 ) ;
QCOMPARE ( view . columnWidth ( 0 ) , 0 ) ;
QCOMPARE ( view . columnWidth ( 1 ) , 0 ) ;
QVERIFY ( view . header ( ) ) ;
2014-09-10 14:09:55 +00:00
const int styledIndentation = view . style ( ) - > pixelMetric ( QStyle : : PM_TreeViewIndentation , 0 , & view ) ;
QCOMPARE ( view . indentation ( ) , styledIndentation ) ;
2011-04-27 10:05:43 +00:00
QCOMPARE ( view . indexAbove ( QModelIndex ( ) ) , QModelIndex ( ) ) ;
QCOMPARE ( view . indexBelow ( QModelIndex ( ) ) , QModelIndex ( ) ) ;
QVERIFY ( ! view . isAnimated ( ) ) ;
QVERIFY ( ! view . isColumnHidden ( - 1 ) ) ;
QVERIFY ( ! view . isColumnHidden ( 0 ) ) ;
QVERIFY ( ! view . isColumnHidden ( 1 ) ) ;
QVERIFY ( ! view . isExpanded ( QModelIndex ( ) ) ) ;
QVERIFY ( ! view . isRowHidden ( - 1 , QModelIndex ( ) ) ) ;
QVERIFY ( ! view . isRowHidden ( 0 , QModelIndex ( ) ) ) ;
QVERIFY ( ! view . isRowHidden ( 1 , QModelIndex ( ) ) ) ;
QVERIFY ( ! view . isFirstColumnSpanned ( - 1 , QModelIndex ( ) ) ) ;
QVERIFY ( ! view . isFirstColumnSpanned ( 0 , QModelIndex ( ) ) ) ;
QVERIFY ( ! view . isFirstColumnSpanned ( 1 , QModelIndex ( ) ) ) ;
QVERIFY ( ! view . isSortingEnabled ( ) ) ;
QVERIFY ( view . itemsExpandable ( ) ) ;
QVERIFY ( view . rootIsDecorated ( ) ) ;
QVERIFY ( ! view . uniformRowHeights ( ) ) ;
QCOMPARE ( view . visualRect ( QModelIndex ( ) ) , QRect ( ) ) ;
QVERIFY ( ! view . wordWrap ( ) ) ;
}
void tst_QTreeView : : alternatingRowColors ( )
{
QTreeView view ;
QVERIFY ( ! view . alternatingRowColors ( ) ) ;
view . setAlternatingRowColors ( true ) ;
QVERIFY ( view . alternatingRowColors ( ) ) ;
view . setAlternatingRowColors ( false ) ;
QVERIFY ( ! view . alternatingRowColors ( ) ) ;
// ### Test visual effect.
}
void tst_QTreeView : : currentIndex_data ( )
{
QTest : : addColumn < int > ( " row " ) ;
QTest : : addColumn < int > ( " column " ) ;
QTest : : addColumn < int > ( " indexRow " ) ;
QTest : : addColumn < int > ( " indexColumn " ) ;
QTest : : addColumn < int > ( " parentIndexRow " ) ;
QTest : : addColumn < int > ( " parentIndexColumn " ) ;
QTest : : newRow ( " -1, -1 " ) < < - 1 < < - 1 < < - 1 < < - 1 < < - 1 < < - 1 ;
QTest : : newRow ( " -1, 0 " ) < < - 1 < < 0 < < - 1 < < - 1 < < - 1 < < - 1 ;
QTest : : newRow ( " 0, -1 " ) < < 0 < < - 1 < < - 1 < < - 1 < < - 1 < < - 1 ;
QTest : : newRow ( " 0, 0 " ) < < 0 < < 0 < < 0 < < 0 < < - 1 < < - 1 ;
QTest : : newRow ( " 0, 1 " ) < < 0 < < 0 < < 0 < < 0 < < - 1 < < - 1 ;
QTest : : newRow ( " 1, 0 " ) < < 1 < < 0 < < 1 < < 0 < < - 1 < < - 1 ;
QTest : : newRow ( " 1, 1 " ) < < 1 < < 1 < < - 1 < < - 1 < < - 1 < < - 1 ;
QTest : : newRow ( " 2, 0 " ) < < 2 < < 0 < < 2 < < 0 < < - 1 < < - 1 ;
QTest : : newRow ( " 2, 1 " ) < < 2 < < 1 < < - 1 < < - 1 < < - 1 < < - 1 ;
QTest : : newRow ( " 3, -1 " ) < < 3 < < - 1 < < - 1 < < - 1 < < - 1 < < - 1 ;
QTest : : newRow ( " 3, 0 " ) < < 3 < < 0 < < - 1 < < - 1 < < - 1 < < - 1 ;
QTest : : newRow ( " 3, 1 " ) < < 3 < < 1 < < - 1 < < - 1 < < - 1 < < - 1 ;
}
void tst_QTreeView : : currentIndex ( )
{
QFETCH ( int , row ) ;
QFETCH ( int , column ) ;
QFETCH ( int , indexRow ) ;
QFETCH ( int , indexColumn ) ;
QFETCH ( int , parentIndexRow ) ;
QFETCH ( int , parentIndexColumn ) ;
QTreeView view ;
QStandardItemModel treeModel ;
initStandardTreeModel ( & treeModel ) ;
view . setModel ( & treeModel ) ;
QCOMPARE ( view . currentIndex ( ) , QModelIndex ( ) ) ;
view . setCurrentIndex ( view . model ( ) - > index ( row , column ) ) ;
QCOMPARE ( view . currentIndex ( ) . row ( ) , indexRow ) ;
QCOMPARE ( view . currentIndex ( ) . column ( ) , indexColumn ) ;
QCOMPARE ( view . currentIndex ( ) . parent ( ) . row ( ) , parentIndexRow ) ;
QCOMPARE ( view . currentIndex ( ) . parent ( ) . column ( ) , parentIndexColumn ) ;
// ### Test child and grandChild indexes.
}
2018-04-13 07:01:43 +00:00
# if QT_CONFIG(draganddrop)
2011-04-27 10:05:43 +00:00
void tst_QTreeView : : dragDropMode_data ( )
{
QTest : : addColumn < QAbstractItemView : : DragDropMode > ( " dragDropMode " ) ;
QTest : : addColumn < bool > ( " acceptDrops " ) ;
QTest : : addColumn < bool > ( " dragEnabled " ) ;
QTest : : newRow ( " NoDragDrop " ) < < QAbstractItemView : : NoDragDrop < < false < < false ;
QTest : : newRow ( " DragOnly " ) < < QAbstractItemView : : DragOnly < < false < < true ;
QTest : : newRow ( " DropOnly " ) < < QAbstractItemView : : DropOnly < < true < < false ;
QTest : : newRow ( " DragDrop " ) < < QAbstractItemView : : DragDrop < < true < < true ;
QTest : : newRow ( " InternalMove " ) < < QAbstractItemView : : InternalMove < < true < < true ;
}
void tst_QTreeView : : dragDropMode ( )
{
QFETCH ( QAbstractItemView : : DragDropMode , dragDropMode ) ;
QFETCH ( bool , acceptDrops ) ;
QFETCH ( bool , dragEnabled ) ;
QTreeView view ;
QCOMPARE ( view . dragDropMode ( ) , QAbstractItemView : : NoDragDrop ) ;
QVERIFY ( ! view . acceptDrops ( ) ) ;
QVERIFY ( ! view . dragEnabled ( ) ) ;
view . setDragDropMode ( dragDropMode ) ;
QCOMPARE ( view . dragDropMode ( ) , dragDropMode ) ;
QCOMPARE ( view . acceptDrops ( ) , acceptDrops ) ;
QCOMPARE ( view . dragEnabled ( ) , dragEnabled ) ;
// ### Test effects of this mode
}
void tst_QTreeView : : dragDropModeFromDragEnabledAndAcceptDrops_data ( )
{
QTest : : addColumn < bool > ( " dragEnabled " ) ;
QTest : : addColumn < bool > ( " acceptDrops " ) ;
QTest : : addColumn < QAbstractItemView : : DragDropMode > ( " dragDropMode " ) ;
2016-07-31 06:04:07 +00:00
QTest : : addColumn < bool > ( " setBehavior " ) ;
QTest : : addColumn < QAbstractItemView : : DragDropMode > ( " behavior " ) ;
QTest : : newRow ( " NoDragDrop -1 " ) < < false < < false < < QAbstractItemView : : NoDragDrop < < false < < QAbstractItemView : : DragDropMode ( ) ;
QTest : : newRow ( " NoDragDrop 0 " ) < < false < < false < < QAbstractItemView : : NoDragDrop < < true < < QAbstractItemView : : NoDragDrop ;
QTest : : newRow ( " NoDragDrop 1 " ) < < false < < false < < QAbstractItemView : : NoDragDrop < < true < < QAbstractItemView : : DragOnly ;
QTest : : newRow ( " NoDragDrop 2 " ) < < false < < false < < QAbstractItemView : : NoDragDrop < < true < < QAbstractItemView : : DropOnly ;
QTest : : newRow ( " NoDragDrop 3 " ) < < false < < false < < QAbstractItemView : : NoDragDrop < < true < < QAbstractItemView : : DragDrop ;
QTest : : newRow ( " NoDragDrop 4 " ) < < false < < false < < QAbstractItemView : : NoDragDrop < < true < < QAbstractItemView : : InternalMove ;
QTest : : newRow ( " DragOnly -1 " ) < < true < < false < < QAbstractItemView : : DragOnly < < false < < QAbstractItemView : : DragDropMode ( ) ;
QTest : : newRow ( " DragOnly 0 " ) < < true < < false < < QAbstractItemView : : DragOnly < < true < < QAbstractItemView : : NoDragDrop ;
QTest : : newRow ( " DragOnly 1 " ) < < true < < false < < QAbstractItemView : : DragOnly < < true < < QAbstractItemView : : DragOnly ;
QTest : : newRow ( " DragOnly 2 " ) < < true < < false < < QAbstractItemView : : DragOnly < < true < < QAbstractItemView : : DropOnly ;
QTest : : newRow ( " DragOnly 3 " ) < < true < < false < < QAbstractItemView : : DragOnly < < true < < QAbstractItemView : : DragDrop ;
QTest : : newRow ( " DragOnly 4 " ) < < true < < false < < QAbstractItemView : : DragOnly < < true < < QAbstractItemView : : InternalMove ;
QTest : : newRow ( " DropOnly -1 " ) < < false < < true < < QAbstractItemView : : DropOnly < < false < < QAbstractItemView : : DragDropMode ( ) ;
QTest : : newRow ( " DropOnly 0 " ) < < false < < true < < QAbstractItemView : : DropOnly < < true < < QAbstractItemView : : NoDragDrop ;
QTest : : newRow ( " DropOnly 1 " ) < < false < < true < < QAbstractItemView : : DropOnly < < true < < QAbstractItemView : : DragOnly ;
QTest : : newRow ( " DropOnly 2 " ) < < false < < true < < QAbstractItemView : : DropOnly < < true < < QAbstractItemView : : DropOnly ;
QTest : : newRow ( " DropOnly 3 " ) < < false < < true < < QAbstractItemView : : DropOnly < < true < < QAbstractItemView : : DragDrop ;
QTest : : newRow ( " DropOnly 4 " ) < < false < < true < < QAbstractItemView : : DropOnly < < true < < QAbstractItemView : : InternalMove ;
QTest : : newRow ( " DragDrop -1 " ) < < true < < true < < QAbstractItemView : : DragDrop < < false < < QAbstractItemView : : DragDropMode ( ) ;
QTest : : newRow ( " DragDrop 0 " ) < < true < < true < < QAbstractItemView : : DragDrop < < false < < QAbstractItemView : : DragDropMode ( ) ;
QTest : : newRow ( " DragDrop 1 " ) < < true < < true < < QAbstractItemView : : DragDrop < < true < < QAbstractItemView : : NoDragDrop ;
QTest : : newRow ( " DragDrop 2 " ) < < true < < true < < QAbstractItemView : : DragDrop < < true < < QAbstractItemView : : DragOnly ;
QTest : : newRow ( " DragDrop 3 " ) < < true < < true < < QAbstractItemView : : DragDrop < < true < < QAbstractItemView : : DropOnly ;
QTest : : newRow ( " DragDrop 4 " ) < < true < < true < < QAbstractItemView : : DragDrop < < true < < QAbstractItemView : : DragDrop ;
QTest : : newRow ( " DragDrop 5 " ) < < true < < true < < QAbstractItemView : : InternalMove < < true < < QAbstractItemView : : InternalMove ;
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : dragDropModeFromDragEnabledAndAcceptDrops ( )
{
QFETCH ( bool , acceptDrops ) ;
QFETCH ( bool , dragEnabled ) ;
QFETCH ( QAbstractItemView : : DragDropMode , dragDropMode ) ;
2016-07-31 06:04:07 +00:00
QFETCH ( bool , setBehavior ) ;
QFETCH ( QAbstractItemView : : DragDropMode , behavior ) ;
2011-04-27 10:05:43 +00:00
QTreeView view ;
QCOMPARE ( view . dragDropMode ( ) , QAbstractItemView : : NoDragDrop ) ;
2016-07-31 06:04:07 +00:00
if ( setBehavior )
view . setDragDropMode ( behavior ) ;
2011-04-27 10:05:43 +00:00
view . setAcceptDrops ( acceptDrops ) ;
view . setDragEnabled ( dragEnabled ) ;
QCOMPARE ( view . dragDropMode ( ) , dragDropMode ) ;
// ### Test effects of this mode
}
void tst_QTreeView : : dragDropOverwriteMode ( )
{
QTreeView view ;
QVERIFY ( ! view . dragDropOverwriteMode ( ) ) ;
view . setDragDropOverwriteMode ( true ) ;
QVERIFY ( view . dragDropOverwriteMode ( ) ) ;
view . setDragDropOverwriteMode ( false ) ;
QVERIFY ( ! view . dragDropOverwriteMode ( ) ) ;
// ### This property changes the behavior of dropIndicatorPosition(),
// which is protected and called only from within QListWidget and
// QTableWidget, from their reimplementations of dropMimeData(). Hard to
// test.
}
# endif
void tst_QTreeView : : editTriggers_data ( )
{
QTest : : addColumn < QAbstractItemView : : EditTriggers > ( " editTriggers " ) ;
QTest : : addColumn < QAbstractItemView : : EditTrigger > ( " triggeredTrigger " ) ;
QTest : : addColumn < bool > ( " editorOpened " ) ;
// NoEditTriggers
QTest : : newRow ( " NoEditTriggers 0 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : NoEditTriggers )
< < QAbstractItemView : : NoEditTriggers < < false ;
QTest : : newRow ( " NoEditTriggers 1 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : NoEditTriggers )
< < QAbstractItemView : : CurrentChanged < < false ;
QTest : : newRow ( " NoEditTriggers 2 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : NoEditTriggers )
< < QAbstractItemView : : DoubleClicked < < false ;
QTest : : newRow ( " NoEditTriggers 3 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : NoEditTriggers )
< < QAbstractItemView : : SelectedClicked < < false ;
QTest : : newRow ( " NoEditTriggers 4 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : NoEditTriggers )
< < QAbstractItemView : : EditKeyPressed < < false ;
// CurrentChanged
QTest : : newRow ( " CurrentChanged 0 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : CurrentChanged )
< < QAbstractItemView : : NoEditTriggers < < false ;
QTest : : newRow ( " CurrentChanged 1 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : CurrentChanged )
< < QAbstractItemView : : CurrentChanged < < true ;
QTest : : newRow ( " CurrentChanged 2 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : CurrentChanged )
< < QAbstractItemView : : DoubleClicked < < false ;
QTest : : newRow ( " CurrentChanged 3 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : CurrentChanged )
< < QAbstractItemView : : SelectedClicked < < false ;
QTest : : newRow ( " CurrentChanged 4 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : CurrentChanged )
< < QAbstractItemView : : EditKeyPressed < < false ;
// DoubleClicked
QTest : : newRow ( " DoubleClicked 0 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : DoubleClicked )
< < QAbstractItemView : : NoEditTriggers < < false ;
QTest : : newRow ( " DoubleClicked 1 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : DoubleClicked )
< < QAbstractItemView : : CurrentChanged < < false ;
QTest : : newRow ( " DoubleClicked 2 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : DoubleClicked )
< < QAbstractItemView : : DoubleClicked < < true ;
QTest : : newRow ( " DoubleClicked 3 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : DoubleClicked )
< < QAbstractItemView : : SelectedClicked < < false ;
QTest : : newRow ( " DoubleClicked 4 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : DoubleClicked )
< < QAbstractItemView : : EditKeyPressed < < false ;
// SelectedClicked
QTest : : newRow ( " SelectedClicked 0 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : SelectedClicked )
< < QAbstractItemView : : NoEditTriggers < < false ;
QTest : : newRow ( " SelectedClicked 1 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : SelectedClicked )
< < QAbstractItemView : : CurrentChanged < < false ;
QTest : : newRow ( " SelectedClicked 2 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : SelectedClicked )
< < QAbstractItemView : : DoubleClicked < < false ;
QTest : : newRow ( " SelectedClicked 3 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : SelectedClicked )
< < QAbstractItemView : : SelectedClicked < < true ;
QTest : : newRow ( " SelectedClicked 4 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : SelectedClicked )
< < QAbstractItemView : : EditKeyPressed < < false ;
// EditKeyPressed
QTest : : newRow ( " EditKeyPressed 0 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : EditKeyPressed )
< < QAbstractItemView : : NoEditTriggers < < false ;
QTest : : newRow ( " EditKeyPressed 1 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : EditKeyPressed )
< < QAbstractItemView : : CurrentChanged < < false ;
QTest : : newRow ( " EditKeyPressed 2 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : EditKeyPressed )
< < QAbstractItemView : : DoubleClicked < < false ;
QTest : : newRow ( " EditKeyPressed 3 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : EditKeyPressed )
< < QAbstractItemView : : SelectedClicked < < false ;
QTest : : newRow ( " EditKeyPressed 4 " ) < < QAbstractItemView : : EditTriggers ( QAbstractItemView : : EditKeyPressed )
< < QAbstractItemView : : EditKeyPressed < < true ;
}
void tst_QTreeView : : editTriggers ( )
{
QFETCH ( QAbstractItemView : : EditTriggers , editTriggers ) ;
QFETCH ( QAbstractItemView : : EditTrigger , triggeredTrigger ) ;
QFETCH ( bool , editorOpened ) ;
QTreeView view ;
QStandardItemModel treeModel ;
initStandardTreeModel ( & treeModel ) ;
view . setModel ( & treeModel ) ;
view . show ( ) ;
QCOMPARE ( view . editTriggers ( ) , QAbstractItemView : : EditKeyPressed | QAbstractItemView : : DoubleClicked ) ;
// Initialize the first index
view . setCurrentIndex ( view . model ( ) - > index ( 0 , 0 ) ) ;
// Verify that we don't have any editor initially
2013-03-27 14:16:32 +00:00
QVERIFY ( ! view . findChild < QLineEdit * > ( QString ( ) ) ) ;
2011-04-27 10:05:43 +00:00
// Set the triggers
view . setEditTriggers ( editTriggers ) ;
// Interact with the view
switch ( triggeredTrigger ) {
case QAbstractItemView : : NoEditTriggers :
// Do nothing, the editor shouldn't be there
break ;
case QAbstractItemView : : CurrentChanged :
// Change the index to open an editor
view . setCurrentIndex ( view . model ( ) - > index ( 1 , 0 ) ) ;
break ;
case QAbstractItemView : : DoubleClicked :
// Doubleclick the center of the current cell
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , 0 ,
view . visualRect ( view . model ( ) - > index ( 0 , 0 ) ) . center ( ) ) ;
QTest : : mouseDClick ( view . viewport ( ) , Qt : : LeftButton , 0 ,
view . visualRect ( view . model ( ) - > index ( 0 , 0 ) ) . center ( ) ) ;
break ;
case QAbstractItemView : : SelectedClicked :
// Click the center of the current cell
view . selectionModel ( ) - > select ( view . model ( ) - > index ( 0 , 0 ) , QItemSelectionModel : : Select ) ;
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , 0 ,
view . visualRect ( view . model ( ) - > index ( 0 , 0 ) ) . center ( ) ) ;
QTest : : qWait ( int ( QApplication : : doubleClickInterval ( ) * 1.5 ) ) ;
break ;
case QAbstractItemView : : EditKeyPressed :
view . setFocus ( ) ;
# ifdef Q_OS_MAC
2015-05-28 10:45:48 +00:00
// OS X uses Enter for editing
2011-04-27 10:05:43 +00:00
QTest : : keyPress ( & view , Qt : : Key_Enter ) ;
# else
// All other platforms use F2
QTest : : keyPress ( & view , Qt : : Key_F2 ) ;
# endif
break ;
default :
break ;
}
// Check if we got an editor
2013-03-27 14:16:32 +00:00
QTRY_COMPARE ( view . findChild < QLineEdit * > ( QString ( ) ) ! = 0 , editorOpened ) ;
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : hasAutoScroll ( )
{
QTreeView view ;
QVERIFY ( view . hasAutoScroll ( ) ) ;
view . setAutoScroll ( false ) ;
QVERIFY ( ! view . hasAutoScroll ( ) ) ;
view . setAutoScroll ( true ) ;
QVERIFY ( view . hasAutoScroll ( ) ) ;
}
void tst_QTreeView : : horizontalScrollMode ( )
{
QStandardItemModel model ;
for ( int i = 0 ; i < 100 ; + + i ) {
model . appendRow ( QList < QStandardItem * > ( )
< < new QStandardItem ( " An item that has very long text and should "
" cause the horizontal scroll bar to appear. " )
< < new QStandardItem ( " An item that has very long text and should "
" cause the horizontal scroll bar to appear. " ) ) ;
}
QTreeView view ;
2012-12-28 16:35:54 +00:00
setFrameless ( & view ) ;
2011-04-27 10:05:43 +00:00
view . setModel ( & model ) ;
view . setFixedSize ( 100 , 100 ) ;
view . header ( ) - > resizeSection ( 0 , 200 ) ;
view . show ( ) ;
QCOMPARE ( view . horizontalScrollMode ( ) , QAbstractItemView : : ScrollPerPixel ) ;
QCOMPARE ( view . horizontalScrollBar ( ) - > minimum ( ) , 0 ) ;
2018-05-17 13:22:16 +00:00
# ifdef Q_OS_WINRT
QEXPECT_FAIL ( " " , " setFixedSize does not work on WinRT - QTBUG-68297 " , Abort ) ;
# endif
2011-04-27 10:05:43 +00:00
QVERIFY ( view . horizontalScrollBar ( ) - > maximum ( ) > 2 ) ;
view . setHorizontalScrollMode ( QAbstractItemView : : ScrollPerItem ) ;
QCOMPARE ( view . horizontalScrollMode ( ) , QAbstractItemView : : ScrollPerItem ) ;
QCOMPARE ( view . horizontalScrollBar ( ) - > minimum ( ) , 0 ) ;
QCOMPARE ( view . horizontalScrollBar ( ) - > maximum ( ) , 1 ) ;
view . setHorizontalScrollMode ( QAbstractItemView : : ScrollPerPixel ) ;
QCOMPARE ( view . horizontalScrollMode ( ) , QAbstractItemView : : ScrollPerPixel ) ;
QCOMPARE ( view . horizontalScrollBar ( ) - > minimum ( ) , 0 ) ;
QVERIFY ( view . horizontalScrollBar ( ) - > maximum ( ) > 2 ) ;
}
class RepaintTreeView : public QTreeView
{
public :
RepaintTreeView ( ) : repainted ( false ) { }
bool repainted ;
protected :
void paintEvent ( QPaintEvent * event )
{ repainted = true ; QTreeView : : paintEvent ( event ) ; }
} ;
void tst_QTreeView : : iconSize ( )
{
RepaintTreeView view ;
QCOMPARE ( view . iconSize ( ) , QSize ( ) ) ;
QStandardItemModel treeModel ;
initStandardTreeModel ( & treeModel ) ;
view . setModel ( & treeModel ) ;
QCOMPARE ( view . iconSize ( ) , QSize ( ) ) ;
QVERIFY ( ! view . repainted ) ;
view . show ( ) ;
view . update ( ) ;
2012-07-24 12:29:01 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & view ) ) ;
2011-04-27 10:05:43 +00:00
QTRY_VERIFY ( view . repainted ) ;
QCOMPARE ( view . iconSize ( ) , QSize ( ) ) ;
view . repainted = false ;
view . setIconSize ( QSize ( ) ) ;
QTRY_VERIFY ( ! view . repainted ) ;
QCOMPARE ( view . iconSize ( ) , QSize ( ) ) ;
view . setIconSize ( QSize ( 10 , 10 ) ) ;
QTRY_VERIFY ( view . repainted ) ;
QCOMPARE ( view . iconSize ( ) , QSize ( 10 , 10 ) ) ;
view . repainted = false ;
view . setIconSize ( QSize ( 10000 , 10000 ) ) ;
QTRY_VERIFY ( view . repainted ) ;
QCOMPARE ( view . iconSize ( ) , QSize ( 10000 , 10000 ) ) ;
}
void tst_QTreeView : : indexAt ( )
{
QtTestModel model ;
model . rows = model . cols = 5 ;
QTreeView view ;
QCOMPARE ( view . indexAt ( QPoint ( ) ) , QModelIndex ( ) ) ;
view . setModel ( & model ) ;
QVERIFY ( view . indexAt ( QPoint ( ) ) ! = QModelIndex ( ) ) ;
QSize itemSize = view . visualRect ( model . index ( 0 , 0 ) ) . size ( ) ;
for ( int i = 0 ; i < model . rowCount ( ) ; + + i ) {
QPoint pos ( itemSize . width ( ) / 2 , ( i * itemSize . height ( ) ) + ( itemSize . height ( ) / 2 ) ) ;
QModelIndex index = view . indexAt ( pos ) ;
QCOMPARE ( index , model . index ( i , 0 ) ) ;
}
/*
// ### this is wrong; the widget _will_ affect the item size
for ( int j = 0 ; j < model . rowCount ( ) ; + + j )
view . setIndexWidget ( model . index ( j , 0 ) , new QPushButton ) ;
*/
for ( int k = 0 ; k < model . rowCount ( ) ; + + k ) {
QPoint pos ( itemSize . width ( ) / 2 , ( k * itemSize . height ( ) ) + ( itemSize . height ( ) / 2 ) ) ;
QModelIndex index = view . indexAt ( pos ) ;
QCOMPARE ( index , model . index ( k , 0 ) ) ;
}
view . show ( ) ;
view . resize ( 600 , 600 ) ;
view . header ( ) - > setStretchLastSection ( false ) ;
QCOMPARE ( view . indexAt ( QPoint ( 550 , 20 ) ) , QModelIndex ( ) ) ;
}
void tst_QTreeView : : indexWidget ( )
{
QTreeView view ;
QStandardItemModel treeModel ;
initStandardTreeModel ( & treeModel ) ;
view . setModel ( & treeModel ) ;
QModelIndex index = view . model ( ) - > index ( 0 , 0 ) ;
QVERIFY ( ! view . indexWidget ( QModelIndex ( ) ) ) ;
QVERIFY ( ! view . indexWidget ( index ) ) ;
QString text = QLatin1String ( " TestLabel " ) ;
QWidget * label = new QLabel ( text ) ;
view . setIndexWidget ( QModelIndex ( ) , label ) ;
QVERIFY ( ! view . indexWidget ( QModelIndex ( ) ) ) ;
QVERIFY ( ! label - > parent ( ) ) ;
view . setIndexWidget ( index , label ) ;
QCOMPARE ( view . indexWidget ( index ) , label ) ;
QCOMPARE ( label - > parentWidget ( ) , view . viewport ( ) ) ;
QTextEdit * widget = new QTextEdit ( text ) ;
widget - > setFixedSize ( 200 , 100 ) ;
view . setIndexWidget ( index , widget ) ;
QCOMPARE ( view . indexWidget ( index ) , static_cast < QWidget * > ( widget ) ) ;
QCOMPARE ( widget - > parentWidget ( ) , view . viewport ( ) ) ;
QCOMPARE ( widget - > geometry ( ) , view . visualRect ( index ) . intersected ( widget - > geometry ( ) ) ) ;
QCOMPARE ( widget - > toPlainText ( ) , text ) ;
//now let's try to do that later when the widget is already shown
view . show ( ) ;
index = view . model ( ) - > index ( 1 , 0 ) ;
QVERIFY ( ! view . indexWidget ( index ) ) ;
widget = new QTextEdit ( text ) ;
widget - > setFixedSize ( 200 , 100 ) ;
view . setIndexWidget ( index , widget ) ;
QCOMPARE ( view . indexWidget ( index ) , static_cast < QWidget * > ( widget ) ) ;
QCOMPARE ( widget - > parentWidget ( ) , view . viewport ( ) ) ;
2013-03-25 09:32:52 +00:00
QCOMPARE ( widget - > geometry ( ) , view . visualRect ( index ) . intersected ( widget - > geometry ( ) ) ) ;
2011-04-27 10:05:43 +00:00
QCOMPARE ( widget - > toPlainText ( ) , text ) ;
}
void tst_QTreeView : : itemDelegate ( )
{
QPointer < QAbstractItemDelegate > oldDelegate ;
QPointer < QItemDelegate > otherItemDelegate ;
{
QTreeView view ;
QVERIFY ( qobject_cast < QStyledItemDelegate * > ( view . itemDelegate ( ) ) ) ;
QPointer < QAbstractItemDelegate > oldDelegate = view . itemDelegate ( ) ;
otherItemDelegate = new QItemDelegate ;
view . setItemDelegate ( otherItemDelegate ) ;
QVERIFY ( ! otherItemDelegate - > parent ( ) ) ;
QVERIFY ( oldDelegate ) ;
QCOMPARE ( view . itemDelegate ( ) , ( QAbstractItemDelegate * ) otherItemDelegate ) ;
view . setItemDelegate ( 0 ) ;
QVERIFY ( ! view . itemDelegate ( ) ) ; // <- view does its own drawing?
QVERIFY ( otherItemDelegate ) ;
}
// This is strange. Why doesn't setItemDelegate() reparent the delegate?
QVERIFY ( ! oldDelegate ) ;
QVERIFY ( otherItemDelegate ) ;
delete otherItemDelegate ;
}
void tst_QTreeView : : itemDelegateForColumnOrRow ( )
{
QTreeView view ;
QAbstractItemDelegate * defaultDelegate = view . itemDelegate ( ) ;
QVERIFY ( defaultDelegate ) ;
QVERIFY ( ! view . itemDelegateForRow ( 0 ) ) ;
QVERIFY ( ! view . itemDelegateForColumn ( 0 ) ) ;
QCOMPARE ( view . itemDelegate ( QModelIndex ( ) ) , defaultDelegate ) ;
QStandardItemModel model ;
for ( int i = 0 ; i < 100 ; + + i ) {
model . appendRow ( QList < QStandardItem * > ( )
< < new QStandardItem ( " An item that has very long text and should "
" cause the horizontal scroll bar to appear. " )
< < new QStandardItem ( " An item that has very long text and should "
" cause the horizontal scroll bar to appear. " )
< < new QStandardItem ( " An item that has very long text and should "
" cause the horizontal scroll bar to appear. " ) ) ;
}
view . setModel ( & model ) ;
QVERIFY ( ! view . itemDelegateForRow ( 0 ) ) ;
QVERIFY ( ! view . itemDelegateForColumn ( 0 ) ) ;
QCOMPARE ( view . itemDelegate ( QModelIndex ( ) ) , defaultDelegate ) ;
QCOMPARE ( view . itemDelegate ( view . model ( ) - > index ( 0 , 0 ) ) , defaultDelegate ) ;
QPointer < QAbstractItemDelegate > rowDelegate = new QItemDelegate ;
view . setItemDelegateForRow ( 0 , rowDelegate ) ;
QVERIFY ( ! rowDelegate - > parent ( ) ) ;
QCOMPARE ( view . itemDelegateForRow ( 0 ) , ( QAbstractItemDelegate * ) rowDelegate ) ;
QCOMPARE ( view . itemDelegate ( view . model ( ) - > index ( 0 , 0 ) ) , ( QAbstractItemDelegate * ) rowDelegate ) ;
QCOMPARE ( view . itemDelegate ( view . model ( ) - > index ( 0 , 1 ) ) , ( QAbstractItemDelegate * ) rowDelegate ) ;
QCOMPARE ( view . itemDelegate ( view . model ( ) - > index ( 1 , 0 ) ) , defaultDelegate ) ;
QCOMPARE ( view . itemDelegate ( view . model ( ) - > index ( 1 , 1 ) ) , defaultDelegate ) ;
QPointer < QAbstractItemDelegate > columnDelegate = new QItemDelegate ;
view . setItemDelegateForColumn ( 1 , columnDelegate ) ;
QVERIFY ( ! columnDelegate - > parent ( ) ) ;
QCOMPARE ( view . itemDelegateForColumn ( 1 ) , ( QAbstractItemDelegate * ) columnDelegate ) ;
QCOMPARE ( view . itemDelegate ( view . model ( ) - > index ( 0 , 0 ) ) , ( QAbstractItemDelegate * ) rowDelegate ) ;
QCOMPARE ( view . itemDelegate ( view . model ( ) - > index ( 0 , 1 ) ) , ( QAbstractItemDelegate * ) rowDelegate ) ; // row wins
QCOMPARE ( view . itemDelegate ( view . model ( ) - > index ( 1 , 0 ) ) , defaultDelegate ) ;
QCOMPARE ( view . itemDelegate ( view . model ( ) - > index ( 1 , 1 ) ) , ( QAbstractItemDelegate * ) columnDelegate ) ;
view . setItemDelegateForRow ( 0 , 0 ) ;
QVERIFY ( ! view . itemDelegateForRow ( 0 ) ) ;
QVERIFY ( rowDelegate ) ; // <- wasn't deleted
view . setItemDelegateForColumn ( 1 , 0 ) ;
QVERIFY ( ! view . itemDelegateForColumn ( 1 ) ) ;
QVERIFY ( columnDelegate ) ; // <- wasn't deleted
delete rowDelegate ;
delete columnDelegate ;
}
void tst_QTreeView : : keyboardSearch ( )
{
QTreeView view ;
QStandardItemModel model ;
model . appendRow ( new QStandardItem ( " Andreas " ) ) ;
model . appendRow ( new QStandardItem ( " Baldrian " ) ) ;
model . appendRow ( new QStandardItem ( " Cecilie " ) ) ;
view . setModel ( & model ) ;
view . show ( ) ;
// Nothing is selected
QVERIFY ( ! view . selectionModel ( ) - > hasSelection ( ) ) ;
QVERIFY ( ! view . selectionModel ( ) - > isSelected ( model . index ( 0 , 0 ) ) ) ;
// First item is selected
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QTRY_VERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 0 , 0 ) ) ) ;
// First item is still selected
view . keyboardSearch ( QLatin1String ( " n " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 0 , 0 ) ) ) ;
// No "AnB" item - keep the same selection.
view . keyboardSearch ( QLatin1String ( " B " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 0 , 0 ) ) ) ;
// Wait a bit.
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
// The item that starts with B is selected.
view . keyboardSearch ( QLatin1String ( " B " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 1 , 0 ) ) ) ;
2017-11-01 11:11:33 +00:00
// Test that it wraps round
model . appendRow ( new QStandardItem ( " Andy " ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 3 , 0 ) ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 0 , 0 ) ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 3 , 0 ) ) ) ;
// Test that it handles the case where the first item is hidden correctly
model . insertRow ( 0 , new QStandardItem ( " Hidden item " ) ) ;
view . setRowHidden ( 0 , QModelIndex ( ) , true ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 1 , 0 ) ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 4 , 0 ) ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 1 , 0 ) ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
model . clear ( ) ;
view . setCurrentIndex ( QModelIndex ( ) ) ;
QList < QStandardItem * > items = { new QStandardItem ( " Andreas " ) , new QStandardItem ( " Alicia " ) } ;
model . appendRow ( items ) ;
items = { new QStandardItem ( " Baldrian " ) , new QStandardItem ( " Belinda " ) } ;
model . appendRow ( items ) ;
items = { new QStandardItem ( " Cecilie " ) , new QStandardItem ( " Claire " ) } ;
model . appendRow ( items ) ;
QVERIFY ( ! view . selectionModel ( ) - > hasSelection ( ) ) ;
QVERIFY ( ! view . selectionModel ( ) - > isSelected ( model . index ( 0 , 0 ) ) ) ;
// We want to search on the 2nd column so we have to force it to have
// an index in that column as a starting point
view . setCurrentIndex ( QModelIndex ( model . index ( 0 , 1 ) ) ) ;
// Second item in first row is selected
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QTRY_VERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 0 , 1 ) ) ) ;
QVERIFY ( view . currentIndex ( ) = = model . index ( 0 , 1 ) ) ;
// Second item in first row is still selected
view . keyboardSearch ( QLatin1String ( " l " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 0 , 1 ) ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 0 , 1 ) ) ;
// No "AnB" item - keep the same selection.
view . keyboardSearch ( QLatin1String ( " B " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 0 , 1 ) ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 0 , 1 ) ) ;
// Wait a bit.
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
// The item that starts with B is selected.
view . keyboardSearch ( QLatin1String ( " B " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 1 , 1 ) ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 1 , 1 ) ) ;
// Test that it wraps round
items = { new QStandardItem ( " Andy " ) , new QStandardItem ( " Adele " ) } ;
model . appendRow ( items ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 3 , 1 ) ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 3 , 1 ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 0 , 1 ) ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 0 , 1 ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 3 , 1 ) ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 3 , 1 ) ) ;
// Test that it handles the case where the first item is hidden correctly
model . insertRow ( 0 , new QStandardItem ( " Hidden item " ) ) ;
view . setRowHidden ( 0 , QModelIndex ( ) , true ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 1 , 1 ) ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 1 , 1 ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 4 , 1 ) ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 4 , 1 ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
view . keyboardSearch ( QLatin1String ( " A " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 1 , 1 ) ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 1 , 1 ) ) ;
2011-04-27 10:05:43 +00:00
}
2012-08-22 14:18:11 +00:00
void tst_QTreeView : : keyboardSearchMultiColumn ( )
{
QTreeView view ;
QStandardItemModel model ( 4 , 2 ) ;
model . setItem ( 0 , 0 , new QStandardItem ( " 1 " ) ) ; model . setItem ( 0 , 1 , new QStandardItem ( " green " ) ) ;
model . setItem ( 1 , 0 , new QStandardItem ( " bad " ) ) ; model . setItem ( 1 , 1 , new QStandardItem ( " eggs " ) ) ;
model . setItem ( 2 , 0 , new QStandardItem ( " moof " ) ) ; model . setItem ( 2 , 1 , new QStandardItem ( " and " ) ) ;
model . setItem ( 3 , 0 , new QStandardItem ( " elf " ) ) ; model . setItem ( 3 , 1 , new QStandardItem ( " ham " ) ) ;
view . setModel ( & model ) ;
view . show ( ) ;
qApp - > setActiveWindow ( & view ) ;
QVERIFY ( QTest : : qWaitForWindowActive ( & view ) ) ;
view . setCurrentIndex ( model . index ( 0 , 1 ) ) ;
// First item is selected
view . keyboardSearch ( QLatin1String ( " eggs " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 1 , 1 ) ) ) ;
QTest : : qWait ( QApplication : : keyboardInputInterval ( ) * 2 ) ;
// 'ham' is selected
view . keyboardSearch ( QLatin1String ( " h " ) ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( model . index ( 3 , 1 ) ) ) ;
}
2011-04-27 10:05:43 +00:00
void tst_QTreeView : : setModel ( )
{
QTreeView view ;
view . show ( ) ;
2016-09-30 13:16:55 +00:00
QCOMPARE ( view . model ( ) , nullptr ) ;
QCOMPARE ( view . selectionModel ( ) , nullptr ) ;
QCOMPARE ( view . header ( ) - > model ( ) , nullptr ) ;
QCOMPARE ( view . header ( ) - > selectionModel ( ) , nullptr ) ;
2011-04-27 10:05:43 +00:00
for ( int x = 0 ; x < 2 ; + + x ) {
QtTestModel * model = new QtTestModel ( 10 , 8 ) ;
QAbstractItemModel * oldModel = view . model ( ) ;
QSignalSpy modelDestroyedSpy ( oldModel ? oldModel : model , SIGNAL ( destroyed ( ) ) ) ;
// set the same model twice
for ( int i = 0 ; i < 2 ; + + i ) {
QItemSelectionModel * oldSelectionModel = view . selectionModel ( ) ;
QItemSelectionModel * dummy = new QItemSelectionModel ( model ) ;
QSignalSpy selectionModelDestroyedSpy (
oldSelectionModel ? oldSelectionModel : dummy , SIGNAL ( destroyed ( ) ) ) ;
view . setModel ( model ) ;
// QCOMPARE(selectionModelDestroyedSpy.count(), (x == 0 || i == 1) ? 0 : 1);
QCOMPARE ( view . model ( ) , ( QAbstractItemModel * ) model ) ;
QCOMPARE ( view . header ( ) - > model ( ) , ( QAbstractItemModel * ) model ) ;
QCOMPARE ( view . selectionModel ( ) ! = oldSelectionModel , ( i = = 0 ) ) ;
}
QTRY_COMPARE ( modelDestroyedSpy . count ( ) , 0 ) ;
view . setModel ( 0 ) ;
2016-09-30 13:16:55 +00:00
QCOMPARE ( view . model ( ) , nullptr ) ;
2011-04-27 10:05:43 +00:00
// ### shouldn't selectionModel also be 0 now?
2016-09-30 13:16:55 +00:00
// QCOMPARE(view.selectionModel(), nullptr);
2011-04-27 10:05:43 +00:00
delete model ;
}
}
void tst_QTreeView : : openPersistentEditor ( )
{
QTreeView view ;
QStandardItemModel treeModel ;
initStandardTreeModel ( & treeModel ) ;
view . setModel ( & treeModel ) ;
view . show ( ) ;
2013-03-27 14:16:32 +00:00
QVERIFY ( ! view . viewport ( ) - > findChild < QLineEdit * > ( ) ) ;
2011-04-27 10:05:43 +00:00
view . openPersistentEditor ( view . model ( ) - > index ( 0 , 0 ) ) ;
2013-03-27 14:16:32 +00:00
QVERIFY ( view . viewport ( ) - > findChild < QLineEdit * > ( ) ) ;
2011-04-27 10:05:43 +00:00
view . closePersistentEditor ( view . model ( ) - > index ( 0 , 0 ) ) ;
2013-03-27 14:16:32 +00:00
QVERIFY ( ! view . viewport ( ) - > findChild < QLineEdit * > ( ) - > isVisible ( ) ) ;
2011-04-27 10:05:43 +00:00
qApp - > sendPostedEvents ( 0 , QEvent : : DeferredDelete ) ;
2013-03-27 14:16:32 +00:00
QVERIFY ( ! view . viewport ( ) - > findChild < QLineEdit * > ( ) ) ;
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : rootIndex ( )
{
QTreeView view ;
QCOMPARE ( view . rootIndex ( ) , QModelIndex ( ) ) ;
QStandardItemModel treeModel ;
initStandardTreeModel ( & treeModel ) ;
view . setModel ( & treeModel ) ;
QCOMPARE ( view . rootIndex ( ) , QModelIndex ( ) ) ;
view . setRootIndex ( view . model ( ) - > index ( 1 , 0 ) ) ;
QCOMPARE ( view . model ( ) - > data ( view . model ( ) - > index ( 0 , view . header ( ) - > visualIndex ( 0 ) , view . rootIndex ( ) ) , Qt : : DisplayRole )
. toString ( ) , QString ( " Row 2 Child Item " ) ) ;
}
void tst_QTreeView : : setHeader ( )
{
QTreeView view ;
QVERIFY ( view . header ( ) ! = 0 ) ;
QCOMPARE ( view . header ( ) - > orientation ( ) , Qt : : Horizontal ) ;
QCOMPARE ( view . header ( ) - > parent ( ) , ( QObject * ) & view ) ;
for ( int x = 0 ; x < 2 ; + + x ) {
QSignalSpy destroyedSpy ( view . header ( ) , SIGNAL ( destroyed ( ) ) ) ;
Qt : : Orientation orient = x ? Qt : : Vertical : Qt : : Horizontal ;
QHeaderView * head = new QHeaderView ( orient ) ;
view . setHeader ( head ) ;
QCOMPARE ( destroyedSpy . count ( ) , 1 ) ;
QCOMPARE ( head - > parent ( ) , ( QObject * ) & view ) ;
QCOMPARE ( view . header ( ) , head ) ;
view . setHeader ( head ) ;
QCOMPARE ( view . header ( ) , head ) ;
// Itemviews in Qt < 4.2 have asserts for this. Qt >= 4.2 should handle this gracefully
view . setHeader ( ( QHeaderView * ) 0 ) ;
QCOMPARE ( view . header ( ) , head ) ;
}
}
void tst_QTreeView : : columnHidden ( )
{
QTreeView view ;
QtTestModel model ( 10 , 8 ) ;
view . setModel ( & model ) ;
view . show ( ) ;
for ( int c = 0 ; c < model . columnCount ( ) ; + + c )
QCOMPARE ( view . isColumnHidden ( c ) , false ) ;
// hide even columns
for ( int c = 0 ; c < model . columnCount ( ) ; c + = 2 )
view . setColumnHidden ( c , true ) ;
for ( int c = 0 ; c < model . columnCount ( ) ; + + c )
QCOMPARE ( view . isColumnHidden ( c ) , ( c & 1 ) = = 0 ) ;
view . update ( ) ;
// hide odd columns too
for ( int c = 1 ; c < model . columnCount ( ) ; c + = 2 )
view . setColumnHidden ( c , true ) ;
for ( int c = 0 ; c < model . columnCount ( ) ; + + c )
QCOMPARE ( view . isColumnHidden ( c ) , true ) ;
view . update ( ) ;
2017-12-17 18:56:35 +00:00
// QTBUG 54610
// QAbstractItemViewPrivate::_q_layoutChanged() is called on
// rows/columnMoved and because this function is virtual,
// QHeaderViewPrivate::_q_layoutChanged() was called and unhided
// all sections because QHeaderViewPrivate::_q_layoutAboutToBeChanged()
// could not fill persistentHiddenSections (and is not needed)
view . hideColumn ( model . cols - 1 ) ;
QCOMPARE ( view . isColumnHidden ( model . cols - 1 ) , true ) ;
model . simulateMoveRows ( ) ;
QCOMPARE ( view . isColumnHidden ( model . cols - 1 ) , true ) ;
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : rowHidden ( )
{
QtTestModel model ( 4 , 6 ) ;
model . levels = 3 ;
QTreeView view ;
view . resize ( 500 , 500 ) ;
view . setModel ( & model ) ;
view . show ( ) ;
QCOMPARE ( view . isRowHidden ( - 1 , QModelIndex ( ) ) , false ) ;
QCOMPARE ( view . isRowHidden ( 999999 , QModelIndex ( ) ) , false ) ;
view . setRowHidden ( - 1 , QModelIndex ( ) , true ) ;
view . setRowHidden ( 999999 , QModelIndex ( ) , true ) ;
QCOMPARE ( view . isRowHidden ( - 1 , QModelIndex ( ) ) , false ) ;
QCOMPARE ( view . isRowHidden ( 999999 , QModelIndex ( ) ) , false ) ;
view . setRowHidden ( 0 , QModelIndex ( ) , true ) ;
QCOMPARE ( view . isRowHidden ( 0 , QModelIndex ( ) ) , true ) ;
view . setRowHidden ( 0 , QModelIndex ( ) , false ) ;
QCOMPARE ( view . isRowHidden ( 0 , QModelIndex ( ) ) , false ) ;
QStack < QModelIndex > parents ;
parents . push ( QModelIndex ( ) ) ;
while ( ! parents . isEmpty ( ) ) {
QModelIndex p = parents . pop ( ) ;
if ( model . canFetchMore ( p ) )
model . fetchMore ( p ) ;
int rows = model . rowCount ( p ) ;
// hide all
for ( int r = 0 ; r < rows ; + + r ) {
view . setRowHidden ( r , p , true ) ;
QCOMPARE ( view . isRowHidden ( r , p ) , true ) ;
}
// hide none
for ( int r = 0 ; r < rows ; + + r ) {
view . setRowHidden ( r , p , false ) ;
QCOMPARE ( view . isRowHidden ( r , p ) , false ) ;
}
// hide only even rows
for ( int r = 0 ; r < rows ; + + r ) {
bool hide = ( r & 1 ) = = 0 ;
view . setRowHidden ( r , p , hide ) ;
QCOMPARE ( view . isRowHidden ( r , p ) , hide ) ;
}
for ( int r = 0 ; r < rows ; + + r )
parents . push ( model . index ( r , 0 , p ) ) ;
}
parents . push ( QModelIndex ( ) ) ;
while ( ! parents . isEmpty ( ) ) {
QModelIndex p = parents . pop ( ) ;
// all even rows should still be hidden
for ( int r = 0 ; r < model . rowCount ( p ) ; + + r )
QCOMPARE ( view . isRowHidden ( r , p ) , ( r & 1 ) = = 0 ) ;
if ( model . rowCount ( p ) > 0 ) {
for ( int r = 0 ; r < model . rowCount ( p ) ; + + r )
parents . push ( model . index ( r , 0 , p ) ) ;
}
}
}
void tst_QTreeView : : noDelegate ( )
{
QtTestModel model ( 10 , 7 ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . setItemDelegate ( 0 ) ;
2016-09-30 13:16:55 +00:00
QCOMPARE ( view . itemDelegate ( ) , nullptr ) ;
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : noModel ( )
{
QTreeView view ;
view . show ( ) ;
view . setRowHidden ( 0 , QModelIndex ( ) , true ) ;
}
void tst_QTreeView : : emptyModel ( )
{
QtTestModel model ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
QVERIFY ( ! model . wrongIndex ) ;
}
void tst_QTreeView : : removeRows ( )
{
QtTestModel model ( 7 , 10 ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
model . removeLastRow ( ) ;
QVERIFY ( ! model . wrongIndex ) ;
model . removeAllRows ( ) ;
QVERIFY ( ! model . wrongIndex ) ;
}
void tst_QTreeView : : removeCols ( )
{
QtTestModel model ( 5 , 8 ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
model . fetched = true ;
model . removeLastColumn ( ) ;
QVERIFY ( ! model . wrongIndex ) ;
QCOMPARE ( view . header ( ) - > count ( ) , model . cols ) ;
model . removeAllColumns ( ) ;
QVERIFY ( ! model . wrongIndex ) ;
QCOMPARE ( view . header ( ) - > count ( ) , model . cols ) ;
}
2012-11-23 14:24:48 +00:00
void tst_QTreeView : : limitedExpand ( )
{
{
QStandardItemModel model ;
QStandardItem * parentItem = model . invisibleRootItem ( ) ;
parentItem - > appendRow ( new QStandardItem ) ;
parentItem - > appendRow ( new QStandardItem ) ;
parentItem - > appendRow ( new QStandardItem ) ;
QStandardItem * firstItem = model . item ( 0 , 0 ) ;
firstItem - > setFlags ( firstItem - > flags ( ) | Qt : : ItemNeverHasChildren ) ;
QTreeView view ;
view . setModel ( & model ) ;
QSignalSpy spy ( & view , SIGNAL ( expanded ( QModelIndex ) ) ) ;
QVERIFY ( spy . isValid ( ) ) ;
view . expand ( model . index ( 0 , 0 ) ) ;
QCOMPARE ( spy . count ( ) , 0 ) ;
view . expand ( model . index ( 1 , 0 ) ) ;
QCOMPARE ( spy . count ( ) , 1 ) ;
}
{
QStringListModel model ( QStringList ( ) < < " one " < < " two " ) ;
QTreeView view ;
view . setModel ( & model ) ;
QSignalSpy spy ( & view , SIGNAL ( expanded ( QModelIndex ) ) ) ;
QVERIFY ( spy . isValid ( ) ) ;
view . expand ( model . index ( 0 , 0 ) ) ;
QCOMPARE ( spy . count ( ) , 0 ) ;
view . expandAll ( ) ;
QCOMPARE ( spy . count ( ) , 0 ) ;
}
}
2011-04-27 10:05:43 +00:00
void tst_QTreeView : : expandAndCollapse_data ( )
{
QTest : : addColumn < bool > ( " animationEnabled " ) ;
QTest : : newRow ( " normal " ) < < false ;
QTest : : newRow ( " animated " ) < < true ;
}
void tst_QTreeView : : expandAndCollapse ( )
{
QFETCH ( bool , animationEnabled ) ;
QtTestModel model ( 10 , 9 ) ;
QTreeView view ;
view . setUniformRowHeights ( true ) ;
view . setModel ( & model ) ;
view . setAnimated ( animationEnabled ) ;
view . show ( ) ;
QModelIndex a = model . index ( 0 , 0 , QModelIndex ( ) ) ;
QModelIndex b = model . index ( 0 , 0 , a ) ;
2012-10-16 09:08:13 +00:00
QSignalSpy expandedSpy ( & view , SIGNAL ( expanded ( QModelIndex ) ) ) ;
QSignalSpy collapsedSpy ( & view , SIGNAL ( collapsed ( QModelIndex ) ) ) ;
2011-04-27 10:05:43 +00:00
QVariantList args ;
for ( int y = 0 ; y < 2 ; + + y ) {
view . setVisible ( y = = 0 ) ;
for ( int x = 0 ; x < 2 ; + + x ) {
view . setItemsExpandable ( x = = 0 ) ;
// Test bad args
view . expand ( QModelIndex ( ) ) ;
QCOMPARE ( view . isExpanded ( QModelIndex ( ) ) , false ) ;
view . collapse ( QModelIndex ( ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 0 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 0 ) ;
// expand a first level item
QVERIFY ( ! view . isExpanded ( a ) ) ;
view . expand ( a ) ;
QVERIFY ( view . isExpanded ( a ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 1 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 0 ) ;
args = expandedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , a ) ;
view . expand ( a ) ;
QVERIFY ( view . isExpanded ( a ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 0 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 0 ) ;
// expand a second level item
QVERIFY ( ! view . isExpanded ( b ) ) ;
view . expand ( b ) ;
QVERIFY ( view . isExpanded ( a ) ) ;
QVERIFY ( view . isExpanded ( b ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 1 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 0 ) ;
args = expandedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , b ) ;
view . expand ( b ) ;
QVERIFY ( view . isExpanded ( b ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 0 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 0 ) ;
// collapse the first level item
view . collapse ( a ) ;
QVERIFY ( ! view . isExpanded ( a ) ) ;
QVERIFY ( view . isExpanded ( b ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 0 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 1 ) ;
args = collapsedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , a ) ;
view . collapse ( a ) ;
QVERIFY ( ! view . isExpanded ( a ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 0 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 0 ) ;
// expand the first level item again
view . expand ( a ) ;
QVERIFY ( view . isExpanded ( a ) ) ;
QVERIFY ( view . isExpanded ( b ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 1 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 0 ) ;
args = expandedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , a ) ;
// collapse the second level item
view . collapse ( b ) ;
QVERIFY ( view . isExpanded ( a ) ) ;
QVERIFY ( ! view . isExpanded ( b ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 0 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 1 ) ;
args = collapsedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , b ) ;
// collapse the first level item
view . collapse ( a ) ;
QVERIFY ( ! view . isExpanded ( a ) ) ;
QVERIFY ( ! view . isExpanded ( b ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 0 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 1 ) ;
args = collapsedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , a ) ;
// expand and remove row
QPersistentModelIndex c = model . index ( 9 , 0 , b ) ;
view . expand ( a ) ;
view . expand ( b ) ;
model . removeLastRow ( ) ; // remove c
QVERIFY ( view . isExpanded ( a ) ) ;
QVERIFY ( view . isExpanded ( b ) ) ;
QVERIFY ( ! view . isExpanded ( c ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 2 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 0 ) ;
args = expandedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , a ) ;
args = expandedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , b ) ;
view . collapse ( a ) ;
view . collapse ( b ) ;
QVERIFY ( ! view . isExpanded ( a ) ) ;
QVERIFY ( ! view . isExpanded ( b ) ) ;
QVERIFY ( ! view . isExpanded ( c ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 0 ) ;
QCOMPARE ( collapsedSpy . count ( ) , 2 ) ;
args = collapsedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , a ) ;
args = collapsedSpy . takeFirst ( ) ;
QCOMPARE ( qvariant_cast < QModelIndex > ( args . at ( 0 ) ) , b ) ;
}
}
}
2018-10-01 14:24:44 +00:00
static void checkExpandState ( const QAbstractItemModel & model , const QTreeView & view ,
const QModelIndex & startIdx , bool bIsExpanded , int * count )
{
* count = 0 ;
QStack < QModelIndex > parents ;
parents . push ( startIdx ) ;
if ( startIdx . isValid ( ) ) {
QCOMPARE ( view . isExpanded ( startIdx ) , bIsExpanded ) ;
* count + = 1 ;
}
while ( ! parents . isEmpty ( ) ) {
const QModelIndex p = parents . pop ( ) ;
const int rows = model . rowCount ( p ) ;
for ( int r = 0 ; r < rows ; + + r ) {
const QModelIndex c = model . index ( r , 0 , p ) ;
QCOMPARE ( view . isExpanded ( c ) , bIsExpanded ) ;
parents . push ( c ) ;
}
* count + = rows ;
}
}
2011-04-27 10:05:43 +00:00
void tst_QTreeView : : expandAndCollapseAll ( )
{
2018-10-01 14:24:44 +00:00
QStandardItemModel model ;
// QtTestModel has a broken parent/child handling which will break the test
for ( int i1 = 0 ; i1 < 3 ; + + i1 ) {
QStandardItem * s1 = new QStandardItem ;
s1 - > setText ( QString : : number ( i1 ) ) ;
model . appendRow ( s1 ) ;
for ( int i2 = 0 ; i2 < 3 ; + + i2 ) {
QStandardItem * s2 = new QStandardItem ;
s2 - > setText ( QStringLiteral ( " %1 - %2 " ) . arg ( i1 ) . arg ( i2 ) ) ;
s1 - > appendRow ( s2 ) ;
for ( int i3 = 0 ; i3 < 3 ; + + i3 ) {
QStandardItem * s3 = new QStandardItem ;
s3 - > setText ( QStringLiteral ( " %1 - %2 - %3 " ) . arg ( i1 ) . arg ( i2 ) . arg ( i3 ) ) ;
s2 - > appendRow ( s3 ) ;
}
}
}
2011-04-27 10:05:43 +00:00
QTreeView view ;
view . setUniformRowHeights ( true ) ;
view . setModel ( & model ) ;
2018-10-01 14:24:44 +00:00
view . show ( ) ;
QVERIFY ( QTest : : qWaitForWindowExposed ( & view ) ) ;
2011-04-27 10:05:43 +00:00
2018-10-01 14:24:44 +00:00
QSignalSpy expandedSpy ( & view , & QTreeView : : expanded ) ;
QSignalSpy collapsedSpy ( & view , & QTreeView : : collapsed ) ;
int count ;
2011-04-27 10:05:43 +00:00
view . expandAll ( ) ;
2018-10-01 14:24:44 +00:00
checkExpandState ( model , view , QModelIndex ( ) , true , & count ) ;
2011-04-27 10:05:43 +00:00
QCOMPARE ( collapsedSpy . count ( ) , 0 ) ;
2018-10-01 14:24:44 +00:00
QCOMPARE ( expandedSpy . count ( ) , 39 ) ; // == 3 (first) + 9 (second) + 27 (third level)
QCOMPARE ( count , 39 ) ;
2011-04-27 10:05:43 +00:00
2018-10-01 14:24:44 +00:00
collapsedSpy . clear ( ) ;
expandedSpy . clear ( ) ;
2011-04-27 10:05:43 +00:00
view . collapseAll ( ) ;
2018-10-01 14:24:44 +00:00
checkExpandState ( model , view , QModelIndex ( ) , false , & count ) ;
QCOMPARE ( collapsedSpy . count ( ) , 39 ) ;
QCOMPARE ( expandedSpy . count ( ) , 0 ) ;
QCOMPARE ( count , 39 ) ;
collapsedSpy . clear ( ) ;
expandedSpy . clear ( ) ;
view . expandRecursively ( model . index ( 0 , 0 ) ) ;
QCOMPARE ( expandedSpy . count ( ) , 13 ) ; // 1 + 3 + 9
checkExpandState ( model , view , model . index ( 0 , 0 ) , true , & count ) ;
QCOMPARE ( count , 13 ) ;
checkExpandState ( model , view , model . index ( 1 , 0 ) , false , & count ) ;
QCOMPARE ( count , 13 ) ;
checkExpandState ( model , view , model . index ( 2 , 0 ) , false , & count ) ;
QCOMPARE ( count , 13 ) ;
expandedSpy . clear ( ) ;
view . collapseAll ( ) ;
view . expandRecursively ( model . index ( 0 , 0 ) , 1 ) ;
QCOMPARE ( expandedSpy . count ( ) , 4 ) ; // 1 + 3
view . expandRecursively ( model . index ( 0 , 0 ) , 2 ) ;
QCOMPARE ( expandedSpy . count ( ) , 13 ) ; // (1 + 3) + 9
checkExpandState ( model , view , model . index ( 0 , 0 ) , true , & count ) ;
QCOMPARE ( count , 13 ) ;
checkExpandState ( model , view , model . index ( 1 , 0 ) , false , & count ) ;
QCOMPARE ( count , 13 ) ;
checkExpandState ( model , view , model . index ( 2 , 0 ) , false , & count ) ;
QCOMPARE ( count , 13 ) ;
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : expandWithNoChildren ( )
{
QTreeView tree ;
QStandardItemModel model ( 1 , 1 ) ;
tree . setModel ( & model ) ;
tree . setAnimated ( true ) ;
tree . doItemsLayout ( ) ;
//this test should not output warnings
tree . expand ( model . index ( 0 , 0 ) ) ;
}
void tst_QTreeView : : keyboardNavigation ( )
{
const int rows = 10 ;
const int columns = 7 ;
QtTestModel model ( rows , columns ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
QVector < Qt : : Key > keymoves ;
keymoves < < Qt : : Key_Down < < Qt : : Key_Right < < Qt : : Key_Right < < Qt : : Key_Right
< < Qt : : Key_Down < < Qt : : Key_Down < < Qt : : Key_Down < < Qt : : Key_Down
< < Qt : : Key_Right < < Qt : : Key_Right < < Qt : : Key_Right
< < Qt : : Key_Left < < Qt : : Key_Up < < Qt : : Key_Left < < Qt : : Key_Left
< < Qt : : Key_Up < < Qt : : Key_Down < < Qt : : Key_Up < < Qt : : Key_Up
< < Qt : : Key_Up < < Qt : : Key_Up < < Qt : : Key_Up < < Qt : : Key_Up
< < Qt : : Key_Left < < Qt : : Key_Left < < Qt : : Key_Up < < Qt : : Key_Down ;
int row = 0 ;
int column = 0 ;
QModelIndex index = model . index ( row , column , QModelIndex ( ) ) ;
view . setCurrentIndex ( index ) ;
QCOMPARE ( view . currentIndex ( ) , index ) ;
for ( int i = 0 ; i < keymoves . size ( ) ; + + i ) {
Qt : : Key key = keymoves . at ( i ) ;
QTest : : keyClick ( & view , key ) ;
switch ( key ) {
case Qt : : Key_Up :
if ( row > 0 ) {
index = index . sibling ( row - 1 , column ) ;
row - = 1 ;
} else if ( index . parent ( ) ! = QModelIndex ( ) ) {
index = index . parent ( ) ;
row = index . row ( ) ;
}
break ;
case Qt : : Key_Down :
if ( view . isExpanded ( index ) ) {
row = 0 ;
index = index . child ( row , column ) ;
} else {
row = qMin ( rows - 1 , row + 1 ) ;
index = index . sibling ( row , column ) ;
}
break ;
case Qt : : Key_Left : {
QScrollBar * b = view . horizontalScrollBar ( ) ;
if ( b - > value ( ) = = b - > minimum ( ) )
QVERIFY ( ! view . isExpanded ( index ) ) ;
// windows style right will walk to the parent
if ( view . currentIndex ( ) ! = index ) {
QCOMPARE ( view . currentIndex ( ) , index . parent ( ) ) ;
index = view . currentIndex ( ) ;
row = index . row ( ) ;
column = index . column ( ) ;
}
break ;
}
case Qt : : Key_Right :
QVERIFY ( view . isExpanded ( index ) ) ;
// windows style right will walk to the first child
if ( view . currentIndex ( ) ! = index ) {
QCOMPARE ( view . currentIndex ( ) . parent ( ) , index ) ;
row = view . currentIndex ( ) . row ( ) ;
column = view . currentIndex ( ) . column ( ) ;
index = view . currentIndex ( ) ;
}
break ;
default :
QVERIFY ( false ) ;
}
QCOMPARE ( view . currentIndex ( ) . row ( ) , row ) ;
QCOMPARE ( view . currentIndex ( ) . column ( ) , column ) ;
QCOMPARE ( view . currentIndex ( ) , index ) ;
}
}
class Dmodel : public QtTestModel
{
public :
Dmodel ( ) : QtTestModel ( 10 , 10 ) { }
int columnCount ( const QModelIndex & parent ) const
{
if ( parent . row ( ) = = 5 )
return 1 ;
return QtTestModel : : columnCount ( parent ) ;
}
} ;
void tst_QTreeView : : headerSections ( )
{
Dmodel model ;
QTreeView view ;
QHeaderView * header = view . header ( ) ;
view . setModel ( & model ) ;
QModelIndex index = model . index ( 5 , 0 ) ;
view . setRootIndex ( index ) ;
QCOMPARE ( model . columnCount ( QModelIndex ( ) ) , 10 ) ;
QCOMPARE ( model . columnCount ( index ) , 1 ) ;
QCOMPARE ( header - > count ( ) , model . columnCount ( index ) ) ;
}
void tst_QTreeView : : moveCursor_data ( )
{
QTest : : addColumn < bool > ( " uniformRowHeights " ) ;
QTest : : addColumn < bool > ( " scrollPerPixel " ) ;
QTest : : newRow ( " uniformRowHeights = false, scrollPerPixel = false " )
< < false < < false ;
QTest : : newRow ( " uniformRowHeights = true, scrollPerPixel = false " )
< < true < < false ;
QTest : : newRow ( " uniformRowHeights = false, scrollPerPixel = true " )
< < false < < true ;
QTest : : newRow ( " uniformRowHeights = true, scrollPerPixel = true " )
< < true < < true ;
}
void tst_QTreeView : : moveCursor ( )
{
QFETCH ( bool , uniformRowHeights ) ;
QFETCH ( bool , scrollPerPixel ) ;
QtTestModel model ( 8 , 6 ) ;
2016-07-28 16:51:53 +00:00
QTreeView view ;
2011-04-27 10:05:43 +00:00
view . setUniformRowHeights ( uniformRowHeights ) ;
view . setModel ( & model ) ;
view . setRowHidden ( 0 , QModelIndex ( ) , true ) ;
view . setVerticalScrollMode ( scrollPerPixel ?
QAbstractItemView : : ScrollPerPixel :
QAbstractItemView : : ScrollPerItem ) ;
QVERIFY ( view . isRowHidden ( 0 , QModelIndex ( ) ) ) ;
view . setColumnHidden ( 0 , true ) ;
QVERIFY ( view . isColumnHidden ( 0 ) ) ;
view . show ( ) ;
qApp - > setActiveWindow ( & view ) ;
//here the first visible index should be selected
//because the view got the focus
QModelIndex expected = model . index ( 1 , 1 , QModelIndex ( ) ) ;
QCOMPARE ( view . currentIndex ( ) , expected ) ;
//then pressing down should go to the next line
2016-07-28 16:51:53 +00:00
QModelIndex actual = view . moveCursor ( QTreeView : : MoveDown , Qt : : NoModifier ) ;
2011-04-27 10:05:43 +00:00
expected = model . index ( 2 , 1 , QModelIndex ( ) ) ;
QCOMPARE ( actual , expected ) ;
view . setRowHidden ( 0 , QModelIndex ( ) , false ) ;
view . setColumnHidden ( 0 , false ) ;
// PageUp was broken with uniform row heights turned on
view . setCurrentIndex ( model . index ( 1 , 0 ) ) ;
2016-07-28 16:51:53 +00:00
actual = view . moveCursor ( QTreeView : : MovePageUp , Qt : : NoModifier ) ;
2011-04-27 10:05:43 +00:00
expected = model . index ( 0 , 0 , QModelIndex ( ) ) ;
QCOMPARE ( actual , expected ) ;
//let's try another column
view . setCurrentIndex ( model . index ( 1 , 1 ) ) ;
view . setSelectionBehavior ( QAbstractItemView : : SelectItems ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Up ) ;
expected = model . index ( 0 , 1 , QModelIndex ( ) ) ;
QCOMPARE ( view . currentIndex ( ) , expected ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Down ) ;
expected = model . index ( 1 , 1 , QModelIndex ( ) ) ;
QCOMPARE ( view . currentIndex ( ) , expected ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Up ) ;
expected = model . index ( 0 , 1 , QModelIndex ( ) ) ;
QCOMPARE ( view . currentIndex ( ) , expected ) ;
view . setColumnHidden ( 0 , true ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Left ) ;
expected = model . index ( 0 , 1 , QModelIndex ( ) ) ; //it shouldn't have changed
QCOMPARE ( view . currentIndex ( ) , expected ) ;
view . setColumnHidden ( 0 , false ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Left ) ;
expected = model . index ( 0 , 0 , QModelIndex ( ) ) ;
QCOMPARE ( view . currentIndex ( ) , expected ) ;
}
class TestDelegate : public QItemDelegate
{
public :
TestDelegate ( QObject * parent ) : QItemDelegate ( parent ) { }
QSize sizeHint ( const QStyleOptionViewItem & , const QModelIndex & ) const { return QSize ( 200 , 50 ) ; }
} ;
typedef QList < QPoint > PointList ;
void tst_QTreeView : : setSelection_data ( )
{
QTest : : addColumn < QRect > ( " selectionRect " ) ;
QTest : : addColumn < int > ( " selectionMode " ) ;
QTest : : addColumn < int > ( " selectionCommand " ) ;
QTest : : addColumn < PointList > ( " expectedItems " ) ;
QTest : : addColumn < int > ( " verticalOffset " ) ;
QTest : : newRow ( " (0,0,50,20),rows " ) < < QRect ( 0 , 0 , 50 , 20 )
< < int ( QAbstractItemView : : SingleSelection )
< < int ( QItemSelectionModel : : ClearAndSelect | QItemSelectionModel : : Rows )
< < ( PointList ( )
< < QPoint ( 0 , 0 ) < < QPoint ( 1 , 0 ) < < QPoint ( 2 , 0 ) < < QPoint ( 3 , 0 ) < < QPoint ( 4 , 0 )
)
< < 0 ;
QTest : : newRow ( " (0,0,50,90),rows " ) < < QRect ( 0 , 0 , 50 , 90 )
< < int ( QAbstractItemView : : ExtendedSelection )
< < int ( QItemSelectionModel : : ClearAndSelect | QItemSelectionModel : : Rows )
< < ( PointList ( )
< < QPoint ( 0 , 0 ) < < QPoint ( 1 , 0 ) < < QPoint ( 2 , 0 ) < < QPoint ( 3 , 0 ) < < QPoint ( 4 , 0 )
< < QPoint ( 0 , 1 ) < < QPoint ( 1 , 1 ) < < QPoint ( 2 , 1 ) < < QPoint ( 3 , 1 ) < < QPoint ( 4 , 1 )
)
< < 0 ;
QTest : : newRow ( " (50,0,0,90),rows,invalid rect " ) < < QRect ( QPoint ( 50 , 0 ) , QPoint ( 0 , 90 ) )
< < int ( QAbstractItemView : : ExtendedSelection )
< < int ( QItemSelectionModel : : ClearAndSelect | QItemSelectionModel : : Rows )
< < ( PointList ( )
< < QPoint ( 0 , 0 ) < < QPoint ( 1 , 0 ) < < QPoint ( 2 , 0 ) < < QPoint ( 3 , 0 ) < < QPoint ( 4 , 0 )
< < QPoint ( 0 , 1 ) < < QPoint ( 1 , 1 ) < < QPoint ( 2 , 1 ) < < QPoint ( 3 , 1 ) < < QPoint ( 4 , 1 )
)
< < 0 ;
QTest : : newRow ( " (0,-20,20,50),rows " ) < < QRect ( 0 , - 20 , 20 , 50 )
< < int ( QAbstractItemView : : ExtendedSelection )
< < int ( QItemSelectionModel : : ClearAndSelect | QItemSelectionModel : : Rows )
< < ( PointList ( )
< < QPoint ( 0 , 0 ) < < QPoint ( 1 , 0 ) < < QPoint ( 2 , 0 ) < < QPoint ( 3 , 0 ) < < QPoint ( 4 , 0 )
< < QPoint ( 0 , 1 ) < < QPoint ( 1 , 1 ) < < QPoint ( 2 , 1 ) < < QPoint ( 3 , 1 ) < < QPoint ( 4 , 1 )
)
< < 1 ;
QTest : : newRow ( " (0,-50,20,90),rows " ) < < QRect ( 0 , - 50 , 20 , 90 )
< < int ( QAbstractItemView : : ExtendedSelection )
< < int ( QItemSelectionModel : : ClearAndSelect | QItemSelectionModel : : Rows )
< < ( PointList ( )
< < QPoint ( 0 , 0 ) < < QPoint ( 1 , 0 ) < < QPoint ( 2 , 0 ) < < QPoint ( 3 , 0 ) < < QPoint ( 4 , 0 )
< < QPoint ( 0 , 1 ) < < QPoint ( 1 , 1 ) < < QPoint ( 2 , 1 ) < < QPoint ( 3 , 1 ) < < QPoint ( 4 , 1 )
)
< < 1 ;
}
void tst_QTreeView : : setSelection ( )
{
QFETCH ( QRect , selectionRect ) ;
QFETCH ( int , selectionMode ) ;
QFETCH ( int , selectionCommand ) ;
QFETCH ( PointList , expectedItems ) ;
QFETCH ( int , verticalOffset ) ;
QtTestModel model ( 10 , 5 ) ;
model . levels = 1 ;
model . setDecorationsEnabled ( true ) ;
2016-07-28 16:51:53 +00:00
QTreeView view ;
2011-04-27 10:05:43 +00:00
view . resize ( 400 , 300 ) ;
view . show ( ) ;
view . setRootIsDecorated ( false ) ;
view . setItemDelegate ( new TestDelegate ( & view ) ) ;
view . setSelectionMode ( QAbstractItemView : : SelectionMode ( selectionMode ) ) ;
view . setModel ( & model ) ;
view . setUniformRowHeights ( true ) ;
view . setVerticalScrollMode ( QAbstractItemView : : ScrollPerItem ) ;
view . scrollTo ( model . index ( verticalOffset , 0 ) , QAbstractItemView : : PositionAtTop ) ;
view . setSelection ( selectionRect , QItemSelectionModel : : SelectionFlags ( selectionCommand ) ) ;
QItemSelectionModel * selectionModel = view . selectionModel ( ) ;
QVERIFY ( selectionModel ) ;
QModelIndexList selectedIndexes = selectionModel - > selectedIndexes ( ) ;
2018-05-17 13:22:16 +00:00
# ifdef Q_OS_WINRT
QEXPECT_FAIL ( " (0,-20,20,50),rows " , " Fails on WinRT - QTBUG-68297 " , Abort ) ;
QEXPECT_FAIL ( " (0,-50,20,90),rows " , " Fails on WinRT - QTBUG-68297 " , Abort ) ;
# endif
2011-04-27 10:05:43 +00:00
QCOMPARE ( selectedIndexes . count ( ) , expectedItems . count ( ) ) ;
for ( int i = 0 ; i < selectedIndexes . count ( ) ; + + i ) {
QModelIndex idx = selectedIndexes . at ( i ) ;
QVERIFY ( expectedItems . contains ( QPoint ( idx . column ( ) , idx . row ( ) ) ) ) ;
}
}
void tst_QTreeView : : indexAbove ( )
{
QtTestModel model ( 6 , 7 ) ;
model . levels = 2 ;
QTreeView view ;
QCOMPARE ( view . indexAbove ( QModelIndex ( ) ) , QModelIndex ( ) ) ;
view . setModel ( & model ) ;
QCOMPARE ( view . indexAbove ( QModelIndex ( ) ) , QModelIndex ( ) ) ;
QStack < QModelIndex > parents ;
parents . push ( QModelIndex ( ) ) ;
while ( ! parents . isEmpty ( ) ) {
QModelIndex p = parents . pop ( ) ;
if ( model . canFetchMore ( p ) )
model . fetchMore ( p ) ;
int rows = model . rowCount ( p ) ;
for ( int r = rows - 1 ; r > 0 ; - - r ) {
2012-08-22 14:10:01 +00:00
for ( int column = 0 ; column < 3 ; + + column ) {
QModelIndex idx = model . index ( r , column , p ) ;
QModelIndex expected = model . index ( r - 1 , column , p ) ;
QCOMPARE ( view . indexAbove ( idx ) , expected ) ;
}
2011-04-27 10:05:43 +00:00
}
// hide even rows
for ( int r = 0 ; r < rows ; r + = 2 )
view . setRowHidden ( r , p , true ) ;
for ( int r = rows - 1 ; r > 0 ; r - = 2 ) {
2012-08-22 14:10:01 +00:00
for ( int column = 0 ; column < 3 ; + + column ) {
QModelIndex idx = model . index ( r , column , p ) ;
QModelIndex expected = model . index ( r - 2 , column , p ) ;
QCOMPARE ( view . indexAbove ( idx ) , expected ) ;
}
2011-04-27 10:05:43 +00:00
}
// for (int r = 0; r < rows; ++r)
// parents.push(model.index(r, 0, p));
}
}
void tst_QTreeView : : indexBelow ( )
{
2012-08-22 14:10:01 +00:00
QtTestModel model ( 2 , 2 ) ;
2011-04-27 10:05:43 +00:00
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
2012-08-22 14:10:01 +00:00
{
QModelIndex i = model . index ( 0 , 0 , view . rootIndex ( ) ) ;
QVERIFY ( i . isValid ( ) ) ;
QCOMPARE ( i . row ( ) , 0 ) ;
QCOMPARE ( i . column ( ) , 0 ) ;
i = view . indexBelow ( i ) ;
QVERIFY ( i . isValid ( ) ) ;
QCOMPARE ( i . row ( ) , 1 ) ;
QCOMPARE ( i . column ( ) , 0 ) ;
i = view . indexBelow ( i ) ;
QVERIFY ( ! i . isValid ( ) ) ;
}
2011-04-27 10:05:43 +00:00
2012-08-22 14:10:01 +00:00
{
QModelIndex i = model . index ( 0 , 1 , view . rootIndex ( ) ) ;
QVERIFY ( i . isValid ( ) ) ;
QCOMPARE ( i . row ( ) , 0 ) ;
QCOMPARE ( i . column ( ) , 1 ) ;
i = view . indexBelow ( i ) ;
QVERIFY ( i . isValid ( ) ) ;
QCOMPARE ( i . row ( ) , 1 ) ;
QCOMPARE ( i . column ( ) , 1 ) ;
i = view . indexBelow ( i ) ;
QVERIFY ( ! i . isValid ( ) ) ;
}
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : clicked ( )
{
QtTestModel model ( 10 , 2 ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
2013-04-09 08:11:41 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & view ) ) ;
2011-04-27 10:05:43 +00:00
QModelIndex firstIndex = model . index ( 0 , 0 , QModelIndex ( ) ) ;
QVERIFY ( firstIndex . isValid ( ) ) ;
int itemHeight = view . visualRect ( firstIndex ) . height ( ) ;
int itemOffset = view . visualRect ( firstIndex ) . width ( ) / 2 ;
view . resize ( 200 , itemHeight * ( model . rows + 2 ) ) ;
for ( int i = 0 ; i < model . rowCount ( ) ; + + i ) {
QPoint p ( itemOffset , 1 + itemHeight * i ) ;
QModelIndex index = view . indexAt ( p ) ;
if ( ! index . isValid ( ) )
continue ;
2012-10-16 09:08:13 +00:00
QSignalSpy spy ( & view , SIGNAL ( clicked ( QModelIndex ) ) ) ;
2011-04-27 10:05:43 +00:00
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , Qt : : NoModifier , p ) ;
QTRY_COMPARE ( spy . count ( ) , 1 ) ;
}
}
void tst_QTreeView : : mouseDoubleClick ( )
{
// Test double clicks outside the viewport.
// (Should be a no-op and should not expand any item.)
QStandardItemModel model ( 20 , 2 ) ;
for ( int i = 0 ; i < model . rowCount ( ) ; i + + ) {
QModelIndex index = model . index ( i , 0 , QModelIndex ( ) ) ;
model . insertRows ( 0 , 20 , index ) ;
model . insertColumns ( 0 , 2 , index ) ;
for ( int i1 = 0 ; i1 < model . rowCount ( index ) ; i1 + + ) {
2012-08-22 10:04:56 +00:00
( void ) model . index ( i1 , 0 , index ) ;
2011-04-27 10:05:43 +00:00
}
}
QTreeView view ;
view . setModel ( & model ) ;
// make sure the viewport height is smaller than the contents height.
view . resize ( 200 , 200 ) ;
view . move ( 0 , 0 ) ;
view . show ( ) ;
QModelIndex index = model . index ( 0 , 0 , QModelIndex ( ) ) ;
view . setCurrentIndex ( index ) ;
view . setExpanded ( model . index ( 0 , 0 , QModelIndex ( ) ) , true ) ;
view . setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOn ) ;
view . setVerticalScrollBarPolicy ( Qt : : ScrollBarAlwaysOn ) ;
// Make sure all items are collapsed
for ( int i = 0 ; i < model . rowCount ( QModelIndex ( ) ) ; i + + ) {
view . setExpanded ( model . index ( i , 0 , QModelIndex ( ) ) , false ) ;
}
int maximum = view . verticalScrollBar ( ) - > maximum ( ) ;
// Doubleclick in the bottom right corner, in the unused area between the vertical and horizontal scrollbar.
int vsw = view . verticalScrollBar ( ) - > width ( ) ;
int hsh = view . horizontalScrollBar ( ) - > height ( ) ;
QTest : : mouseDClick ( & view , Qt : : LeftButton , Qt : : NoModifier , QPoint ( view . width ( ) - vsw + 1 , view . height ( ) - hsh + 1 ) ) ;
// Should not have expanded, thus maximum() should have the same value.
QCOMPARE ( maximum , view . verticalScrollBar ( ) - > maximum ( ) ) ;
view . setExpandsOnDoubleClick ( false ) ;
QTest : : mouseDClick ( & view , Qt : : LeftButton , Qt : : NoModifier , view . visualRect ( index ) . center ( ) ) ;
QVERIFY ( ! view . isExpanded ( index ) ) ;
}
void tst_QTreeView : : rowsAboutToBeRemoved ( )
{
QStandardItemModel model ( 3 , 1 ) ;
for ( int i = 0 ; i < model . rowCount ( ) ; i + + ) {
2015-10-16 07:38:51 +00:00
const QString iS = QString : : number ( i ) ;
2011-04-27 10:05:43 +00:00
QModelIndex index = model . index ( i , 0 , QModelIndex ( ) ) ;
2015-10-16 07:38:51 +00:00
model . setData ( index , iS ) ;
2011-04-27 10:05:43 +00:00
model . insertRows ( 0 , 4 , index ) ;
model . insertColumns ( 0 , 1 , index ) ;
for ( int i1 = 0 ; i1 < model . rowCount ( index ) ; i1 + + ) {
QModelIndex index2 = model . index ( i1 , 0 , index ) ;
2015-10-16 07:38:51 +00:00
model . setData ( index2 , iS + QString : : number ( i1 ) ) ;
2011-04-27 10:05:43 +00:00
}
}
2016-07-28 16:51:53 +00:00
QTreeView view ;
2011-04-27 10:05:43 +00:00
view . setModel ( & model ) ;
view . show ( ) ;
QModelIndex index = model . index ( 0 , 0 , QModelIndex ( ) ) ;
view . setCurrentIndex ( index ) ;
view . setExpanded ( model . index ( 0 , 0 , QModelIndex ( ) ) , true ) ;
for ( int i = 0 ; i < model . rowCount ( QModelIndex ( ) ) ; i + + ) {
view . setExpanded ( model . index ( i , 0 , QModelIndex ( ) ) , true ) ;
}
QSignalSpy spy1 ( & model , SIGNAL ( rowsAboutToBeRemoved ( QModelIndex , int , int ) ) ) ;
model . removeRows ( 1 , 1 ) ;
2016-07-28 16:51:53 +00:00
QCOMPARE ( int ( view . state ( ) ) , 0 ) ;
2011-04-27 10:05:43 +00:00
// Should not be 5 (or any other number for that sake :)
QCOMPARE ( spy1 . count ( ) , 1 ) ;
}
void tst_QTreeView : : headerSections_unhideSection ( )
{
QtTestModel model ( 10 , 7 ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
int size = view . header ( ) - > sectionSize ( 0 ) ;
view . setColumnHidden ( 0 , true ) ;
// should go back to old size
view . setColumnHidden ( 0 , false ) ;
QCOMPARE ( size , view . header ( ) - > sectionSize ( 0 ) ) ;
}
void tst_QTreeView : : columnAt ( )
{
QtTestModel model ;
model . rows = model . cols = 10 ;
QTreeView view ;
view . resize ( 500 , 500 ) ;
view . setModel ( & model ) ;
QCOMPARE ( view . columnAt ( 0 ) , 0 ) ;
// really this is testing the header... so not much more should be needed if the header is working...
}
void tst_QTreeView : : scrollTo ( )
{
# define CHECK_VISIBLE(ROW,COL) QVERIFY(QRect(QPoint(),view.viewport()->size()).contains(\
view . visualRect ( model . index ( ( ROW ) , ( COL ) , QModelIndex ( ) ) ) ) )
QtTestModel model ;
model . rows = model . cols = 100 ;
QTreeView view ;
view . setUniformRowHeights ( true ) ;
view . scrollTo ( QModelIndex ( ) , QTreeView : : PositionAtTop ) ;
view . setModel ( & model ) ;
// ### check the scrollbar values an make sure it actually scrolls to the item
// ### check for bot item based and pixel based scrolling
// ### create a data function for this test
view . scrollTo ( QModelIndex ( ) ) ;
view . scrollTo ( model . index ( 0 , 0 , QModelIndex ( ) ) ) ;
view . scrollTo ( model . index ( 0 , 0 , QModelIndex ( ) ) , QTreeView : : PositionAtTop ) ;
view . scrollTo ( model . index ( 0 , 0 , QModelIndex ( ) ) , QTreeView : : PositionAtBottom ) ;
//
view . show ( ) ;
view . setVerticalScrollMode ( QAbstractItemView : : ScrollPerItem ) ; //some styles change that in Polish
view . resize ( 300 , 200 ) ;
//view.verticalScrollBar()->setValue(0);
view . scrollTo ( model . index ( 0 , 0 , QModelIndex ( ) ) ) ;
CHECK_VISIBLE ( 0 , 0 ) ;
QCOMPARE ( view . verticalScrollBar ( ) - > value ( ) , 0 ) ;
view . header ( ) - > resizeSection ( 0 , 5 ) ; // now we only see the branches
view . scrollTo ( model . index ( 5 , 0 , QModelIndex ( ) ) , QTreeView : : PositionAtTop ) ;
QCOMPARE ( view . verticalScrollBar ( ) - > value ( ) , 5 ) ;
view . scrollTo ( model . index ( 60 , 60 , QModelIndex ( ) ) ) ;
CHECK_VISIBLE ( 60 , 60 ) ;
view . scrollTo ( model . index ( 60 , 30 , QModelIndex ( ) ) ) ;
CHECK_VISIBLE ( 60 , 30 ) ;
view . scrollTo ( model . index ( 30 , 30 , QModelIndex ( ) ) ) ;
CHECK_VISIBLE ( 30 , 30 ) ;
// TODO force it to move to the left and then the right
}
void tst_QTreeView : : rowsAboutToBeRemoved_move ( )
{
QStandardItemModel model ( 3 , 1 ) ;
QTreeView view ;
view . setModel ( & model ) ;
QModelIndex indexThatWantsToLiveButWillDieDieITellYou ;
QModelIndex parent = model . index ( 2 , 0 ) ;
view . expand ( parent ) ;
for ( int i = 0 ; i < 6 ; + + i ) {
model . insertRows ( 0 , 1 , parent ) ;
model . insertColumns ( 0 , 1 , parent ) ;
QModelIndex index = model . index ( 0 , 0 , parent ) ;
view . expand ( index ) ;
if ( i = = 3 )
indexThatWantsToLiveButWillDieDieITellYou = index ;
model . setData ( index , i ) ;
parent = index ;
}
view . resize ( 600 , 800 ) ;
view . show ( ) ;
view . doItemsLayout ( ) ;
2016-07-28 16:51:53 +00:00
static_cast < QTreeView * > ( & view ) - > executeDelayedItemsLayout ( ) ;
2011-04-27 10:05:43 +00:00
parent = indexThatWantsToLiveButWillDieDieITellYou . parent ( ) ;
QCOMPARE ( view . isExpanded ( indexThatWantsToLiveButWillDieDieITellYou ) , true ) ;
QCOMPARE ( parent . isValid ( ) , true ) ;
QCOMPARE ( parent . parent ( ) . isValid ( ) , true ) ;
view . expand ( parent ) ;
QCOMPARE ( view . isExpanded ( parent ) , true ) ;
QCOMPARE ( view . isExpanded ( indexThatWantsToLiveButWillDieDieITellYou ) , true ) ;
model . removeRow ( 0 , indexThatWantsToLiveButWillDieDieITellYou ) ;
QCOMPARE ( view . isExpanded ( parent ) , true ) ;
QCOMPARE ( view . isExpanded ( indexThatWantsToLiveButWillDieDieITellYou ) , true ) ;
}
void tst_QTreeView : : resizeColumnToContents ( )
{
QStandardItemModel model ( 50 , 2 ) ;
for ( int r = 0 ; r < model . rowCount ( ) ; + + r ) {
2015-10-16 07:38:51 +00:00
const QString rS = QString : : number ( r ) ;
2011-04-27 10:05:43 +00:00
for ( int c = 0 ; c < model . columnCount ( ) ; + + c ) {
QModelIndex idx = model . index ( r , c ) ;
2015-10-16 07:38:51 +00:00
model . setData ( idx , rS + QLatin1Char ( ' , ' ) + QString : : number ( c ) ) ;
2011-04-27 10:05:43 +00:00
model . insertColumns ( 0 , 2 , idx ) ;
model . insertRows ( 0 , 6 , idx ) ;
for ( int i = 0 ; i < 6 ; + + i ) {
2015-10-16 07:38:51 +00:00
const QString iS = QString : : number ( i ) ;
2011-04-27 10:05:43 +00:00
for ( int j = 0 ; j < 2 ; + + j ) {
2015-10-16 07:38:51 +00:00
model . setData ( model . index ( i , j , idx ) , QLatin1String ( " child " ) + iS + QString : : number ( j ) ) ;
2011-04-27 10:05:43 +00:00
}
}
}
}
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
qApp - > processEvents ( ) ; //must have this, or else it will not scroll
view . scrollToBottom ( ) ;
view . resizeColumnToContents ( 0 ) ;
int oldColumnSize = view . header ( ) - > sectionSize ( 0 ) ;
view . setRootIndex ( model . index ( 0 , 0 ) ) ;
view . resizeColumnToContents ( 0 ) ; //Earlier, this gave an assert
QVERIFY ( view . header ( ) - > sectionSize ( 0 ) > oldColumnSize ) ;
}
void tst_QTreeView : : insertAfterSelect ( )
{
QtTestModel model ;
model . rows = model . cols = 10 ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
QModelIndex firstIndex = model . index ( 0 , 0 , QModelIndex ( ) ) ;
QVERIFY ( firstIndex . isValid ( ) ) ;
int itemOffset = view . visualRect ( firstIndex ) . width ( ) / 2 ;
QPoint p ( itemOffset , 1 ) ;
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , Qt : : NoModifier , p ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( firstIndex ) ) ;
model . insertNewRow ( ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( firstIndex ) ) ; // Should still be selected
}
void tst_QTreeView : : removeAfterSelect ( )
{
QtTestModel model ;
model . rows = model . cols = 10 ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
QModelIndex firstIndex = model . index ( 0 , 0 , QModelIndex ( ) ) ;
QVERIFY ( firstIndex . isValid ( ) ) ;
int itemOffset = view . visualRect ( firstIndex ) . width ( ) / 2 ;
QPoint p ( itemOffset , 1 ) ;
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , Qt : : NoModifier , p ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( firstIndex ) ) ;
model . removeLastRow ( ) ;
QVERIFY ( view . selectionModel ( ) - > isSelected ( firstIndex ) ) ; // Should still be selected
}
void tst_QTreeView : : hiddenItems ( )
{
QtTestModel model ;
model . rows = model . cols = 10 ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
QModelIndex firstIndex = model . index ( 1 , 0 , QModelIndex ( ) ) ;
QVERIFY ( firstIndex . isValid ( ) ) ;
if ( model . canFetchMore ( firstIndex ) )
model . fetchMore ( firstIndex ) ;
for ( int i = 0 ; i < model . rowCount ( firstIndex ) ; i + + )
view . setRowHidden ( i , firstIndex , true ) ;
int itemOffset = view . visualRect ( firstIndex ) . width ( ) / 2 ;
int itemHeight = view . visualRect ( firstIndex ) . height ( ) ;
QPoint p ( itemOffset , itemHeight + 1 ) ;
view . setExpanded ( firstIndex , false ) ;
QTest : : mouseDClick ( view . viewport ( ) , Qt : : LeftButton , Qt : : NoModifier , p ) ;
QCOMPARE ( view . isExpanded ( firstIndex ) , false ) ;
p . setX ( 5 ) ;
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , Qt : : NoModifier , p ) ;
QCOMPARE ( view . isExpanded ( firstIndex ) , false ) ;
}
void tst_QTreeView : : spanningItems ( )
{
QtTestModel model ;
model . rows = model . cols = 10 ;
2016-07-28 16:51:53 +00:00
QTreeView view ;
2011-04-27 10:05:43 +00:00
view . setModel ( & model ) ;
view . show ( ) ;
int itemWidth = view . header ( ) - > sectionSize ( 0 ) ;
int itemHeight = view . visualRect ( model . index ( 0 , 0 , QModelIndex ( ) ) ) . height ( ) ;
// every second row is spanning
for ( int i = 1 ; i < model . rowCount ( QModelIndex ( ) ) ; i + = 2 )
view . setFirstColumnSpanned ( i , QModelIndex ( ) , true ) ;
// non-spanning item
QPoint p ( itemWidth / 2 , itemHeight / 2 ) ; // column 0, row 0
view . setCurrentIndex ( QModelIndex ( ) ) ;
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , Qt : : NoModifier , p ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 0 , 0 , QModelIndex ( ) ) ) ;
QCOMPARE ( view . header ( ) - > sectionSize ( 0 ) - view . indentation ( ) ,
view . visualRect ( model . index ( 0 , 0 , QModelIndex ( ) ) ) . width ( ) ) ;
// spanning item
p . setX ( itemWidth + ( itemWidth / 2 ) ) ; // column 1
p . setY ( itemHeight + ( itemHeight / 2 ) ) ; // row 1
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , Qt : : NoModifier , p ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 1 , 0 , QModelIndex ( ) ) ) ;
QCOMPARE ( view . header ( ) - > length ( ) - view . indentation ( ) ,
view . visualRect ( model . index ( 1 , 0 , QModelIndex ( ) ) ) . width ( ) ) ;
// size hint
// every second row is un-spanned
QStyleOptionViewItem option = view . viewOptions ( ) ;
int w = view . header ( ) - > sectionSizeHint ( 0 ) ;
for ( int i = 0 ; i < model . rowCount ( QModelIndex ( ) ) ; + + i ) {
if ( ! view . isFirstColumnSpanned ( i , QModelIndex ( ) ) ) {
QModelIndex index = model . index ( i , 0 , QModelIndex ( ) ) ;
w = qMax ( w , view . itemDelegate ( index ) - > sizeHint ( option , index ) . width ( ) + view . indentation ( ) ) ;
}
}
QCOMPARE ( view . sizeHintForColumn ( 0 ) , w ) ;
}
void tst_QTreeView : : selectionOrderTest ( )
{
QVERIFY ( ( ( QItemSelectionModel * ) sender ( ) ) - > currentIndex ( ) . row ( ) ! = - 1 ) ;
}
void tst_QTreeView : : selection ( )
{
2015-09-24 07:25:25 +00:00
if ( ! QGuiApplication : : platformName ( ) . compare ( QLatin1String ( " wayland " ) , Qt : : CaseInsensitive ) )
2014-08-21 13:28:52 +00:00
QSKIP ( " Wayland: This causes a crash triggered by setVisible(false) " ) ;
2011-04-27 10:05:43 +00:00
QTreeView treeView ;
QStandardItemModel m ( 10 , 2 ) ;
for ( int i = 0 ; i < 10 ; + + i )
m . setData ( m . index ( i , 0 ) , i ) ;
treeView . setModel ( & m ) ;
2018-09-07 19:08:48 +00:00
treeView . show ( ) ;
QVERIFY ( QTest : : qWaitForWindowExposed ( & treeView ) ) ;
2011-04-27 10:05:43 +00:00
treeView . setSelectionBehavior ( QAbstractItemView : : SelectRows ) ;
treeView . setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
2012-10-16 09:08:13 +00:00
connect ( treeView . selectionModel ( ) , SIGNAL ( selectionChanged ( QItemSelection , QItemSelection ) ) ,
2011-04-27 10:05:43 +00:00
this , SLOT ( selectionOrderTest ( ) ) ) ;
treeView . show ( ) ;
QTest : : mousePress ( treeView . viewport ( ) , Qt : : LeftButton , 0 , treeView . visualRect ( m . index ( 1 , 0 ) ) . center ( ) ) ;
QTest : : keyPress ( treeView . viewport ( ) , Qt : : Key_Down ) ;
2018-09-07 19:08:48 +00:00
auto selectedRows = treeView . selectionModel ( ) - > selectedRows ( ) ;
QCOMPARE ( selectedRows . size ( ) , 1 ) ;
QCOMPARE ( selectedRows . first ( ) , m . index ( 2 , 0 , QModelIndex ( ) ) ) ;
QTest : : keyPress ( treeView . viewport ( ) , Qt : : Key_5 ) ;
selectedRows = treeView . selectionModel ( ) - > selectedRows ( ) ;
QCOMPARE ( selectedRows . size ( ) , 1 ) ;
QCOMPARE ( selectedRows . first ( ) , m . index ( 5 , 0 , QModelIndex ( ) ) ) ;
2011-04-27 10:05:43 +00:00
}
//From task 151686 QTreeView ExtendedSelection selects hidden rows
void tst_QTreeView : : selectionWithHiddenItems ( )
{
QStandardItemModel model ;
for ( int i = 0 ; i < model . rowCount ( ) ; + + i )
2015-10-16 07:38:51 +00:00
model . setData ( model . index ( i , 0 ) , QLatin1String ( " row " ) + QString : : number ( i ) ) ;
2011-04-27 10:05:43 +00:00
QStandardItem item0 ( " row 0 " ) ;
QStandardItem item1 ( " row 1 " ) ;
QStandardItem item2 ( " row 2 " ) ;
QStandardItem item3 ( " row 3 " ) ;
model . appendColumn ( QList < QStandardItem * > ( ) < < & item0 < < & item1 < < & item2 < < & item3 ) ;
QStandardItem child ( " child " ) ;
item1 . appendRow ( & child ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
view . show ( ) ;
qApp - > processEvents ( ) ;
//child should not be selected as it is hidden (its parent is not expanded)
view . selectAll ( ) ;
QCOMPARE ( view . selectionModel ( ) - > selection ( ) . count ( ) , 1 ) ; //one range
QCOMPARE ( view . selectionModel ( ) - > selectedRows ( ) . count ( ) , 4 ) ;
view . expandAll ( ) ;
QVERIFY ( view . isExpanded ( item1 . index ( ) ) ) ;
QCOMPARE ( view . selectionModel ( ) - > selection ( ) . count ( ) , 1 ) ;
QCOMPARE ( view . selectionModel ( ) - > selectedRows ( ) . count ( ) , 4 ) ;
QVERIFY ( ! view . selectionModel ( ) - > isSelected ( model . indexFromItem ( & child ) ) ) ;
view . clearSelection ( ) ;
QVERIFY ( view . isExpanded ( item1 . index ( ) ) ) ;
//child should be selected as it is visible (its parent is expanded)
view . selectAll ( ) ;
QCOMPARE ( view . selectionModel ( ) - > selection ( ) . count ( ) , 2 ) ;
QCOMPARE ( view . selectionModel ( ) - > selectedRows ( ) . count ( ) , 5 ) ; //everything is selected
view . clearSelection ( ) ;
//we hide the node with a child (there should then be 3 items selected in 2 ranges)
view . setRowHidden ( 1 , QModelIndex ( ) , true ) ;
QVERIFY ( view . isExpanded ( item1 . index ( ) ) ) ;
qApp - > processEvents ( ) ;
view . selectAll ( ) ;
QCOMPARE ( view . selectionModel ( ) - > selection ( ) . count ( ) , 2 ) ;
QCOMPARE ( view . selectionModel ( ) - > selectedRows ( ) . count ( ) , 3 ) ;
QVERIFY ( ! view . selectionModel ( ) - > isSelected ( model . indexFromItem ( & item1 ) ) ) ;
QVERIFY ( ! view . selectionModel ( ) - > isSelected ( model . indexFromItem ( & child ) ) ) ;
view . setRowHidden ( 1 , QModelIndex ( ) , false ) ;
QVERIFY ( view . isExpanded ( item1 . index ( ) ) ) ;
view . clearSelection ( ) ;
//we hide a node without children (there should then be 4 items selected in 3 ranges)
view . setRowHidden ( 2 , QModelIndex ( ) , true ) ;
qApp - > processEvents ( ) ;
QVERIFY ( view . isExpanded ( item1 . index ( ) ) ) ;
view . selectAll ( ) ;
QVERIFY ( view . isExpanded ( item1 . index ( ) ) ) ;
QCOMPARE ( view . selectionModel ( ) - > selection ( ) . count ( ) , 3 ) ;
QCOMPARE ( view . selectionModel ( ) - > selectedRows ( ) . count ( ) , 4 ) ;
QVERIFY ( ! view . selectionModel ( ) - > isSelected ( model . indexFromItem ( & item2 ) ) ) ;
view . setRowHidden ( 2 , QModelIndex ( ) , false ) ;
QVERIFY ( view . isExpanded ( item1 . index ( ) ) ) ;
view . clearSelection ( ) ;
}
void tst_QTreeView : : selectAll ( )
{
QStandardItemModel model ( 4 , 4 ) ;
2016-07-28 16:51:53 +00:00
QTreeView view2 ;
2011-04-27 10:05:43 +00:00
view2 . setModel ( & model ) ;
view2 . setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
view2 . selectAll ( ) ; // Should work with an empty model
//everything should be selected since we are in ExtendedSelection mode
QCOMPARE ( view2 . selectedIndexes ( ) . count ( ) , model . rowCount ( ) * model . columnCount ( ) ) ;
for ( int i = 0 ; i < model . rowCount ( ) ; + + i )
2015-10-16 07:38:51 +00:00
model . setData ( model . index ( i , 0 ) , QLatin1String ( " row " ) + QString : : number ( i ) ) ;
2016-07-28 16:51:53 +00:00
QTreeView view ;
2011-04-27 10:05:43 +00:00
view . setModel ( & model ) ;
int selectedCount = view . selectedIndexes ( ) . count ( ) ;
view . selectAll ( ) ;
QCOMPARE ( view . selectedIndexes ( ) . count ( ) , selectedCount ) ;
2012-08-08 13:50:31 +00:00
2016-07-28 16:51:53 +00:00
QTreeView view3 ;
2012-08-08 13:50:31 +00:00
view3 . setModel ( & model ) ;
view3 . setSelectionMode ( QAbstractItemView : : NoSelection ) ;
view3 . selectAll ( ) ;
QCOMPARE ( view3 . selectedIndexes ( ) . count ( ) , 0 ) ;
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : extendedSelection_data ( )
{
QTest : : addColumn < QPoint > ( " mousePressPos " ) ;
QTest : : addColumn < int > ( " selectedCount " ) ;
QTest : : newRow ( " select " ) < < QPoint ( 10 , 10 ) < < 2 ;
2014-04-10 10:07:02 +00:00
QTest : : newRow ( " unselect " ) < < QPoint ( 10 , 300 ) < < 0 ;
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : extendedSelection ( )
{
QFETCH ( QPoint , mousePressPos ) ;
QFETCH ( int , selectedCount ) ;
QStandardItemModel model ( 5 , 2 ) ;
QWidget topLevel ;
QTreeView view ( & topLevel ) ;
2014-04-10 10:07:02 +00:00
view . resize ( qMax ( mousePressPos . x ( ) * 2 , 300 ) , qMax ( mousePressPos . y ( ) * 2 , 350 ) ) ;
2011-04-27 10:05:43 +00:00
view . setModel ( & model ) ;
view . setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
topLevel . show ( ) ;
QTest : : mousePress ( view . viewport ( ) , Qt : : LeftButton , 0 , mousePressPos ) ;
QCOMPARE ( view . selectionModel ( ) - > selectedIndexes ( ) . count ( ) , selectedCount ) ;
}
void tst_QTreeView : : rowSizeHint ( )
{
//tests whether the correct visible columns are taken into account when
//calculating the height of a line
QStandardItemModel model ( 1 , 3 ) ;
model . setData ( model . index ( 0 , 0 ) , QSize ( 20 , 40 ) , Qt : : SizeHintRole ) ;
model . setData ( model . index ( 0 , 1 ) , QSize ( 20 , 10 ) , Qt : : SizeHintRole ) ;
model . setData ( model . index ( 0 , 2 ) , QSize ( 20 , 10 ) , Qt : : SizeHintRole ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . header ( ) - > moveSection ( 1 , 0 ) ; //the 2nd column goes to the 1st place
view . show ( ) ;
//it must be 40 since the tallest item that defines the height of a line
QCOMPARE ( view . visualRect ( model . index ( 0 , 0 ) ) . height ( ) , 40 ) ;
QCOMPARE ( view . visualRect ( model . index ( 0 , 1 ) ) . height ( ) , 40 ) ;
QCOMPARE ( view . visualRect ( model . index ( 0 , 2 ) ) . height ( ) , 40 ) ;
}
//From task 155449 (QTreeWidget has a large width for the first section when sorting
//is turned on before items are added)
2016-02-18 15:15:44 +00:00
void tst_QTreeView : : setSortingEnabledTopLevel ( )
2011-04-27 10:05:43 +00:00
{
2016-02-18 15:15:44 +00:00
QTreeView view ;
QStandardItemModel model ( 1 , 1 ) ;
view . setModel ( & model ) ;
const int size = view . header ( ) - > sectionSize ( 0 ) ;
view . setSortingEnabled ( true ) ;
model . setColumnCount ( 3 ) ;
//we test that changing the column count doesn't change the 1st column size
QCOMPARE ( view . header ( ) - > sectionSize ( 0 ) , size ) ;
}
2011-04-27 10:05:43 +00:00
2016-02-18 15:15:44 +00:00
void tst_QTreeView : : setSortingEnabledChild ( )
{
QMainWindow win ;
QTreeView view ;
2018-03-13 18:53:27 +00:00
// two columns to not get in trouble with stretchLastSection
QStandardItemModel model ( 1 , 2 ) ;
2016-02-18 15:15:44 +00:00
view . setModel ( & model ) ;
2018-03-13 18:53:27 +00:00
view . header ( ) - > setDefaultSectionSize ( 92 ) ;
2016-02-18 15:15:44 +00:00
win . setCentralWidget ( & view ) ;
const int size = view . header ( ) - > sectionSize ( 0 ) ;
view . setSortingEnabled ( true ) ;
model . setColumnCount ( 3 ) ;
//we test that changing the column count doesn't change the 1st column size
QCOMPARE ( view . header ( ) - > sectionSize ( 0 ) , size ) ;
2011-04-27 10:05:43 +00:00
}
void tst_QTreeView : : headerHidden ( )
{
QTreeView view ;
QStandardItemModel model ;
view . setModel ( & model ) ;
QCOMPARE ( view . isHeaderHidden ( ) , false ) ;
QCOMPARE ( view . header ( ) - > isHidden ( ) , false ) ;
view . setHeaderHidden ( true ) ;
QCOMPARE ( view . isHeaderHidden ( ) , true ) ;
QCOMPARE ( view . header ( ) - > isHidden ( ) , true ) ;
}
2014-09-10 14:09:55 +00:00
class TestTreeViewStyle : public QProxyStyle
{
public :
TestTreeViewStyle ( ) : indentation ( 20 ) { }
2017-09-18 08:36:49 +00:00
int pixelMetric ( PixelMetric metric , const QStyleOption * option = 0 , const QWidget * widget = 0 ) const override
2014-09-10 14:09:55 +00:00
{
if ( metric = = QStyle : : PM_TreeViewIndentation )
return indentation ;
else
return QProxyStyle : : pixelMetric ( metric , option , widget ) ;
}
int indentation ;
} ;
void tst_QTreeView : : indentation ( )
{
TestTreeViewStyle style1 ;
TestTreeViewStyle style2 ;
style1 . indentation = 20 ;
style2 . indentation = 30 ;
QTreeView view ;
view . setStyle ( & style1 ) ;
QCOMPARE ( view . indentation ( ) , style1 . indentation ) ;
view . setStyle ( & style2 ) ;
QCOMPARE ( view . indentation ( ) , style2 . indentation ) ;
view . setIndentation ( 70 ) ;
QCOMPARE ( view . indentation ( ) , 70 ) ;
view . setStyle ( & style1 ) ;
QCOMPARE ( view . indentation ( ) , 70 ) ;
view . resetIndentation ( ) ;
QCOMPARE ( view . indentation ( ) , style1 . indentation ) ;
view . setStyle ( & style2 ) ;
QCOMPARE ( view . indentation ( ) , style2 . indentation ) ;
}
2011-04-27 10:05:43 +00:00
// From Task 145199 (crash when column 0 having at least one expanded item is removed and then
// inserted). The test passes simply if it doesn't crash, hence there are no calls
// to QCOMPARE() or QVERIFY().
void tst_QTreeView : : removeAndInsertExpandedCol0 ( )
{
QTreeView view ;
QStandardItemModel model ;
view . setModel ( & model ) ;
model . setColumnCount ( 1 ) ;
QStandardItem * item0 = new QStandardItem ( QString ( " item 0 " ) ) ;
model . invisibleRootItem ( ) - > appendRow ( item0 ) ;
view . expand ( item0 - > index ( ) ) ;
QStandardItem * item1 = new QStandardItem ( QString ( " item 1 " ) ) ;
item0 - > appendRow ( item1 ) ;
model . removeColumns ( 0 , 1 ) ;
model . insertColumns ( 0 , 1 ) ;
view . show ( ) ;
qApp - > processEvents ( ) ;
}
void tst_QTreeView : : disabledButCheckable ( )
{
QTreeView view ;
QStandardItemModel model ;
QStandardItem * item ;
item = new QStandardItem ( QLatin1String ( " Row 1 Item " ) ) ;
model . insertRow ( 0 , item ) ;
item = new QStandardItem ( QLatin1String ( " Row 2 Item " ) ) ;
item - > setCheckable ( true ) ;
item - > setEnabled ( false ) ;
model . insertRow ( 1 , item ) ;
view . setModel ( & model ) ;
view . setCurrentIndex ( model . index ( 1 , 0 ) ) ;
QCOMPARE ( item - > checkState ( ) , Qt : : Unchecked ) ;
view . show ( ) ;
QTest : : keyClick ( & view , Qt : : Key_Space ) ;
QCOMPARE ( item - > checkState ( ) , Qt : : Unchecked ) ;
}
void tst_QTreeView : : sortByColumn_data ( )
{
QTest : : addColumn < bool > ( " sortingEnabled " ) ;
QTest : : newRow ( " sorting enabled " ) < < true ;
QTest : : newRow ( " sorting disabled " ) < < false ;
}
// Checks sorting and that sortByColumn also sets the sortIndicator
void tst_QTreeView : : sortByColumn ( )
{
QFETCH ( bool , sortingEnabled ) ;
QTreeView view ;
QStandardItemModel model ( 4 , 2 ) ;
model . setItem ( 0 , 0 , new QStandardItem ( " b " ) ) ;
model . setItem ( 1 , 0 , new QStandardItem ( " d " ) ) ;
model . setItem ( 2 , 0 , new QStandardItem ( " c " ) ) ;
model . setItem ( 3 , 0 , new QStandardItem ( " a " ) ) ;
model . setItem ( 0 , 1 , new QStandardItem ( " e " ) ) ;
model . setItem ( 1 , 1 , new QStandardItem ( " g " ) ) ;
model . setItem ( 2 , 1 , new QStandardItem ( " h " ) ) ;
model . setItem ( 3 , 1 , new QStandardItem ( " f " ) ) ;
view . setSortingEnabled ( sortingEnabled ) ;
view . setModel ( & model ) ;
2018-10-26 18:38:58 +00:00
view . sortByColumn ( 1 , Qt : : DescendingOrder ) ;
2011-04-27 10:05:43 +00:00
QCOMPARE ( view . header ( ) - > sortIndicatorSection ( ) , 1 ) ;
QCOMPARE ( view . model ( ) - > data ( view . model ( ) - > index ( 0 , 1 ) ) . toString ( ) , QString : : fromLatin1 ( " h " ) ) ;
QCOMPARE ( view . model ( ) - > data ( view . model ( ) - > index ( 1 , 1 ) ) . toString ( ) , QString : : fromLatin1 ( " g " ) ) ;
view . sortByColumn ( 0 , Qt : : AscendingOrder ) ;
QCOMPARE ( view . header ( ) - > sortIndicatorSection ( ) , 0 ) ;
QCOMPARE ( view . model ( ) - > data ( view . model ( ) - > index ( 0 , 0 ) ) . toString ( ) , QString : : fromLatin1 ( " a " ) ) ;
QCOMPARE ( view . model ( ) - > data ( view . model ( ) - > index ( 1 , 0 ) ) . toString ( ) , QString : : fromLatin1 ( " b " ) ) ;
}
/*
This is a model that every time kill ( ) is called it will completely change
2011-05-03 05:55:30 +00:00
all of its nodes for new nodes . It then qFatal ' s if you later use a dead node .
2011-04-27 10:05:43 +00:00
*/
class EvilModel : public QAbstractItemModel
{
public :
class Node {
public :
Node ( Node * p = 0 , int level = 0 ) : parent ( p ) , isDead ( false ) {
populate ( level ) ;
}
~ Node ( )
{
qDeleteAll ( children . begin ( ) , children . end ( ) ) ;
qDeleteAll ( deadChildren . begin ( ) , deadChildren . end ( ) ) ;
}
void populate ( int level = 0 ) {
if ( level < 4 )
for ( int i = 0 ; i < 5 ; + + i )
children . append ( new Node ( this , level + 1 ) ) ;
}
void kill ( ) {
for ( int i = children . count ( ) - 1 ; i > = 0 ; - - i ) {
children . at ( i ) - > kill ( ) ;
if ( parent = = 0 ) {
deadChildren . append ( children . at ( i ) ) ;
children . removeAt ( i ) ;
}
}
if ( parent = = 0 ) {
2011-05-09 07:14:39 +00:00
if ( ! children . isEmpty ( ) )
qFatal ( " %s: children should be empty when parent is null " , Q_FUNC_INFO ) ;
2011-04-27 10:05:43 +00:00
populate ( ) ;
} else {
isDead = true ;
}
}
QList < Node * > children ;
QList < Node * > deadChildren ;
Node * parent ;
bool isDead ;
} ;
Node * root ;
EvilModel ( QObject * parent = 0 ) : QAbstractItemModel ( parent ) , root ( new Node )
{
}
~ EvilModel ( )
{
delete root ;
}
void change ( )
{
emit layoutAboutToBeChanged ( ) ;
QModelIndexList oldList = persistentIndexList ( ) ;
QList < QStack < int > > oldListPath ;
for ( int i = 0 ; i < oldList . count ( ) ; + + i ) {
QModelIndex idx = oldList . at ( i ) ;
QStack < int > path ;
while ( idx . isValid ( ) ) {
path . push ( idx . row ( ) ) ;
idx = idx . parent ( ) ;
}
oldListPath . append ( path ) ;
}
root - > kill ( ) ;
QModelIndexList newList ;
for ( int i = 0 ; i < oldListPath . count ( ) ; + + i ) {
QStack < int > path = oldListPath [ i ] ;
QModelIndex idx ;
while ( ! path . isEmpty ( ) ) {
idx = index ( path . pop ( ) , 0 , idx ) ;
}
newList . append ( idx ) ;
}
changePersistentIndexList ( oldList , newList ) ;
emit layoutChanged ( ) ;
}
int rowCount ( const QModelIndex & parent = QModelIndex ( ) ) const {
Node * parentNode = root ;
if ( parent . isValid ( ) ) {
parentNode = static_cast < Node * > ( parent . internalPointer ( ) ) ;
2011-05-03 05:55:30 +00:00
if ( parentNode - > isDead )
qFatal ( " %s: parentNode is dead! " , Q_FUNC_INFO ) ;
2011-04-27 10:05:43 +00:00
}
return parentNode - > children . count ( ) ;
}
int columnCount ( const QModelIndex & parent = QModelIndex ( ) ) const {
if ( parent . column ( ) > 0 )
return 0 ;
return 1 ;
}
QModelIndex index ( int row , int column , const QModelIndex & parent = QModelIndex ( ) ) const
{
Node * grandparentNode = static_cast < Node * > ( parent . internalPointer ( ) ) ;
Node * parentNode = root ;
if ( parent . isValid ( ) ) {
2011-05-03 05:55:30 +00:00
if ( grandparentNode - > isDead )
qFatal ( " %s: grandparentNode is dead! " , Q_FUNC_INFO ) ;
2011-04-27 10:05:43 +00:00
parentNode = grandparentNode - > children [ parent . row ( ) ] ;
2011-05-03 05:55:30 +00:00
if ( parentNode - > isDead )
qFatal ( " %s: grandparentNode is dead! " , Q_FUNC_INFO ) ;
2011-04-27 10:05:43 +00:00
}
return createIndex ( row , column , parentNode ) ;
}
QModelIndex parent ( const QModelIndex & index ) const
{
Node * parent = static_cast < Node * > ( index . internalPointer ( ) ) ;
Node * grandparent = parent - > parent ;
if ( ! grandparent )
return QModelIndex ( ) ;
return createIndex ( grandparent - > children . indexOf ( parent ) , 0 , grandparent ) ;
}
QVariant data ( const QModelIndex & idx , int role ) const
{
if ( idx . isValid ( ) & & role = = Qt : : DisplayRole ) {
Node * parentNode = root ;
if ( idx . isValid ( ) ) {
parentNode = static_cast < Node * > ( idx . internalPointer ( ) ) ;
2011-05-03 05:55:30 +00:00
if ( parentNode - > isDead )
qFatal ( " %s: grandparentNode is dead! " , Q_FUNC_INFO ) ;
2011-04-27 10:05:43 +00:00
}
2015-10-16 07:38:51 +00:00
return QLatin1Char ( ' [ ' ) + QString : : number ( idx . row ( ) ) + QLatin1Char ( ' , ' )
+ QString : : number ( idx . column ( ) ) + QLatin1Char ( ' , ' )
+ QLatin1String ( parentNode - > isDead ? " dead " : " alive " ) + QLatin1Char ( ' ] ' ) ;
2011-04-27 10:05:43 +00:00
}
return QVariant ( ) ;
}
} ;
void tst_QTreeView : : evilModel_data ( )
{
QTest : : addColumn < bool > ( " visible " ) ;
QTest : : newRow ( " visible " ) < < false ;
}
void tst_QTreeView : : evilModel ( )
{
QFETCH ( bool , visible ) ;
// init
2016-07-28 16:51:53 +00:00
QTreeView view ;
2011-04-27 10:05:43 +00:00
EvilModel model ;
view . setModel ( & model ) ;
view . setVisible ( visible ) ;
QPersistentModelIndex firstLevel = model . index ( 0 , 0 ) ;
QPersistentModelIndex secondLevel = model . index ( 1 , 0 , firstLevel ) ;
QPersistentModelIndex thirdLevel = model . index ( 2 , 0 , secondLevel ) ;
view . setExpanded ( firstLevel , true ) ;
view . setExpanded ( secondLevel , true ) ;
view . setExpanded ( thirdLevel , true ) ;
model . change ( ) ;
// tests
view . setRowHidden ( 0 , firstLevel , true ) ;
model . change ( ) ;
return ;
view . setFirstColumnSpanned ( 1 , QModelIndex ( ) , true ) ;
model . change ( ) ;
view . expand ( secondLevel ) ;
model . change ( ) ;
view . collapse ( secondLevel ) ;
model . change ( ) ;
view . isExpanded ( secondLevel ) ;
view . setCurrentIndex ( firstLevel ) ;
model . change ( ) ;
view . keyboardSearch ( " foo " ) ;
model . change ( ) ;
view . visualRect ( secondLevel ) ;
model . change ( ) ;
view . scrollTo ( thirdLevel ) ;
model . change ( ) ;
view . repaint ( ) ;
model . change ( ) ;
QTest : : mouseDClick ( view . viewport ( ) , Qt : : LeftButton ) ;
model . change ( ) ;
view . indexAt ( QPoint ( 10 , 10 ) ) ;
model . change ( ) ;
view . indexAbove ( model . index ( 2 , 0 ) ) ;
model . change ( ) ;
view . indexBelow ( model . index ( 1 , 0 ) ) ;
model . change ( ) ;
QRect rect ( 0 , 0 , 10 , 10 ) ;
view . setSelection ( rect , QItemSelectionModel : : Select ) ;
model . change ( ) ;
2016-07-28 16:51:53 +00:00
view . moveCursor ( QTreeView : : MoveDown , Qt : : NoModifier ) ;
2011-04-27 10:05:43 +00:00
model . change ( ) ;
view . resizeColumnToContents ( 1 ) ;
model . change ( ) ;
view . QAbstractItemView : : sizeHintForColumn ( 1 ) ;
model . change ( ) ;
view . rowHeight ( secondLevel ) ;
model . change ( ) ;
view . setRootIsDecorated ( true ) ;
model . change ( ) ;
view . setItemsExpandable ( false ) ;
model . change ( ) ;
view . columnViewportPosition ( 0 ) ;
model . change ( ) ;
view . columnWidth ( 0 ) ;
model . change ( ) ;
view . setColumnWidth ( 0 , 30 ) ;
model . change ( ) ;
view . columnAt ( 15 ) ;
model . change ( ) ;
view . isColumnHidden ( 1 ) ;
model . change ( ) ;
view . setColumnHidden ( 2 , true ) ;
model . change ( ) ;
view . isHeaderHidden ( ) ;
model . change ( ) ;
view . setHeaderHidden ( true ) ;
model . change ( ) ;
view . isRowHidden ( 2 , secondLevel ) ;
model . change ( ) ;
view . setRowHidden ( 3 , secondLevel , true ) ;
model . change ( ) ;
view . isFirstColumnSpanned ( 3 , thirdLevel ) ;
model . change ( ) ;
view . setSortingEnabled ( true ) ;
model . change ( ) ;
view . isSortingEnabled ( ) ;
model . change ( ) ;
view . setAnimated ( true ) ;
model . change ( ) ;
view . isAnimated ( ) ;
model . change ( ) ;
view . setAllColumnsShowFocus ( true ) ;
model . change ( ) ;
view . allColumnsShowFocus ( ) ;
model . change ( ) ;
view . doItemsLayout ( ) ;
model . change ( ) ;
view . reset ( ) ;
model . change ( ) ;
view . sortByColumn ( 1 , Qt : : AscendingOrder ) ;
model . change ( ) ;
view . dataChanged ( secondLevel , secondLevel ) ;
model . change ( ) ;
view . hideColumn ( 1 ) ;
model . change ( ) ;
view . showColumn ( 1 ) ;
model . change ( ) ;
view . resizeColumnToContents ( 1 ) ;
model . change ( ) ;
2018-10-26 18:38:58 +00:00
view . sortByColumn ( 1 , Qt : : DescendingOrder ) ;
2011-04-27 10:05:43 +00:00
model . change ( ) ;
view . selectAll ( ) ;
model . change ( ) ;
view . expandAll ( ) ;
model . change ( ) ;
view . collapseAll ( ) ;
model . change ( ) ;
view . expandToDepth ( 3 ) ;
model . change ( ) ;
view . setRootIndex ( secondLevel ) ;
}
void tst_QTreeView : : indexRowSizeHint ( )
{
QStandardItemModel model ( 10 , 1 ) ;
2016-07-28 16:51:53 +00:00
QTreeView view ;
2011-04-27 10:05:43 +00:00
view . setModel ( & model ) ;
QModelIndex index = model . index ( 5 , 0 ) ;
QPushButton * w = new QPushButton ( " Test " ) ;
view . setIndexWidget ( index , w ) ;
view . show ( ) ;
QCOMPARE ( view . indexRowSizeHint ( index ) , w - > sizeHint ( ) . height ( ) ) ;
}
void tst_QTreeView : : filterProxyModelCrash ( )
{
QStandardItemModel model ;
QList < QStandardItem * > items ;
for ( int i = 0 ; i < 100 ; i + + )
2015-10-16 07:38:51 +00:00
items < < new QStandardItem ( QLatin1String ( " item " ) + QString : : number ( i ) ) ;
2011-04-27 10:05:43 +00:00
model . appendColumn ( items ) ;
QSortFilterProxyModel proxy ;
proxy . setSourceModel ( & model ) ;
QTreeView view ;
view . setModel ( & proxy ) ;
view . show ( ) ;
QTest : : qWait ( 30 ) ;
proxy . invalidate ( ) ;
view . verticalScrollBar ( ) - > setValue ( 15 ) ;
QTest : : qWait ( 20 ) ;
proxy . invalidate ( ) ;
view . repaint ( ) ; //used to crash
}
2012-04-17 17:45:20 +00:00
void tst_QTreeView : : renderToPixmap_data ( )
{
QTest : : addColumn < int > ( " row " ) ;
QTest : : newRow ( " row-0 " ) < < 0 ;
QTest : : newRow ( " row-1 " ) < < 1 ;
}
void tst_QTreeView : : renderToPixmap ( )
{
QFETCH ( int , row ) ;
2016-07-28 16:51:53 +00:00
QTreeView view ;
2012-04-17 17:45:20 +00:00
QStandardItemModel model ;
model . appendRow ( new QStandardItem ( " Spanning " ) ) ;
model . appendRow ( QList < QStandardItem * > ( ) < < new QStandardItem ( " Not " ) < < new QStandardItem ( " Spanning " ) ) ;
view . setModel ( & model ) ;
view . setFirstColumnSpanned ( 0 , QModelIndex ( ) , true ) ;
# ifdef QT_BUILD_INTERNAL
{
// We select the index at row=0 because it spans the
// column (regression test for an assert)
// We select the index at row=1 for coverage.
QItemSelection sel ( model . index ( row , 0 ) , model . index ( row , 1 ) ) ;
QRect rect ;
2016-07-28 16:51:53 +00:00
view . d_func ( ) - > renderToPixmap ( sel . indexes ( ) , & rect ) ;
2012-04-17 17:45:20 +00:00
}
# endif
}
2011-04-27 10:05:43 +00:00
void tst_QTreeView : : styleOptionViewItem ( )
{
class MyDelegate : public QStyledItemDelegate
{
2015-11-02 15:42:21 +00:00
static QString posToString ( QStyleOptionViewItem : : ViewItemPosition pos ) {
2011-11-29 19:55:26 +00:00
static const char * s_pos [ ] = { " Invalid " , " Beginning " , " Middle " , " End " , " OnlyOne " } ;
return s_pos [ pos ] ;
}
2014-04-07 11:53:36 +00:00
public :
MyDelegate ( )
: QStyledItemDelegate ( ) ,
count ( 0 ) ,
allCollapsed ( false )
{ }
2011-04-27 10:05:43 +00:00
void paint ( QPainter * painter , const QStyleOptionViewItem & option , const QModelIndex & index ) const
{
2015-11-02 15:42:21 +00:00
QStyleOptionViewItem opt ( option ) ;
2011-04-27 10:05:43 +00:00
initStyleOption ( & opt , index ) ;
QVERIFY ( ! opt . text . isEmpty ( ) ) ;
QCOMPARE ( opt . index , index ) ;
//qDebug() << index << opt.text;
if ( allCollapsed )
2015-11-02 15:42:21 +00:00
QCOMPARE ( ! ( opt . features & QStyleOptionViewItem : : Alternate ) , ! ( index . row ( ) % 2 ) ) ;
QCOMPARE ( ! ( opt . features & QStyleOptionViewItem : : HasCheckIndicator ) , ! opt . text . contains ( " Checkable " ) ) ;
2011-04-27 10:05:43 +00:00
if ( opt . text . contains ( " Beginning " ) )
2015-11-02 15:42:21 +00:00
QCOMPARE ( posToString ( opt . viewItemPosition ) , posToString ( QStyleOptionViewItem : : Beginning ) ) ;
2011-04-27 10:05:43 +00:00
if ( opt . text . contains ( " Middle " ) )
2015-11-02 15:42:21 +00:00
QCOMPARE ( posToString ( opt . viewItemPosition ) , posToString ( QStyleOptionViewItem : : Middle ) ) ;
2011-04-27 10:05:43 +00:00
if ( opt . text . contains ( " End " ) )
2015-11-02 15:42:21 +00:00
QCOMPARE ( posToString ( opt . viewItemPosition ) , posToString ( QStyleOptionViewItem : : End ) ) ;
2011-04-27 10:05:43 +00:00
if ( opt . text . contains ( " OnlyOne " ) )
2015-11-02 15:42:21 +00:00
QCOMPARE ( posToString ( opt . viewItemPosition ) , posToString ( QStyleOptionViewItem : : OnlyOne ) ) ;
2011-04-27 10:05:43 +00:00
if ( opt . text . contains ( " Checked " ) )
QCOMPARE ( opt . checkState , Qt : : Checked ) ;
else
QCOMPARE ( opt . checkState , Qt : : Unchecked ) ;
QCOMPARE ( ! ( opt . state & QStyle : : State_Children ) , ! opt . text . contains ( " HasChildren " ) ) ;
QCOMPARE ( ! ! ( opt . state & QStyle : : State_Sibling ) , ! opt . text . contains ( " Last " ) ) ;
QVERIFY ( ! opt . text . contains ( " Assert " ) ) ;
QStyledItemDelegate : : paint ( painter , option , index ) ;
count + + ;
}
mutable int count ;
bool allCollapsed ;
} ;
2016-07-28 16:51:53 +00:00
QTreeView view ;
2011-04-27 10:05:43 +00:00
QStandardItemModel model ;
view . setModel ( & model ) ;
MyDelegate delegate ;
view . setItemDelegate ( & delegate ) ;
model . appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < new QStandardItem ( " Beginning " ) < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Middle " ) < < new QStandardItem ( " Middle " ) < < new QStandardItem ( " End " ) ) ;
2011-04-27 10:05:43 +00:00
QStandardItem * par1 = new QStandardItem ( " Beginning HasChildren " ) ;
model . appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < par1 < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Middle HasChildren " ) < < new QStandardItem ( " Middle HasChildren " ) < < new QStandardItem ( " End HasChildren " ) ) ;
2011-04-27 10:05:43 +00:00
model . appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < new QStandardItem ( " OnlyOne " ) < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Assert " ) < < new QStandardItem ( " Assert " ) < < new QStandardItem ( " Assert " ) ) ;
2011-04-27 10:05:43 +00:00
QStandardItem * checkable = new QStandardItem ( " Checkable " ) ;
checkable - > setCheckable ( true ) ;
QStandardItem * checked = new QStandardItem ( " Checkable Checked " ) ;
2011-11-29 19:55:26 +00:00
checked - > setCheckable ( true ) ;
2011-04-27 10:05:43 +00:00
checked - > setCheckState ( Qt : : Checked ) ;
model . appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < new QStandardItem ( " Beginning " ) < < new QStandardItem ( " Hidden " ) < < checkable < < checked < < new QStandardItem ( " End " ) ) ;
2011-04-27 10:05:43 +00:00
model . appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < new QStandardItem ( " Beginning Last " ) < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Middle Last " ) < < new QStandardItem ( " Middle Last " ) < < new QStandardItem ( " End Last " ) ) ;
2011-04-27 10:05:43 +00:00
par1 - > appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < new QStandardItem ( " Beginning " ) < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Middle " ) < < new QStandardItem ( " Middle " ) < < new QStandardItem ( " End " ) ) ;
2011-04-27 10:05:43 +00:00
QStandardItem * par2 = new QStandardItem ( " Beginning HasChildren " ) ;
par1 - > appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < par2 < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Middle HasChildren " ) < < new QStandardItem ( " Middle HasChildren " ) < < new QStandardItem ( " End HasChildren " ) ) ;
2011-04-27 10:05:43 +00:00
par2 - > appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < new QStandardItem ( " Beginning Last " ) < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Middle Last " ) < < new QStandardItem ( " Middle Last " ) < < new QStandardItem ( " End Last " ) ) ;
2011-04-27 10:05:43 +00:00
QStandardItem * par3 = new QStandardItem ( " Beginning Last " ) ;
par1 - > appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < par3 < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Middle Last " ) < < new QStandardItem ( " Middle Last " ) < < new QStandardItem ( " End Last " ) ) ;
2011-04-27 10:05:43 +00:00
par3 - > appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < new QStandardItem ( " Assert " ) < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Assert " ) < < new QStandardItem ( " Assert " ) < < new QStandardItem ( " Asser " ) ) ;
2011-04-27 10:05:43 +00:00
view . setRowHidden ( 0 , par3 - > index ( ) , true ) ;
par1 - > appendRow ( QList < QStandardItem * > ( )
2011-11-29 19:55:26 +00:00
< < new QStandardItem ( " Assert " ) < < new QStandardItem ( " Hidden " ) < < new QStandardItem ( " Assert " ) < < new QStandardItem ( " Assert " ) < < new QStandardItem ( " Asser " ) ) ;
2011-04-27 10:05:43 +00:00
view . setRowHidden ( 3 , par1 - > index ( ) , true ) ;
2011-11-29 19:55:26 +00:00
view . setColumnHidden ( 1 , true ) ;
const int visibleColumns = 4 ;
const int modelColumns = 5 ;
2011-04-27 10:05:43 +00:00
2011-11-29 19:55:26 +00:00
view . header ( ) - > swapSections ( 2 , 3 ) ;
2011-04-27 10:05:43 +00:00
view . setFirstColumnSpanned ( 2 , QModelIndex ( ) , true ) ;
view . setAlternatingRowColors ( true ) ;
2012-04-12 15:23:19 +00:00
# ifdef QT_BUILD_INTERNAL
{
// Test the rendering to pixmap before painting the widget.
// The rendering to pixmap should not depend on having been
// painted already yet.
delegate . count = 0 ;
QItemSelection sel ( model . index ( 0 , 0 ) , model . index ( 0 , modelColumns - 1 ) ) ;
QRect rect ;
2016-07-28 16:51:53 +00:00
view . d_func ( ) - > renderToPixmap ( sel . indexes ( ) , & rect ) ;
2012-04-19 14:52:02 +00:00
if ( delegate . count ! = visibleColumns ) {
qDebug ( ) < < rect < < view . rect ( ) < < view . isVisible ( ) ;
}
QTRY_COMPARE ( delegate . count , visibleColumns ) ;
2012-04-12 15:23:19 +00:00
}
# endif
2011-04-27 10:05:43 +00:00
delegate . count = 0 ;
delegate . allCollapsed = true ;
view . showMaximized ( ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 13 ) ;
delegate . count = 0 ;
delegate . allCollapsed = false ;
view . expandAll ( ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 13 ) ;
delegate . count = 0 ;
view . collapse ( par2 - > index ( ) ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 4 ) ;
2010-12-03 10:34:09 +00:00
// test that the rendering of drag pixmap sets the correct options too (QTBUG-15834)
# ifdef QT_BUILD_INTERNAL
delegate . count = 0 ;
2011-11-29 19:55:26 +00:00
QItemSelection sel ( model . index ( 0 , 0 ) , model . index ( 0 , modelColumns - 1 ) ) ;
2010-12-03 10:34:09 +00:00
QRect rect ;
2016-07-28 16:51:53 +00:00
view . d_func ( ) - > renderToPixmap ( sel . indexes ( ) , & rect ) ;
2012-04-19 14:52:02 +00:00
if ( delegate . count ! = visibleColumns ) {
qDebug ( ) < < rect < < view . rect ( ) < < view . isVisible ( ) ;
}
QTRY_COMPARE ( delegate . count , visibleColumns ) ;
2010-12-03 10:34:09 +00:00
# endif
2011-04-27 10:05:43 +00:00
//test dynamic models
{
delegate . count = 0 ;
QStandardItemModel model2 ;
QStandardItem * item0 = new QStandardItem ( " OnlyOne Last " ) ;
model2 . appendRow ( QList < QStandardItem * > ( ) < < item0 ) ;
view . setModel ( & model2 ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 1 ) ;
QApplication : : processEvents ( ) ;
QStandardItem * item00 = new QStandardItem ( " OnlyOne Last " ) ;
item0 - > appendRow ( QList < QStandardItem * > ( ) < < item00 ) ;
item0 - > setText ( " OnlyOne Last HasChildren " ) ;
QApplication : : processEvents ( ) ;
delegate . count = 0 ;
view . expandAll ( ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 2 ) ;
QApplication : : processEvents ( ) ;
QStandardItem * item1 = new QStandardItem ( " OnlyOne Last " ) ;
delegate . count = 0 ;
item0 - > setText ( " OnlyOne HasChildren " ) ;
model2 . appendRow ( QList < QStandardItem * > ( ) < < item1 ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 3 ) ;
QApplication : : processEvents ( ) ;
QStandardItem * item01 = new QStandardItem ( " OnlyOne Last " ) ;
delegate . count = 0 ;
item00 - > setText ( " OnlyOne " ) ;
item0 - > appendRow ( QList < QStandardItem * > ( ) < < item01 ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 4 ) ;
QApplication : : processEvents ( ) ;
QStandardItem * item000 = new QStandardItem ( " OnlyOne Last " ) ;
delegate . count = 0 ;
item00 - > setText ( " OnlyOne HasChildren " ) ;
item00 - > appendRow ( QList < QStandardItem * > ( ) < < item000 ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 5 ) ;
QApplication : : processEvents ( ) ;
delegate . count = 0 ;
item0 - > removeRow ( 0 ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 3 ) ;
QApplication : : processEvents ( ) ;
item00 = new QStandardItem ( " OnlyOne " ) ;
item0 - > insertRow ( 0 , QList < QStandardItem * > ( ) < < item00 ) ;
QApplication : : processEvents ( ) ;
delegate . count = 0 ;
view . expandAll ( ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 4 ) ;
QApplication : : processEvents ( ) ;
delegate . count = 0 ;
item0 - > removeRow ( 1 ) ;
item00 - > setText ( " OnlyOne Last " ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 3 ) ;
QApplication : : processEvents ( ) ;
delegate . count = 0 ;
item0 - > removeRow ( 0 ) ;
item0 - > setText ( " OnlyOne " ) ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 2 ) ;
QApplication : : processEvents ( ) ;
//with hidden items
item0 - > setText ( " OnlyOne HasChildren " ) ;
item00 = new QStandardItem ( " OnlyOne " ) ;
item0 - > appendRow ( QList < QStandardItem * > ( ) < < item00 ) ;
item01 = new QStandardItem ( " Assert " ) ;
item0 - > appendRow ( QList < QStandardItem * > ( ) < < item01 ) ;
view . setRowHidden ( 1 , item0 - > index ( ) , true ) ;
view . expandAll ( ) ;
QStandardItem * item02 = new QStandardItem ( " OnlyOne Last " ) ;
item0 - > appendRow ( QList < QStandardItem * > ( ) < < item02 ) ;
delegate . count = 0 ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 4 ) ;
QApplication : : processEvents ( ) ;
item0 - > removeRow ( 2 ) ;
item00 - > setText ( " OnlyOne Last " ) ;
delegate . count = 0 ;
QApplication : : processEvents ( ) ;
QTRY_VERIFY ( delegate . count > = 3 ) ;
QApplication : : processEvents ( ) ;
item00 - > setText ( " OnlyOne " ) ;
item0 - > insertRow ( 2 , new QStandardItem ( " OnlyOne Last " ) ) ;
view . collapse ( item0 - > index ( ) ) ;
item0 - > removeRow ( 0 ) ;
delegate . count = 0 ;
QTRY_VERIFY ( delegate . count > = 2 ) ;
QApplication : : processEvents ( ) ;
item0 - > removeRow ( 1 ) ;
item0 - > setText ( " OnlyOne " ) ;
delegate . count = 0 ;
QTRY_VERIFY ( delegate . count > = 2 ) ;
QApplication : : processEvents ( ) ;
}
}
class task174627_TreeView : public QTreeView
{
Q_OBJECT
protected slots :
void currentChanged ( const QModelIndex & current , const QModelIndex & )
{ emit currentChanged ( current ) ; }
signals :
void currentChanged ( const QModelIndex & ) ;
} ;
void tst_QTreeView : : task174627_moveLeftToRoot ( )
{
QStandardItemModel model ;
QStandardItem * item1 = new QStandardItem ( QString ( " item 1 " ) ) ;
model . invisibleRootItem ( ) - > appendRow ( item1 ) ;
QStandardItem * item2 = new QStandardItem ( QString ( " item 2 " ) ) ;
item1 - > appendRow ( item2 ) ;
task174627_TreeView view ;
view . setModel ( & model ) ;
view . setRootIndex ( item1 - > index ( ) ) ;
view . setCurrentIndex ( item2 - > index ( ) ) ;
QSignalSpy spy ( & view , SIGNAL ( currentChanged ( QModelIndex ) ) ) ;
QTest : : keyClick ( & view , Qt : : Key_Left ) ;
QCOMPARE ( spy . count ( ) , 0 ) ;
}
void tst_QTreeView : : task171902_expandWith1stColHidden ( )
{
//the task was: if the first column of a treeview is hidden, the expanded state is not correctly restored
QStandardItemModel model ;
QStandardItem root ( " root " ) , root2 ( " root " ) ,
subitem ( " subitem " ) , subitem2 ( " subitem " ) ,
subsubitem ( " subsubitem " ) , subsubitem2 ( " subsubitem " ) ;
model . appendRow ( QList < QStandardItem * > ( ) < < & root < < & root2 ) ;
root . appendRow ( QList < QStandardItem * > ( ) < < & subitem < < & subitem2 ) ;
subitem . appendRow ( QList < QStandardItem * > ( ) < < & subsubitem < < & subsubitem2 ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . setColumnHidden ( 0 , true ) ;
view . expandAll ( ) ;
view . collapse ( root . index ( ) ) ;
view . expand ( root . index ( ) ) ;
QCOMPARE ( view . isExpanded ( root . index ( ) ) , true ) ;
QCOMPARE ( view . isExpanded ( subitem . index ( ) ) , true ) ;
}
void tst_QTreeView : : task203696_hidingColumnsAndRowsn ( )
{
QTreeView view ;
QStandardItemModel * model = new QStandardItemModel ( 0 , 3 , & view ) ;
2015-10-16 07:38:51 +00:00
for ( int i = 0 ; i < 3 ; + + i ) {
const QString prefix = QLatin1String ( " row " ) + QString : : number ( i ) + QLatin1String ( " col " ) ;
2011-04-27 10:05:43 +00:00
model - > insertRow ( model - > rowCount ( ) ) ;
for ( int j = 0 ; j < model - > columnCount ( ) ; + + j )
2015-10-16 07:38:51 +00:00
model - > setData ( model - > index ( i , j ) , prefix + QString : : number ( j ) ) ;
2011-04-27 10:05:43 +00:00
}
view . setModel ( model ) ;
view . show ( ) ;
view . setColumnHidden ( 0 , true ) ;
view . setRowHidden ( 0 , QModelIndex ( ) , true ) ;
QCOMPARE ( view . indexAt ( QPoint ( 0 , 0 ) ) , model - > index ( 1 , 1 ) ) ;
}
void tst_QTreeView : : addRowsWhileSectionsAreHidden ( )
{
QTreeView view ;
for ( int pass = 1 ; pass < = 2 ; + + pass ) {
QStandardItemModel * model = new QStandardItemModel ( 6 , pass , & view ) ;
view . setModel ( model ) ;
view . show ( ) ;
2018-04-09 10:37:33 +00:00
QVERIFY ( QTest : : qWaitForWindowActive ( & view ) ) ;
2011-04-27 10:05:43 +00:00
int i ;
for ( i = 0 ; i < 3 ; + + i )
{
model - > insertRow ( model - > rowCount ( ) ) ;
2015-10-16 07:38:51 +00:00
const QString prefix = QLatin1String ( " row " ) + QString : : number ( i ) + QLatin1String ( " col " ) ;
2011-04-27 10:05:43 +00:00
for ( int j = 0 ; j < model - > columnCount ( ) ; + + j ) {
2015-10-16 07:38:51 +00:00
model - > setData ( model - > index ( i , j ) , prefix + QString : : number ( j ) ) ;
2011-04-27 10:05:43 +00:00
}
}
int col ;
for ( col = 0 ; col < pass ; + + col )
view . setColumnHidden ( col , true ) ;
for ( i = 3 ; i < 6 ; + + i )
{
model - > insertRow ( model - > rowCount ( ) ) ;
2015-10-16 07:38:51 +00:00
const QString prefix = QLatin1String ( " row " ) + QString : : number ( i ) + QLatin1String ( " col " ) ;
2011-04-27 10:05:43 +00:00
for ( int j = 0 ; j < model - > columnCount ( ) ; + + j ) {
2015-10-16 07:38:51 +00:00
model - > setData ( model - > index ( i , j ) , prefix + QString : : number ( j ) ) ;
2011-04-27 10:05:43 +00:00
}
}
for ( col = 0 ; col < pass ; + + col )
view . setColumnHidden ( col , false ) ;
2018-04-09 10:37:33 +00:00
auto allVisualRectsValid = [ ] ( QTreeView * view , QStandardItemModel * model ) {
for ( int i = 0 ; i < 6 ; + + i ) {
if ( ! view - > visualRect ( model - > index ( i , 0 ) ) . isValid ( ) )
return false ;
}
return true ;
} ;
QTRY_VERIFY ( allVisualRectsValid ( & view , model ) ) ;
2011-04-27 10:05:43 +00:00
delete model ;
}
}
void tst_QTreeView : : task216717_updateChildren ( )
{
class Tree : public QTreeWidget {
protected :
void paintEvent ( QPaintEvent * e )
{
QTreeWidget : : paintEvent ( e ) ;
refreshed = true ;
}
public :
bool refreshed ;
} tree ;
tree . show ( ) ;
2012-07-24 12:29:01 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & tree ) ) ;
2011-04-27 10:05:43 +00:00
tree . refreshed = false ;
QTreeWidgetItem * parent = new QTreeWidgetItem ( QStringList ( ) < < " parent " ) ;
tree . addTopLevelItem ( parent ) ;
QTRY_VERIFY ( tree . refreshed ) ;
tree . refreshed = false ;
parent - > addChild ( new QTreeWidgetItem ( QStringList ( ) < < " child " ) ) ;
QTRY_VERIFY ( tree . refreshed ) ;
}
void tst_QTreeView : : task220298_selectColumns ( )
{
//this is a very simple 3x3 model where the internalId of the index are different for each cell
class Model : public QAbstractTableModel
{ public :
virtual int columnCount ( const QModelIndex & parent = QModelIndex ( ) ) const
{ return parent . isValid ( ) ? 0 : 3 ; }
virtual int rowCount ( const QModelIndex & parent = QModelIndex ( ) ) const
{ return parent . isValid ( ) ? 0 : 3 ; }
virtual QVariant data ( const QModelIndex & index , int role = Qt : : DisplayRole ) const
{
2015-10-16 07:38:51 +00:00
if ( role = = Qt : : DisplayRole ) {
return QVariant ( QString : : number ( index . column ( ) ) + QLatin1Char ( ' - ' )
+ QString : : number ( index . row ( ) ) ) ;
}
2011-04-27 10:05:43 +00:00
return QVariant ( ) ;
}
virtual QModelIndex index ( int row , int column , const QModelIndex & parent = QModelIndex ( ) ) const
{
return hasIndex ( row , column , parent ) ? createIndex ( row , column , column * 10 + row ) : QModelIndex ( ) ;
}
} ;
class TreeView : public QTreeView { public : QModelIndexList selectedIndexes ( ) const { return QTreeView : : selectedIndexes ( ) ; } } view ;
Model model ;
view . setModel ( & model ) ;
view . show ( ) ;
2018-04-09 10:37:33 +00:00
QVERIFY ( QTest : : qWaitForWindowActive ( & view ) ) ;
2011-04-27 10:05:43 +00:00
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , 0 ,
view . visualRect ( view . model ( ) - > index ( 1 , 1 ) ) . center ( ) ) ;
2018-04-09 10:37:33 +00:00
QTRY_VERIFY ( view . selectedIndexes ( ) . contains ( view . model ( ) - > index ( 1 , 2 ) ) ) ;
2011-04-27 10:05:43 +00:00
QVERIFY ( view . selectedIndexes ( ) . contains ( view . model ( ) - > index ( 1 , 1 ) ) ) ;
QVERIFY ( view . selectedIndexes ( ) . contains ( view . model ( ) - > index ( 1 , 0 ) ) ) ;
}
void tst_QTreeView : : task224091_appendColumns ( )
{
QStandardItemModel * model = new QStandardItemModel ( ) ;
QWidget * topLevel = new QWidget ;
2012-12-28 16:35:54 +00:00
setFrameless ( topLevel ) ;
2011-04-27 10:05:43 +00:00
QTreeView * treeView = new QTreeView ( topLevel ) ;
treeView - > setModel ( model ) ;
topLevel - > show ( ) ;
treeView - > resize ( 50 , 50 ) ;
2012-07-18 11:12:59 +00:00
qApp - > setActiveWindow ( topLevel ) ;
QVERIFY ( QTest : : qWaitForWindowActive ( topLevel ) ) ;
2011-04-27 10:05:43 +00:00
2018-04-09 10:37:33 +00:00
QVERIFY ( ! treeView - > verticalScrollBar ( ) - > isVisible ( ) ) ;
2011-04-27 10:05:43 +00:00
QList < QStandardItem * > projlist ;
for ( int k = 0 ; k < 10 ; + + k )
2015-10-16 07:38:51 +00:00
projlist . append ( new QStandardItem ( QLatin1String ( " Top Level " ) + QString : : number ( k ) ) ) ;
2011-04-27 10:05:43 +00:00
model - > appendColumn ( projlist ) ;
model - > invisibleRootItem ( ) - > appendRow ( new QStandardItem ( " end " ) ) ;
QTRY_VERIFY ( treeView - > verticalScrollBar ( ) - > isVisible ( ) ) ;
delete topLevel ;
delete model ;
}
void tst_QTreeView : : task211293_removeRootIndex ( )
{
QTreeView view ;
QStandardItemModel model ;
QStandardItem * A1 = new QStandardItem ( " A1 " ) ;
QStandardItem * B11 = new QStandardItem ( " B1.1 " ) ;
QStandardItem * C111 = new QStandardItem ( " C1.1.1 " ) ;
QStandardItem * C112 = new QStandardItem ( " C1.1.2 " ) ;
QStandardItem * C113 = new QStandardItem ( " C1.1.3 " ) ;
QStandardItem * D1131 = new QStandardItem ( " D1.1.3.1 " ) ;
QStandardItem * E11311 = new QStandardItem ( " E1.1.3.1.1 " ) ;
QStandardItem * E11312 = new QStandardItem ( " E1.1.3.1.2 " ) ;
QStandardItem * E11313 = new QStandardItem ( " E1.1.3.1.3 " ) ;
QStandardItem * E11314 = new QStandardItem ( " E1.1.3.1.4 " ) ;
QStandardItem * D1132 = new QStandardItem ( " D1.1.3.2 " ) ;
QStandardItem * E11321 = new QStandardItem ( " E1.1.3.2.1 " ) ;
D1132 - > appendRow ( E11321 ) ;
D1131 - > appendRow ( E11311 ) ;
D1131 - > appendRow ( E11312 ) ;
D1131 - > appendRow ( E11313 ) ;
D1131 - > appendRow ( E11314 ) ;
C113 - > appendRow ( D1131 ) ;
C113 - > appendRow ( D1132 ) ;
B11 - > appendRow ( C111 ) ;
B11 - > appendRow ( C112 ) ;
B11 - > appendRow ( C113 ) ;
A1 - > appendRow ( B11 ) ;
model . appendRow ( A1 ) ;
view . setModel ( & model ) ;
view . setRootIndex ( model . indexFromItem ( B11 ) ) ;
view . setExpanded ( model . indexFromItem ( B11 ) , true ) ;
view . setCurrentIndex ( model . indexFromItem ( E11314 ) ) ;
view . setExpanded ( model . indexFromItem ( E11314 ) , true ) ;
view . show ( ) ;
qApp - > processEvents ( ) ;
model . removeRows ( 0 , 1 ) ;
qApp - > processEvents ( ) ;
}
void tst_QTreeView : : task225539_deleteModel ( )
{
QTreeView treeView ;
treeView . show ( ) ;
QStandardItemModel * model = new QStandardItemModel ( & treeView ) ;
QStandardItem * parentItem = model - > invisibleRootItem ( ) ;
QStandardItem * item = new QStandardItem ( QString ( " item " ) ) ;
parentItem - > appendRow ( item ) ;
treeView . setModel ( model ) ;
QCOMPARE ( item - > index ( ) , treeView . indexAt ( QPoint ( ) ) ) ;
delete model ;
QVERIFY ( ! treeView . indexAt ( QPoint ( ) ) . isValid ( ) ) ;
}
void tst_QTreeView : : task230123_setItemsExpandable ( )
{
//let's check that we prevent the expansion inside a treeview
//when the property is set.
QTreeWidget tree ;
QTreeWidgetItem root ;
QTreeWidgetItem child ;
root . addChild ( & child ) ;
tree . addTopLevelItem ( & root ) ;
tree . setCurrentItem ( & root ) ;
tree . setItemsExpandable ( false ) ;
QTest : : keyClick ( & tree , Qt : : Key_Plus ) ;
QVERIFY ( ! root . isExpanded ( ) ) ;
QTest : : keyClick ( & tree , Qt : : Key_Right ) ;
QVERIFY ( ! root . isExpanded ( ) ) ;
tree . setItemsExpandable ( true ) ;
QTest : : keyClick ( & tree , Qt : : Key_Plus ) ;
QVERIFY ( root . isExpanded ( ) ) ;
QTest : : keyClick ( & tree , Qt : : Key_Minus ) ;
QVERIFY ( ! root . isExpanded ( ) ) ;
QTest : : keyClick ( & tree , Qt : : Key_Right ) ;
QVERIFY ( root . isExpanded ( ) ) ;
QTest : : keyClick ( & tree , Qt : : Key_Left ) ;
QVERIFY ( ! root . isExpanded ( ) ) ;
QTest : : keyClick ( & tree , Qt : : Key_Right ) ;
QVERIFY ( root . isExpanded ( ) ) ;
const bool navToChild = tree . style ( ) - > styleHint ( QStyle : : SH_ItemView_ArrowKeysNavigateIntoChildren , 0 , & tree ) ;
QTest : : keyClick ( & tree , Qt : : Key_Right ) ;
QCOMPARE ( tree . currentItem ( ) , navToChild ? & child : & root ) ;
QTest : : keyClick ( & tree , Qt : : Key_Right ) ;
//it should not be expanded: it has no leaf
QCOMPARE ( child . isExpanded ( ) , false ) ;
QTest : : keyClick ( & tree , Qt : : Key_Left ) ;
QCOMPARE ( tree . currentItem ( ) , & root ) ;
QTest : : keyClick ( & tree , Qt : : Key_Left ) ;
QVERIFY ( ! root . isExpanded ( ) ) ;
}
void tst_QTreeView : : task202039_closePersistentEditor ( )
{
QStandardItemModel model ( 1 , 1 ) ;
QTreeView view ;
view . setModel ( & model ) ;
QModelIndex current = model . index ( 0 , 0 ) ;
QTest : : mousePress ( view . viewport ( ) , Qt : : LeftButton , 0 , view . visualRect ( current ) . center ( ) ) ;
QTest : : mouseDClick ( view . viewport ( ) , Qt : : LeftButton , 0 , view . visualRect ( current ) . center ( ) ) ;
QCOMPARE ( view . currentIndex ( ) , current ) ;
QVERIFY ( view . indexWidget ( current ) ) ;
view . closePersistentEditor ( current ) ;
2015-07-30 13:16:36 +00:00
QVERIFY ( ! view . indexWidget ( current ) ) ;
2011-04-27 10:05:43 +00:00
//here was the bug: closing the persistent editor would not reset the state
//and it was impossible to go into editinon again
QTest : : mousePress ( view . viewport ( ) , Qt : : LeftButton , 0 , view . visualRect ( current ) . center ( ) ) ;
QTest : : mouseDClick ( view . viewport ( ) , Qt : : LeftButton , 0 , view . visualRect ( current ) . center ( ) ) ;
QCOMPARE ( view . currentIndex ( ) , current ) ;
QVERIFY ( view . indexWidget ( current ) ) ;
}
void tst_QTreeView : : task238873_avoidAutoReopening ( )
{
QStandardItemModel model ;
QStandardItem item0 ( " row 0 " ) ;
QStandardItem item1 ( " row 1 " ) ;
QStandardItem item2 ( " row 2 " ) ;
QStandardItem item3 ( " row 3 " ) ;
model . appendColumn ( QList < QStandardItem * > ( ) < < & item0 < < & item1 < < & item2 < < & item3 ) ;
QStandardItem child ( " child " ) ;
item1 . appendRow ( & child ) ;
QTreeView view ;
view . setModel ( & model ) ;
view . show ( ) ;
view . expandAll ( ) ;
2018-04-09 10:37:33 +00:00
QVERIFY ( QTest : : qWaitForWindowActive ( & view ) ) ;
2011-04-27 10:05:43 +00:00
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , 0 , view . visualRect ( child . index ( ) ) . center ( ) ) ;
2018-04-09 10:37:33 +00:00
QTRY_COMPARE ( view . currentIndex ( ) , child . index ( ) ) ;
2011-04-27 10:05:43 +00:00
view . setExpanded ( item1 . index ( ) , false ) ;
QTest : : qWait ( 500 ) ; //enough to trigger the delayedAutoScroll timer
QVERIFY ( ! view . isExpanded ( item1 . index ( ) ) ) ;
}
void tst_QTreeView : : task244304_clickOnDecoration ( )
{
QTreeView view ;
QStandardItemModel model ;
QStandardItem item0 ( " row 0 " ) ;
QStandardItem item00 ( " row 0 " ) ;
item0 . appendRow ( & item00 ) ;
QStandardItem item1 ( " row 1 " ) ;
model . appendColumn ( QList < QStandardItem * > ( ) < < & item0 < < & item1 ) ;
view . setModel ( & model ) ;
QVERIFY ( ! view . currentIndex ( ) . isValid ( ) ) ;
QRect rect = view . visualRect ( item0 . index ( ) ) ;
//we click on the decoration
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , 0 , rect . topLeft ( ) + QPoint ( - rect . left ( ) / 2 , rect . height ( ) / 2 ) ) ;
QVERIFY ( ! view . currentIndex ( ) . isValid ( ) ) ;
QVERIFY ( view . isExpanded ( item0 . index ( ) ) ) ;
rect = view . visualRect ( item1 . index ( ) ) ;
//the item has no decoration, it should get selected
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , 0 , rect . topLeft ( ) + QPoint ( - rect . left ( ) / 2 , rect . height ( ) / 2 ) ) ;
QCOMPARE ( view . currentIndex ( ) , item1 . index ( ) ) ;
}
void tst_QTreeView : : task246536_scrollbarsNotWorking ( )
{
struct MyObject : public QObject
{
MyObject ( ) : count ( 0 )
{
}
bool eventFilter ( QObject * , QEvent * e )
{
if ( e - > type ( ) = = QEvent : : Paint )
count + + ;
return false ;
}
int count ;
} ;
QTreeView tree ;
MyObject o ;
tree . viewport ( ) - > installEventFilter ( & o ) ;
QStandardItemModel model ;
tree . setModel ( & model ) ;
tree . show ( ) ;
2012-07-24 12:29:01 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & tree ) ) ;
2011-04-27 10:05:43 +00:00
QList < QStandardItem * > items ;
for ( int i = 0 ; i < 100 ; + + i ) {
2015-10-16 07:38:51 +00:00
items < < new QStandardItem ( QLatin1String ( " item " ) + QString : : number ( i ) ) ;
2011-04-27 10:05:43 +00:00
}
model . invisibleRootItem ( ) - > appendColumn ( items ) ;
QTest : : qWait ( 100 ) ;
o . count = 0 ;
tree . verticalScrollBar ( ) - > setValue ( 50 ) ;
QTRY_VERIFY ( o . count > 0 ) ;
}
void tst_QTreeView : : task250683_wrongSectionSize ( )
{
2014-01-23 15:04:16 +00:00
QStandardItemModel model ;
populateFakeDirModel ( & model ) ;
2011-04-27 10:05:43 +00:00
QTreeView treeView ;
2012-05-06 10:54:24 +00:00
treeView . header ( ) - > setSectionResizeMode ( QHeaderView : : ResizeToContents ) ;
2011-04-27 10:05:43 +00:00
treeView . setModel ( & model ) ;
treeView . setColumnHidden ( 2 , true ) ;
treeView . setColumnHidden ( 3 , true ) ;
treeView . show ( ) ;
2018-04-09 10:37:33 +00:00
QVERIFY ( QTest : : qWaitForWindowActive ( & treeView ) ) ;
2011-04-27 10:05:43 +00:00
QCOMPARE ( treeView . header ( ) - > sectionSize ( 0 ) + treeView . header ( ) - > sectionSize ( 1 ) , treeView . viewport ( ) - > width ( ) ) ;
}
void tst_QTreeView : : task239271_addRowsWithFirstColumnHidden ( )
{
class MyDelegate : public QStyledItemDelegate
{
public :
void paint ( QPainter * painter , const QStyleOptionViewItem & option , const QModelIndex & index ) const
{
paintedIndexes < < index ;
QStyledItemDelegate : : paint ( painter , option , index ) ;
}
mutable QSet < QModelIndex > paintedIndexes ;
} ;
QTreeView view ;
QStandardItemModel model ;
view . setModel ( & model ) ;
MyDelegate delegate ;
view . setItemDelegate ( & delegate ) ;
QStandardItem root0 ( " root0 " ) , root1 ( " root1 " ) ;
model . invisibleRootItem ( ) - > appendRow ( QList < QStandardItem * > ( ) < < & root0 < < & root1 ) ;
QStandardItem sub0 ( " sub0 " ) , sub00 ( " sub00 " ) ;
root0 . appendRow ( QList < QStandardItem * > ( ) < < & sub0 < < & sub00 ) ;
view . expand ( root0 . index ( ) ) ;
view . hideColumn ( 0 ) ;
view . show ( ) ;
2012-07-24 12:29:01 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & view ) ) ;
2011-04-27 10:05:43 +00:00
delegate . paintedIndexes . clear ( ) ;
QStandardItem sub1 ( " sub1 " ) , sub11 ( " sub11 " ) ;
root0 . appendRow ( QList < QStandardItem * > ( ) < < & sub1 < < & sub11 ) ;
//items in the 2nd column should have been painted
QTRY_VERIFY ( ! delegate . paintedIndexes . isEmpty ( ) ) ;
QVERIFY ( delegate . paintedIndexes . contains ( sub00 . index ( ) ) ) ;
QVERIFY ( delegate . paintedIndexes . contains ( sub11 . index ( ) ) ) ;
}
void tst_QTreeView : : task254234_proxySort ( )
{
//based on tst_QTreeView::sortByColumn
// it used not to work when setting the source of a proxy after enabling sorting
QTreeView view ;
QStandardItemModel model ( 4 , 2 ) ;
model . setItem ( 0 , 0 , new QStandardItem ( " b " ) ) ;
model . setItem ( 1 , 0 , new QStandardItem ( " d " ) ) ;
model . setItem ( 2 , 0 , new QStandardItem ( " c " ) ) ;
model . setItem ( 3 , 0 , new QStandardItem ( " a " ) ) ;
model . setItem ( 0 , 1 , new QStandardItem ( " e " ) ) ;
model . setItem ( 1 , 1 , new QStandardItem ( " g " ) ) ;
model . setItem ( 2 , 1 , new QStandardItem ( " h " ) ) ;
model . setItem ( 3 , 1 , new QStandardItem ( " f " ) ) ;
2018-10-26 18:38:58 +00:00
view . sortByColumn ( 1 , Qt : : DescendingOrder ) ;
2011-04-27 10:05:43 +00:00
view . setSortingEnabled ( true ) ;
QSortFilterProxyModel proxy ;
proxy . setDynamicSortFilter ( true ) ;
view . setModel ( & proxy ) ;
proxy . setSourceModel ( & model ) ;
QCOMPARE ( view . header ( ) - > sortIndicatorSection ( ) , 1 ) ;
QCOMPARE ( view . model ( ) - > data ( view . model ( ) - > index ( 0 , 1 ) ) . toString ( ) , QString : : fromLatin1 ( " h " ) ) ;
QCOMPARE ( view . model ( ) - > data ( view . model ( ) - > index ( 1 , 1 ) ) . toString ( ) , QString : : fromLatin1 ( " g " ) ) ;
}
class TreeView : public QTreeView
{
Q_OBJECT
public slots :
void handleSelectionChanged ( )
{
//let's select the last item
QModelIndex idx = model ( ) - > index ( 0 , 0 ) ;
selectionModel ( ) - > select ( QItemSelection ( idx , idx ) , QItemSelectionModel : : Select ) ;
2012-10-16 09:08:13 +00:00
disconnect ( selectionModel ( ) , SIGNAL ( selectionChanged ( QItemSelection , QItemSelection ) ) , this , SLOT ( handleSelectionChanged ( ) ) ) ;
2011-04-27 10:05:43 +00:00
}
} ;
void tst_QTreeView : : task248022_changeSelection ( )
{
//we check that changing the selection between the mouse press and the mouse release
//works correctly
TreeView view ;
QStringList list = QStringList ( ) < < " 1 " < < " 2 " ;
QStringListModel model ( list ) ;
view . setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
view . setModel ( & model ) ;
2012-10-16 09:08:13 +00:00
view . connect ( view . selectionModel ( ) , SIGNAL ( selectionChanged ( QItemSelection , QItemSelection ) ) , SLOT ( handleSelectionChanged ( ) ) ) ;
2011-04-27 10:05:43 +00:00
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , 0 , view . visualRect ( model . index ( 1 ) ) . center ( ) ) ;
QCOMPARE ( view . selectionModel ( ) - > selectedIndexes ( ) . count ( ) , list . count ( ) ) ;
}
void tst_QTreeView : : task245654_changeModelAndExpandAll ( )
{
QTreeView view ;
2017-01-14 10:45:25 +00:00
QScopedPointer < QStandardItemModel > model ( new QStandardItemModel ) ;
2011-04-27 10:05:43 +00:00
QStandardItem * top = new QStandardItem ( " top " ) ;
QStandardItem * sub = new QStandardItem ( " sub " ) ;
top - > appendRow ( sub ) ;
model - > appendRow ( top ) ;
2017-01-14 10:45:25 +00:00
view . setModel ( model . data ( ) ) ;
2011-04-27 10:05:43 +00:00
view . expandAll ( ) ;
QApplication : : processEvents ( ) ;
QVERIFY ( view . isExpanded ( top - > index ( ) ) ) ;
//now let's try to delete the model
//then repopulate and expand again
2017-01-14 10:45:25 +00:00
model . reset ( new QStandardItemModel ) ;
2011-04-27 10:05:43 +00:00
top = new QStandardItem ( " top " ) ;
sub = new QStandardItem ( " sub " ) ;
top - > appendRow ( sub ) ;
model - > appendRow ( top ) ;
2017-01-14 10:45:25 +00:00
view . setModel ( model . data ( ) ) ;
2011-04-27 10:05:43 +00:00
view . expandAll ( ) ;
QApplication : : processEvents ( ) ;
QVERIFY ( view . isExpanded ( top - > index ( ) ) ) ;
}
void tst_QTreeView : : doubleClickedWithSpans ( )
{
QTreeView view ;
QStandardItemModel model ( 1 , 2 ) ;
view . setModel ( & model ) ;
view . setFirstColumnSpanned ( 0 , QModelIndex ( ) , true ) ;
view . show ( ) ;
QApplication : : setActiveWindow ( & view ) ;
2012-07-24 12:29:01 +00:00
QVERIFY ( QTest : : qWaitForWindowActive ( & view ) ) ;
QVERIFY ( view . isActiveWindow ( ) ) ;
2011-04-27 10:05:43 +00:00
QPoint p ( 10 , 10 ) ;
QCOMPARE ( view . indexAt ( p ) , model . index ( 0 , 0 ) ) ;
QSignalSpy spy ( & view , SIGNAL ( doubleClicked ( QModelIndex ) ) ) ;
QTest : : mousePress ( view . viewport ( ) , Qt : : LeftButton , 0 , p ) ;
QTest : : mouseDClick ( view . viewport ( ) , Qt : : LeftButton , 0 , p ) ;
QTest : : mouseRelease ( view . viewport ( ) , Qt : : LeftButton , 0 , p ) ;
QCOMPARE ( spy . count ( ) , 1 ) ;
//let's click on the 2nd column
p . setX ( p . x ( ) + view . header ( ) - > sectionSize ( 0 ) ) ;
QCOMPARE ( view . indexAt ( p ) , model . index ( 0 , 0 ) ) ;
//end the previous edition
QTest : : mouseClick ( view . viewport ( ) , Qt : : LeftButton , 0 , p ) ;
QTest : : mousePress ( view . viewport ( ) , Qt : : LeftButton , 0 , p ) ;
QTest : : mouseDClick ( view . viewport ( ) , Qt : : LeftButton , 0 , p ) ;
QTest : : mouseRelease ( view . viewport ( ) , Qt : : LeftButton , 0 , p ) ;
QTRY_COMPARE ( spy . count ( ) , 2 ) ;
}
void tst_QTreeView : : taskQTBUG_6450_selectAllWith1stColumnHidden ( )
{
QTreeWidget tree ;
tree . setSelectionMode ( QAbstractItemView : : MultiSelection ) ;
tree . setColumnCount ( 2 ) ;
QList < QTreeWidgetItem * > items ;
const int nrRows = 10 ;
for ( int i = 0 ; i < nrRows ; + + i ) {
2015-10-16 07:38:51 +00:00
const QString text = QLatin1String ( " item: " ) + QString : : number ( i ) ;
items . append ( new QTreeWidgetItem ( ( QTreeWidget * ) 0 , QStringList ( text ) ) ) ;
2011-04-27 10:05:43 +00:00
items . last ( ) - > setText ( 1 , QString ( " is an item " ) ) ;
}
tree . insertTopLevelItems ( 0 , items ) ;
tree . hideColumn ( 0 ) ;
tree . selectAll ( ) ;
QVERIFY ( tree . selectionModel ( ) - > hasSelection ( ) ) ;
for ( int i = 0 ; i < nrRows ; + + i )
QVERIFY ( tree . selectionModel ( ) - > isRowSelected ( i , QModelIndex ( ) ) ) ;
}
class TreeViewQTBUG_9216 : public QTreeView
{
Q_OBJECT
public :
void paintEvent ( QPaintEvent * event )
{
if ( doCompare )
QCOMPARE ( event - > rect ( ) , viewport ( ) - > rect ( ) ) ;
QTreeView : : paintEvent ( event ) ;
painted + + ;
}
int painted ;
bool doCompare ;
} ;
void tst_QTreeView : : taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint ( )
{
QStandardItemModel model ( 10 , 10 , this ) ;
2015-10-16 07:38:51 +00:00
for ( int row = 0 ; row < 10 ; row + + ) {
const QString prefix = QLatin1String ( " row " ) + QString : : number ( row ) + QLatin1String ( " , col " ) ;
2011-04-27 10:05:43 +00:00
for ( int col = 0 ; col < 10 ; col + + )
2015-10-16 07:38:51 +00:00
model . setItem ( row , col , new QStandardItem ( prefix + QString : : number ( col ) ) ) ;
}
2011-04-27 10:05:43 +00:00
TreeViewQTBUG_9216 view ;
view . setUniformRowHeights ( true ) ;
view . setModel ( & model ) ;
view . painted = 0 ;
view . doCompare = false ;
view . show ( ) ;
2012-07-24 12:29:01 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & view ) ) ;
2011-04-27 10:05:43 +00:00
QTRY_VERIFY ( view . painted > 0 ) ;
QTest : : qWait ( 100 ) ; // This one is needed to make the test fail before the patch.
view . painted = 0 ;
view . doCompare = true ;
model . setData ( model . index ( 0 , 0 ) , QVariant ( QSize ( 50 , 50 ) ) , Qt : : SizeHintRole ) ;
QTRY_VERIFY ( view . painted > 0 ) ;
}
void tst_QTreeView : : keyboardNavigationWithDisabled ( )
{
QWidget topLevel ;
QTreeView view ( & topLevel ) ;
QStandardItemModel model ( 90 , 0 ) ;
for ( int i = 0 ; i < 90 ; i + + ) {
model . setItem ( i , new QStandardItem ( QString : : number ( i ) ) ) ;
model . item ( i ) - > setEnabled ( i % 6 = = 0 ) ;
}
view . setModel ( & model ) ;
view . resize ( 200 , view . visualRect ( model . index ( 0 , 0 ) ) . height ( ) * 10 ) ;
topLevel . show ( ) ;
QApplication : : setActiveWindow ( & topLevel ) ;
2012-07-18 11:12:59 +00:00
QVERIFY ( QTest : : qWaitForWindowActive ( & topLevel ) ) ;
QVERIFY ( topLevel . isActiveWindow ( ) ) ;
2011-04-27 10:05:43 +00:00
view . setCurrentIndex ( model . index ( 1 , 0 ) ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Up ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 0 , 0 ) ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Down ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 6 , 0 ) ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_PageDown ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 18 , 0 ) ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Down ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 24 , 0 ) ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_PageUp ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 12 , 0 ) ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Up ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 6 , 0 ) ) ;
2018-12-23 16:59:18 +00:00
// QTBUG-44746 - when first/last item is disabled,
// Key_PageUp/Down/Home/End will not work as expected.
model . item ( 0 ) - > setEnabled ( false ) ;
model . item ( 1 ) - > setEnabled ( true ) ;
model . item ( 2 ) - > setEnabled ( true ) ;
model . item ( model . rowCount ( ) - 1 ) - > setEnabled ( false ) ;
model . item ( model . rowCount ( ) - 2 ) - > setEnabled ( true ) ;
model . item ( model . rowCount ( ) - 3 ) - > setEnabled ( true ) ;
// PageUp
view . setCurrentIndex ( model . index ( 2 , 0 ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 2 , 0 ) ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_PageUp ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 1 , 0 ) ) ;
// PageDown
view . setCurrentIndex ( model . index ( model . rowCount ( ) - 3 , 0 ) ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( model . rowCount ( ) - 3 , 0 ) ) ;
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_PageDown ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( model . rowCount ( ) - 2 , 0 ) ) ;
// Key_Home
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_Home ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( 1 , 0 ) ) ;
// Key_End
QTest : : keyClick ( view . viewport ( ) , Qt : : Key_End ) ;
QCOMPARE ( view . currentIndex ( ) , model . index ( model . rowCount ( ) - 2 , 0 ) ) ;
2011-04-27 10:05:43 +00:00
}
2018-03-01 10:04:00 +00:00
class RemoveColumnOne : public QSortFilterProxyModel
{
public :
bool filterAcceptsColumn ( int source_column , const QModelIndex & ) const override
{
if ( m_removeColumn )
return source_column ! = 1 ;
return true ;
}
void removeColumn ( )
{
m_removeColumn = true ;
invalidate ( ) ;
}
private :
bool m_removeColumn = false ;
} ;
void tst_QTreeView : : saveRestoreState ( )
{
QStandardItemModel model ;
for ( int i = 0 ; i < 100 ; i + + ) {
QList < QStandardItem * > items ;
items < < new QStandardItem ( QLatin1String ( " item " ) + QString : : number ( i ) ) < < new QStandardItem ( QStringLiteral ( " hidden by proxy " ) ) < < new QStandardItem ( QStringLiteral ( " hidden by user " ) ) ;
model . appendRow ( items ) ;
}
QCOMPARE ( model . columnCount ( ) , 3 ) ;
RemoveColumnOne proxy ;
proxy . setSourceModel ( & model ) ;
QCOMPARE ( proxy . columnCount ( ) , 3 ) ;
QTreeView view ;
view . setModel ( & proxy ) ;
view . resize ( 500 , 500 ) ;
view . show ( ) ;
view . header ( ) - > hideSection ( 2 ) ;
QVERIFY ( view . header ( ) - > isSectionHidden ( 2 ) ) ;
proxy . removeColumn ( ) ;
QCOMPARE ( proxy . columnCount ( ) , 2 ) ;
QVERIFY ( view . header ( ) - > isSectionHidden ( 1 ) ) ;
const QByteArray data = view . header ( ) - > saveState ( ) ;
QTreeView view2 ;
view2 . setModel ( & proxy ) ;
view2 . resize ( 500 , 500 ) ;
view2 . show ( ) ;
view2 . header ( ) - > restoreState ( data ) ;
QVERIFY ( view2 . header ( ) - > isSectionHidden ( 1 ) ) ;
}
2011-04-27 10:05:43 +00:00
class Model_11466 : public QAbstractItemModel
{
Q_OBJECT
public :
2011-05-19 14:19:01 +00:00
Model_11466 ( QObject * /* parent */ ) :
2011-04-27 10:05:43 +00:00
m_block ( false )
{
// set up the model to have two top level items and a few others
m_selectionModel = new QItemSelectionModel ( this , this ) ; // owned by this
2012-10-16 09:08:13 +00:00
connect ( m_selectionModel , SIGNAL ( currentChanged ( QModelIndex , QModelIndex ) ) ,
this , SLOT ( slotCurrentChanged ( QModelIndex , QModelIndex ) ) ) ;
2011-04-27 10:05:43 +00:00
} ;
int rowCount ( const QModelIndex & parent ) const
{
if ( parent . isValid ( ) )
return ( parent . internalId ( ) = = 0 ) ? 4 : 0 ;
return 2 ; // two top level items
}
2011-05-19 14:19:01 +00:00
int columnCount ( const QModelIndex & /* parent */ ) const
2011-04-27 10:05:43 +00:00
{
return 2 ;
}
QVariant data ( const QModelIndex & index , int role ) const
{
if ( role = = Qt : : DisplayRole & & index . isValid ( ) ) {
qint64 parentRowPlusOne = index . internalId ( ) ;
QString str ;
QTextStream stream ( & str ) ;
if ( parentRowPlusOne > 0 )
stream < < parentRowPlusOne < < " -> " < < index . row ( ) < < " : " < < index . column ( ) ;
else
stream < < index . row ( ) < < " : " < < index . column ( ) ;
return QVariant ( str ) ;
}
return QVariant ( ) ;
}
QModelIndex parent ( const QModelIndex & index ) const
{
if ( index . isValid ( ) ) {
qint64 parentRowPlusOne = index . internalId ( ) ;
if ( parentRowPlusOne > 0 ) {
int row = static_cast < int > ( parentRowPlusOne - 1 ) ;
2012-02-24 15:32:53 +00:00
return createIndex ( row , 0 ) ;
2011-04-27 10:05:43 +00:00
}
}
return QModelIndex ( ) ;
}
void bindView ( QTreeView * view )
{
// sets the view to this model with a shared selection model
QItemSelectionModel * oldModel = view - > selectionModel ( ) ;
if ( oldModel ! = m_selectionModel )
delete oldModel ;
2011-10-24 22:11:03 +00:00
view - > setModel ( this ) ; // this creates a new selection model for the view, but we don't want it either ...
2011-04-27 10:05:43 +00:00
oldModel = view - > selectionModel ( ) ;
view - > setSelectionModel ( m_selectionModel ) ;
delete oldModel ;
}
QModelIndex index ( int row , int column , const QModelIndex & parent ) const
{
2012-02-24 15:32:53 +00:00
return createIndex ( row , column , parent . isValid ( ) ? ( quintptr ) ( parent . row ( ) + 1 ) : ( quintptr ) 0 ) ;
2011-04-27 10:05:43 +00:00
}
public slots :
void slotCurrentChanged ( const QModelIndex & current , const QModelIndex & )
{
if ( m_block )
return ;
if ( current . isValid ( ) ) {
int selectedRow = current . row ( ) ;
2012-02-24 15:32:53 +00:00
const quintptr parentRowPlusOne = current . internalId ( ) ;
2011-04-27 10:05:43 +00:00
for ( int i = 0 ; i < 2 ; + + i ) {
// announce the removal of all non top level items
2012-02-24 15:32:53 +00:00
beginRemoveRows ( createIndex ( i , 0 ) , 0 , 3 ) ;
2011-04-27 10:05:43 +00:00
// nothing to actually do for the removal
endRemoveRows ( ) ;
// put them back in again
2012-02-24 15:32:53 +00:00
beginInsertRows ( createIndex ( i , 0 ) , 0 , 3 ) ;
2011-04-27 10:05:43 +00:00
// nothing to actually do for the insertion
endInsertRows ( ) ;
}
// reselect the current item ...
QModelIndex selectedIndex = createIndex ( selectedRow , 0 , parentRowPlusOne ) ;
m_block = true ; // recursion block
m_selectionModel - > select ( selectedIndex , QItemSelectionModel : : ClearAndSelect | QItemSelectionModel : : Current | QItemSelectionModel : : Rows ) ;
m_selectionModel - > setCurrentIndex ( selectedIndex , QItemSelectionModel : : NoUpdate ) ;
m_block = false ;
} else {
m_selectionModel - > clear ( ) ;
}
}
private :
bool m_block ;
QItemSelectionModel * m_selectionModel ;
} ;
void tst_QTreeView : : taskQTBUG_11466_keyboardNavigationRegression ( )
{
QTreeView treeView ;
treeView . setSelectionBehavior ( QAbstractItemView : : SelectRows ) ;
treeView . setSelectionMode ( QAbstractItemView : : SingleSelection ) ;
Model_11466 model ( & treeView ) ;
model . bindView ( & treeView ) ;
treeView . expandAll ( ) ;
treeView . show ( ) ;
2012-07-24 12:29:01 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & treeView ) ) ;
2011-04-27 10:05:43 +00:00
QTest : : keyPress ( treeView . viewport ( ) , Qt : : Key_Down ) ;
QTRY_COMPARE ( treeView . currentIndex ( ) , treeView . selectionModel ( ) - > selection ( ) . indexes ( ) . first ( ) ) ;
}
void tst_QTreeView : : taskQTBUG_13567_removeLastItemRegression ( )
{
QtTestModel model ( 200 , 1 ) ;
QTreeView view ;
view . setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
view . setModel ( & model ) ;
view . show ( ) ;
2012-07-24 12:29:01 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & view ) ) ;
2011-04-27 10:05:43 +00:00
view . scrollToBottom ( ) ;
QTest : : qWait ( 10 ) ;
CHECK_VISIBLE ( 199 , 0 ) ;
view . setCurrentIndex ( model . index ( 199 , 0 ) ) ;
model . removeLastRow ( ) ;
2018-04-09 10:37:33 +00:00
QTRY_COMPARE ( view . currentIndex ( ) , model . index ( 198 , 0 ) ) ;
2011-04-27 10:05:43 +00:00
CHECK_VISIBLE ( 198 , 0 ) ;
}
2012-05-25 13:41:03 +00:00
// From QTBUG-25333 (QTreeWidget drag crashes when there was a hidden item in tree)
// The test passes simply if it doesn't crash, hence there are no calls
// to QCOMPARE() or QVERIFY().
// Note: define QT_BUILD_INTERNAL to run this test
void tst_QTreeView : : taskQTBUG_25333_adjustViewOptionsForIndex ( )
{
2016-07-28 16:51:53 +00:00
QTreeView view ;
2012-05-25 13:41:03 +00:00
QStandardItemModel model ;
QStandardItem * item1 = new QStandardItem ( " Item1 " ) ;
QStandardItem * item2 = new QStandardItem ( " Item2 " ) ;
QStandardItem * item3 = new QStandardItem ( " Item3 " ) ;
QStandardItem * data1 = new QStandardItem ( " Data1 " ) ;
QStandardItem * data2 = new QStandardItem ( " Data2 " ) ;
QStandardItem * data3 = new QStandardItem ( " Data3 " ) ;
// Create a treeview
model . appendRow ( QList < QStandardItem * > ( ) < < item1 < < data1 ) ;
model . appendRow ( QList < QStandardItem * > ( ) < < item2 < < data2 ) ;
model . appendRow ( QList < QStandardItem * > ( ) < < item3 < < data3 ) ;
view . setModel ( & model ) ;
// Hide a row
view . setRowHidden ( 1 , QModelIndex ( ) , true ) ;
view . expandAll ( ) ;
view . show ( ) ;
# ifdef QT_BUILD_INTERNAL
{
2015-11-02 15:42:21 +00:00
QStyleOptionViewItem option ;
2012-05-25 13:41:03 +00:00
2016-07-28 16:51:53 +00:00
view . d_func ( ) - > adjustViewOptionsForIndex ( & option , model . indexFromItem ( item1 ) ) ;
2012-05-25 13:41:03 +00:00
2016-07-28 16:51:53 +00:00
view . d_func ( ) - > adjustViewOptionsForIndex ( & option , model . indexFromItem ( item3 ) ) ;
2012-05-25 13:41:03 +00:00
}
# endif
}
2012-08-13 09:53:05 +00:00
void tst_QTreeView : : taskQTBUG_18539_emitLayoutChanged ( )
{
QTreeView view ;
QStandardItem * item = new QStandardItem ( " Orig " ) ;
QStandardItem * child = new QStandardItem ( " Child " ) ;
item - > setChild ( 0 , 0 , child ) ;
QStandardItemModel model ;
model . appendRow ( item ) ;
view . setModel ( & model ) ;
QStandardItem * replacementItem = new QStandardItem ( " Replacement " ) ;
QStandardItem * replacementChild = new QStandardItem ( " ReplacementChild " ) ;
replacementItem - > setChild ( 0 , 0 , replacementChild ) ;
QSignalSpy beforeSpy ( & model , SIGNAL ( layoutAboutToBeChanged ( ) ) ) ;
QSignalSpy afterSpy ( & model , SIGNAL ( layoutChanged ( ) ) ) ;
QSignalSpy beforeRISpy ( & model , SIGNAL ( rowsAboutToBeInserted ( QModelIndex , int , int ) ) ) ;
QSignalSpy afterRISpy ( & model , SIGNAL ( rowsInserted ( QModelIndex , int , int ) ) ) ;
QSignalSpy beforeRRSpy ( & model , SIGNAL ( rowsAboutToBeRemoved ( QModelIndex , int , int ) ) ) ;
QSignalSpy afterRRSpy ( & model , SIGNAL ( rowsRemoved ( QModelIndex , int , int ) ) ) ;
model . setItem ( 0 , 0 , replacementItem ) ;
QCOMPARE ( beforeSpy . size ( ) , 1 ) ;
QCOMPARE ( afterSpy . size ( ) , 1 ) ;
QCOMPARE ( beforeRISpy . size ( ) , 0 ) ;
QCOMPARE ( afterRISpy . size ( ) , 0 ) ;
QCOMPARE ( beforeRISpy . size ( ) , 0 ) ;
QCOMPARE ( afterRISpy . size ( ) , 0 ) ;
}
2012-05-25 13:41:03 +00:00
2012-11-06 20:08:10 +00:00
void tst_QTreeView : : taskQTBUG_8176_emitOnExpandAll ( )
{
QTreeWidget tw ;
QTreeWidgetItem * item = new QTreeWidgetItem ( & tw , QStringList ( QString ( " item 1 " ) ) ) ;
QTreeWidgetItem * item2 = new QTreeWidgetItem ( item , QStringList ( QString ( " item 2 " ) ) ) ;
new QTreeWidgetItem ( item2 , QStringList ( QString ( " item 3 " ) ) ) ;
new QTreeWidgetItem ( item2 , QStringList ( QString ( " item 4 " ) ) ) ;
QTreeWidgetItem * item5 = new QTreeWidgetItem ( & tw , QStringList ( QString ( " item 5 " ) ) ) ;
new QTreeWidgetItem ( item5 , QStringList ( QString ( " item 6 " ) ) ) ;
QSignalSpy spy ( & tw , SIGNAL ( expanded ( const QModelIndex & ) ) ) ;
2012-11-07 07:08:44 +00:00
2012-11-06 20:08:10 +00:00
// expand all
tw . expandAll ( ) ;
QCOMPARE ( spy . size ( ) , 6 ) ;
spy . clear ( ) ;
tw . collapseAll ( ) ;
item2 - > setExpanded ( true ) ;
spy . clear ( ) ;
tw . expandAll ( ) ;
QCOMPARE ( spy . size ( ) , 5 ) ;
2012-11-07 07:08:44 +00:00
// collapse all
QSignalSpy spy2 ( & tw , SIGNAL ( collapsed ( const QModelIndex & ) ) ) ;
tw . collapseAll ( ) ;
QCOMPARE ( spy2 . size ( ) , 6 ) ;
tw . expandAll ( ) ;
item2 - > setExpanded ( false ) ;
spy2 . clear ( ) ;
tw . collapseAll ( ) ;
QCOMPARE ( spy2 . size ( ) , 5 ) ;
2012-11-07 14:04:31 +00:00
// expand to depth
item2 - > setExpanded ( true ) ;
spy . clear ( ) ;
spy2 . clear ( ) ;
tw . expandToDepth ( 0 ) ;
QCOMPARE ( spy . size ( ) , 2 ) ; // item and item5 are expanded
QCOMPARE ( spy2 . size ( ) , 1 ) ; // item2 is collapsed
2012-11-06 20:08:10 +00:00
}
2013-08-26 18:26:07 +00:00
void tst_QTreeView : : testInitialFocus ( )
{
QTreeWidget treeWidget ;
treeWidget . setColumnCount ( 5 ) ;
2015-10-13 07:46:56 +00:00
new QTreeWidgetItem ( & treeWidget , QStringList ( QString ( " 1;2;3;4;5 " ) . split ( QLatin1Char ( ' ; ' ) ) ) ) ;
2013-08-26 18:26:07 +00:00
treeWidget . setTreePosition ( 2 ) ;
treeWidget . header ( ) - > hideSection ( 0 ) ; // make sure we skip hidden section(s)
treeWidget . header ( ) - > swapSections ( 1 , 2 ) ; // make sure that we look for first visual index (and not first logical)
treeWidget . show ( ) ;
2017-09-08 16:42:25 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & treeWidget ) ) ;
2013-08-26 18:26:07 +00:00
QApplication : : processEvents ( ) ;
QCOMPARE ( treeWidget . currentIndex ( ) . column ( ) , 2 ) ;
}
2018-09-26 13:39:35 +00:00
# if QT_CONFIG(animation)
2012-08-29 12:24:40 +00:00
void tst_QTreeView : : quickExpandCollapse ( )
{
//this unit tests makes sure the state after the animation is restored correctly
//after starting a 2nd animation while the first one was still on-going
//this tests that the stateBeforeAnimation is not set to AnimatingState
2016-07-28 16:51:53 +00:00
QTreeView tree ;
2012-08-29 12:24:40 +00:00
tree . setAnimated ( true ) ;
QStandardItemModel model ;
QStandardItem * root = new QStandardItem ( " root " ) ;
root - > appendRow ( new QStandardItem ( " subnode " ) ) ;
model . appendRow ( root ) ;
tree . setModel ( & model ) ;
QModelIndex rootIndex = root - > index ( ) ;
QVERIFY ( rootIndex . isValid ( ) ) ;
tree . show ( ) ;
2017-09-08 16:42:25 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & tree ) ) ;
2012-08-29 12:24:40 +00:00
2016-07-28 16:51:53 +00:00
const QAbstractItemView : : State initialState = tree . state ( ) ;
2012-08-29 12:24:40 +00:00
tree . expand ( rootIndex ) ;
2016-07-28 16:51:53 +00:00
QCOMPARE ( tree . state ( ) , QTreeView : : AnimatingState ) ;
2012-08-29 12:24:40 +00:00
tree . collapse ( rootIndex ) ;
2016-07-28 16:51:53 +00:00
QCOMPARE ( tree . state ( ) , QTreeView : : AnimatingState ) ;
2012-08-29 12:24:40 +00:00
QTest : : qWait ( 500 ) ; //the animation lasts for 250ms max so 500 should be enough
QCOMPARE ( tree . state ( ) , initialState ) ;
}
2018-09-26 13:39:35 +00:00
# endif // animation
2012-08-29 12:24:40 +00:00
2014-05-05 08:59:56 +00:00
void tst_QTreeView : : taskQTBUG_37813_crash ( )
{
// QTBUG_37813: Crash in visual / logical index mapping in QTreeViewPrivate::adjustViewOptionsForIndex()
// when hiding/moving columns. It is reproduceable with a QTreeWidget only.
# ifdef QT_BUILD_INTERNAL
QTreeWidget treeWidget ;
treeWidget . setDragEnabled ( true ) ;
treeWidget . setColumnCount ( 2 ) ;
QList < QTreeWidgetItem * > items ;
for ( int r = 0 ; r < 2 ; + + r ) {
2015-10-16 07:38:51 +00:00
const QString prefix = QLatin1String ( " Row " ) + QString : : number ( r ) + QLatin1String ( " Column " ) ;
2014-05-05 08:59:56 +00:00
QTreeWidgetItem * item = new QTreeWidgetItem ( ) ;
for ( int c = 0 ; c < treeWidget . columnCount ( ) ; + + c )
2015-10-16 07:38:51 +00:00
item - > setText ( c , prefix + QString : : number ( c ) ) ;
2014-05-05 08:59:56 +00:00
items . append ( item ) ;
}
treeWidget . addTopLevelItems ( items ) ;
treeWidget . setColumnHidden ( 0 , true ) ;
treeWidget . header ( ) - > moveSection ( 0 , 1 ) ;
QItemSelection sel ( treeWidget . model ( ) - > index ( 0 , 0 ) , treeWidget . model ( ) - > index ( 0 , 1 ) ) ;
QRect rect ;
QAbstractItemViewPrivate * av = static_cast < QAbstractItemViewPrivate * > ( qt_widget_private ( & treeWidget ) ) ;
const QPixmap pixmap = av - > renderToPixmap ( sel . indexes ( ) , & rect ) ;
QVERIFY ( pixmap . size ( ) . isValid ( ) ) ;
# endif // QT_BUILD_INTERNAL
}
2015-05-27 10:27:19 +00:00
// QTBUG-45697: Using a QTreeView with a multi-column model filtered by QSortFilterProxyModel,
// when sorting the source model while the widget is not yet visible and showing the widget
// later on, corruption occurs in QTreeView.
class Qtbug45697TestWidget : public QWidget
{
Q_OBJECT
public :
static const int columnCount = 3 ;
explicit Qtbug45697TestWidget ( ) ;
int timerTick ( ) const { return m_timerTick ; }
public slots :
void slotTimer ( ) ;
private :
QTreeView * m_treeView ;
QStandardItemModel * m_model ;
QSortFilterProxyModel * m_sortFilterProxyModel ;
int m_timerTick ;
} ;
Qtbug45697TestWidget : : Qtbug45697TestWidget ( )
: m_treeView ( new QTreeView ( this ) )
, m_model ( new QStandardItemModel ( 0 , Qtbug45697TestWidget : : columnCount , this ) )
, m_sortFilterProxyModel ( new QSortFilterProxyModel ( this ) )
, m_timerTick ( 0 )
{
QVBoxLayout * vBoxLayout = new QVBoxLayout ( this ) ;
vBoxLayout - > addWidget ( m_treeView ) ;
for ( char sortChar = ' z ' ; sortChar > = ' a ' ; - - sortChar ) {
QList < QStandardItem * > items ;
for ( int column = 0 ; column < Qtbug45697TestWidget : : columnCount ; + + column ) {
const QString text = QLatin1Char ( sortChar ) + QLatin1String ( " " ) + QString : : number ( column ) ;
items . append ( new QStandardItem ( text ) ) ;
}
m_model - > appendRow ( items ) ;
}
m_sortFilterProxyModel - > setSourceModel ( m_model ) ;
m_treeView - > setModel ( m_sortFilterProxyModel ) ;
QHeaderView * headerView = m_treeView - > header ( ) ;
for ( int s = 1 , lastSection = headerView - > count ( ) - 1 ; s < lastSection ; + + s )
headerView - > setSectionResizeMode ( s , QHeaderView : : ResizeToContents ) ;
QTimer * timer = new QTimer ( this ) ;
timer - > setInterval ( 50 ) ;
connect ( timer , & QTimer : : timeout , this , & Qtbug45697TestWidget : : slotTimer ) ;
timer - > start ( ) ;
}
void Qtbug45697TestWidget : : slotTimer ( )
{
switch ( m_timerTick + + ) {
case 0 :
m_model - > sort ( 0 ) ;
break ;
case 1 :
show ( ) ;
break ;
default :
close ( ) ;
break ;
}
}
void tst_QTreeView : : taskQTBUG_45697_crash ( )
{
Qtbug45697TestWidget testWidget ;
testWidget . setWindowTitle ( QTest : : currentTestFunction ( ) ) ;
testWidget . resize ( 400 , 400 ) ;
testWidget . move ( QGuiApplication : : primaryScreen ( ) - > availableGeometry ( ) . topLeft ( ) + QPoint ( 100 , 100 ) ) ;
QTRY_VERIFY ( testWidget . timerTick ( ) > = 2 ) ;
}
2012-11-07 18:06:01 +00:00
void tst_QTreeView : : taskQTBUG_7232_AllowUserToControlSingleStep ( )
{
// When we set the scrollMode to ScrollPerPixel it will adjust the scrollbars singleStep automatically
// Setting a singlestep on a scrollbar should however imply that the user takes control.
// Setting a singlestep to -1 return to an automatic control of the singleStep.
QTreeWidget t ;
t . setVerticalScrollBarPolicy ( Qt : : ScrollBarAlwaysOn ) ;
t . setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOn ) ;
t . setColumnCount ( 2 ) ;
QTreeWidgetItem * mainItem = new QTreeWidgetItem ( & t , QStringList ( ) < < " Root " ) ;
for ( int i = 0 ; i < 200 ; + + i ) {
QTreeWidgetItem * item = new QTreeWidgetItem ( mainItem , QStringList ( QString ( " Item " ) ) ) ;
new QTreeWidgetItem ( item , QStringList ( ) < < " Child " < < " 1 " ) ;
new QTreeWidgetItem ( item , QStringList ( ) < < " Child " < < " 2 " ) ;
new QTreeWidgetItem ( item , QStringList ( ) < < " Child " < < " 3 " ) ;
}
t . expandAll ( ) ;
t . setVerticalScrollMode ( QAbstractItemView : : ScrollPerPixel ) ;
t . setHorizontalScrollMode ( QAbstractItemView : : ScrollPerPixel ) ;
t . setGeometry ( 200 , 200 , 200 , 200 ) ;
int vStep1 = t . verticalScrollBar ( ) - > singleStep ( ) ;
int hStep1 = t . horizontalScrollBar ( ) - > singleStep ( ) ;
QVERIFY ( vStep1 > 1 ) ;
QVERIFY ( hStep1 > 1 ) ;
t . verticalScrollBar ( ) - > setSingleStep ( 1 ) ;
t . setGeometry ( 300 , 300 , 300 , 300 ) ;
QCOMPARE ( t . verticalScrollBar ( ) - > singleStep ( ) , 1 ) ;
t . horizontalScrollBar ( ) - > setSingleStep ( 1 ) ;
t . setGeometry ( 400 , 400 , 400 , 400 ) ;
QCOMPARE ( t . horizontalScrollBar ( ) - > singleStep ( ) , 1 ) ;
t . setGeometry ( 200 , 200 , 200 , 200 ) ;
t . verticalScrollBar ( ) - > setSingleStep ( - 1 ) ;
t . horizontalScrollBar ( ) - > setSingleStep ( - 1 ) ;
QCOMPARE ( vStep1 , t . verticalScrollBar ( ) - > singleStep ( ) ) ;
QCOMPARE ( hStep1 , t . horizontalScrollBar ( ) - > singleStep ( ) ) ;
}
2017-05-08 07:29:17 +00:00
void tst_QTreeView : : statusTip_data ( )
{
QTest : : addColumn < bool > ( " intermediateParent " ) ;
QTest : : newRow ( " noIntermediate " ) < < false ;
QTest : : newRow ( " intermediate " ) < < true ;
}
void tst_QTreeView : : statusTip ( )
{
QFETCH ( bool , intermediateParent ) ;
QMainWindow mw ;
QtTestModel model ;
model . statusTipsEnabled = true ;
model . rows = model . cols = 5 ;
QTreeView * view = new QTreeView ;
view - > setModel ( & model ) ;
view - > viewport ( ) - > setMouseTracking ( true ) ;
view - > header ( ) - > viewport ( ) - > setMouseTracking ( true ) ;
if ( intermediateParent ) {
QWidget * inter = new QWidget ;
QVBoxLayout * vbox = new QVBoxLayout ;
inter - > setLayout ( vbox ) ;
vbox - > addWidget ( view ) ;
mw . setCentralWidget ( inter ) ;
} else {
mw . setCentralWidget ( view ) ;
}
mw . statusBar ( ) ;
mw . setGeometry ( QRect ( QPoint ( QApplication : : desktop ( ) - > geometry ( ) . center ( ) - QPoint ( 250 , 250 ) ) ,
QSize ( 500 , 500 ) ) ) ;
mw . show ( ) ;
qApp - > setActiveWindow ( & mw ) ;
2017-09-08 16:42:25 +00:00
QVERIFY ( QTest : : qWaitForWindowActive ( & mw ) ) ;
2017-05-08 07:29:17 +00:00
// Ensure it is moved away first and then moved to the relevant section
QTest : : mouseMove ( mw . windowHandle ( ) , view - > mapTo ( & mw , view - > rect ( ) . bottomLeft ( ) + QPoint ( 20 , 20 ) ) ) ;
QPoint centerPoint = view - > viewport ( ) - > mapTo ( & mw , view - > visualRect ( model . index ( 0 , 0 ) ) . center ( ) ) ;
QTest : : mouseMove ( mw . windowHandle ( ) , centerPoint ) ;
QTRY_COMPARE ( mw . statusBar ( ) - > currentMessage ( ) , QLatin1String ( " [0,0,0] -- Status " ) ) ;
centerPoint = view - > viewport ( ) - > mapTo ( & mw , view - > visualRect ( model . index ( 0 , 1 ) ) . center ( ) ) ;
QTest : : mouseMove ( mw . windowHandle ( ) , centerPoint ) ;
QTRY_COMPARE ( mw . statusBar ( ) - > currentMessage ( ) , QLatin1String ( " [0,1,0] -- Status " ) ) ;
centerPoint = view - > header ( ) - > viewport ( ) - > mapTo ( & mw ,
QPoint ( view - > header ( ) - > sectionViewportPosition ( 0 ) + view - > header ( ) - > sectionSize ( 0 ) / 2 ,
view - > header ( ) - > height ( ) / 2 ) ) ;
QTest : : mouseMove ( mw . windowHandle ( ) , centerPoint ) ;
QTRY_COMPARE ( mw . statusBar ( ) - > currentMessage ( ) , QLatin1String ( " Header 0 -- Status " ) ) ;
}
2016-11-23 10:09:47 +00:00
class FetchMoreModel : public QStandardItemModel
{
public :
FetchMoreModel ( ) : QStandardItemModel ( ) , canFetchReady ( false )
{
for ( int i = 0 ; i < 20 ; + + i ) {
QStandardItem * item = new QStandardItem ( " Row " ) ;
item - > appendRow ( new QStandardItem ( " Child " ) ) ;
appendRow ( item ) ;
}
}
bool canFetchMore ( const QModelIndex & parent ) const override
{
if ( ! canFetchReady | | ! parent . isValid ( ) )
return false ;
if ( ! parent . parent ( ) . isValid ( ) )
return rowCount ( parent ) < 20 ;
return false ;
}
void fetchMore ( const QModelIndex & parent ) override
{
QStandardItem * item = itemFromIndex ( parent ) ;
for ( int i = 0 ; i < 19 ; + + i )
item - > appendRow ( new QStandardItem ( QString ( " New Child %1 " ) . arg ( i ) ) ) ;
}
bool canFetchReady ;
} ;
void tst_QTreeView : : fetchMoreOnScroll ( )
{
QTreeView tw ;
FetchMoreModel im ;
tw . setModel ( & im ) ;
tw . show ( ) ;
tw . expandAll ( ) ;
2017-12-17 18:56:35 +00:00
QVERIFY ( QTest : : qWaitForWindowActive ( & tw ) ) ;
2016-11-23 10:09:47 +00:00
// Now we can allow the fetch to happen
im . canFetchReady = true ;
tw . verticalScrollBar ( ) - > setValue ( tw . verticalScrollBar ( ) - > maximum ( ) ) ;
// The item should have now fetched the other children, thus bringing the count to 20
QCOMPARE ( im . item ( 19 ) - > rowCount ( ) , 20 ) ;
}
2017-11-12 12:33:25 +00:00
static void fillModeltaskQTBUG_8376 ( QAbstractItemModel & model )
{
model . insertRow ( 0 ) ;
model . insertColumn ( 0 ) ;
model . insertColumn ( 1 ) ;
QModelIndex index = model . index ( 0 , 0 ) ;
model . setData ( index , " Level0 " ) ;
{
model . insertRow ( 0 , index ) ;
model . insertRow ( 1 , index ) ;
model . insertColumn ( 0 , index ) ;
model . insertColumn ( 1 , index ) ;
QModelIndex idx ;
idx = model . index ( 0 , 0 , index ) ;
model . setData ( idx , " Level1 " ) ;
idx = model . index ( 0 , 1 , index ) ;
model . setData ( idx , " very \n very \n high \n cell " ) ;
}
}
void tst_QTreeView : : taskQTBUG_8376 ( )
{
QTreeView tv ;
QStandardItemModel model ;
fillModeltaskQTBUG_8376 ( model ) ;
tv . setModel ( & model ) ;
tv . expandAll ( ) ; // init layout
QModelIndex idxLvl0 = model . index ( 0 , 0 ) ;
QModelIndex idxLvl1 = model . index ( 0 , 1 , idxLvl0 ) ;
const int rowHeightLvl0 = tv . rowHeight ( idxLvl0 ) ;
const int rowHeightLvl1Visible = tv . rowHeight ( idxLvl1 ) ;
QVERIFY ( rowHeightLvl0 < rowHeightLvl1Visible ) ;
tv . hideColumn ( 1 ) ;
const int rowHeightLvl1Hidden = tv . rowHeight ( idxLvl1 ) ;
QCOMPARE ( rowHeightLvl0 , rowHeightLvl1Hidden ) ;
tv . showColumn ( 1 ) ;
const int rowHeightLvl1Visible2 = tv . rowHeight ( idxLvl1 ) ;
QCOMPARE ( rowHeightLvl1Visible , rowHeightLvl1Visible2 ) ;
}
2011-04-27 10:05:43 +00:00
QTEST_MAIN ( tst_QTreeView )
# include "tst_qtreeview.moc"