/**************************************************************************** ** ** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #pragma once #include "utils_global.h" #include "treemodel.h" namespace Utils { template class BaseListModel : public TreeModel, ChildType> { public: using BaseModel = TreeModel, ChildType>; using BaseModel::rootItem; explicit BaseListModel(QObject *parent = nullptr) : BaseModel(parent) {} int itemCount() const { return rootItem()->childCount(); } ChildType *itemAt(int row) const { return rootItem()->childAt(row); } void appendItem(ChildType *item) { rootItem()->appendChild(item); } template void forItems(const Predicate &pred) const { rootItem()->forFirstLevelChildren(pred); } template ChildType *findItem(const Predicate &pred) const { return rootItem()->findFirstLevelChild(pred); } void sortItems(const std::function &lessThan) { return rootItem()->sortChildren([lessThan](const TreeItem *a, const TreeItem *b) { return lessThan(static_cast(a), static_cast(b)); }); } int indexOf(const ChildType *item) const { return rootItem()->indexOf(item); } void clear() { rootItem()->removeChildren(); } using const_iterator = typename QVector::const_iterator; const_iterator begin() const { return rootItem()->begin(); } const_iterator end() const { return rootItem()->end(); } }; template class ListItem : public TreeItem { public: ItemData itemData; }; template class ListModel : public BaseListModel> { public: using ChildType = ListItem; using BaseModel = BaseListModel; explicit ListModel(QObject *parent = nullptr) : BaseModel(parent) {} const ItemData &dataAt(int row) const { static const ItemData dummyData = {}; auto item = BaseModel::itemAt(row); return item ? item->itemData : dummyData; } ChildType *findItemByData(const std::function &pred) const { return BaseModel::rootItem()->findFirstLevelChild([pred](ChildType *child) { return pred(child->itemData); }); } void destroyItems(const std::function &pred) { QList toDestroy; BaseModel::rootItem()->forFirstLevelChildren([pred, &toDestroy](ChildType *item) { if (pred(item->itemData)) toDestroy.append(item); }); for (ChildType *item : toDestroy) this->destroyItem(item); } ItemData *findData(const std::function &pred) const { ChildType *item = findItemByData(pred); return item ? &item->itemData : nullptr; } void forItems(const std::function &func) const { BaseModel::rootItem()->forFirstLevelChildren([func](ChildType *child) { func(child->itemData); }); } ChildType *appendItem(const ItemData &data) { auto item = new ChildType; item->itemData = data; BaseModel::rootItem()->appendChild(item); return item; } QVariant data(const QModelIndex &idx, int role) const override { TreeItem *item = BaseModel::itemForIndex(idx); if (item && item->parent() == BaseModel::rootItem()) return itemData(static_cast(item)->itemData, idx.column(), role); return {}; } Qt::ItemFlags flags(const QModelIndex &idx) const override { TreeItem *item = BaseModel::itemForIndex(idx); if (item && item->parent() == BaseModel::rootItem()) return itemFlags(static_cast(item)->itemData, idx.column()); return {}; } virtual QVariant itemData(const ItemData &idata, int column, int role) const { if (m_dataAccessor) return m_dataAccessor(idata, column, role); return {}; } virtual Qt::ItemFlags itemFlags(const ItemData &idata, int column) const { if (m_flagsAccessor) return m_flagsAccessor(idata, column); return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } void setDataAccessor(const std::function &accessor) { m_dataAccessor = accessor; } void setFlagsAccessor(const std::function &accessor) { m_flagsAccessor = accessor; } private: std::function m_dataAccessor; std::function m_flagsAccessor; }; } // namespace Utils