9395f35c.patch 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. From 9395f35cb18725995910531ca8b09f1d84efa96c Mon Sep 17 00:00:00 2001
  2. From: Christian Ehrlicher <ch.ehrlicher@gmx.de>
  3. Date: Sat, 17 Feb 2018 10:02:19 +0100
  4. Subject: QHeaderView: Preserve settings on layoutChange with empty model
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Do not clear the settings of QHeaderView during layoutChange when the
  9. model is empty and the section count did not change. This will not work
  10. when a section is moved or a section is replaced with a new one during
  11. layoutChange. But since layoutChanged is also called on sorting, this
  12. patch ensures that the settings are not cleared in this case.
  13. This restores the behavior to the same as before 5.9.4.
  14. Task-number: QTBUG-66444
  15. Task-number: QTBUG-65478
  16. Change-Id: I39989cfd45b42e58f49d18ec014d3a941cadb6c9
  17. Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
  18. ---
  19. src/widgets/itemviews/qheaderview.cpp | 24 ++++++++
  20. .../itemviews/qheaderview/tst_qheaderview.cpp | 71 ++++++++++++++++++++++
  21. 2 files changed, 95 insertions(+)
  22. diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
  23. index edef2e9bf8..b0359de3ea 100644
  24. --- a/src/widgets/itemviews/qheaderview.cpp
  25. +++ b/src/widgets/itemviews/qheaderview.cpp
  26. @@ -2205,6 +2205,30 @@ void QHeaderViewPrivate::_q_sectionsChanged()
  27. return;
  28. }
  29. + bool hasPersistantIndexes = false;
  30. + for (const auto &item : oldPersistentSections) {
  31. + if (item.index.isValid()) {
  32. + hasPersistantIndexes = true;
  33. + break;
  34. + }
  35. + }
  36. +
  37. + // Though far from perfect we here try to retain earlier/existing behavior
  38. + // ### See QHeaderViewPrivate::_q_layoutAboutToBeChanged()
  39. + // When we don't have valid hasPersistantIndexes it can be due to
  40. + // - all sections are default sections
  41. + // - the row/column 0 which is used for persistent indexes is gone
  42. + // - all non-default sections were removed
  43. + // case one is trivial, in case two we assume nothing else changed (it's the best
  44. + // guess we can do - everything else can not be handled correctly for now)
  45. + // case three can not be handled correctly with layoutChanged - removeSections
  46. + // should be used instead for this
  47. + if (!hasPersistantIndexes) {
  48. + if (oldCount != newCount)
  49. + q->initializeSections();
  50. + return;
  51. + }
  52. +
  53. // adjust section size
  54. if (newCount != oldCount) {
  55. const int min = qBound(0, oldCount, newCount - 1);
  56. diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
  57. index c69c0de949..97aa8a0299 100644
  58. --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
  59. +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
  60. @@ -206,6 +206,7 @@ private slots:
  61. void task248050_hideRow();
  62. void QTBUG6058_reset();
  63. void QTBUG7833_sectionClicked();
  64. + void checkLayoutChangeEmptyModel();
  65. void QTBUG8650_crashOnInsertSections();
  66. void QTBUG12268_hiddenMovedSectionSorting();
  67. void QTBUG14242_hideSectionAutoSize();
  68. @@ -286,6 +287,13 @@ public:
  69. endInsertColumns();
  70. }
  71. + void removeFirstRow()
  72. + {
  73. + beginRemoveRows(QModelIndex(), 0, 0);
  74. + --rows;
  75. + endRemoveRows();
  76. + }
  77. +
  78. void removeLastRow()
  79. {
  80. beginRemoveRows(QModelIndex(), rows - 1, rows - 1);
  81. @@ -328,6 +336,24 @@ public:
  82. emit layoutChanged();
  83. }
  84. + void emitLayoutChanged()
  85. + {
  86. + emit layoutAboutToBeChanged();
  87. + emit layoutChanged();
  88. + }
  89. +
  90. + void emitLayoutChangedWithRemoveFirstRow()
  91. + {
  92. + emit layoutAboutToBeChanged();
  93. + QModelIndexList milNew;
  94. + const auto milOld = persistentIndexList();
  95. + milNew.reserve(milOld.size());
  96. + for (int i = 0; i < milOld.size(); ++i)
  97. + milNew += QModelIndex();
  98. + changePersistentIndexList(milOld, milNew);
  99. + emit layoutChanged();
  100. + }
  101. +
  102. int cols, rows;
  103. mutable bool wrongIndex;
  104. };
  105. @@ -2332,6 +2358,51 @@ void tst_QHeaderView::QTBUG7833_sectionClicked()
  106. QCOMPARE(pressedSpy.at(2).at(0).toInt(), 0);
  107. }
  108. +void tst_QHeaderView::checkLayoutChangeEmptyModel()
  109. +{
  110. + QtTestModel tm;
  111. + tm.cols = 11;
  112. + QTableView tv;
  113. + tv.setModel(&tm);
  114. +
  115. + const int section4Size = tv.horizontalHeader()->sectionSize(4) + 1;
  116. + const int section5Size = section4Size + 1;
  117. + tv.horizontalHeader()->resizeSection(4, section4Size);
  118. + tv.horizontalHeader()->resizeSection(5, section5Size);
  119. + tv.setColumnHidden(5, true);
  120. + tv.setColumnHidden(6, true);
  121. + tv.horizontalHeader()->swapSections(8, 10);
  122. +
  123. + tv.sortByColumn(1, Qt::AscendingOrder);
  124. + tm.emitLayoutChanged();
  125. +
  126. + QCOMPARE(tv.isColumnHidden(5), true);
  127. + QCOMPARE(tv.isColumnHidden(6), true);
  128. + QCOMPARE(tv.horizontalHeader()->sectionsMoved(), true);
  129. + QCOMPARE(tv.horizontalHeader()->logicalIndex(8), 10);
  130. + QCOMPARE(tv.horizontalHeader()->logicalIndex(10), 8);
  131. + QCOMPARE(tv.horizontalHeader()->sectionSize(4), section4Size);
  132. + tv.setColumnHidden(5, false); // unhide, section size must be properly restored
  133. + QCOMPARE(tv.horizontalHeader()->sectionSize(5), section5Size);
  134. + tv.setColumnHidden(5, true);
  135. +
  136. + // adjust
  137. + tm.rows = 3;
  138. + tm.emitLayoutChanged();
  139. +
  140. + // remove the row used for QPersistenModelIndexes
  141. + tm.emitLayoutChangedWithRemoveFirstRow();
  142. + QCOMPARE(tv.isColumnHidden(5), true);
  143. + QCOMPARE(tv.isColumnHidden(6), true);
  144. + QCOMPARE(tv.horizontalHeader()->sectionsMoved(), true);
  145. + QCOMPARE(tv.horizontalHeader()->logicalIndex(8), 10);
  146. + QCOMPARE(tv.horizontalHeader()->logicalIndex(10), 8);
  147. + QCOMPARE(tv.horizontalHeader()->sectionSize(4), section4Size);
  148. + tv.setColumnHidden(5, false); // unhide, section size must be properly restored
  149. + QCOMPARE(tv.horizontalHeader()->sectionSize(5), section5Size);
  150. + tv.setColumnHidden(5, true);
  151. +}
  152. +
  153. void tst_QHeaderView::QTBUG8650_crashOnInsertSections()
  154. {
  155. QStringList headerLabels;
  156. --
  157. cgit v1.2.1