forked from qt-creator/qt-creator
Utils: Introduce a class template TypedTreeItem
For better typesafety on the user side (and optional) for items with uniformly typed children. Use it for UniformTreeModels, and consequently WatchModel to get rid of some of the static_casts there. Change-Id: Ic20e507036e180c24997b236230f0f71b285202c Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -188,13 +188,32 @@ private:
|
||||
|
||||
TreeItem *m_parent; // Not owned.
|
||||
TreeModel *m_model; // Not owned.
|
||||
QVector<TreeItem *> m_children; // Owned.
|
||||
QStringList *m_displays;
|
||||
Qt::ItemFlags m_flags;
|
||||
|
||||
protected:
|
||||
QVector<TreeItem *> m_children; // Owned.
|
||||
friend class TreeModel;
|
||||
};
|
||||
|
||||
// A TreeItem with children all of the same type.
|
||||
template <class ChildType>
|
||||
class TypedTreeItem : public TreeItem
|
||||
{
|
||||
public:
|
||||
void sortChildren(const std::function<bool(const ChildType *, const ChildType *)> &lessThan)
|
||||
{
|
||||
return TreeItem::sortChildren([lessThan](const TreeItem *a, const TreeItem *b) {
|
||||
return lessThan(static_cast<const ChildType *>(a), static_cast<const ChildType *>(b));
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Predicate>
|
||||
void forAllChildren(const Predicate &pred) const {
|
||||
return TreeItem::forAllChildren<ChildType *, Predicate>(pred);
|
||||
}
|
||||
};
|
||||
|
||||
// A general purpose multi-level model where each item can have its
|
||||
// own (TreeItem-derived) type.
|
||||
class QTCREATOR_UTILS_EXPORT TreeModel : public QAbstractItemModel
|
||||
|
||||
@@ -2418,9 +2418,8 @@ void QmlEnginePrivate::insertSubItems(WatchItem *parent, const QVariantList &pro
|
||||
}
|
||||
|
||||
if (boolSetting(SortStructMembers)) {
|
||||
parent->sortChildren([](const TreeItem *item1, const TreeItem *item2) -> bool {
|
||||
return static_cast<const WatchItem *>(item1)->name
|
||||
< static_cast<const WatchItem *>(item2)->name;
|
||||
parent->sortChildren([](const WatchItem *item1, const WatchItem *item2) {
|
||||
return item1->name < item2->name;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -394,15 +394,12 @@ public:
|
||||
quint64 addrstep;
|
||||
};
|
||||
|
||||
static bool sortByName(const Utils::TreeItem *a, const Utils::TreeItem *b)
|
||||
static bool sortByName(const WatchItem *a, const WatchItem *b)
|
||||
{
|
||||
auto aa = static_cast<const WatchItem *>(a);
|
||||
auto bb = static_cast<const WatchItem *>(b);
|
||||
if (a->sortGroup != b->sortGroup)
|
||||
return a->sortGroup > b->sortGroup;
|
||||
|
||||
if (aa->sortGroup != bb->sortGroup)
|
||||
return aa->sortGroup > bb->sortGroup;
|
||||
|
||||
return aa->name < bb->name;
|
||||
return a->name < b->name;
|
||||
}
|
||||
|
||||
void WatchItem::parseHelper(const GdbMi &input, bool maySort)
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Internal {
|
||||
|
||||
class GdbMi;
|
||||
|
||||
class WatchItem : public Utils::TreeItem
|
||||
class WatchItem : public Utils::TypedTreeItem<WatchItem>
|
||||
{
|
||||
public:
|
||||
WatchItem();
|
||||
|
||||
@@ -1253,16 +1253,14 @@ void WatchHandler::cleanup()
|
||||
m_model->m_separatedView->hide();
|
||||
}
|
||||
|
||||
static bool sortByName(const TreeItem *a, const TreeItem *b)
|
||||
static bool sortByName(const WatchItem *a, const WatchItem *b)
|
||||
{
|
||||
auto aa = static_cast<const WatchItem *>(a);
|
||||
auto bb = static_cast<const WatchItem *>(b);
|
||||
return aa->name < bb->name;
|
||||
return a->name < b->name;
|
||||
}
|
||||
|
||||
void WatchHandler::insertItems(const GdbMi &data)
|
||||
{
|
||||
QSet<TreeItem *> itemsToSort;
|
||||
QSet<WatchItem *> itemsToSort;
|
||||
|
||||
const bool sortStructMembers = boolSetting(SortStructMembers);
|
||||
foreach (const GdbMi &child, data.children()) {
|
||||
@@ -1274,10 +1272,10 @@ void WatchHandler::insertItems(const GdbMi &data)
|
||||
|
||||
const bool added = insertItem(item);
|
||||
if (added && item->level() == 2)
|
||||
itemsToSort.insert(item->parent());
|
||||
itemsToSort.insert(static_cast<WatchItem *>(item->parent()));
|
||||
}
|
||||
|
||||
foreach (TreeItem *toplevel, itemsToSort)
|
||||
foreach (WatchItem *toplevel, itemsToSort)
|
||||
toplevel->sortChildren(&sortByName);
|
||||
}
|
||||
|
||||
@@ -1303,7 +1301,7 @@ bool WatchHandler::insertItem(WatchItem *item)
|
||||
|
||||
item->update();
|
||||
|
||||
item->forAllChildren<WatchItem *>([this](WatchItem *sub) { m_model->showEditValue(sub); });
|
||||
item->forAllChildren([this](WatchItem *sub) { m_model->showEditValue(sub); });
|
||||
|
||||
return !found;
|
||||
}
|
||||
@@ -1349,16 +1347,16 @@ void WatchHandler::resetWatchers()
|
||||
|
||||
void WatchHandler::notifyUpdateStarted(const QStringList &inames)
|
||||
{
|
||||
auto marker = [](TreeItem *it) { static_cast<WatchItem *>(it)->outdated = true; };
|
||||
auto marker = [](WatchItem *item) { item->outdated = true; };
|
||||
|
||||
if (inames.isEmpty()) {
|
||||
m_model->forSecondLevelItems([marker](WatchItem *item) {
|
||||
item->forAllChildren<WatchItem *>(marker);
|
||||
item->forAllChildren(marker);
|
||||
});
|
||||
} else {
|
||||
for (auto iname : inames) {
|
||||
if (WatchItem *item = m_model->findItem(iname))
|
||||
item->forAllChildren<WatchItem *>(marker);
|
||||
item->forAllChildren(marker);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user