QTreeWidget: Keep items hidden even if their parents are reparented

When an item is explicitly hidden, then it should stay that way even if
its parent is reparented. The item itself needs to be explicitly shown
for it to be made visible.

Task-number: QTBUG-54843
Change-Id: I0c6eea9a936f82d5874e3246292bd16365440411
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Andy Shaw 2018-05-30 22:00:08 +02:00
parent fc6ae3957e
commit d760f39d5c
4 changed files with 74 additions and 10 deletions

View File

@ -1001,7 +1001,6 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
*/ */
/*! /*!
\fn void QTreeWidgetItem::setHidden(bool hide)
\since 4.2 \since 4.2
Hides the item if \a hide is true, otherwise shows the item. Hides the item if \a hide is true, otherwise shows the item.
@ -1012,6 +1011,14 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
\sa isHidden() \sa isHidden()
*/ */
void QTreeWidgetItem::setHidden(bool ahide)
{
if (view) {
view->setItemHidden(this, ahide);
d->hidden = ahide;
}
}
/*! /*!
\fn bool QTreeWidgetItem::isHidden() const \fn bool QTreeWidgetItem::isHidden() const
\since 4.2 \since 4.2
@ -1021,6 +1028,11 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
\sa setHidden() \sa setHidden()
*/ */
bool QTreeWidgetItem::isHidden() const
{
return (view ? d->hidden : false);
}
/*! /*!
\fn void QTreeWidgetItem::setExpanded(bool expand) \fn void QTreeWidgetItem::setExpanded(bool expand)
\since 4.2 \since 4.2
@ -1648,6 +1660,25 @@ void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)
itemChanged(); itemChanged();
} }
void QTreeWidgetItemPrivate::updateHiddenStatus(QTreeWidgetItem *item, bool inserting)
{
QTreeModel *model = (item->view ? qobject_cast<QTreeModel*>(item->view->model()) : 0);
if (!model)
return;
QStack<QTreeWidgetItem *> parents;
parents.push(item);
while (!parents.isEmpty()) {
QTreeWidgetItem *parent = parents.pop();
QModelIndex index = model->index(parent, 0);
if (parent->d->hidden)
item->view->setRowHidden(index.row(), index.parent(), inserting);
for (int i = 0; i < parent->children.count(); ++i) {
QTreeWidgetItem *child = parent->children.at(i);
parents.push(child);
}
}
}
void QTreeWidgetItemPrivate::propagateDisabled(QTreeWidgetItem *item) void QTreeWidgetItemPrivate::propagateDisabled(QTreeWidgetItem *item)
{ {
Q_ASSERT(item); Q_ASSERT(item);
@ -1937,6 +1968,7 @@ void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
stack.push(i->children.at(c)); stack.push(i->children.at(c));
} }
children.insert(index, child); children.insert(index, child);
d->updateHiddenStatus(child, true);
model->endInsertItems(); model->endInsertItems();
model->skipPendingSort = wasSkipSort; model->skipPendingSort = wasSkipSort;
} else { } else {
@ -1974,6 +2006,7 @@ QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
} }
if (index >= 0 && index < children.count()) { if (index >= 0 && index < children.count()) {
if (model) model->beginRemoveItems(this, index, 1); if (model) model->beginRemoveItems(this, index, 1);
d->updateHiddenStatus(children.at(index), false);
QTreeWidgetItem *item = children.takeAt(index); QTreeWidgetItem *item = children.takeAt(index);
item->par = 0; item->par = 0;
QStack<QTreeWidgetItem*> stack; QStack<QTreeWidgetItem*> stack;
@ -2052,6 +2085,7 @@ void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &c
this->children.insert(index + n, child); this->children.insert(index + n, child);
if (child->par) if (child->par)
d->propagateDisabled(child); d->propagateDisabled(child);
d->updateHiddenStatus(child, true);
} }
if (model) model->endInsertItems(); if (model) model->endInsertItems();
} }
@ -3099,6 +3133,8 @@ bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const
*/ */
void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide) void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
{ {
if (!item)
return;
Q_D(QTreeWidget); Q_D(QTreeWidget);
if (item == d->treeModel()->headerItem) { if (item == d->treeModel()->headerItem) {
header()->setHidden(hide); header()->setHidden(hide);
@ -3106,6 +3142,7 @@ void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
const QModelIndex index = d->index(item); const QModelIndex index = d->index(item);
setRowHidden(index.row(), index.parent(), hide); setRowHidden(index.row(), index.parent(), hide);
} }
item->d->hidden = hide;
} }
/*! /*!

View File

@ -82,8 +82,8 @@ public:
inline void setSelected(bool select); inline void setSelected(bool select);
inline bool isSelected() const; inline bool isSelected() const;
inline void setHidden(bool hide); void setHidden(bool hide);
inline bool isHidden() const; bool isHidden() const;
inline void setExpanded(bool expand); inline void setExpanded(bool expand);
inline bool isExpanded() const; inline bool isExpanded() const;
@ -410,12 +410,6 @@ inline void QTreeWidgetItem::setSelected(bool aselect)
inline bool QTreeWidgetItem::isSelected() const inline bool QTreeWidgetItem::isSelected() const
{ return (view ? view->isItemSelected(this) : false); } { return (view ? view->isItemSelected(this) : false); }
inline void QTreeWidgetItem::setHidden(bool ahide)
{ if (view) view->setItemHidden(this, ahide); }
inline bool QTreeWidgetItem::isHidden() const
{ return (view ? view->isItemHidden(this) : false); }
inline void QTreeWidgetItem::setExpanded(bool aexpand) inline void QTreeWidgetItem::setExpanded(bool aexpand)
{ if (view) view->setItemExpanded(this, aexpand); } { if (view) view->setItemExpanded(this, aexpand); }

View File

@ -187,13 +187,16 @@ class QTreeWidgetItemPrivate
{ {
public: public:
QTreeWidgetItemPrivate(QTreeWidgetItem *item) QTreeWidgetItemPrivate(QTreeWidgetItem *item)
: q(item), disabled(false), selected(false), rowGuess(-1), policy(QTreeWidgetItem::DontShowIndicatorWhenChildless) {} : q(item), disabled(false), selected(false), hidden(false), rowGuess(-1),
policy(QTreeWidgetItem::DontShowIndicatorWhenChildless) {}
void propagateDisabled(QTreeWidgetItem *item); void propagateDisabled(QTreeWidgetItem *item);
void updateHiddenStatus(QTreeWidgetItem *item, bool inserting);
void sortChildren(int column, Qt::SortOrder order, bool climb); void sortChildren(int column, Qt::SortOrder order, bool climb);
QTreeWidgetItem *q; QTreeWidgetItem *q;
QVariantList display; QVariantList display;
uint disabled : 1; uint disabled : 1;
uint selected : 1; uint selected : 1;
uint hidden : 1;
int rowGuess; int rowGuess;
QTreeWidgetItem::ChildIndicatorPolicy policy; QTreeWidgetItem::ChildIndicatorPolicy policy;
}; };

View File

@ -160,6 +160,7 @@ private slots:
void task20345_sortChildren(); void task20345_sortChildren();
void getMimeDataWithInvalidItem(); void getMimeDataWithInvalidItem();
void testVisualItemRect(); void testVisualItemRect();
void reparentHiddenItem();
public slots: public slots:
void itemSelectionChanged(); void itemSelectionChanged();
@ -3498,5 +3499,34 @@ void tst_QTreeWidget::testVisualItemRect()
QCOMPARE(r.width(), sectionSize); QCOMPARE(r.width(), sectionSize);
} }
void tst_QTreeWidget::reparentHiddenItem()
{
QTreeWidgetItem *parent = new QTreeWidgetItem(testWidget);
parent->setText(0, "parent");
QTreeWidgetItem *otherParent = new QTreeWidgetItem(testWidget);
otherParent->setText(0, "other parent");
QTreeWidgetItem *child = new QTreeWidgetItem(parent);
child->setText(0, "child");
QTreeWidgetItem *grandChild = new QTreeWidgetItem(child);
grandChild->setText(0, "grandchild");
QVERIFY(child->parent());
QVERIFY(grandChild->parent());
testWidget->expandItem(parent);
testWidget->expandItem(otherParent);
testWidget->expandItem(child);
QVERIFY(!parent->isHidden());
QVERIFY(!child->isHidden());
QVERIFY(!grandChild->isHidden());
grandChild->setHidden(true);
QVERIFY(grandChild->isHidden());
parent->removeChild(child);
otherParent->addChild(child);
QVERIFY(grandChild->isHidden());
}
QTEST_MAIN(tst_QTreeWidget) QTEST_MAIN(tst_QTreeWidget)
#include "tst_qtreewidget.moc" #include "tst_qtreewidget.moc"