@@ -138,6 +138,13 @@ void ListViewWithPageHeader::ListItem::setCulled(bool culled)
138 QQuickItemPrivate::get(m_sectionItem)->setCulled(culled);
138 QQuickItemPrivate::get(m_sectionItem)->setCulled(culled);
141+void ListViewWithPageHeader::ListItem::setSectionItem(QQuickItem *sectionItem)
143+ m_sectionItem = sectionItem;
144+ QQmlContext *context = QQmlEngine::contextForObject(m_item)->parentContext();
145+ context->setContextProperty(QLatin1String("hasSectionHeader"), QVariant::fromValue<bool>(sectionItem != nullptr));
141ListViewWithPageHeader::ListViewWithPageHeader()
148ListViewWithPageHeader::ListViewWithPageHeader()
142 : m_delegateModel(nullptr)
149 : m_delegateModel(nullptr)
143 , m_asyncRequestedIndex(-1)
150 , m_asyncRequestedIndex(-1)
@@ -422,7 +429,7 @@ bool ListViewWithPageHeader::maximizeVisibleArea(int modelIndex, int itemHeight)
423 ListItem *listItem = itemAtIndex(modelIndex);
430 ListItem *listItem = itemAtIndex(modelIndex);
424 if (listItem) {
431 if (listItem) {
425− return maximizeVisibleArea(listItem, itemHeight + (listItem->m_sectionItem ? listItem->m_sectionItem->height() : 0));
432+ return maximizeVisibleArea(listItem, itemHeight + (listItem->sectionItem() ? listItem->sectionItem()->height() : 0));
428 return false;
435 return false;
@@ -440,7 +447,7 @@ bool ListViewWithPageHeader::maximizeVisibleArea(ListItem *listItem, int listIte
440 contentYAnimationType = ContentYAnimationMaximizeVisibleArea;
447 contentYAnimationType = ContentYAnimationMaximizeVisibleArea;
441 m_contentYAnimation->start();
448 m_contentYAnimation->start();
442 } else if ((listItemY < contentY() && listItemY + listItemHeight < contentY() + height()) ||
449 } else if ((listItemY < contentY() && listItemY + listItemHeight < contentY() + height()) ||
443− (m_topSectionItem && !listItem->m_sectionItem && listItemY - m_topSectionItem->height() < contentY() && listItemY + listItemHeight < contentY() + height()))
450+ (m_topSectionItem && !listItem->sectionItem() && listItemY - m_topSectionItem->height() < contentY() && listItemY + listItemHeight < contentY() + height()))
445 // we can scroll the list down to show more stuff
452 // we can scroll the list down to show more stuff
446 auto realVisibleListItemY = listItemY;
453 auto realVisibleListItemY = listItemY;
@@ -449,7 +456,7 @@ bool ListViewWithPageHeader::maximizeVisibleArea(ListItem *listItem, int listIte
449 // item we have to make sure to scroll it a bit more so that it is not underlapping
456 // item we have to make sure to scroll it a bit more so that it is not underlapping
450 // the top section sticky item
457 // the top section sticky item
451 bool topSectionShown = !QQuickItemPrivate::get(m_topSectionItem)->culled;
458 bool topSectionShown = !QQuickItemPrivate::get(m_topSectionItem)->culled;
452− if (topSectionShown && !listItem->m_sectionItem) {
459+ if (topSectionShown && !listItem->sectionItem()) {
453 realVisibleListItemY -= m_topSectionItem->height();
460 realVisibleListItemY -= m_topSectionItem->height();
@@ -645,7 +652,7 @@ void ListViewWithPageHeader::reallyReleaseItem(ListItem *listItem)
645 if (flags & QQmlDelegateModel::Destroyed) {
652 if (flags & QQmlDelegateModel::Destroyed) {
646 item->setParentItem(nullptr);
653 item->setParentItem(nullptr);
648− delete listItem->m_sectionItem;
655+ delete listItem->sectionItem();
649 delete listItem;
656 delete listItem;
@@ -672,6 +679,9 @@ QQuickItem *ListViewWithPageHeader::getSectionItem(int modelIndex, bool alreadyI
672 return nullptr;
679 return nullptr;
674 const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
681 const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
682+ if (section.isEmpty())
675 if (modelIndex > 0) {
685 if (modelIndex > 0) {
676 const QString prevSection = m_delegateModel->stringValue(modelIndex - 1, m_sectionProperty);
686 const QString prevSection = m_delegateModel->stringValue(modelIndex - 1, m_sectionProperty);
677 if (section == prevSection)
687 if (section == prevSection)
@@ -684,8 +694,8 @@ QQuickItem *ListViewWithPageHeader::getSectionItem(int modelIndex, bool alreadyI
684 // Steal the section header
694 // Steal the section header
685 ListItem *nextItem = itemAtIndex(modelIndex); // Not +1 since not yet inserted into m_visibleItems
695 ListItem *nextItem = itemAtIndex(modelIndex); // Not +1 since not yet inserted into m_visibleItems
686 if (nextItem) {
696 if (nextItem) {
687− QQuickItem *sectionItem = nextItem->m_sectionItem;
697+ QQuickItem *sectionItem = nextItem->sectionItem();
688− nextItem->m_sectionItem = nullptr;
698+ nextItem->setSectionItem(nullptr);
689 return sectionItem;
699 return sectionItem;
@@ -793,7 +803,7 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
793// qDebug() << "ListViewWithPageHeader::createItem::We have the item" << modelIndex << item;
803// qDebug() << "ListViewWithPageHeader::createItem::We have the item" << modelIndex << item;
794 ListItem *listItem = new ListItem;
804 ListItem *listItem = new ListItem;
795 listItem->m_item = item;
805 listItem->m_item = item;
796− listItem->m_sectionItem = getSectionItem(modelIndex, false /*Not yet inserted into m_visibleItems*/);
806+ listItem->setSectionItem(getSectionItem(modelIndex, false /*Not yet inserted into m_visibleItems*/));
797 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry);
807 QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry);
798 ListItem *prevItem = itemAtIndex(modelIndex - 1);
808 ListItem *prevItem = itemAtIndex(modelIndex - 1);
799 bool lostItem = false; // Is an item that we requested async but because of model changes
809 bool lostItem = false; // Is an item that we requested async but because of model changes
@@ -832,8 +842,8 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
832 m_firstVisibleIndex = modelIndex;
842 m_firstVisibleIndex = modelIndex;
833 polish();
843 polish();
835− if (listItem->m_sectionItem) {
845+ if (listItem->sectionItem()) {
836− QQmlContext *context = QQmlEngine::contextForObject(listItem->m_sectionItem)->parentContext();
846+ QQmlContext *context = QQmlEngine::contextForObject(listItem->sectionItem())->parentContext();
837 context->setContextProperty(QLatin1String("delegateIndex"), modelIndex);
847 context->setContextProperty(QLatin1String("delegateIndex"), modelIndex);
839 adjustMinYExtent();
849 adjustMinYExtent();
@@ -861,6 +871,7 @@ void ListViewWithPageHeader::itemCreated(int modelIndex, QObject *object)
861 QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
871 QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
862 context->setContextProperty(QLatin1String("ListViewWithPageHeader"), this);
872 context->setContextProperty(QLatin1String("ListViewWithPageHeader"), this);
863 context->setContextProperty(QLatin1String("heightToClip"), QVariant::fromValue<int>(0));
873 context->setContextProperty(QLatin1String("heightToClip"), QVariant::fromValue<int>(0));
874+ context->setContextProperty(QLatin1String("hasSectionHeader"), QVariant::fromValue<bool>(false));
864 if (modelIndex == m_asyncRequestedIndex) {
875 if (modelIndex == m_asyncRequestedIndex) {
865 createItem(modelIndex, false);
876 createItem(modelIndex, false);
866 refill();
877 refill();
@@ -915,11 +926,11 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
915 if (visibleIndex >= 0 && visibleIndex < m_visibleItems.count()) {
926 if (visibleIndex >= 0 && visibleIndex < m_visibleItems.count()) {
916 ListItem *item = m_visibleItems[visibleIndex];
927 ListItem *item = m_visibleItems[visibleIndex];
917 // Pass the section item down if needed
928 // Pass the section item down if needed
918− if (item->m_sectionItem && visibleIndex + 1 < m_visibleItems.count()) {
929+ if (item->sectionItem() && visibleIndex + 1 < m_visibleItems.count()) {
919 ListItem *nextItem = m_visibleItems[visibleIndex + 1];
930 ListItem *nextItem = m_visibleItems[visibleIndex + 1];
920− if (!nextItem->m_sectionItem) {
931+ if (!nextItem->sectionItem()) {
921− nextItem->m_sectionItem = item->m_sectionItem;
932+ nextItem->setSectionItem(item->sectionItem());
922− item->m_sectionItem = nullptr;
933+ item->setSectionItem(nullptr);
925 releaseItem(item);
936 releaseItem(item);
@@ -982,11 +993,11 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
982 // if we need adding a new section item
993 // if we need adding a new section item
983 if (m_sectionDelegate) {
994 if (m_sectionDelegate) {
984 ListItem *nextItem = itemAtIndex(modelIndex + 1);
995 ListItem *nextItem = itemAtIndex(modelIndex + 1);
985− if (nextItem && !nextItem->m_sectionItem) {
996+ if (nextItem && !nextItem->sectionItem()) {
986− nextItem->m_sectionItem = getSectionItem(modelIndex + 1, true /* alredy inserted into m_visibleItems*/);
997+ nextItem->setSectionItem(getSectionItem(modelIndex + 1, true /* alredy inserted into m_visibleItems*/));
987− if (growUp && nextItem->m_sectionItem) {
998+ if (growUp && nextItem->sectionItem()) {
988 ListItem *firstItem = m_visibleItems.first();
999 ListItem *firstItem = m_visibleItems.first();
989− firstItem->setY(firstItem->y() - nextItem->m_sectionItem->height());
1000+ firstItem->setY(firstItem->y() - nextItem->sectionItem()->height());
@@ -1012,8 +1023,8 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
1012// qDebug() << "ListViewWithPageHeader::onModelUpdated Change" << change.index << change.count;
1023// qDebug() << "ListViewWithPageHeader::onModelUpdated Change" << change.index << change.count;
1013 for (int i = change.index; i < change.count; ++i) {
1024 for (int i = change.index; i < change.count; ++i) {
1014 ListItem *item = itemAtIndex(i);
1025 ListItem *item = itemAtIndex(i);
1015− if (item && item->m_sectionItem) {
1026+ if (item && item->sectionItem()) {
1016− QQmlContext *context = QQmlEngine::contextForObject(item->m_sectionItem)->parentContext();
1027+ QQmlContext *context = QQmlEngine::contextForObject(item->sectionItem())->parentContext();
1017 const QString sectionText = m_delegateModel->stringValue(i, m_sectionProperty);
1028 const QString sectionText = m_delegateModel->stringValue(i, m_sectionProperty);
1018 context->setContextProperty(QLatin1String("section"), sectionText);
1029 context->setContextProperty(QLatin1String("section"), sectionText);
@@ -1026,8 +1037,8 @@ void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool
1027 for (int i = 0; i < m_visibleItems.count(); ++i) {
1038 for (int i = 0; i < m_visibleItems.count(); ++i) {
1028 ListItem *item = m_visibleItems[i];
1039 ListItem *item = m_visibleItems[i];
1029− if (item->m_sectionItem) {
1040+ if (item->sectionItem()) {
1030− QQmlContext *context = QQmlEngine::contextForObject(item->m_sectionItem)->parentContext();
1041+ QQmlContext *context = QQmlEngine::contextForObject(item->sectionItem())->parentContext();
1031 context->setContextProperty(QLatin1String("delegateIndex"), m_firstVisibleIndex + i);
1042 context->setContextProperty(QLatin1String("delegateIndex"), m_firstVisibleIndex + i);
@@ -1156,18 +1167,18 @@ void ListViewWithPageHeader::layout()
1156 if (topSectionStickPos > pos) {
1167 if (topSectionStickPos > pos) {
1157 showStickySectionItem = true;
1168 showStickySectionItem = true;
1158 } else if (topSectionStickPos == pos) {
1169 } else if (topSectionStickPos == pos) {
1159− showStickySectionItem = !item->m_sectionItem;
1170+ showStickySectionItem = !item->sectionItem();
1160 } else {
1171 } else {
1161 showStickySectionItem = false;
1172 showStickySectionItem = false;
1163 if (!showStickySectionItem) {
1174 if (!showStickySectionItem) {
1164 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
1175 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
1165− if (item->m_sectionItem) {
1176+ if (item->sectionItem()) {
1166 // This seems it should happen since why would we cull the top section
1177 // This seems it should happen since why would we cull the top section
1167 // if the first visible item has no section header? This only happens briefly
1178 // if the first visible item has no section header? This only happens briefly
1168 // when increasing the height of a list that is at the bottom, the m_topSectionItem
1179 // when increasing the height of a list that is at the bottom, the m_topSectionItem
1169 // gets shown shortly in the next polish call
1180 // gets shown shortly in the next polish call
1170− QQuickItemPrivate::get(item->m_sectionItem)->setCulled(false);
1181+ QQuickItemPrivate::get(item->sectionItem())->setCulled(false);
1172 } else {
1183 } else {
1173 // Update the top sticky section header
1184 // Update the top sticky section header
@@ -1186,14 +1197,14 @@ void ListViewWithPageHeader::layout()
1186 delegateIndex--;
1197 delegateIndex--;
1188 context->setContextProperty(QLatin1String("delegateIndex"), delegateIndex);
1199 context->setContextProperty(QLatin1String("delegateIndex"), delegateIndex);
1189− if (item->m_sectionItem) {
1200+ if (item->sectionItem()) {
1190− QQuickItemPrivate::get(item->m_sectionItem)->setCulled(true);
1201+ QQuickItemPrivate::get(item->sectionItem())->setCulled(true);
1195 QQmlContext *context = QQmlEngine::contextForObject(item->m_item)->parentContext();
1206 QQmlContext *context = QQmlEngine::contextForObject(item->m_item)->parentContext();
1196− const qreal clipFrom = visibleFrom + (!item->m_sectionItem && m_topSectionItem && !QQuickItemPrivate::get(m_topSectionItem)->culled ? m_topSectionItem->height() : 0);
1207+ const qreal clipFrom = visibleFrom + (!item->sectionItem() && m_topSectionItem && !QQuickItemPrivate::get(m_topSectionItem)->culled ? m_topSectionItem->height() : 0);
1197 if (!cull && pos < clipFrom) {
1208 if (!cull && pos < clipFrom) {
1198 context->setContextProperty(QLatin1String("heightToClip"), clipFrom - pos);
1209 context->setContextProperty(QLatin1String("heightToClip"), clipFrom - pos);
1199 } else {
1210 } else {
@@ -1210,7 +1221,7 @@ void ListViewWithPageHeader::layout()
1210 if (firstReallyVisibleItem >= 0) {
1221 if (firstReallyVisibleItem >= 0) {
1211 for (int i = firstReallyVisibleItem - m_firstVisibleIndex + 1; i < m_visibleItems.count(); ++i) {
1222 for (int i = firstReallyVisibleItem - m_firstVisibleIndex + 1; i < m_visibleItems.count(); ++i) {
1212 ListItem *item = m_visibleItems[i];
1223 ListItem *item = m_visibleItems[i];
1213− if (item->m_sectionItem) {
1224+ if (item->sectionItem()) {
1214 if (m_topSectionItem->y() + m_topSectionItem->height() > item->y()) {
1225 if (m_topSectionItem->y() + m_topSectionItem->height() > item->y()) {
1215 m_topSectionItem->setY(item->y() - m_topSectionItem->height());
1226 m_topSectionItem->setY(item->y() - m_topSectionItem->height());