Add the Qt::ItemNeverHasChildren flag and use it in QTreeView.
It can be used to determine whether expand() should really expand. Change-Id: If79d8c295a4ca1356e60051682b227524a065126 Reviewed-by: David Faure (KDE) <faure@kde.org> Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
This commit is contained in:
parent
d78bd439dc
commit
d315e01218
@ -1395,7 +1395,8 @@ public:
|
|||||||
ItemIsDropEnabled = 8,
|
ItemIsDropEnabled = 8,
|
||||||
ItemIsUserCheckable = 16,
|
ItemIsUserCheckable = 16,
|
||||||
ItemIsEnabled = 32,
|
ItemIsEnabled = 32,
|
||||||
ItemIsTristate = 64
|
ItemIsTristate = 64,
|
||||||
|
ItemNeverHasChildren = 128
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(ItemFlags, ItemFlag)
|
Q_DECLARE_FLAGS(ItemFlags, ItemFlag)
|
||||||
|
|
||||||
|
@ -2441,6 +2441,7 @@
|
|||||||
\value ItemIsUserCheckable It can be checked or unchecked by the user.
|
\value ItemIsUserCheckable It can be checked or unchecked by the user.
|
||||||
\value ItemIsEnabled The user can interact with the item.
|
\value ItemIsEnabled The user can interact with the item.
|
||||||
\value ItemIsTristate The item is checkable with three separate states.
|
\value ItemIsTristate The item is checkable with three separate states.
|
||||||
|
\value ItemNeverHasChildren The item never has child items.
|
||||||
|
|
||||||
Note that checkable items need to be given both a suitable set of flags
|
Note that checkable items need to be given both a suitable set of flags
|
||||||
and an initial state, indicating whether the item is checked or not.
|
and an initial state, indicating whether the item is checked or not.
|
||||||
|
@ -3271,6 +3271,17 @@ bool QAbstractTableModel::hasChildren(const QModelIndex &parent) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
Qt::ItemFlags QAbstractTableModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Qt::ItemFlags f = QAbstractItemModel::flags(index);
|
||||||
|
if (index.isValid())
|
||||||
|
f |= Qt::ItemNeverHasChildren;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class QAbstractListModel
|
\class QAbstractListModel
|
||||||
\inmodule QtCore
|
\inmodule QtCore
|
||||||
@ -3391,6 +3402,17 @@ QModelIndex QAbstractListModel::parent(const QModelIndex & /* index */) const
|
|||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\reimp
|
||||||
|
*/
|
||||||
|
Qt::ItemFlags QAbstractListModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Qt::ItemFlags f = QAbstractItemModel::flags(index);
|
||||||
|
if (index.isValid())
|
||||||
|
f |= Qt::ItemNeverHasChildren;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
|
|
||||||
|
@ -419,6 +419,7 @@ public:
|
|||||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action,
|
bool dropMimeData(const QMimeData *data, Qt::DropAction action,
|
||||||
int row, int column, const QModelIndex &parent);
|
int row, int column, const QModelIndex &parent);
|
||||||
|
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
|
||||||
protected:
|
protected:
|
||||||
QAbstractTableModel(QAbstractItemModelPrivate &dd, QObject *parent);
|
QAbstractTableModel(QAbstractItemModelPrivate &dd, QObject *parent);
|
||||||
|
|
||||||
@ -439,6 +440,8 @@ public:
|
|||||||
QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
|
QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
|
||||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action,
|
bool dropMimeData(const QMimeData *data, Qt::DropAction action,
|
||||||
int row, int column, const QModelIndex &parent);
|
int row, int column, const QModelIndex &parent);
|
||||||
|
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
|
||||||
protected:
|
protected:
|
||||||
QAbstractListModel(QAbstractItemModelPrivate &dd, QObject *parent);
|
QAbstractListModel(QAbstractItemModelPrivate &dd, QObject *parent);
|
||||||
|
|
||||||
|
@ -964,6 +964,8 @@ Qt::ItemFlags QFileSystemModel::flags(const QModelIndex &index) const
|
|||||||
flags |= Qt::ItemIsEditable;
|
flags |= Qt::ItemIsEditable;
|
||||||
if (indexNode->isDir())
|
if (indexNode->isDir())
|
||||||
flags |= Qt::ItemIsDropEnabled;
|
flags |= Qt::ItemIsDropEnabled;
|
||||||
|
else
|
||||||
|
flags |= Qt::ItemNeverHasChildren;
|
||||||
}
|
}
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
@ -749,6 +749,8 @@ void QTreeView::expand(const QModelIndex &index)
|
|||||||
Q_D(QTreeView);
|
Q_D(QTreeView);
|
||||||
if (!d->isIndexValid(index))
|
if (!d->isIndexValid(index))
|
||||||
return;
|
return;
|
||||||
|
if (index.flags() & Qt::ItemNeverHasChildren)
|
||||||
|
return;
|
||||||
if (d->delayedPendingLayout) {
|
if (d->delayedPendingLayout) {
|
||||||
//A complete relayout is going to be performed, just store the expanded index, no need to layout.
|
//A complete relayout is going to be performed, just store the expanded index, no need to layout.
|
||||||
if (d->storeExpanded(index))
|
if (d->storeExpanded(index))
|
||||||
@ -2887,6 +2889,9 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
|
|||||||
|
|
||||||
if (item == -1 || viewItems.at(item).expanded)
|
if (item == -1 || viewItems.at(item).expanded)
|
||||||
return;
|
return;
|
||||||
|
const QModelIndex index = viewItems.at(item).index;
|
||||||
|
if (index.flags() & Qt::ItemNeverHasChildren)
|
||||||
|
return;
|
||||||
|
|
||||||
#ifndef QT_NO_ANIMATION
|
#ifndef QT_NO_ANIMATION
|
||||||
if (emitSignal && animationsEnabled)
|
if (emitSignal && animationsEnabled)
|
||||||
@ -2896,7 +2901,6 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
|
|||||||
if (state != QAbstractItemView::AnimatingState)
|
if (state != QAbstractItemView::AnimatingState)
|
||||||
stateBeforeAnimation = state;
|
stateBeforeAnimation = state;
|
||||||
q->setState(QAbstractItemView::ExpandingState);
|
q->setState(QAbstractItemView::ExpandingState);
|
||||||
const QModelIndex index = viewItems.at(item).index;
|
|
||||||
storeExpanded(index);
|
storeExpanded(index);
|
||||||
viewItems[item].expanded = true;
|
viewItems[item].expanded = true;
|
||||||
layout(item);
|
layout(item);
|
||||||
@ -3189,7 +3193,7 @@ void QTreeViewPrivate::layout(int i, bool recursiveExpanding, bool afterIsUninit
|
|||||||
item->expanded = false;
|
item->expanded = false;
|
||||||
item->total = 0;
|
item->total = 0;
|
||||||
item->hasMoreSiblings = false;
|
item->hasMoreSiblings = false;
|
||||||
if (recursiveExpanding || isIndexExpanded(current)) {
|
if ((recursiveExpanding && !(current.flags() & Qt::ItemNeverHasChildren)) || isIndexExpanded(current)) {
|
||||||
if (recursiveExpanding)
|
if (recursiveExpanding)
|
||||||
expandedIndexes.insert(current);
|
expandedIndexes.insert(current);
|
||||||
item->expanded = true;
|
item->expanded = true;
|
||||||
|
@ -203,7 +203,7 @@ public:
|
|||||||
|
|
||||||
inline bool isIndexExpanded(const QModelIndex &idx) const {
|
inline bool isIndexExpanded(const QModelIndex &idx) const {
|
||||||
//We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
|
//We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
|
||||||
return isPersistent(idx) && expandedIndexes.contains(idx);
|
return !(idx.flags() & Qt::ItemNeverHasChildren) && isPersistent(idx) && expandedIndexes.contains(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// used when hiding and showing items
|
// used when hiding and showing items
|
||||||
|
@ -177,6 +177,7 @@ private slots:
|
|||||||
void emptyModel();
|
void emptyModel();
|
||||||
void removeRows();
|
void removeRows();
|
||||||
void removeCols();
|
void removeCols();
|
||||||
|
void limitedExpand();
|
||||||
void expandAndCollapse_data();
|
void expandAndCollapse_data();
|
||||||
void expandAndCollapse();
|
void expandAndCollapse();
|
||||||
void expandAndCollapseAll();
|
void expandAndCollapseAll();
|
||||||
@ -1414,6 +1415,45 @@ void tst_QTreeView::removeCols()
|
|||||||
QCOMPARE(view.header()->count(), model.cols);
|
QCOMPARE(view.header()->count(), model.cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QTreeView::limitedExpand()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
QStandardItemModel model;
|
||||||
|
QStandardItem *parentItem = model.invisibleRootItem();
|
||||||
|
parentItem->appendRow(new QStandardItem);
|
||||||
|
parentItem->appendRow(new QStandardItem);
|
||||||
|
parentItem->appendRow(new QStandardItem);
|
||||||
|
|
||||||
|
QStandardItem *firstItem = model.item(0, 0);
|
||||||
|
firstItem->setFlags(firstItem->flags() | Qt::ItemNeverHasChildren);
|
||||||
|
|
||||||
|
QTreeView view;
|
||||||
|
view.setModel(&model);
|
||||||
|
|
||||||
|
QSignalSpy spy(&view, SIGNAL(expanded(QModelIndex)));
|
||||||
|
QVERIFY(spy.isValid());
|
||||||
|
|
||||||
|
view.expand(model.index(0, 0));
|
||||||
|
QCOMPARE(spy.count(), 0);
|
||||||
|
|
||||||
|
view.expand(model.index(1, 0));
|
||||||
|
QCOMPARE(spy.count(), 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QStringListModel model(QStringList() << "one" << "two");
|
||||||
|
QTreeView view;
|
||||||
|
view.setModel(&model);
|
||||||
|
|
||||||
|
QSignalSpy spy(&view, SIGNAL(expanded(QModelIndex)));
|
||||||
|
QVERIFY(spy.isValid());
|
||||||
|
|
||||||
|
view.expand(model.index(0, 0));
|
||||||
|
QCOMPARE(spy.count(), 0);
|
||||||
|
view.expandAll();
|
||||||
|
QCOMPARE(spy.count(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QTreeView::expandAndCollapse_data()
|
void tst_QTreeView::expandAndCollapse_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<bool>("animationEnabled");
|
QTest::addColumn<bool>("animationEnabled");
|
||||||
|
Loading…
Reference in New Issue
Block a user