diff options
Diffstat (limited to 'src/widgets/itemviews/qheaderview.cpp')
-rw-r--r-- | src/widgets/itemviews/qheaderview.cpp | 148 |
1 files changed, 127 insertions, 21 deletions
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index e1aec3f4bd..c90a61d4ff 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -361,7 +361,9 @@ void QHeaderView::setModel(QAbstractItemModel *model) QObject::disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(_q_sectionsRemoved(QModelIndex,int,int))); QObject::disconnect(d->model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_layoutAboutToBeChanged())); + this, SLOT(_q_sectionsAboutToBeChanged())); + QObject::disconnect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sectionsChanged())); } else { QObject::disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(sectionsInserted(QModelIndex,int,int))); @@ -370,12 +372,16 @@ void QHeaderView::setModel(QAbstractItemModel *model) QObject::disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_sectionsRemoved(QModelIndex,int,int))); QObject::disconnect(d->model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_layoutAboutToBeChanged())); + this, SLOT(_q_sectionsAboutToBeChanged())); + QObject::disconnect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sectionsChanged())); } QObject::disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), this, SLOT(headerDataChanged(Qt::Orientation,int,int))); QObject::disconnect(d->model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_layoutAboutToBeChanged())); + this, SLOT(_q_sectionsAboutToBeChanged())); + QObject::disconnect(d->model, SIGNAL(layoutChanged()), + this, SLOT(_q_sectionsChanged())); } if (model && model != QAbstractItemModelPrivate::staticEmptyModel()) { @@ -387,7 +393,9 @@ void QHeaderView::setModel(QAbstractItemModel *model) QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(_q_sectionsRemoved(QModelIndex,int,int))); QObject::connect(model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_layoutAboutToBeChanged())); + this, SLOT(_q_sectionsAboutToBeChanged())); + QObject::connect(model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sectionsChanged())); } else { QObject::connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(sectionsInserted(QModelIndex,int,int))); @@ -396,12 +404,16 @@ void QHeaderView::setModel(QAbstractItemModel *model) QObject::connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_sectionsRemoved(QModelIndex,int,int))); QObject::connect(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), - this, SLOT(_q_layoutAboutToBeChanged())); + this, SLOT(_q_sectionsAboutToBeChanged())); + QObject::connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sectionsChanged())); } QObject::connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), this, SLOT(headerDataChanged(Qt::Orientation,int,int))); QObject::connect(model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_layoutAboutToBeChanged())); + this, SLOT(_q_sectionsAboutToBeChanged())); + QObject::connect(model, SIGNAL(layoutChanged()), + this, SLOT(_q_sectionsChanged())); } d->state = QHeaderViewPrivate::NoClear; @@ -608,7 +620,7 @@ int QHeaderView::visualIndexAt(int position) const return -1; if (d->reverse()) - vposition = d->viewport->width() - vposition; + vposition = d->viewport->width() - vposition - 1; vposition += d->offset; if (vposition > d->length) @@ -874,6 +886,10 @@ void QHeaderView::resizeSection(int logical, int size) if (logical < 0 || logical >= count() || size < 0 || size > maxSizeSection) return; + // make sure to not exceed bounds when setting size programmatically + if (size > 0) + size = qBound(minimumSectionSize(), size, maximumSectionSize()); + if (isSectionHidden(logical)) { d->hiddenSectionSize.insert(logical, size); return; @@ -1103,10 +1119,15 @@ int QHeaderView::logicalIndex(int visualIndex) const /*! \since 5.0 - If \a movable is true, the header may be moved by the user; otherwise it - is fixed in place. + If \a movable is true, the header sections may be moved by the user; + otherwise they are fixed in place. + + When used in combination with QTreeView, the first column is not + movable (since it contains the tree structure), by default. + You can make it movable with setFirstSectionMovable(true). \sa sectionsMovable(), sectionMoved() + \sa setFirstSectionMovable() */ void QHeaderView::setSectionsMovable(bool movable) @@ -1131,6 +1152,9 @@ void QHeaderView::setSectionsMovable(bool movable) Returns \c true if the header can be moved by the user; otherwise returns false. + By default, sections are movable in QTreeView (except for the first one), + and not movable in QTableView. + \sa setSectionsMovable() */ @@ -1151,6 +1175,39 @@ bool QHeaderView::sectionsMovable() const */ /*! + \since 5.10 + + If \a movable is true, the first column can be moved by the user. + In a QTreeView, the first column holds the tree structure and is + therefore non-movable by default, even after setSectionsMovable(true). + + It can be made movable again, for instance in the case of flat lists + without a tree structure, by calling this method. + In such a scenario, it is recommended to call QTreeView::setRootIsDecorated(false) + as well. + + This method has no effect unless setSectionsMovable(true) is called as well. + \sa setSectionsMovable() +*/ +void QHeaderView::setFirstSectionMovable(bool movable) +{ + Q_D(QHeaderView); + d->allowUserMoveOfSection0 = movable; +} + +/*! + \since 5.10 + + Returns \c true if the first column can be moved by the user, + when this header is used in a QTreeView. +*/ +bool QHeaderView::firstSectionMovable() const +{ + Q_D(const QHeaderView); + return d->allowUserMoveOfSection0; +} + +/*! \since 5.0 If \a clickable is true, the header will respond to single clicks. @@ -1608,9 +1665,25 @@ void QHeaderView::setMinimumSectionSize(int size) Q_D(QHeaderView); if (size < -1 || size > maxSizeSection) return; + // larger new min size - check current section sizes + const bool needSizeCheck = size > d->minimumSectionSize; d->minimumSectionSize = size; if (d->minimumSectionSize > maximumSectionSize()) - d->maximumSectionSize = size; + setMaximumSectionSize(size); + + if (needSizeCheck) { + if (d->hasAutoResizeSections()) { + d->doDelayedResizeSections(); + } else { + for (int visual = 0; visual < d->sectionCount(); ++visual) { + if (d->isVisualIndexHidden(visual)) + continue; + if (d->headerSectionSize(visual) < d->minimumSectionSize) + resizeSection(logicalIndex(visual), size); + } + } + } + } /*! @@ -1647,7 +1720,22 @@ void QHeaderView::setMaximumSectionSize(int size) if (minimumSectionSize() > size) d->minimumSectionSize = size; + // smaller new max size - check current section sizes + const bool needSizeCheck = size < d->maximumSectionSize; d->maximumSectionSize = size; + + if (needSizeCheck) { + if (d->hasAutoResizeSections()) { + d->doDelayedResizeSections(); + } else { + for (int visual = 0; visual < d->sectionCount(); ++visual) { + if (d->isVisualIndexHidden(visual)) + continue; + if (d->headerSectionSize(visual) > d->maximumSectionSize) + resizeSection(logicalIndex(visual), size); + } + } + } } @@ -2062,7 +2150,7 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent, viewport->update(); } -void QHeaderViewPrivate::_q_layoutAboutToBeChanged() +void QHeaderViewPrivate::_q_sectionsAboutToBeChanged() { //if there is no row/column we can't have mapping for columns //because no QModelIndex in the model would be valid @@ -2096,7 +2184,7 @@ void QHeaderViewPrivate::_q_layoutAboutToBeChanged() } } -void QHeaderViewPrivate::_q_layoutChanged() +void QHeaderViewPrivate::_q_sectionsChanged() { Q_Q(QHeaderView); viewport->update(); @@ -2565,8 +2653,20 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e) if (handle != -1 && (sectionResizeMode(handle) == Interactive)) { if (!hasCursor) setCursor(d->orientation == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor); - } else if (hasCursor) { - unsetCursor(); + } else { + if (hasCursor) + unsetCursor(); +#ifndef QT_NO_STATUSTIP + int logical = logicalIndexAt(pos); + QString statusTip; + if (logical != -1) + statusTip = d->model->headerData(logical, d->orientation, Qt::StatusTipRole).toString(); + if (d->shouldClearStatusTip || !statusTip.isEmpty()) { + QStatusTipEvent tip(statusTip); + QCoreApplication::sendEvent(d->parent, &tip); + d->shouldClearStatusTip = !statusTip.isEmpty(); + } +#endif // !QT_NO_STATUSTIP } #endif return; @@ -2794,14 +2894,18 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex && isHeaderArrowOnTheSide) margin += style()->pixelMetric(QStyle::PM_HeaderMarkSize, 0, this); - if (d->textElideMode != Qt::ElideNone) - opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode , rect.width() - margin); - - QVariant variant = d->model->headerData(logicalIndex, d->orientation, - Qt::DecorationRole); + const QVariant variant = d->model->headerData(logicalIndex, d->orientation, + Qt::DecorationRole); opt.icon = qvariant_cast<QIcon>(variant); if (opt.icon.isNull()) opt.icon = qvariant_cast<QPixmap>(variant); + if (!opt.icon.isNull()) // see CT_HeaderSection + margin += style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this) + + style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this); + + if (d->textElideMode != Qt::ElideNone) + opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode , rect.width() - margin); + QVariant foregroundBrush = d->model->headerData(logicalIndex, d->orientation, Qt::ForegroundRole); if (foregroundBrush.canConvert<QBrush>()) @@ -3412,9 +3516,11 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool int logicalIndex = q->logicalIndex(i); sectionSize = qMax(viewSectionSizeHint(logicalIndex), q->sectionSizeHint(logicalIndex)); - if (sectionSize > q->maximumSectionSize()) - sectionSize = q->maximumSectionSize(); } + sectionSize = qBound(q->minimumSectionSize(), + sectionSize, + q->maximumSectionSize()); + section_sizes.append(sectionSize); lengthToStretch -= sectionSize; } |