From 7c3abdb3bd7d10f2f25eaa18a3c606a7be5683fc Mon Sep 17 00:00:00 2001 From: Bastiaan Veelo Date: Mon, 24 Jan 2011 17:32:14 +0100 Subject: [PATCH 2/2] QTreeView::spanOverAvailableSpace property. --- src/gui/itemviews/qtreeview.cpp | 92 ++++++++++++++++++++++++++++++++++----- src/gui/itemviews/qtreeview.h | 4 ++ src/gui/itemviews/qtreeview_p.h | 4 +- 3 files changed, 88 insertions(+), 12 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 40b51fe..1c9b366 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -478,6 +478,29 @@ void QTreeView::setExpandsOnDoubleClick(bool enable) } /*! + \property QTreeView::spanOverAvailableSpace + \since 4.7.1+ + \brief whether the items span over columns with empty cells. + + This property holds whether the items may span over adjacent columns when + there is no data there. The default value is false. + + \sa isFirstColumnSpanned + \sa setFirstColumnSpanned +*/ +bool QTreeView::spanOverAvailableSpace() const +{ + Q_D(const QTreeView); + return d->spanOverAvailableSpace; +} + +void QTreeView::setSpanOverAvailableSpace(bool enable) +{ + Q_D(QTreeView); + d->spanOverAvailableSpace = enable; +} + +/*! Returns the horizontal position of the \a column in the viewport. */ int QTreeView::columnViewportPosition(int column) const @@ -1050,11 +1073,34 @@ QRect QTreeView::visualRect(const QModelIndex &index) const if (vi < 0) return QRect(); - bool spanning = d->viewItems.at(vi).spanning; + int x(0), w(0); + if (d->viewItems.at(vi).spanning) { + // Cover isFirstColumnSpanned(). + w = d->header->length(); + } + else if (d->spanOverAvailableSpace) { + // Cover spanOverAvailableSpace(). + x = columnViewportPosition(index.column()); + int logicalIndex = index.column(); + QModelIndex cell = index; + int visualIndex = d->header->visualIndex(logicalIndex); + do { + if (!d->header->isSectionHidden(logicalIndex)) + w += columnWidth(logicalIndex); + + visualIndex++; + if (visualIndex >= d->header->count()) + break; + logicalIndex = d->header->logicalIndex(visualIndex); + cell = d->model->index(index.row(), logicalIndex, index.parent()); + } while (!cell.isValid() || cell.data().isNull()); + } + else { + // The normal case. + x = columnViewportPosition(index.column()); + w = columnWidth(index.column()); + } - // if we have a spanning item, make the selection stretch from left to right - int x = (spanning ? 0 : columnViewportPosition(index.column())); - int w = (spanning ? d->header->length() : columnWidth(index.column())); // handle indentation if (index.column() == 0) { int i = d->indentationForItem(vi); @@ -1186,8 +1232,7 @@ void QTreeView::timerEvent(QTimerEvent *event) QRect rect; int viewportHeight = d->viewport->height(); int viewportWidth = d->viewport->width(); - for (int i = d->columnsToUpdate.size() - 1; i >= 0; --i) { - int column = d->columnsToUpdate.at(i); + foreach(int column, d->columnsToUpdate) { int x = columnViewportPosition(column); if (isRightToLeft()) rect |= QRect(0, 0, x + columnWidth(column), viewportHeight); @@ -1464,7 +1509,7 @@ static inline bool ancestorOf(QObject *widget, QObject *other) /*! 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 + using the \a painter given. The \a option controls how the item is displayed. \sa setAlternatingRowColors() @@ -1563,6 +1608,10 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, position = columnViewportPosition(headerSection) + offset.x(); width = header->sectionSize(headerSection); + modelIndex = d->model->index(index.row(), headerSection, parent); + if (!modelIndex.isValid()) + continue; + if (spanning) { int lastSection = header->logicalIndex(header->count() - 1); if (!reverse) { @@ -1572,10 +1621,23 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, position = columnViewportPosition(lastSection); } } + else if (d->spanOverAvailableSpace) { + width = 0; + int logicalIndex = headerSection; + QModelIndex cell = modelIndex; + int visualIndex = header->visualIndex(logicalIndex); + do { + if (!header->isSectionHidden(logicalIndex)) + width += header->sectionSize(logicalIndex); + + visualIndex++; + if (visualIndex > right) + break; + logicalIndex = header->logicalIndex(visualIndex); + cell = d->model->index(index.row(), logicalIndex, parent); + } while (!cell.isValid() || cell.data().isNull()); + } - modelIndex = d->model->index(index.row(), headerSection, parent); - if (!modelIndex.isValid()) - continue; opt.state = state; // determine the viewItemPosition depending on the position of column 0 @@ -2661,7 +2723,15 @@ void QTreeView::expandToDepth(int depth) void QTreeView::columnResized(int column, int /* oldSize */, int /* newSize */) { Q_D(QTreeView); - d->columnsToUpdate.append(column); + d->columnsToUpdate << column; + if (d->spanOverAvailableSpace) { + // Items to the left may span into this column, and must be updated. + int visualColumn = d->header->visualIndex(column) - 1; + while (visualColumn >= 0) { + d->columnsToUpdate << d->header->logicalIndex(visualColumn); + visualColumn--; + } + } if (d->columnResizeTimerID == 0) d->columnResizeTimerID = startTimer(0); } diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index 1d04893..ccac96f 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -69,6 +69,7 @@ class Q_GUI_EXPORT QTreeView : public QAbstractItemView Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap) Q_PROPERTY(bool headerHidden READ isHeaderHidden WRITE setHeaderHidden) Q_PROPERTY(bool expandsOnDoubleClick READ expandsOnDoubleClick WRITE setExpandsOnDoubleClick) + Q_PROPERTY(bool spanOverAvailableSpace READ spanOverAvailableSpace WRITE setSpanOverAvailableSpace) public: explicit QTreeView(QWidget *parent = 0); @@ -99,6 +100,9 @@ public: bool expandsOnDoubleClick() const; void setExpandsOnDoubleClick(bool enable); + bool spanOverAvailableSpace() const; + void setSpanOverAvailableSpace(bool enable); + int columnViewportPosition(int column) const; int columnWidth(int column) const; void setColumnWidth(int column, int width); diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index cbbfd0e..331cf19 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -89,6 +89,7 @@ public: uniformRowHeights(false), rootDecoration(true), itemsExpandable(true), sortingEnabled(false), expandsOnDoubleClick(true), + spanOverAvailableSpace(false), allColumnsShowFocus(false), current(0), spanning(false), animationsEnabled(false), columnResizeTimerID(0), autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false) {} @@ -178,6 +179,7 @@ public: bool itemsExpandable; bool sortingEnabled; bool expandsOnDoubleClick; + bool spanOverAvailableSpace; bool allColumnsShowFocus; // used for drawing @@ -228,7 +230,7 @@ public: // used for updating resized columns int columnResizeTimerID; - QList columnsToUpdate; + QSet columnsToUpdate; // used for the automatic opening of nodes during DND int autoExpandDelay; -- 1.7.3.1.msysgit.0