Fix out of bounds use of QVector API.
authorStephen Kelly <stephen.kelly@kdab.com>
Thu, 12 Apr 2012 15:23:19 +0000 (17:23 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 17 Apr 2012 14:28:46 +0000 (16:28 +0200)
This is a regression introduced by commit
22b7d211865c1505862627a2e65bcd063e314e45.

Task-number: QTBUG-24965
Task-number: QTBUG-25140

Change-Id: I3f3bfe23af802444b078a29ee5565dd2bd24a34d
Reviewed-by: David Faure <faure@kde.org>
src/widgets/itemviews/qtreeview.cpp
src/widgets/itemviews/qtreeview_p.h
tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp

index be78cdb..aaec2b1 100644 (file)
@@ -1390,7 +1390,10 @@ void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItemV4 *option,
 
     QVector<int> logicalIndices; // index = visual index of visible columns only. data = logical index.
     QVector<QStyleOptionViewItemV4::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex, visible columns only.
-    calcLogicalIndices(&logicalIndices, &viewItemPosList);
+    const bool spanning = viewItems.at(row).spanning;
+    const int left = (spanning ? header->visualIndex(0) : 0);
+    const int right = (spanning ? header->visualIndex(0) : header->count() - 1 );
+    calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);
 
     int columnIndex = 0;
     for (int visualIndex = 0; visualIndex < current.column(); ++visualIndex) {
@@ -1488,10 +1491,8 @@ static inline bool ancestorOf(QObject *widget, QObject *other)
     return false;
 }
 
-void QTreeViewPrivate::calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItemV4::ViewItemPosition> *itemPositions) const
+void QTreeViewPrivate::calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItemV4::ViewItemPosition> *itemPositions, int left, int right) const
 {
-    const int left = (spanning ? header->visualIndex(0) : leftAndRight.first);
-    const int right = (spanning ? header->visualIndex(0) : leftAndRight.second);
     const int columnCount = header->count();
     /* 'left' and 'right' are the left-most and right-most visible visual indices.
        Compute the first visible logical indices before and after the left and right.
@@ -1615,7 +1616,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
 
     QVector<int> logicalIndices;
     QVector<QStyleOptionViewItemV4::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex
-    d->calcLogicalIndices(&logicalIndices, &viewItemPosList);
+    d->calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);
 
     for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices.count(); ++currentLogicalSection) {
         int headerSection = logicalIndices.at(currentLogicalSection);
index c8fb885..091420e 100644 (file)
@@ -170,7 +170,7 @@ public:
 
     // logicalIndices: vector of currently visibly logical indices
     // itemPositions: vector of view item positions (beginning/middle/end/onlyone)
-    void calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItemV4::ViewItemPosition> *itemPositions) const;
+    void calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItemV4::ViewItemPosition> *itemPositions, int left, int right) const;
 
     QHeaderView *header;
     int indent;
index e1f175a..5908605 100644 (file)
@@ -2990,6 +2990,19 @@ void tst_QTreeView::styleOptionViewItem()
     view.setFirstColumnSpanned(2, QModelIndex(), true);
     view.setAlternatingRowColors(true);
 
+#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;
+        view.aiv_priv()->renderToPixmap(sel.indexes(), &rect);
+        QTRY_VERIFY(delegate.count == visibleColumns);
+    }
+#endif
+
     delegate.count = 0;
     delegate.allCollapsed = true;
     view.showMaximized();