22#if QT_CONFIG(whatsthis)
25#include <private/qheaderview_p.h>
26#include <private/qabstractitemmodel_p.h>
27#include <private/qabstractitemdelegate_p.h>
29#ifndef QT_NO_DATASTREAM
35#ifndef QT_NO_DATASTREAM
299 d->disconnectModel();
312 d->viewport->setMouseTracking(
true);
315 delete d->itemDelegate;
326 d->layoutChangePersistentSections.clear();
328 d->disconnectModel();
332 d->modelConnections = {
377 return d->orientation;
390 return d->headerOffset;
404 if (
d->headerOffset == newOffset)
406 int ndelta =
d->headerOffset - newOffset;
407 d->headerOffset = newOffset;
409 d->viewport->scroll(isRightToLeft() ? -ndelta : ndelta, 0);
411 d->viewport->scroll(0, ndelta);
418 d->firstPos += ndelta;
419 d->lastPos += ndelta;
434 if (visualSectionNumber > -1 && visualSectionNumber < d->sectionCount()) {
435 int position =
d->headerSectionPosition(
d->adjustedVisualIndex(visualSectionNumber));
463 d->executePostedLayout();
464 d->executePostedResize();
478 if (
d->cachedSizeHint.isValid())
479 return d->cachedSizeHint;
480 d->cachedSizeHint =
QSize(0, 0);
481 const int sectionCount =
count();
485 for (
int checked = 0; checked < 100 &&
i < sectionCount; ++
i) {
490 d->cachedSizeHint =
d->cachedSizeHint.expandedTo(
hint);
493 i =
qMax(
i, sectionCount - 100 );
494 for (
int j = sectionCount - 1, checked = 0;
j >=
i && checked < 100; --
j) {
499 d->cachedSizeHint =
d->cachedSizeHint.expandedTo(
hint);
501 return d->cachedSizeHint;
511 QAbstractItemView::setVisible(
v);
513 QAbstractScrollArea *parent = qobject_cast<QAbstractScrollArea*>(parentWidget());
515 parent->updateGeometry();
532 if (logicalIndex < 0 || logicalIndex >=
count())
555 d->executePostedLayout();
556 d->executePostedResize();
557 const int count =
d->sectionCount();
562 vposition =
d->viewport->width() - vposition - 1;
563 vposition +=
d->headerOffset;
565 if (vposition >
d->length)
567 int visual =
d->headerVisualIndexAt(vposition);
571 while (
d->isVisualIndexHidden(visual)){
605 if (logicalIndex < 0 || logicalIndex >=
count())
610 d->executePostedResize();
611 return d->headerSectionSize(visual);
633 d->executePostedResize();
634 return d->headerSectionPosition(visual);
653 int offsetPosition =
position -
d->headerOffset;
656 return offsetPosition;
677template<
typename Container>
679 typename Container::size_type rangeStart,
680 typename Container::size_type rangeEnd,
681 typename Container::size_type targetPosition)
684 Q_ASSERT(targetPosition < rangeStart || targetPosition >= rangeEnd);
686 const bool forwardMove = targetPosition > rangeStart;
687 typename Container::size_type
first = std::min(rangeStart, targetPosition);
688 typename Container::size_type mid = forwardMove ? rangeEnd : rangeStart;
689 typename Container::size_type last = forwardMove ? targetPosition + 1 : rangeEnd;
690 std::rotate(
c.begin() +
first,
c.begin() + mid,
c.begin() + last);
703 d->executePostedLayout();
704 if (from < 0 || from >=
d->sectionCount() || to < 0 || to >=
d->sectionCount())
714 d->initializeIndexMapping();
716 int *visualIndices =
d->visualIndices.data();
717 int *logicalIndices =
d->logicalIndices.data();
718 int logical = logicalIndices[from];
722 while (visual < to) {
723 visualIndices[logicalIndices[visual + 1]] = visual;
724 logicalIndices[visual] = logicalIndices[visual + 1];
728 while (visual > to) {
729 visualIndices[logicalIndices[visual - 1]] = visual;
730 logicalIndices[visual] = logicalIndices[visual - 1];
734 visualIndices[logical] = to;
735 logicalIndices[to] = logical;
739 d->sectionStartposRecalc =
true;
741 if (
d->hasAutoResizeSections())
742 d->doDelayedResizeSections();
743 d->viewport->update();
748 const int lastSectionVisualIdx =
visualIndex(
d->lastSectionLogicalIdx);
749 if (from >= lastSectionVisualIdx || to >= lastSectionVisualIdx)
750 d->maybeRestorePrevLastSectionAndStretchLast();
767 d->executePostedLayout();
768 if (first < 0 || first >=
d->sectionCount() || second < 0 || second >=
d->sectionCount())
771 int firstSize =
d->headerSectionSize(
first);
773 int firstLogical =
d->logicalIndex(
first);
775 int secondSize =
d->headerSectionSize(second);
776 ResizeMode secondMode =
d->headerSectionResizeMode(second);
777 int secondLogical =
d->logicalIndex(second);
780 d->preventCursorChangeInSetOffset =
true;
782 d->createSectionItems(second, second, firstSize, firstMode);
783 d->createSectionItems(
first,
first, secondSize, secondMode);
785 d->initializeIndexMapping();
787 d->visualIndices[firstLogical] = second;
788 d->logicalIndices[second] = firstLogical;
790 d->visualIndices[secondLogical] =
first;
791 d->logicalIndices[
first] = secondLogical;
793 if (!
d->hiddenSectionSize.isEmpty()) {
794 bool firstHidden =
d->isVisualIndexHidden(
first);
795 bool secondHidden =
d->isVisualIndexHidden(second);
796 d->setVisualIndexHidden(
first, secondHidden);
797 d->setVisualIndexHidden(second, firstHidden);
800 d->viewport->update();
805 const int lastSectionVisualIdx =
visualIndex(
d->lastSectionLogicalIdx);
806 if (
first >= lastSectionVisualIdx || second >= lastSectionVisualIdx)
807 d->maybeRestorePrevLastSectionAndStretchLast();
833 d->hiddenSectionSize.insert(logical,
size);
842 d->preventCursorChangeInSetOffset =
true;
844 int oldSize =
d->headerSectionSize(visual);
848 d->executePostedLayout();
849 d->invalidateCachedSizeHint();
852 d->lastSectionSize =
size;
854 d->createSectionItems(visual, visual,
size,
d->headerSectionResizeMode(visual));
856 if (!updatesEnabled()) {
857 if (
d->hasAutoResizeSections())
858 d->doDelayedResizeSections();
863 int w =
d->viewport->width();
864 int h =
d->viewport->height();
875 if (
d->hasAutoResizeSections()) {
876 d->doDelayedResizeSections();
877 r =
d->viewport->rect();
887 QAbstractScrollArea *parent = qobject_cast<QAbstractScrollArea *>(parentWidget());
888 if (parent && parent->sizeAdjustPolicy() == QAbstractScrollArea::AdjustToContents)
889 parent->updateGeometry();
891 d->viewport->update(
r.normalized());
905 d->resizeSections(
mode,
true);
934 d->executePostedLayout();
935 if (
d->hiddenSectionSize.isEmpty() || logicalIndex < 0 || logicalIndex >=
d->sectionCount())
939 return d->isVisualIndexHidden(visual);
952 return d->hiddenSectionSize.size();
965 if (logicalIndex < 0 || logicalIndex >=
count())
968 d->executePostedLayout();
971 if (
hide ==
d->isVisualIndexHidden(visual))
975 if (isHidingLastSection)
976 d->restoreSizeOnPrevLastSection();
977 int size =
d->headerSectionSize(visual);
978 if (!
d->hasAutoResizeSections())
981 d->setVisualIndexHidden(visual,
true);
982 if (isHidingLastSection)
983 d->setNewLastSection(
d->lastVisibleVisualIndex());
984 if (
d->hasAutoResizeSections())
985 d->doDelayedResizeSections();
989 d->setVisualIndexHidden(visual,
false);
993 if (newLastSection) {
994 d->restoreSizeOnPrevLastSection();
995 d->setNewLastSection(visual);
1011 d->executePostedLayout();
1012 return d->sectionCount();
1029 d->executePostedLayout();
1030 if (
d->visualIndices.isEmpty()) {
1031 if (logicalIndex < d->sectionCount())
1033 }
else if (logicalIndex < d->visualIndices.size()) {
1035 Q_ASSERT(visual < d->sectionCount());
1053 if (visualIndex < 0 || visualIndex >=
d->sectionCount())
1078 d->movableSections = movable;
1087 return d->movableSections;
1117 d->allowUserMoveOfSection0 = movable;
1123 return d->allowUserMoveOfSection0;
1141 d->clickableSections = clickable;
1150 return d->clickableSections;
1156 d->highlightSelected = highlight;
1162 return d->highlightSelected;
1180 d->setGlobalHeaderResizeMode(
mode);
1181 if (
d->hasAutoResizeSections())
1182 d->doDelayedResizeSections();
1205 ResizeMode old =
d->headerSectionResizeMode(visual);
1206 d->setHeaderSectionResizeMode(visual,
mode);
1209 ++
d->stretchSections;
1211 ++
d->contentsSections;
1213 --
d->stretchSections;
1215 --
d->contentsSections;
1218 d->doDelayedResizeSections();
1236 return d->headerSectionResizeMode(visual);
1278 return d->resizeContentsPrecision;
1294 return d->stretchSections;
1309 if (
d->sortIndicatorShown ==
show)
1312 d->sortIndicatorShown =
show;
1320 d->viewport->update();
1326 return d->sortIndicatorShown;
1346 int old =
d->sortIndicatorSection;
1350 d->sortIndicatorOrder =
order;
1361 d->viewport->update();
1382 return d->sortIndicatorSection;
1395 return d->sortIndicatorOrder;
1421 if (
d->sortIndicatorClearable == clearable)
1423 d->sortIndicatorClearable = clearable;
1430 return d->sortIndicatorClearable;
1451 return d->stretchLastSection;
1457 if (
d->stretchLastSection == stretch)
1459 d->stretchLastSection = stretch;
1463 d->setNewLastSection(
d->lastVisibleVisualIndex());
1466 d->restoreSizeOnPrevLastSection();
1487 return d->cascadingResizing;
1493 d->cascadingResizing =
enable;
1513 return d->defaultSectionSize;
1521 d->setDefaultSectionSize(
size);
1527 if (
d->customDefaultSectionSize) {
1528 d->updateDefaultSectionSizeFromStyle();
1529 d->customDefaultSectionSize =
false;
1549 if (
d->minimumSectionSize == -1) {
1555 return d->minimumSectionSize;
1564 const bool needSizeCheck =
size >
d->minimumSectionSize;
1565 d->minimumSectionSize =
size;
1569 if (needSizeCheck) {
1570 if (
d->hasAutoResizeSections()) {
1571 d->doDelayedResizeSections();
1573 for (
int visual = 0; visual <
d->sectionCount(); ++visual) {
1574 if (
d->isVisualIndexHidden(visual))
1576 if (
d->headerSectionSize(visual) <
d->minimumSectionSize)
1601 if (
d->maximumSectionSize == -1)
1603 return d->maximumSectionSize;
1616 d->minimumSectionSize =
size;
1619 const bool needSizeCheck =
size <
d->maximumSectionSize;
1620 d->maximumSectionSize =
size;
1622 if (needSizeCheck) {
1623 if (
d->hasAutoResizeSections()) {
1624 d->doDelayedResizeSections();
1626 for (
int visual = 0; visual <
d->sectionCount(); ++visual) {
1627 if (
d->isVisualIndexHidden(visual))
1629 if (
d->headerSectionSize(visual) >
d->maximumSectionSize)
1646 return d->defaultAlignment;
1656 d->viewport->update();
1677 return !
d->visualIndices.isEmpty();
1691 return !
d->hiddenSectionSize.isEmpty();
1694#ifndef QT_NO_DATASTREAM
1709 stream.setVersion(QDataStream::Qt_5_0);
1727 if (
state.isEmpty())
1730 for (
const auto dataStreamVersion : {QDataStream::Qt_5_0, QDataStream::Qt_6_0}) {
1734 stream.setVersion(dataStreamVersion);
1739 if (
stream.status() != QDataStream::Ok
1747 d->viewport->update();
1766 d->invalidateCachedSizeHint();
1779 if (logicalFirst < 0 || logicalLast < 0 || logicalFirst >=
count() || logicalLast >=
count())
1782 d->invalidateCachedSizeHint();
1784 int firstVisualIndex = INT_MAX, lastVisualIndex = -1;
1786 for (
int section = logicalFirst; section <= logicalLast; ++section) {
1788 firstVisualIndex =
qMin(firstVisualIndex, visual);
1789 lastVisualIndex =
qMax(lastVisualIndex, visual);
1792 d->executePostedResize();
1793 const int first =
d->headerSectionPosition(firstVisualIndex),
1794 last =
d->headerSectionPosition(lastVisualIndex)
1795 +
d->headerSectionSize(lastVisualIndex);
1798 d->viewport->update(
first, 0, last -
first,
d->viewport->height());
1800 d->viewport->update(0,
first,
d->viewport->width(), last -
first);
1830 if (
d->hasAutoResizeSections())
1844 int logicalFirst,
int logicalLast)
1848 if (parent !=
d->root ||
d->modelSectionCount() ==
d->sectionCount())
1850 int oldCount =
d->sectionCount();
1852 d->invalidateCachedSizeHint();
1855 d->preventCursorChangeInSetOffset =
true;
1858 int insertAt = logicalFirst;
1859 int insertCount = logicalLast - logicalFirst + 1;
1861 bool lastSectionActualChange =
false;
1864 int visualIndexForStretch =
d->lastSectionLogicalIdx;
1865 if (
d->lastSectionLogicalIdx >= 0 &&
d->lastSectionLogicalIdx <
d->visualIndices.size())
1866 visualIndexForStretch =
d->visualIndices[
d->lastSectionLogicalIdx];
1869 if (
d->lastSectionLogicalIdx < 0 || insertAt >= visualIndexForStretch)
1870 lastSectionActualChange =
true;
1872 if (
d->lastSectionLogicalIdx >= logicalFirst)
1873 d->lastSectionLogicalIdx += insertCount;
1877 d->sectionStartposRecalc =
true;
1879 if (
d->sectionItems.isEmpty() || insertAt >=
d->sectionItems.size()) {
1880 int insertLength =
d->defaultSectionSize * insertCount;
1881 d->length += insertLength;
1882 d->sectionItems.insert(
d->sectionItems.size(), insertCount, section);
1885 int insertLength =
d->defaultSectionSize * insertCount;
1886 d->length += insertLength;
1887 d->sectionItems.insert(insertAt, insertCount, section);
1891 if (
d->sortIndicatorSection >= logicalFirst)
1892 d->sortIndicatorSection += insertCount;
1895 if (
d->globalResizeMode ==
Stretch)
1896 d->stretchSections =
d->sectionCount();
1898 d->contentsSections =
d->sectionCount();
1901 d->sectionSelected.clear();
1904 if (!
d->visualIndices.isEmpty() && !
d->logicalIndices.isEmpty()) {
1905 Q_ASSERT(
d->visualIndices.size() ==
d->logicalIndices.size());
1906 int mappingCount =
d->visualIndices.size();
1907 for (
int i = 0;
i < mappingCount; ++
i) {
1908 if (
d->visualIndices.at(
i) >= logicalFirst)
1909 d->visualIndices[
i] += insertCount;
1910 if (
d->logicalIndices.at(
i) >= logicalFirst)
1911 d->logicalIndices[
i] += insertCount;
1913 for (
int j = logicalFirst;
j <= logicalLast; ++
j) {
1914 d->visualIndices.insert(
j,
j);
1915 d->logicalIndices.insert(
j,
j);
1920 QHash<int, int> newHiddenSectionSize;
1922 end =
d->hiddenSectionSize.cend();
it !=
end; ++
it) {
1923 const int oldIndex =
it.key();
1924 const int newIndex = (oldIndex < logicalFirst) ? oldIndex : oldIndex + insertCount;
1925 newHiddenSectionSize[newIndex] =
it.value();
1927 d->hiddenSectionSize.
swap(newHiddenSectionSize);
1929 d->doDelayedResizeSections();
1932 if (lastSectionActualChange)
1933 d->maybeRestorePrevLastSectionAndStretchLast();
1936 if (!
d->hasAutoResizeSections())
1937 d->viewport->update();
1949 int logicalFirst,
int logicalLast)
1959 const int changeCount = logicalLast - logicalFirst + 1;
1962 QHash<int, int> newHiddenSectionSize;
1963 for (
int i = 0;
i < logicalFirst; ++
i)
1964 if (
q->isSectionHidden(
i))
1967 if (
q->isSectionHidden(
j))
1973 int logicalFirst,
int logicalLast)
1978 if (
qMin(logicalFirst, logicalLast) < 0
1981 int oldCount =
q->count();
1982 int changeCount = logicalLast - logicalFirst + 1;
1993 if (logicalFirst == logicalLast) {
1994 int l = logicalFirst;
2023 if (logindex > logicalFirst)
2024 logindex -= changeCount;
2025 visual_data[logindex] =
w;
2026 logical_data[
w] = logindex;
2044 emit q->sectionCountChanged(oldCount,
q->count());
2046 if (
q->stretchLastSection()) {
2048 if (lastSectionRemoved)
2059 int logicalEnd,
const QModelIndex &destinationParent,
2060 int logicalDestination)
2062 if (sourceParent !=
root || destinationParent !=
root)
2071 int logicalEnd,
const QModelIndex &destinationParent,
2072 int logicalDestination)
2074 if (sourceParent !=
root || destinationParent !=
root)
2143 if (newCount == 0) {
2146 emit q->sectionCountChanged(oldCount, 0);
2150 bool hasPersistantIndexes =
false;
2151 for (
const auto &
item : oldPersistentSections) {
2152 if (
item.index.isValid()) {
2153 hasPersistantIndexes =
true;
2168 if (!hasPersistantIndexes) {
2169 if (oldCount != newCount)
2170 q->initializeSections();
2175 if (newCount != oldCount) {
2176 const int min =
qBound(0, oldCount, newCount - 1);
2177 q->initializeSections(min, newCount - 1);
2185 for (
const auto &
item : oldPersistentSections) {
2187 if (!
index.isValid())
2194 const int newVisualIndex =
visualIndex(newLogicalIndex);
2197 newSection =
item.section;
2199 if (newSection.isHidden) {
2201 newSection.isHidden =
false;
2202 q->setSectionHidden(newLogicalIndex,
true);
2224 const int oldCount =
d->sectionCount();
2225 const int newCount =
d->modelSectionCount();
2226 if (newCount <= 0) {
2229 }
else if (newCount != oldCount) {
2230 const int min =
qBound(0, oldCount, newCount - 1);
2233 d->maybeRestorePrevLastSectionAndStretchLast();
2237 if (newCount < oldCount)
2238 d->updateHiddenSections(newCount, oldCount);
2253 d->invalidateCachedSizeHint();
2254 int oldCount =
d->sectionCount();
2256 if (
end + 1 <
d->sectionCount()) {
2257 int newCount =
end + 1;
2258 d->removeSectionsFromSectionItems(newCount,
d->sectionCount() - 1);
2259 if (!
d->hiddenSectionSize.isEmpty()) {
2260 if (oldCount - newCount >
d->hiddenSectionSize.size()) {
2261 for (
int i =
end + 1;
i <
d->sectionCount(); ++
i)
2262 d->hiddenSectionSize.remove(
i);
2265 while (
it !=
d->hiddenSectionSize.
end()) {
2275 int newSectionCount =
end + 1;
2277 if (!
d->logicalIndices.isEmpty()) {
2278 if (oldCount <= newSectionCount) {
2279 d->logicalIndices.resize(newSectionCount);
2280 d->visualIndices.resize(newSectionCount);
2281 for (
int i = oldCount;
i < newSectionCount; ++
i) {
2282 d->logicalIndices[
i] =
i;
2283 d->visualIndices[
i] =
i;
2287 for (
int i = 0;
i < oldCount; ++
i) {
2288 int v =
d->logicalIndices.at(
i);
2289 if (
v < newSectionCount) {
2290 d->logicalIndices[
j] =
v;
2291 d->visualIndices[
v] =
j;
2295 d->logicalIndices.resize(newSectionCount);
2296 d->visualIndices.resize(newSectionCount);
2300 if (
d->globalResizeMode ==
Stretch)
2301 d->stretchSections = newSectionCount;
2303 d->contentsSections = newSectionCount;
2305 if (newSectionCount > oldCount)
2306 d->createSectionItems(
start,
end,
d->defaultSectionSize,
d->globalResizeMode);
2309 if (
d->sectionCount() != oldCount)
2311 d->viewport->update();
2347 switch (e->
type()) {
2362 int oldHover =
d->hover;
2364 if (
d->hover != oldHover) {
2373 if (te->timerId() ==
d->delayedResize.timerId()) {
2374 d->delayedResize.stop();
2379 if (!
d->customDefaultSectionSize)
2380 d->updateDefaultSectionSizeFromStyle();
2426 d->prepareSectionSelected();
2428 QRect currentSectionRect;
2430 const int height =
d->viewport->height();
2431 const int rtlHorizontalOffset =
d->reverse() ? 1 : 0;
2433 if (
d->isVisualIndexHidden(
i))
2444 currentSectionRect.translate(
offset);
2461 if (currentSectionRect.left() > translatedEventRect.left()) {
2463 currentSectionRect.left() - translatedEventRect.left(),
height);
2466 }
else if (currentSectionRect.right() < translatedEventRect.right()) {
2470 translatedEventRect.right() - currentSectionRect.right(),
height);
2472 }
else if (currentSectionRect.bottom() < translatedEventRect.bottom()) {
2482 for (
int a = 0,
i = 0;
i <
d->sectionItems.count(); ++
i) {
2483 QColor color((
i & 4 ? 255 : 0), (
i & 2 ? 255 : 0), (
i & 1 ? 255 : 0));
2488 a +=
d->sectionItems.at(
i).size;
2505 d->originalSize = -1;
2508 if (
d->clickableSections)
2511 bool acceptMoveSection =
d->movableSections;
2512 if (acceptMoveSection &&
d->pressed == 0 && !
d->allowUserMoveOfSection0)
2513 acceptMoveSection =
false;
2515 if (acceptMoveSection) {
2517 d->section =
d->pressed;
2518 if (
d->section == -1)
2521 d->setupSectionIndicator(
d->section,
pos);
2522 }
else if (
d->clickableSections &&
d->pressed != -1) {
2530 d->preventCursorChangeInSetOffset =
false;
2536 d->clearCascadingSections();
2556 d->firstPressed =
d->pressed = -1;
2561 if (
d->cascadingResizing) {
2562 int delta =
d->reverse() ?
d->lastPos -
pos :
pos -
d->lastPos;
2564 d->cascadingResize(visual,
d->headerSectionSize(visual) + delta);
2566 int delta =
d->reverse() ?
d->firstPos -
pos :
pos -
d->firstPos;
2575 d->draggedPosition = e->
pos() +
d->offset();
2576 d->startAutoScroll();
2580 || !
d->sectionIndicator->isHidden()
2586 if (visual == 0 &&
logicalIndex(0) == 0 && !
d->allowUserMoveOfSection0)
2589 const int posThreshold =
d->headerSectionPosition(visual) -
d->headerOffset +
d->headerSectionSize(visual) / 2;
2590 const int checkPos =
d->reverse() ?
d->viewport->width() -
pos :
pos;
2592 int oldTarget =
d->target;
2593 if (visual < moving) {
2594 if (checkPos < posThreshold)
2595 d->target =
d->logicalIndex(visual);
2597 d->target =
d->logicalIndex(visual + 1);
2598 }
else if (visual > moving) {
2599 if (checkPos > posThreshold)
2600 d->target =
d->logicalIndex(visual);
2602 d->target =
d->logicalIndex(visual - 1);
2604 d->target =
d->section;
2606 if (oldTarget !=
d->target || oldTarget == -1)
2607 d->updateSectionsBeforeAfter(
d->target);
2608 d->updateSectionIndicator(
d->section,
pos);
2614 if (logical == -1 &&
pos > 0)
2616 if (logical ==
d->pressed)
2618 else if (
d->pressed != -1)
2620 d->pressed = logical;
2621 if (
d->clickableSections && logical != -1) {
2637#ifndef QT_NO_STATUSTIP
2642 if (
d->shouldClearStatusTip || !statusTip.
isEmpty()) {
2645 d->shouldClearStatusTip = !statusTip.
isEmpty();
2669 && !
d->sectionIndicator->isHidden()
2677 d->section =
d->target = -1;
2678 d->updateSectionIndicator(
d->section,
pos);
2680 d->updateSectionsBeforeAfter(from);
2685 if (!
d->clickableSections) {
2691 if (
d->clickableSections) {
2693 if (section != -1 && section ==
d->firstPressed) {
2694 QRect firstPressedSectionRect;
2695 switch (
d->orientation) {
2700 d->viewport->height());
2703 firstPressedSectionRect.setRect(0,
2705 d->viewport->width(),
2711 d->flipSortIndicator(section);
2715 if (
d->pressed != -1)
2720 d->originalSize = -1;
2721 d->clearCascadingSections();
2727 d->firstPressed =
d->pressed = -1;
2744 if (
cursor().shape() == splitCursor) {
2763 switch (e->
type()) {
2764#if QT_CONFIG(tooltip)
2768 if (logical != -1) {
2777#if QT_CONFIG(whatsthis)
2788 if (logical != -1) {
2789 QVariant whatsthis =
d->model->headerData(logical,
d->orientation,
2798#if QT_CONFIG(statustip)
2802 if (logical != -1) {
2803 QString statustip =
d->model->headerData(logical,
d->orientation,
2806 setStatusTip(statustip);
2813 d->invalidateCachedSizeHint();
2817 QAbstractScrollArea *parent = qobject_cast<QAbstractScrollArea *>(parentWidget());
2818 if (parent && parent->isVisible())
2824 d->pressed =
d->section =
d->target = -1;
2825 d->updateSectionIndicator(
d->section, -1);
2828 QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea *>(parentWidget());
2859 if (
window()->isActiveWindow())
2861 if (
d->clickableSections) {
2866 else if (
d->highlightSelected) {
2883 ? QtPrivate::legacyFlagValueFromModelData<Qt::Alignment>(textAlignment)
2884 :
d->defaultAlignment;
2901 optV2->textElideMode =
d->textElideMode;
2918 bool first =
d->isFirstVisibleSection(visual);
2919 bool last =
d->isLastVisibleSection(visual);
2928 opt.orientation =
d->orientation;
2930 bool previousSelected =
d->isSectionSelected(this->
logicalIndex(visual - 1));
2931 bool nextSelected =
d->isSectionSelected(this->
logicalIndex(visual + 1));
2932 if (previousSelected && nextSelected)
2934 else if (previousSelected)
2936 else if (nextSelected)
2953 if (!
rect.isValid())
2972 if (oBrushButton != nBrushButton || oBrushWindow != nBrushWindow) {
2998 return qvariant_cast<QSize>(
variant);
3008 fnt = qvariant_cast<QFont>(
var);
3035 return d->headerOffset;
3050 return d->headerOffset;
3062 d->layoutChildren();
3063 if (
d->hasAutoResizeSections())
3064 d->doDelayedResizeSections();
3075 d->scrollDirtyRegion(dx, dy);
3083 const QList<int> &roles)
3086 if (!roles.isEmpty()) {
3087 const auto doesRoleAffectSize = [](
int role) ->
bool {
3099 if (std::none_of(roles.begin(), roles.end(), doesRoleAffectSize))
3102 d->invalidateCachedSizeHint();
3103 if (
d->hasAutoResizeSections()) {
3107 for (
int i =
first;
i <= last && !resizeRequired; ++
i)
3110 d->doDelayedResizeSections();
3206 const int max =
d->modelSectionCount();
3209 int logicalLeft = max;
3210 int logicalRight = 0;
3212 if (
d->visualIndices.empty()) {
3215 if (
r.parent().isValid() || !
r.isValid())
3217 if (
r.left() < logicalLeft)
3218 logicalLeft =
r.left();
3219 if (
r.right() > logicalRight)
3220 logicalRight =
r.right();
3226 if (
r.parent().isValid() || !
r.isValid())
3228 for (
int k =
r.left(); k <=
r.right(); ++k) {
3242 if (logicalLeft < 0 || logicalLeft >=
count() ||
3243 logicalRight < 0 || logicalRight >=
count())
3249 return QRect(leftPos, 0, rightPos - leftPos,
height());
3252 int logicalTop = max;
3253 int logicalBottom = 0;
3255 if (
d->visualIndices.empty()) {
3258 if (
r.parent().isValid() || !
r.isValid())
3260 if (
r.top() < logicalTop)
3261 logicalTop =
r.top();
3262 if (
r.bottom() > logicalBottom)
3263 logicalBottom =
r.bottom();
3270 if (
r.parent().isValid() || !
r.isValid())
3272 for (
int k =
r.top(); k <=
r.bottom(); ++k) {
3287 if (logicalTop < 0 || logicalTop >=
count() ||
3288 logicalBottom < 0 || logicalBottom >=
count())
3294 return QRect(0, topPos,
width(), bottomPos - topPos);
3303 int visual =
q->visualIndexAt(
position);
3307 int pos =
q->sectionViewportPosition(log);
3311 bool atRight = (
position >
pos +
q->sectionSize(log) - grip);
3313 qSwap(atLeft, atRight);
3317 while(visual > -1) {
3318 int logical =
q->logicalIndex(--visual);
3319 if (!
q->isSectionHidden(logical))
3322 }
else if (atRight) {
3333 if (!sectionIndicator) {
3339 int p =
q->sectionViewportPosition(
section);
3348 sectionIndicator->resize(
w,
h);
3351 const qreal pixmapDevicePixelRatio =
q->devicePixelRatio();
3361 const QFont sectionFont = qvariant_cast<QFont>(
variant);
3372 sectionIndicator->setPixmap(pm);
3380 if (!sectionIndicator)
3384 sectionIndicator->hide();
3393 sectionIndicator->show();
3409 option->orientation =
d->orientation;
3446 return item.size > 0 &&
item.calculated_startpos == 0;
3464 for (
int visual =
q->count()-1; visual >= 0; --visual) {
3465 if (!
q->isSectionHidden(
q->logicalIndex(visual)))
3495 if (!
q->stretchLastSection())
3540 int stretchSection = -1;
3542 stretchSection = lastSectionVisualIdx;
3546 int numberOfStretchedSections = 0;
3547 QList<int> section_sizes;
3553 if (useGlobalMode && (
i != stretchSection))
3554 resizeMode = globalMode;
3559 ++numberOfStretchedSections;
3565 int sectionSize = 0;
3573 sectionSize =
qBound(
q->minimumSectionSize(),
3575 q->maximumSectionSize());
3577 section_sizes.append(sectionSize);
3578 lengthToStretch -= sectionSize;
3582 int stretchSectionLength = -1;
3583 int pixelReminder = 0;
3584 if (numberOfStretchedSections > 0 && lengthToStretch > 0) {
3585 int hintLengthForEveryStretchedSection = lengthToStretch / numberOfStretchedSections;
3586 stretchSectionLength =
qMax(hintLengthForEveryStretchedSection,
q->minimumSectionSize());
3587 pixelReminder = lengthToStretch % numberOfStretchedSections;
3591 int spanStartSection = 0;
3592 int previousSectionLength = 0;
3599 int newSectionLength = -1;
3603 newSectionLength = 0;
3607 resizeMode = globalMode;
3609 resizeMode = (
i == stretchSection
3611 : newSectionResizeMode);
3613 if (
i == lastSectionVisualIdx)
3616 newSectionLength = stretchSectionLength;
3617 if (pixelReminder > 0) {
3618 newSectionLength += 1;
3621 section_sizes.removeFirst();
3623 newSectionLength = section_sizes.takeFirst();
3628 if ((previousSectionResizeMode != newSectionResizeMode
3629 || previousSectionLength != newSectionLength) &&
i > 0) {
3630 createSectionItems(spanStartSection,
i - 1, previousSectionLength, previousSectionResizeMode);
3632 spanStartSection =
i;
3635 if (newSectionLength != oldSectionLength)
3638 previousSectionLength = newSectionLength;
3639 previousSectionResizeMode = newSectionResizeMode;
3643 previousSectionLength, previousSectionResizeMode);
3657 length += (sizePerSection - sectiondata[
i].size);
3659 sectiondata[
i].size = sizePerSection;
3660 sectiondata[
i].resizeMode =
mode;
3668 int removedlength = 0;
3719 q->setSortIndicator(
section, sortOrder);
3725 if (
value.canConvert<
int>())
3733 const int minimumSize =
q->minimumSectionSize();
3735 int delta = newSize - oldSize;
3738 bool sectionResized =
false;
3745 if (currentSectionSize < originalSectionSize) {
3746 int newSectionSize = currentSectionSize + delta;
3748 if (newSectionSize >= originalSectionSize &&
false)
3750 sectionResized =
true;
3758 if (!sectionResized) {
3759 newSize =
qMax(newSize, minimumSize);
3760 if (oldSize != newSize)
3771 if (currentSectionSize <= minimumSize)
3773 int newSectionSize =
qMax(currentSectionSize - delta, minimumSize);
3776 delta = delta - (currentSectionSize - newSectionSize);
3781 bool sectionResized =
false;
3789 if (currentSectionSize >= originalSectionSize)
3791 int newSectionSize = currentSectionSize - delta;
3793 if (newSectionSize >= originalSectionSize &&
false) {
3796 sectionResized =
true;
3804 if (delta < 0 && newSize < minimumSize) {
3805 for (
int i = visual - 1;
i >= 0; --
i) {
3811 if (sectionSize <= minimumSize)
3820 if (!sectionResized) {
3827 int newSectionSize =
qMax(currentSectionSize - delta, minimumSize);
3853 const int newSize =
size;
3854 if (newSize !=
section.size) {
3856 const int oldSectionSize =
section.sectionSize();
3883 i.calculated_startpos = pixelpos;
3920 while (startidx <= endidx) {
3921 int middle = (endidx + startidx) / 2;
3923 endidx = middle - 1;
3926 startidx = middle + 1;
3958 ?
view->sizeHintForColumn(logical)
3959 :
view->sizeHintForRow(logical));
3968 int currentVisualIndex = 0;
3973 ++currentVisualIndex;
3987 q->setOffsetToLastSection();
4004 std::swap(from, to);
4005 updateRect =
QRect(
QPoint(
q->sectionViewportPosition(from), 0),
4008 updateRect =
QRect(
QPoint(0,
q->sectionViewportPosition(from)),
4014#ifndef QT_NO_DATASTREAM
4054 int sortIndicatorSectionIn;
4055 bool sortIndicatorShownIn;
4057 QList<int> visualIndicesIn;
4058 QList<int> logicalIndicesIn;
4059 QHash<int, int> hiddenSectionSizeIn;
4060 bool movableSectionsIn;
4061 bool clickableSectionsIn;
4062 bool highlightSelectedIn;
4063 bool stretchLastSectionIn;
4064 bool cascadingResizingIn;
4065 int stretchSectionsIn;
4066 int contentsSectionsIn;
4067 int defaultSectionSizeIn;
4068 int minimumSectionSizeIn;
4069 QList<SectionItem> sectionItemsIn;
4074 in >> sortIndicatorSectionIn;
4075 in >> sortIndicatorShownIn;
4077 in >> visualIndicesIn;
4078 in >> logicalIndicesIn;
4081 in >> sectionHidden;
4082 in >> hiddenSectionSizeIn;
4085 int unusedSectionCount;
4086 in >> unusedSectionCount;
4088 if (
in.status() != QDataStream::Ok || lengthIn < 0)
4091 in >> movableSectionsIn;
4092 in >> clickableSectionsIn;
4093 in >> highlightSelectedIn;
4094 in >> stretchLastSectionIn;
4095 in >> cascadingResizingIn;
4096 in >> stretchSectionsIn;
4097 in >> contentsSectionsIn;
4098 in >> defaultSectionSizeIn;
4099 in >> minimumSectionSizeIn;
4114 in >> sectionItemsIn;
4118 QList<SectionItem> newSectionItems;
4119 for (
int u = 0; u < sectionItemsIn.size(); ++u) {
4120 int count = sectionItemsIn.at(u).tmpDataStreamSectionCount;
4122 sectionItemsIn[u].size /=
count;
4124 newSectionItems.append(sectionItemsIn[u]);
4127 int sectionItemsLengthTotal = 0;
4129 sectionItemsLengthTotal +=
section.size;
4130 if (sectionItemsLengthTotal != lengthIn)
4134 if (newSectionItems.size() < currentCount) {
4136 if (!visualIndicesIn.isEmpty() && !logicalIndicesIn.isEmpty()) {
4137 for (
int i = newSectionItems.size();
i < currentCount; ++
i) {
4138 visualIndicesIn.append(
i);
4139 logicalIndicesIn.append(
i);
4142 const int insertCount = currentCount - newSectionItems.size();
4143 const int insertLength = defaultSectionSizeIn * insertCount;
4144 lengthIn += insertLength;
4146 newSectionItems.insert(newSectionItems.size(), insertCount,
section);
4177 if (
in.status() == QDataStream::Ok)
4182 if (
in.status() == QDataStream::Ok) {
4189 int inLastSectionSize;
4190 in >> inLastSectionSize;
4191 if (
in.status() == QDataStream::Ok)
4200 int inSortIndicatorClearable;
4201 in >> inSortIndicatorClearable;
4202 if (
in.status() == QDataStream::Ok)
4212#include "moc_qheaderview.cpp"
static QAbstractItemModel * staticEmptyModel()
void rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow, QPrivateSignal)
void columnsRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after columns have been removed from the model.
LayoutChangeHint
This enum describes the way the model changes layout.
virtual Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
Returns the data for the given role and section in the header with the specified orientation.
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
virtual Q_INVOKABLE int rowCount(const QModelIndex &parent=QModelIndex()) const =0
Returns the number of rows under the given parent.
void columnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn, QPrivateSignal)
void columnsAboutToBeRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted just before columns are removed from the model.
void layoutChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
void headerDataChanged(Qt::Orientation orientation, int first, int last)
This signal is emitted whenever a header is changed.
void rowsAboutToBeRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted just before rows are removed from the model.
void rowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow, QPrivateSignal)
virtual Q_INVOKABLE int columnCount(const QModelIndex &parent=QModelIndex()) const =0
Returns the number of columns for the children of the given parent.
void rowsInserted(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after rows have been inserted into the model.
void columnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn, QPrivateSignal)
void columnsInserted(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after columns have been inserted into the model.
virtual Q_INVOKABLE QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const =0
Returns the index of the item in the model specified by the given row, column and parent index.
void rowsRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after rows have been removed from the model.
QPersistentModelIndex root
QAbstractItemModel * model
void executePostedLayout() const
The QAbstractItemView class provides the basic functionality for item view classes.
QAbstractItemModel * model() const
Returns the model that this view is presenting.
bool event(QEvent *event) override
\reimp
State state() const
Returns the item view's state.
virtual void reset()
Reset the internal state of the view.
bool viewportEvent(QEvent *event) override
This function is used to handle tool tips, and What's This? mode, if the given event is a QEvent::Too...
virtual void setModel(QAbstractItemModel *model)
Sets the model for the view to present.
virtual void doItemsLayout()
CursorAction
This enum describes the different ways to navigate between items,.
ScrollHint
\value EnsureVisible Scroll to ensure that the item is visible.
int value
the slider's current value
int maximum
the slider's maximum value
int startDragDistance
the minimum distance required for a drag and drop operation to start.
void stop()
Stops the timer.
void clear()
Clears the contents of the bit array and makes it empty.
bool testBit(qsizetype i) const
Returns true if the bit at index position i is 1; otherwise returns false.
void setBit(qsizetype i)
Sets the bit at index position i to 1.
qsizetype size() const
Returns the number of bits stored in the bit array.
The QColor class provides colors based on RGB, HSV or CMYK values.
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
static void setPos(int x, int y)
Moves the cursor (hot spot) of the primary screen to the global screen position (x,...
static QPoint pos()
Returns the position of the cursor (hot spot) of the primary screen in global screen coordinates.
\inmodule QtCore\reentrant
Type type() const
Returns the event type.
\reentrant \inmodule QtGui
void setBold(bool)
If enable is true sets the font's weight to \l{Weight}{QFont::Bold}; otherwise sets the weight to \l{...
virtual void initStyleOption(QStyleOptionFrame *option) const
bool remove(const Key &key)
Removes the item that has the key from the hash.
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
T value(const Key &key) const noexcept
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
bool isEmpty() const noexcept
Returns true if the hash contains no items; otherwise returns false.
The QHelpEvent class provides an event that is used to request helpful information about a particular...
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
The QLabel widget provides a text or image display.
qsizetype size() const noexcept
bool isEmpty() const noexcept
const_reference at(qsizetype i) const noexcept
void remove(qsizetype i, qsizetype n=1)
void resize(qsizetype size)
constexpr int row() const noexcept
Returns the row this model index refers to.
QModelIndex parent() const
Returns the parent of the model index, or QModelIndex() if it has no parent.
constexpr int column() const noexcept
Returns the column this model index refers to.
constexpr bool isValid() const noexcept
Returns {true} if this model index is valid; otherwise returns {false}.
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
The QPaintEvent class contains event parameters for paint events.
const QRect & rect() const
Returns the rectangle that needs to be updated.
The QPainter class performs low-level painting on widgets and other paint devices.
void setBrushOrigin(int x, int y)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void restore()
Restores the current painter state (pops a saved state off the stack).
void setOpacity(qreal opacity)
void save()
Saves the current painter state (pushes the state onto a stack).
void setFont(const QFont &f)
Sets the painter's font to the given font.
QPoint brushOrigin() const
Returns the currently set brush origin.
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
const QBrush & brush(ColorGroup cg, ColorRole cr) const
Returns the brush in the specified color group, used for the given color role.
void setBrush(ColorRole cr, const QBrush &brush)
Sets the brush for the given color role to the specified brush for all groups in the palette.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
void setDevicePixelRatio(qreal scaleFactor)
Sets the device pixel ratio for the pixmap.
void fill(const QColor &fillColor=Qt::white)
Fills the pixmap with the given color.
\inmodule QtCore\reentrant
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
\inmodule QtCore\reentrant
constexpr int x() const noexcept
Returns the x coordinate of this point.
constexpr int y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
constexpr void setRect(int x, int y, int w, int h) noexcept
Sets the coordinates of the rectangle's top-left corner to ({x}, {y}), and its size to the given widt...
constexpr void translate(int dx, int dy) noexcept
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position.
constexpr int width() const noexcept
Returns the width of the rectangle.
The QRegion class specifies a clip region for a painter.
void swap(QSet< T > &other) noexcept
iterator erase(const_iterator i)
const_iterator cbegin() const noexcept
QPointF position() const
Returns the position of the point in this event, relative to the widget or item that received the eve...
Qt::MouseButton button() const
Returns the button that caused the event.
Qt::MouseButtons buttons() const
Returns the button state when the event was generated.
The QStatusTipEvent class provides an event that is used to show messages in a status bar.
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
\variable QStyleOptionFocusRect::backgroundColor
The QStyleOption class stores the parameters used by QStyle functions.
void initFrom(const QWidget *w)
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
@ PM_HeaderDefaultSectionSizeHorizontal
@ PM_HeaderDefaultSectionSizeVertical
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
bool canConvert(QMetaType targetType) const
static void showText(const QPoint &pos, const QString &text, QWidget *w=nullptr)
Shows text as a "What's This?" window, at global position pos.
QSet< QString >::iterator it
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static void unsetCursor(QWindow *w)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
GLsizei const GLfloat * v
[13]
GLuint64 GLenum void * handle
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLdouble GLdouble GLdouble GLdouble top
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLsizei const GLchar * label
[43]
GLenum GLuint GLintptr offset
GLfloat GLfloat GLfloat GLfloat h
GLdouble GLdouble GLdouble GLdouble q
GLfixed GLfixed GLint GLint order
GLenum GLint GLint * precision
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
QT_BEGIN_NAMESPACE constexpr void qSwap(T &value1, T &value2) noexcept(std::is_nothrow_swappable_v< T >)
#define QT_CONFIG(feature)
QSqlQueryModel * model
[16]
QTextStream out(stdout)
[7]
item setCursor(Qt::IBeamCursor)
[1]
view viewport() -> scroll(dx, dy, deviceRect)
QItemSelection * selection
[0]