Use boolean to indicate QTableWidgetItem is header item

QTableWidgetItem uses additional enum flag ItemIsHeaderItem which has
the same numerical value as ItemFlag ItemNeverHasChildren.
This causes conflict since the user can set the latter flag using
the setFlags, while the ItemIsHeaderItem is only used internally
to mark header items.

Remove the additional flag and use boolean instead to fix the conflict.

Pick-to: 6.2 6.5 6.5.1
Fixes: QTBUG-113209
Change-Id: Icff549c7e452d9f84575a524361719204817274e
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Antti Määttä 2023-05-02 12:39:59 +03:00 committed by Volker Hilsheimer
parent 2434573f5e
commit fa67cd0334
3 changed files with 27 additions and 10 deletions

View File

@ -248,7 +248,7 @@ void QTableModel::setHorizontalHeaderItem(int section, QTableWidgetItem *item)
if (item) { if (item) {
item->view = view; item->view = view;
item->itemFlags = Qt::ItemFlags(int(item->itemFlags)|ItemIsHeaderItem); item->d->headerItem = true;
} }
horizontalHeaderItems[section] = item; horizontalHeaderItems[section] = item;
emit headerDataChanged(Qt::Horizontal, section, section); emit headerDataChanged(Qt::Horizontal, section, section);
@ -270,7 +270,7 @@ void QTableModel::setVerticalHeaderItem(int section, QTableWidgetItem *item)
if (item) { if (item) {
item->view = view; item->view = view;
item->itemFlags = Qt::ItemFlags(int(item->itemFlags)|ItemIsHeaderItem); item->d->headerItem = true;
} }
verticalHeaderItems[section] = item; verticalHeaderItems[section] = item;
emit headerDataChanged(Qt::Vertical, section, section); emit headerDataChanged(Qt::Vertical, section, section);
@ -283,7 +283,7 @@ QTableWidgetItem *QTableModel::takeHorizontalHeaderItem(int section)
QTableWidgetItem *itm = horizontalHeaderItems.at(section); QTableWidgetItem *itm = horizontalHeaderItems.at(section);
if (itm) { if (itm) {
itm->view = nullptr; itm->view = nullptr;
itm->itemFlags &= ~ItemIsHeaderItem; itm->d->headerItem = false;
horizontalHeaderItems[section] = 0; horizontalHeaderItems[section] = 0;
} }
return itm; return itm;
@ -296,7 +296,7 @@ QTableWidgetItem *QTableModel::takeVerticalHeaderItem(int section)
QTableWidgetItem *itm = verticalHeaderItems.at(section); QTableWidgetItem *itm = verticalHeaderItems.at(section);
if (itm) { if (itm) {
itm->view = nullptr; itm->view = nullptr;
itm->itemFlags &= ~ItemIsHeaderItem; itm->d->headerItem = false;
verticalHeaderItems[section] = 0; verticalHeaderItems[section] = 0;
} }
return itm; return itm;
@ -761,7 +761,7 @@ void QTableModel::itemChanged(QTableWidgetItem *item, const QList<int> &roles)
{ {
if (!item) if (!item)
return; return;
if (item->flags() & ItemIsHeaderItem) { if (item->d->headerItem) {
int row = verticalHeaderItems.indexOf(item); int row = verticalHeaderItems.indexOf(item);
if (row >= 0) { if (row >= 0) {
emit headerDataChanged(Qt::Vertical, row, row); emit headerDataChanged(Qt::Vertical, row, row);

View File

@ -53,10 +53,6 @@ class QTableModel : public QAbstractTableModel
friend class QTableWidget; friend class QTableWidget;
public: public:
enum ItemFlagsExtension {
ItemIsHeaderItem = 128
}; // we need this to separate header items from other items
QTableModel(int rows, int columns, QTableWidget *parent); QTableModel(int rows, int columns, QTableWidget *parent);
~QTableModel(); ~QTableModel();
@ -173,9 +169,10 @@ public:
class QTableWidgetItemPrivate class QTableWidgetItemPrivate
{ {
public: public:
QTableWidgetItemPrivate(QTableWidgetItem *item) : q(item), id(-1) {} QTableWidgetItemPrivate(QTableWidgetItem *item) : q(item), id(-1), headerItem(false) {}
QTableWidgetItem *q; QTableWidgetItem *q;
int id; int id;
bool headerItem; // Qt 7 TODO: inline this stuff in the public class.
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -63,6 +63,7 @@ private slots:
void task219380_removeLastRow(); void task219380_removeLastRow();
void task262056_sortDuplicate(); void task262056_sortDuplicate();
void itemWithHeaderItems(); void itemWithHeaderItems();
void checkHeaderItemFlagsConflict();
void mimeData(); void mimeData();
void selectedRowAfterSorting(); void selectedRowAfterSorting();
void search(); void search();
@ -1669,6 +1670,25 @@ void tst_QTableWidget::itemWithHeaderItems()
QCOMPARE(table.item(0, 1), nullptr); QCOMPARE(table.item(0, 1), nullptr);
} }
void tst_QTableWidget::checkHeaderItemFlagsConflict()
{
// QTBUG-113209
// Check that setting header item doesn't set Qt::ItemNeverHasChildren
// Chech that header items do not emit itemChanged.
QTableWidget table(1, 1);
QSignalSpy itemChangeSpy(&table, &QTableWidget::itemChanged);
QVERIFY(itemChangeSpy.isValid());
QTableWidgetItem *item = new QTableWidgetItem("Initial");
table.setHorizontalHeaderItem(0, item);
QVERIFY(!(item->flags() & Qt::ItemNeverHasChildren));
item->setData(Qt::DisplayRole, "updated");
QCOMPARE(itemChangeSpy.size(), 0);
}
class TestTableWidget : public QTableWidget class TestTableWidget : public QTableWidget
{ {
Q_OBJECT Q_OBJECT