summaryrefslogtreecommitdiffstats
path: root/src/widgets/itemviews
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/itemviews')
-rw-r--r--src/widgets/itemviews/qheaderview.cpp128
-rw-r--r--src/widgets/itemviews/qheaderview_p.h7
2 files changed, 120 insertions, 15 deletions
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 496d36015e..9b0959dda3 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -753,9 +753,6 @@ void QHeaderView::moveSection(int from, int to)
return;
}
- if (stretchLastSection() && to == d->lastVisibleVisualIndex())
- d->lastSectionSize = sectionSize(from);
-
d->initializeIndexMapping();
int *visualIndices = d->visualIndices.data();
@@ -788,6 +785,12 @@ void QHeaderView::moveSection(int from, int to)
d->viewport->update();
emit sectionMoved(logical, from, to);
+
+ if (stretchLastSection()) {
+ const int lastSectionVisualIdx = visualIndex(d->lastSectionLogicalIdx);
+ if (from >= lastSectionVisualIdx || to >= lastSectionVisualIdx)
+ d->maybeRestorePrevLastSectionAndStretchLast();
+ }
}
/*!
@@ -839,6 +842,12 @@ void QHeaderView::swapSections(int first, int second)
d->viewport->update();
emit sectionMoved(firstLogical, first, second);
emit sectionMoved(secondLogical, second, first);
+
+ if (stretchLastSection()) {
+ const int lastSectionVisualIdx = visualIndex(d->lastSectionLogicalIdx);
+ if (first >= lastSectionVisualIdx || second >= lastSectionVisualIdx)
+ d->maybeRestorePrevLastSectionAndStretchLast();
+ }
}
/*!
@@ -877,7 +886,7 @@ void QHeaderView::resizeSection(int logical, int size)
d->executePostedLayout();
d->invalidateCachedSizeHint();
- if (stretchLastSection() && visual == d->lastVisibleVisualIndex())
+ if (stretchLastSection() && logical == d->lastSectionLogicalIdx)
d->lastSectionSize = size;
d->createSectionItems(visual, visual, size, d->headerSectionResizeMode(visual));
@@ -1000,11 +1009,16 @@ void QHeaderView::setSectionHidden(int logicalIndex, bool hide)
if (hide == d->isVisualIndexHidden(visual))
return;
if (hide) {
+ const bool isHidingLastSection = (stretchLastSection() && logicalIndex == d->lastSectionLogicalIdx);
+ if (isHidingLastSection)
+ d->restoreSizeOnPrevLastSection(); // Restore here/now to get the right restore size.
int size = d->headerSectionSize(visual);
if (!d->hasAutoResizeSections())
resizeSection(logicalIndex, 0);
d->hiddenSectionSize.insert(logicalIndex, size);
d->setVisualIndexHidden(visual, true);
+ if (isHidingLastSection)
+ d->setNewLastSection(d->lastVisibleVisualIndex());
if (d->hasAutoResizeSections())
d->doDelayedResizeSections();
} else {
@@ -1012,6 +1026,12 @@ void QHeaderView::setSectionHidden(int logicalIndex, bool hide)
d->hiddenSectionSize.remove(logicalIndex);
d->setVisualIndexHidden(visual, false);
resizeSection(logicalIndex, size);
+
+ const bool newLastSection = (stretchLastSection() && visual > visualIndex(d->lastSectionLogicalIdx));
+ if (newLastSection) {
+ d->restoreSizeOnPrevLastSection();
+ d->setNewLastSection(visual);
+ }
}
}
@@ -1473,13 +1493,17 @@ bool QHeaderView::stretchLastSection() const
void QHeaderView::setStretchLastSection(bool stretch)
{
Q_D(QHeaderView);
+ const bool changedStretchMode = (d->stretchLastSection != stretch);
d->stretchLastSection = stretch;
if (d->state != QHeaderViewPrivate::NoState)
return;
- if (stretch)
+ if (stretch) {
+ d->setNewLastSection(d->lastVisibleVisualIndex());
resizeSections();
- else if (count())
- resizeSection(count() - 1, d->defaultSectionSize);
+ } else {
+ if (changedStretchMode)
+ d->restoreSizeOnPrevLastSection();
+ }
}
/*!
@@ -1834,6 +1858,21 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
int insertAt = logicalFirst;
int insertCount = logicalLast - logicalFirst + 1;
+ bool lastSectionActualChange = false;
+ if (stretchLastSection()) {
+
+ int visualIndexForStretch = d->lastSectionLogicalIdx;
+ if (d->lastSectionLogicalIdx >= 0 && d->lastSectionLogicalIdx < d->visualIndices.size())
+ visualIndexForStretch = d->visualIndices[d->lastSectionLogicalIdx]; // We cannot call visualIndex since it executes executePostedLayout()
+ // and it is likely to bypass initializeSections() and we may end up here again. Doing the insert twice.
+
+ if (d->lastSectionLogicalIdx < 0 || insertAt >= visualIndexForStretch)
+ lastSectionActualChange = true;
+
+ if (d->lastSectionLogicalIdx >= logicalFirst)
+ d->lastSectionLogicalIdx += insertCount; // We do not want to emit resize before we have fixed the count
+ }
+
QHeaderViewPrivate::SectionItem section(d->defaultSectionSize, d->globalResizeMode);
d->sectionStartposRecalc = true;
@@ -1890,6 +1929,9 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
d->doDelayedResizeSections();
emit sectionCountChanged(oldCount, count());
+ if (lastSectionActualChange)
+ d->maybeRestorePrevLastSectionAndStretchLast();
+
// if the new sections were not updated by resizing, we need to update now
if (!d->hasAutoResizeSections())
d->viewport->update();
@@ -2000,6 +2042,16 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
clear();
invalidateCachedSizeHint();
emit q->sectionCountChanged(oldCount, q->count());
+
+ if (q->stretchLastSection()) {
+ const bool lastSectionRemoved = lastSectionLogicalIdx >= logicalFirst && lastSectionLogicalIdx <= logicalLast;
+ if (lastSectionRemoved)
+ setNewLastSection(lastVisibleVisualIndex());
+ else
+ lastSectionLogicalIdx = logicalIndex(lastVisibleVisualIndex()); // Just update the last log index.
+ doDelayedResizeSections();
+ }
+
viewport->update();
}
@@ -2078,8 +2130,8 @@ void QHeaderView::initializeSections()
} else if (newCount != oldCount) {
const int min = qBound(0, oldCount, newCount - 1);
initializeSections(min, newCount - 1);
- if (stretchLastSection()) // we've already gotten the size hint
- d->lastSectionSize = sectionSize(logicalIndex(d->sectionCount() - 1));
+ if (stretchLastSection()) // we've already gotten the size hint
+ d->maybeRestorePrevLastSectionAndStretchLast();
//make sure we update the hidden sections
if (newCount < oldCount)
@@ -3169,6 +3221,42 @@ int QHeaderViewPrivate::lastVisibleVisualIndex() const
return -1;
}
+void QHeaderViewPrivate::restoreSizeOnPrevLastSection()
+{
+ Q_Q(QHeaderView);
+ if (lastSectionLogicalIdx < 0)
+ return;
+ int resizeLogIdx = lastSectionLogicalIdx;
+ lastSectionLogicalIdx = -1; // We do not want resize to catch it as the last section.
+ q->resizeSection(resizeLogIdx, lastSectionSize);
+}
+
+void QHeaderViewPrivate::setNewLastSection(int visualIndexForLastSection)
+{
+ Q_Q(QHeaderView);
+ lastSectionSize = -1;
+ lastSectionLogicalIdx = q->logicalIndex(visualIndexForLastSection);
+ lastSectionSize = headerSectionSize(visualIndexForLastSection); // pick size directly since ...
+ // q->sectionSize(lastSectionLogicalIdx) may do delayed resize and stretch it before we get the value.
+}
+
+void QHeaderViewPrivate::maybeRestorePrevLastSectionAndStretchLast()
+{
+ Q_Q(const QHeaderView);
+ if (!q->stretchLastSection())
+ return;
+
+ int nowLastVisualSection = lastVisibleVisualIndex();
+ if (lastSectionLogicalIdx == q->logicalIndex(nowLastVisualSection))
+ return;
+
+ // restore old last section.
+ restoreSizeOnPrevLastSection();
+ setNewLastSection(nowLastVisualSection);
+ doDelayedResizeSections(); // Do stretch of last section soon (but not now).
+}
+
+
/*!
\internal
Go through and resize all of the sections applying stretchLastSection,
@@ -3197,13 +3285,12 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
resizeRecursionBlock = true;
invalidateCachedSizeHint();
-
- const int lastVisibleSection = lastVisibleVisualIndex();
+ const int lastSectionVisualIdx = q->visualIndex(lastSectionLogicalIdx);
// find stretchLastSection if we have it
int stretchSection = -1;
if (stretchLastSection && !useGlobalMode)
- stretchSection = lastVisibleVisualIndex();
+ stretchSection = lastSectionVisualIdx;
// count up the number of stretched sections and how much space left for them
int lengthToStretch = (orientation == Qt::Horizontal ? viewport->width() : viewport->height());
@@ -3272,7 +3359,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
? QHeaderView::Stretch
: newSectionResizeMode);
if (resizeMode == QHeaderView::Stretch && stretchSectionLength != -1) {
- if (i == lastVisibleSection)
+ if (i == lastSectionVisualIdx)
newSectionLength = qMax(stretchSectionLength, lastSectionSize);
else
newSectionLength = stretchSectionLength;
@@ -3661,10 +3748,12 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << sectionItems;
out << resizeContentsPrecision;
out << customDefaultSectionSize;
+ out << lastSectionSize;
}
bool QHeaderViewPrivate::read(QDataStream &in)
{
+ Q_Q(QHeaderView);
int orient, order, align, global;
int sortIndicatorSectionIn;
bool sortIndicatorShownIn;
@@ -3683,7 +3772,6 @@ bool QHeaderViewPrivate::read(QDataStream &in)
int minimumSectionSizeIn;
QVector<SectionItem> sectionItemsIn;
-
in >> orient;
in >> order;
@@ -3776,6 +3864,18 @@ bool QHeaderViewPrivate::read(QDataStream &in)
updateDefaultSectionSizeFromStyle();
}
+ lastSectionSize = -1;
+ int inLastSectionSize;
+ in >> inLastSectionSize;
+ if (in.status() == QDataStream::Ok)
+ lastSectionSize = inLastSectionSize;
+
+ lastSectionLogicalIdx = -1;
+ if (stretchLastSection) {
+ lastSectionLogicalIdx = q->logicalIndex(lastVisibleVisualIndex());
+ doDelayedResizeSections();
+ }
+
return true;
}
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
index 60542e297a..d1982d4777 100644
--- a/src/widgets/itemviews/qheaderview_p.h
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -90,6 +90,7 @@ public:
minimumSectionSize(-1),
maximumSectionSize(-1),
lastSectionSize(0),
+ lastSectionLogicalIdx(-1), // Only trust when we stretch last section
sectionIndicatorOffset(0),
sectionIndicator(0),
globalResizeMode(QHeaderView::Interactive),
@@ -99,6 +100,9 @@ public:
int lastVisibleVisualIndex() const;
+ void restoreSizeOnPrevLastSection();
+ void setNewLastSection(int visualIndexForLastSection);
+ void maybeRestorePrevLastSectionAndStretchLast();
int sectionHandleAt(int position);
void setupSectionIndicator(int section, int position);
void updateSectionIndicator(int section, int position);
@@ -281,7 +285,8 @@ public:
int defaultSectionSize;
int minimumSectionSize;
int maximumSectionSize;
- int lastSectionSize; // $$$
+ int lastSectionSize;
+ int lastSectionLogicalIdx; // Only trust if we stretch LastSection
int sectionIndicatorOffset;
Qt::Alignment defaultAlignment;
QLabel *sectionIndicator;