File indexing completed on 2025-01-05 04:59:44
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Mario Bensi <mbensi@ipsquad.net> 0003 SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org> 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 0008 0009 #ifndef PRESENTATION_QUERYTREENODE_H 0010 #define PRESENTATION_QUERYTREENODE_H 0011 0012 #include <functional> 0013 0014 #include "domain/task.h" 0015 0016 #include "domain/queryresultinterface.h" 0017 0018 #include "querytreemodelbase.h" 0019 0020 namespace Presentation { 0021 0022 template<typename ItemType, typename AdditionalInfo> 0023 class QueryTreeNode : public QueryTreeNodeBase 0024 { 0025 public: 0026 typedef Domain::QueryResultInterface<ItemType> ItemQuery; 0027 typedef typename ItemQuery::Ptr ItemQueryPtr; 0028 0029 typedef std::function<ItemQueryPtr(const ItemType &)> QueryGenerator; 0030 typedef std::function<Qt::ItemFlags(const ItemType &)> FlagsFunction; 0031 typedef std::function<QVariant(const ItemType &, int, const AdditionalInfo &)> DataFunction; 0032 typedef std::function<bool(const ItemType &, const QVariant &, int)> SetDataFunction; 0033 typedef std::function<bool(const QMimeData *, Qt::DropAction, const ItemType &)> DropFunction; 0034 0035 QueryTreeNode(const ItemType &item, QueryTreeNodeBase *parentNode, QueryTreeModelBase *model, 0036 const QueryGenerator &queryGenerator, 0037 const FlagsFunction &flagsFunction, 0038 const DataFunction &dataFunction, 0039 const SetDataFunction &setDataFunction) 0040 : QueryTreeNodeBase(parentNode, model), 0041 m_item(item), 0042 m_flagsFunction(flagsFunction), 0043 m_dataFunction(dataFunction), 0044 m_setDataFunction(setDataFunction) 0045 { 0046 init(model, queryGenerator); 0047 } 0048 0049 QueryTreeNode(const ItemType &item, QueryTreeNodeBase *parentNode, QueryTreeModelBase *model, 0050 const QueryGenerator &queryGenerator, 0051 const FlagsFunction &flagsFunction, 0052 const DataFunction &dataFunction, 0053 const SetDataFunction &setDataFunction, 0054 const DropFunction &dropFunction) 0055 : QueryTreeNodeBase(parentNode, model), 0056 m_item(item), 0057 m_flagsFunction(flagsFunction), 0058 m_dataFunction(dataFunction), 0059 m_setDataFunction(setDataFunction), 0060 m_dropFunction(dropFunction) 0061 { 0062 init(model, queryGenerator); 0063 } 0064 0065 ItemType item() const { return m_item; } 0066 0067 Qt::ItemFlags flags() const override { return m_flagsFunction(m_item); } 0068 0069 QVariant data(int role) const override 0070 { 0071 if (role == QueryTreeModelBase::ObjectRole) 0072 return QVariant::fromValue(m_item); 0073 0074 return m_dataFunction(m_item, role, m_additionalInfo); 0075 } 0076 0077 bool setData(const QVariant &value, int role) override { return m_setDataFunction(m_item, value, role); } 0078 0079 bool dropMimeData(const QMimeData *data, Qt::DropAction action) override 0080 { 0081 if (m_dropFunction) 0082 return m_dropFunction(data, action, m_item); 0083 else 0084 return false; 0085 } 0086 0087 bool hasAdditionalInfo() const { return hasAdditionalInfo(m_additionalInfo); } 0088 void setAdditionalInfo(const AdditionalInfo &info) { m_additionalInfo = info; } 0089 0090 private: 0091 template <typename T> 0092 inline bool hasAdditionalInfo(const QSharedPointer<T> &p) const { 0093 return !p.isNull(); 0094 } 0095 template <typename T> 0096 inline bool hasAdditionalInfo(const T &value) const 0097 { 0098 return value; 0099 } 0100 0101 void init(QueryTreeModelBase *model, const QueryGenerator &queryGenerator) 0102 { 0103 m_children = queryGenerator(m_item); 0104 0105 if (!m_children) 0106 return; 0107 0108 for (auto child : m_children->data()) { 0109 QueryTreeNodeBase *node = new QueryTreeNode<ItemType, AdditionalInfo>(child, this, 0110 model, queryGenerator, 0111 m_flagsFunction, 0112 m_dataFunction, m_setDataFunction, 0113 m_dropFunction); 0114 appendChild(node); 0115 } 0116 0117 m_children->addPreInsertHandler([this](const ItemType &, int index) { 0118 QModelIndex parentIndex = parent() ? createIndex(row(), 0, this) : QModelIndex(); 0119 beginInsertRows(parentIndex, index, index); 0120 }); 0121 m_children->addPostInsertHandler([this, model, queryGenerator](const ItemType &item, int index) { 0122 QueryTreeNodeBase *node = new QueryTreeNode<ItemType, AdditionalInfo>(item, this, 0123 model, queryGenerator, 0124 m_flagsFunction, 0125 m_dataFunction, m_setDataFunction, 0126 m_dropFunction); 0127 insertChild(index, node); 0128 endInsertRows(); 0129 }); 0130 m_children->addPreRemoveHandler([this](const ItemType &, int index) { 0131 QModelIndex parentIndex = parent() ? createIndex(row(), 0, this) : QModelIndex(); 0132 beginRemoveRows(parentIndex, index, index); 0133 }); 0134 m_children->addPostRemoveHandler([this](const ItemType &, int index) { 0135 removeChildAt(index); 0136 endRemoveRows(); 0137 }); 0138 m_children->addPostReplaceHandler([this](const ItemType &, int idx) { 0139 const QModelIndex parentIndex = parent() ? createIndex(row(), 0, this) : QModelIndex(); 0140 const QModelIndex dataIndex = index(idx, 0, parentIndex); 0141 emitDataChanged(dataIndex, dataIndex); 0142 }); 0143 } 0144 0145 ItemType m_item; 0146 ItemQueryPtr m_children; 0147 mutable AdditionalInfo m_additionalInfo; 0148 0149 FlagsFunction m_flagsFunction; 0150 DataFunction m_dataFunction; 0151 SetDataFunction m_setDataFunction; 0152 DropFunction m_dropFunction; 0153 }; 0154 0155 } 0156 0157 #endif // PRESENTATION_QUERYTREENODE_H