summaryrefslogtreecommitdiffstats
path: root/src/widgets/itemviews/qheaderview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/itemviews/qheaderview.cpp')
-rw-r--r--src/widgets/itemviews/qheaderview.cpp148
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;
}