summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Pley <qt@pley.org>2013-11-15 22:01:54 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-16 16:40:46 +0100
commit6c04c21c101b70401ad9cb08de1562dc90166e9c (patch)
treecffa52c1e385b5b1c2d1bf204b066ec9d7706099
parent8cbea7a886e336bca6e17f5cb8404a91cbec9fda (diff)
Crash fix in QTreeView::sizeHintForColumn().
Vertical scrollbar may get out of sync. When this happens, the calculation of firstVisibleItem will retrun "-1". This must be handled in ::sizeHintForColumn(). Added an auto-test for the crashes. Task-number: QTBUG-34717 Change-Id: I867fd144ef3ce45e382337c5eafe345f573cd944 Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
-rw-r--r--src/widgets/itemviews/qtreeview.cpp20
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp30
2 files changed, 49 insertions, 1 deletions
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index fc0d639483..4d0eb5c3ad 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -2858,6 +2858,21 @@ int QTreeView::sizeHintForColumn(int column) const
int offset = 0;
int start = d->firstVisibleItem(&offset);
int end = d->lastVisibleItem(start, offset);
+ if (start < 0 || end < 0 || end == viewItems.size() - 1) {
+ end = viewItems.size() - 1;
+ if (maximumProcessRows < 0) {
+ start = 0;
+ } else if (maximumProcessRows == 0) {
+ start = qMax(0, end - 1);
+ int remainingHeight = viewport()->height();
+ while (start > 0 && remainingHeight > 0) {
+ remainingHeight -= d->itemHeight(start);
+ --start;
+ }
+ } else {
+ start = qMax(0, end - maximumProcessRows);
+ }
+ }
int rowsProcessed = 0;
@@ -3606,8 +3621,11 @@ int QTreeViewPrivate::firstVisibleItem(int *offset) const
int QTreeViewPrivate::lastVisibleItem(int firstVisual, int offset) const
{
- if (firstVisual < 0 || offset < 0)
+ if (firstVisual < 0 || offset < 0) {
firstVisual = firstVisibleItem(&offset);
+ if (firstVisual < 0)
+ return -1;
+ }
int y = - offset;
int value = viewport->height();
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index 8d31fcdf13..ccdce1fe0c 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -259,6 +259,7 @@ private slots:
void taskQTBUG_25333_adjustViewOptionsForIndex();
void taskQTBUG_18539_emitLayoutChanged();
void taskQTBUG_8176_emitOnExpandAll();
+ void taskQTBUG_34717_collapseAtBottom();
void testInitialFocus();
};
@@ -4240,6 +4241,35 @@ void tst_QTreeView::taskQTBUG_8176_emitOnExpandAll()
QCOMPARE(spy2.size(), 1); // item2 is collapsed
}
+// From QTBUG_34717 (QTreeWidget crashes when scrolling to the end
+// of an expanded tree, then collapse all)
+// The test passes simply if it doesn't crash.
+void tst_QTreeView::taskQTBUG_34717_collapseAtBottom()
+{
+ QTreeWidget treeWidget;
+ treeWidget.header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ treeWidget.setColumnCount(2);
+ QTreeWidgetItem *mainItem = new QTreeWidgetItem(&treeWidget, 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");
+ }
+ treeWidget.show();
+ treeWidget.expandAll();
+ treeWidget.scrollToBottom();
+ treeWidget.collapseAll();
+
+ treeWidget.setAnimated(true);
+ treeWidget.expandAll();
+ treeWidget.scrollToBottom();
+ mainItem->setExpanded(false);
+
+ PublicView *pview = (PublicView*) &treeWidget;
+ QVERIFY(pview->sizeHintForColumn(1) >= 0);
+}
+
void tst_QTreeView::testInitialFocus()
{
QTreeWidget treeWidget;