Eliminate QTreeWidget drag crash

In QTreeViewPrivate::adjustViewOptionsForIndex() wrong index had been
used when referencing to array of viewItems. Variable row is set to the
index of the QModelIndex, however it is not as same as the index in
viewItems[] when there was hidden item in treeWidget. Index of viewItems[]
should be used here. Unit test is added as well.

Change-Id: Idc7eda979e7d09c5a07bd6dffd92b7abbac10e67
Task-Id: QTBUG-25333
Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
This commit is contained in:
Jiewen Wang 2012-05-25 09:41:03 -04:00 committed by Qt by Nokia
parent 177070cb7b
commit 3be6ca3ee8
2 changed files with 43 additions and 1 deletions

View File

@ -1357,7 +1357,7 @@ QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList
void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItemV4 *option, const QModelIndex &current) const void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItemV4 *option, const QModelIndex &current) const
{ {
const int row = current.row(); const int row = viewIndex(current); // get the index in viewItems[]
option->state = option->state | (viewItems.at(row).expanded ? QStyle::State_Open : QStyle::State_None) option->state = option->state | (viewItems.at(row).expanded ? QStyle::State_Open : QStyle::State_None)
| (viewItems.at(row).hasChildren ? QStyle::State_Children : QStyle::State_None) | (viewItems.at(row).hasChildren ? QStyle::State_Children : QStyle::State_None)
| (viewItems.at(row).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None); | (viewItems.at(row).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);

View File

@ -239,6 +239,7 @@ private slots:
void taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint(); void taskQTBUG_9216_setSizeAndUniformRowHeightsWrongRepaint();
void taskQTBUG_11466_keyboardNavigationRegression(); void taskQTBUG_11466_keyboardNavigationRegression();
void taskQTBUG_13567_removeLastItemRegression(); void taskQTBUG_13567_removeLastItemRegression();
void taskQTBUG_25333_adjustViewOptionsForIndex();
}; };
class QtTestModel: public QAbstractItemModel class QtTestModel: public QAbstractItemModel
@ -4008,5 +4009,46 @@ void tst_QTreeView::taskQTBUG_13567_removeLastItemRegression()
CHECK_VISIBLE(198, 0); CHECK_VISIBLE(198, 0);
} }
// 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()
{
PublicView view;
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
{
QStyleOptionViewItemV4 option;
view.aiv_priv()->adjustViewOptionsForIndex(&option, model.indexFromItem(item1));
view.aiv_priv()->adjustViewOptionsForIndex(&option, model.indexFromItem(item3));
}
#endif
}
QTEST_MAIN(tst_QTreeView) QTEST_MAIN(tst_QTreeView)
#include "tst_qtreeview.moc" #include "tst_qtreeview.moc"