diff options
author | David Faure <faure@kde.org> | 2010-12-03 10:34:09 (GMT) |
---|---|---|
committer | Gabriel de Dietrich <gabriel.dietrich-de@nokia.com> | 2011-09-29 09:33:26 (GMT) |
commit | d63910575949106f84dacf04abaa14fc866aa66b (patch) | |
tree | 57dbdb8ca4da4ef9c8782a0b93704bc53b376d44 | |
parent | 2c1e828af311bb103a6f02513cd339973e9582f6 (diff) | |
download | Qt-d63910575949106f84dacf04abaa14fc866aa66b.zip Qt-d63910575949106f84dacf04abaa14fc866aa66b.tar.gz Qt-d63910575949106f84dacf04abaa14fc866aa66b.tar.bz2 |
Set missing flags in the option when rendering QTreeView drag pixmap
QAbstractItemViewPrivate::renderToPixmap was not setting all the flags
that the normal QTreeView painting sets:
option.showDecorationSelected, option.viewItemPosition (so the drag pixmap
looked wrong on Windows 7, with rects around each cell), and then the
unittest also discovered that State_Children/State_Sibling wasn't set either.
Task-number: QTBUG-15834
Merge-request: 2517
Reviewed-by: Gabriel
-rw-r--r-- | src/gui/itemviews/qabstractitemview.cpp | 1 | ||||
-rw-r--r-- | src/gui/itemviews/qabstractitemview_p.h | 2 | ||||
-rw-r--r-- | src/gui/itemviews/qtreeview.cpp | 113 | ||||
-rw-r--r-- | src/gui/itemviews/qtreeview_p.h | 5 | ||||
-rw-r--r-- | tests/auto/qtreeview/tst_qtreeview.cpp | 11 |
5 files changed, 92 insertions, 40 deletions
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index ded4d63..1676c46 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -4238,6 +4238,7 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, for (int j = 0; j < paintPairs.count(); ++j) { option.rect = paintPairs.at(j).first.translated(-r->topLeft()); const QModelIndex ¤t = paintPairs.at(j).second; + adjustViewOptionsForIndex(&option, current); delegateForIndex(current)->paint(&painter, option, current); } return pixmap; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 04babde..b742529 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -193,6 +193,8 @@ public: #endif virtual QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; + // reimplemented in subclasses + virtual void adjustViewOptionsForIndex(QStyleOptionViewItemV4*, const QModelIndex&) const {} inline void releaseEditor(QWidget *editor) const { if (editor) { diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 9228ac8..868cd92 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1378,6 +1378,23 @@ QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList return ret; } +void QTreeViewPrivate::adjustViewOptionsForIndex(QStyleOptionViewItemV4 *option, const QModelIndex ¤t) const +{ + const int row = current.row(); + 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).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None); + + option->showDecorationSelected = (selectionBehavior & QTreeView::SelectRows) + || option->showDecorationSelected; + + QVector<int> logicalIndices; + QVector<QStyleOptionViewItemV4::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex + calcLogicalIndices(&logicalIndices, &viewItemPosList); + int logicalIndex = header->logicalIndex(current.column()); + option->viewItemPosition = viewItemPosList.at(logicalIndex); +} + /*! \since 4.2 @@ -1463,6 +1480,59 @@ static inline bool ancestorOf(QObject *widget, QObject *other) return false; } +void QTreeViewPrivate::calcLogicalIndices(QVector<int> *logicalIndices, QVector<QStyleOptionViewItemV4::ViewItemPosition> *itemPositions) 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. + We will use these values to determine the QStyleOptionViewItemV4::viewItemPosition. */ + int logicalIndexBeforeLeft = -1, logicalIndexAfterRight = -1; + for (int visualIndex = left - 1; visualIndex >= 0; --visualIndex) { + int logicalIndex = header->logicalIndex(visualIndex); + if (!header->isSectionHidden(logicalIndex)) { + logicalIndexBeforeLeft = logicalIndex; + break; + } + } + + for (int visualIndex = left; visualIndex < columnCount; ++visualIndex) { + int logicalIndex = header->logicalIndex(visualIndex); + if (!header->isSectionHidden(logicalIndex)) { + if (visualIndex > right) { + logicalIndexAfterRight = logicalIndex; + break; + } + logicalIndices->append(logicalIndex); + } + } + + itemPositions->resize(logicalIndices->count()); + for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices->count(); ++currentLogicalSection) { + const int headerSection = logicalIndices->at(currentLogicalSection); + // determine the viewItemPosition depending on the position of column 0 + int nextLogicalSection = currentLogicalSection + 1 >= logicalIndices->count() + ? logicalIndexAfterRight + : logicalIndices->at(currentLogicalSection + 1); + int prevLogicalSection = currentLogicalSection - 1 < 0 + ? logicalIndexBeforeLeft + : logicalIndices->at(currentLogicalSection - 1); + QStyleOptionViewItemV4::ViewItemPosition pos; + if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1) + || (headerSection == 0 && nextLogicalSection == -1) || spanning) + pos = QStyleOptionViewItemV4::OnlyOne; + else if (headerSection == 0 || (nextLogicalSection != 0 && prevLogicalSection == -1)) + pos = QStyleOptionViewItemV4::Beginning; + else if (nextLogicalSection == 0 || nextLogicalSection == -1) + pos = QStyleOptionViewItemV4::End; + else + pos = QStyleOptionViewItemV4::Middle; + (*itemPositions)[currentLogicalSection] = pos; + } +} + + /*! Draws the row in the tree view that contains the model item \a index, using the \a painter given. The \a option control how the item is @@ -1531,33 +1601,13 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, int width, height = option.rect.height(); int position; QModelIndex modelIndex; - int columnCount = header->count(); const bool hoverRow = selectionBehavior() == QAbstractItemView::SelectRows && index.parent() == hover.parent() && index.row() == hover.row(); - /* '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. - We will use these values to determine the QStyleOptionViewItemV4::viewItemPosition. */ - int logicalIndexBeforeLeft = -1, logicalIndexAfterRight = -1; - for (int visualIndex = left - 1; visualIndex >= 0; --visualIndex) { - int logicalIndex = header->logicalIndex(visualIndex); - if (!header->isSectionHidden(logicalIndex)) { - logicalIndexBeforeLeft = logicalIndex; - break; - } - } - QVector<int> logicalIndices; // vector of currently visibly logical indices - for (int visualIndex = left; visualIndex < columnCount; ++visualIndex) { - int logicalIndex = header->logicalIndex(visualIndex); - if (!header->isSectionHidden(logicalIndex)) { - if (visualIndex > right) { - logicalIndexAfterRight = logicalIndex; - break; - } - logicalIndices.append(logicalIndex); - } - } + QVector<int> logicalIndices; + QVector<QStyleOptionViewItemV4::ViewItemPosition> viewItemPosList; // vector of left/middle/end for each logicalIndex + d->calcLogicalIndices(&logicalIndices, &viewItemPosList); for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices.count(); ++currentLogicalSection) { int headerSection = logicalIndices.at(currentLogicalSection); @@ -1579,22 +1629,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, continue; opt.state = state; - // determine the viewItemPosition depending on the position of column 0 - int nextLogicalSection = currentLogicalSection + 1 >= logicalIndices.count() - ? logicalIndexAfterRight - : logicalIndices.at(currentLogicalSection + 1); - int prevLogicalSection = currentLogicalSection - 1 < 0 - ? logicalIndexBeforeLeft - : logicalIndices.at(currentLogicalSection - 1); - if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1) - || (headerSection == 0 && nextLogicalSection == -1) || spanning) - opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne; - else if (headerSection == 0 || (nextLogicalSection != 0 && prevLogicalSection == -1)) - opt.viewItemPosition = QStyleOptionViewItemV4::Beginning; - else if (nextLogicalSection == 0 || nextLogicalSection == -1) - opt.viewItemPosition = QStyleOptionViewItemV4::End; - else - opt.viewItemPosition = QStyleOptionViewItemV4::Middle; + opt.viewItemPosition = viewItemPosList.at(currentLogicalSection); // fake activeness when row editor has focus if (indexWidgetHasFocus) diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index a9dc452..ef8f11c 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -97,6 +97,7 @@ public: void initialize(); QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; + void adjustViewOptionsForIndex(QStyleOptionViewItemV4 *option, const QModelIndex ¤t) const; #ifndef QT_NO_ANIMATION struct AnimatedOperation : public QVariantAnimation @@ -167,6 +168,10 @@ public: void paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItemV4 *option, int y, int bottom) const; + // 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; + QHeaderView *header; int indent; diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index facb982..c37a4ea 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -45,6 +45,7 @@ #include <QtTest/QtTest> #include <QtGui/QtGui> +#include <private/qabstractitemview_p.h> #include "../../shared/util.h" //TESTED_CLASS= @@ -112,6 +113,8 @@ struct PublicView : public QTreeView inline QStyleOptionViewItem viewOptions() const { return QTreeView::viewOptions(); } inline int sizeHintForColumn(int column) const { return QTreeView::sizeHintForColumn(column); } + inline void startDrag(Qt::DropActions supportedActions) { QTreeView::startDrag(supportedActions); } + QAbstractItemViewPrivate* aiv_priv() { return static_cast<QAbstractItemViewPrivate*>(d_ptr.data()); } }; class tst_QTreeView : public QObject @@ -2947,7 +2950,7 @@ void tst_QTreeView::styleOptionViewItem() bool allCollapsed; }; - QTreeView view; + PublicView view; QStandardItemModel model; view.setModel(&model); MyDelegate delegate; @@ -3006,6 +3009,12 @@ void tst_QTreeView::styleOptionViewItem() QApplication::processEvents(); QTRY_VERIFY(delegate.count >= 4); + // test that the rendering of drag pixmap sets the correct options too (QTBUG-15834) + delegate.count = 0; + QItemSelection sel(model.index(0,0), model.index(0,3)); + QRect rect; + view.aiv_priv()->renderToPixmap(sel.indexes(), &rect); + QTRY_VERIFY(delegate.count >= 4); //test dynamic models { |