1 /* 2 * SPDX-FileCopyrightText: 2014 Mario Bensi <mbensi@ipsquad.net> 3 SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org> 4 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 5 */ 6 7 8 9 #ifndef PRESENTATION_QUERYTREENODE_H 10 #define PRESENTATION_QUERYTREENODE_H 11 12 #include <functional> 13 14 #include "domain/task.h" 15 16 #include "domain/queryresultinterface.h" 17 18 #include "querytreemodelbase.h" 19 20 namespace Presentation { 21 22 template<typename ItemType, typename AdditionalInfo> 23 class QueryTreeNode : public QueryTreeNodeBase 24 { 25 public: 26 typedef Domain::QueryResultInterface<ItemType> ItemQuery; 27 typedef typename ItemQuery::Ptr ItemQueryPtr; 28 29 typedef std::function<ItemQueryPtr(const ItemType &)> QueryGenerator; 30 typedef std::function<Qt::ItemFlags(const ItemType &)> FlagsFunction; 31 typedef std::function<QVariant(const ItemType &, int, const AdditionalInfo &)> DataFunction; 32 typedef std::function<bool(const ItemType &, const QVariant &, int)> SetDataFunction; 33 typedef std::function<bool(const QMimeData *, Qt::DropAction, const ItemType &)> DropFunction; 34 QueryTreeNode(const ItemType & item,QueryTreeNodeBase * parentNode,QueryTreeModelBase * model,const QueryGenerator & queryGenerator,const FlagsFunction & flagsFunction,const DataFunction & dataFunction,const SetDataFunction & setDataFunction)35 QueryTreeNode(const ItemType &item, QueryTreeNodeBase *parentNode, QueryTreeModelBase *model, 36 const QueryGenerator &queryGenerator, 37 const FlagsFunction &flagsFunction, 38 const DataFunction &dataFunction, 39 const SetDataFunction &setDataFunction) 40 : QueryTreeNodeBase(parentNode, model), 41 m_item(item), 42 m_flagsFunction(flagsFunction), 43 m_dataFunction(dataFunction), 44 m_setDataFunction(setDataFunction) 45 { 46 init(model, queryGenerator); 47 } 48 QueryTreeNode(const ItemType & item,QueryTreeNodeBase * parentNode,QueryTreeModelBase * model,const QueryGenerator & queryGenerator,const FlagsFunction & flagsFunction,const DataFunction & dataFunction,const SetDataFunction & setDataFunction,const DropFunction & dropFunction)49 QueryTreeNode(const ItemType &item, QueryTreeNodeBase *parentNode, QueryTreeModelBase *model, 50 const QueryGenerator &queryGenerator, 51 const FlagsFunction &flagsFunction, 52 const DataFunction &dataFunction, 53 const SetDataFunction &setDataFunction, 54 const DropFunction &dropFunction) 55 : QueryTreeNodeBase(parentNode, model), 56 m_item(item), 57 m_flagsFunction(flagsFunction), 58 m_dataFunction(dataFunction), 59 m_setDataFunction(setDataFunction), 60 m_dropFunction(dropFunction) 61 { 62 init(model, queryGenerator); 63 } 64 item()65 ItemType item() const { return m_item; } 66 flags()67 Qt::ItemFlags flags() const override { return m_flagsFunction(m_item); } 68 data(int role)69 QVariant data(int role) const override 70 { 71 if (role == QueryTreeModelBase::ObjectRole) 72 return QVariant::fromValue(m_item); 73 74 return m_dataFunction(m_item, role, m_additionalInfo); 75 } 76 setData(const QVariant & value,int role)77 bool setData(const QVariant &value, int role) override { return m_setDataFunction(m_item, value, role); } 78 dropMimeData(const QMimeData * data,Qt::DropAction action)79 bool dropMimeData(const QMimeData *data, Qt::DropAction action) override 80 { 81 if (m_dropFunction) 82 return m_dropFunction(data, action, m_item); 83 else 84 return false; 85 } 86 hasAdditionalInfo()87 bool hasAdditionalInfo() const { return m_additionalInfo; } setAdditionalInfo(const AdditionalInfo & info)88 void setAdditionalInfo(const AdditionalInfo &info) { m_additionalInfo = info; } 89 90 private: init(QueryTreeModelBase * model,const QueryGenerator & queryGenerator)91 void init(QueryTreeModelBase *model, const QueryGenerator &queryGenerator) 92 { 93 m_children = queryGenerator(m_item); 94 95 if (!m_children) 96 return; 97 98 for (auto child : m_children->data()) { 99 QueryTreeNodeBase *node = new QueryTreeNode<ItemType, AdditionalInfo>(child, this, 100 model, queryGenerator, 101 m_flagsFunction, 102 m_dataFunction, m_setDataFunction, 103 m_dropFunction); 104 appendChild(node); 105 } 106 107 m_children->addPreInsertHandler([this](const ItemType &, int index) { 108 QModelIndex parentIndex = parent() ? createIndex(row(), 0, this) : QModelIndex(); 109 beginInsertRows(parentIndex, index, index); 110 }); 111 m_children->addPostInsertHandler([this, model, queryGenerator](const ItemType &item, int index) { 112 QueryTreeNodeBase *node = new QueryTreeNode<ItemType, AdditionalInfo>(item, this, 113 model, queryGenerator, 114 m_flagsFunction, 115 m_dataFunction, m_setDataFunction, 116 m_dropFunction); 117 insertChild(index, node); 118 endInsertRows(); 119 }); 120 m_children->addPreRemoveHandler([this](const ItemType &, int index) { 121 QModelIndex parentIndex = parent() ? createIndex(row(), 0, this) : QModelIndex(); 122 beginRemoveRows(parentIndex, index, index); 123 }); 124 m_children->addPostRemoveHandler([this](const ItemType &, int index) { 125 removeChildAt(index); 126 endRemoveRows(); 127 }); 128 m_children->addPostReplaceHandler([this](const ItemType &, int idx) { 129 const QModelIndex parentIndex = parent() ? createIndex(row(), 0, this) : QModelIndex(); 130 const QModelIndex dataIndex = index(idx, 0, parentIndex); 131 emitDataChanged(dataIndex, dataIndex); 132 }); 133 } 134 135 ItemType m_item; 136 ItemQueryPtr m_children; 137 mutable AdditionalInfo m_additionalInfo; 138 139 FlagsFunction m_flagsFunction; 140 DataFunction m_dataFunction; 141 SetDataFunction m_setDataFunction; 142 DropFunction m_dropFunction; 143 }; 144 145 } 146 147 #endif // PRESENTATION_QUERYTREENODE_H 148