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_QUERYTREEMODEL_H
10 #define PRESENTATION_QUERYTREEMODEL_H
11 
12 #include "querytreenode.h"
13 
14 #include <functional>
15 #include <algorithm>
16 
17 namespace Presentation {
18 
19 template<typename ItemType, typename AdditionalInfo = int>
20 class QueryTreeModel : public QueryTreeModelBase
21 {
22 public:
23     typedef typename QueryTreeNode<ItemType, AdditionalInfo>::QueryGenerator QueryGenerator;
24     typedef typename QueryTreeNode<ItemType, AdditionalInfo>::FlagsFunction FlagsFunction;
25     typedef typename QueryTreeNode<ItemType, AdditionalInfo>::DataFunction DataFunction;
26     typedef typename QueryTreeNode<ItemType, AdditionalInfo>::SetDataFunction SetDataFunction;
27     typedef typename QueryTreeNode<ItemType, AdditionalInfo>::DropFunction DropFunction;
28     typedef std::function<QMimeData*(const QList<ItemType> &)> DragFunction;
29     using FetchAdditionalInfoFunction = std::function<AdditionalInfo(const QModelIndex &index, ItemType)>;
30     using NodeType = QueryTreeNode<ItemType, AdditionalInfo>;
31 
32     explicit QueryTreeModel(const QueryGenerator &queryGenerator,
33                             const FlagsFunction &flagsFunction,
34                             const DataFunction &dataFunction,
35                             const SetDataFunction &setDataFunction,
36                             QObject *parent = nullptr)
QueryTreeModelBase(new QueryTreeNode<ItemType,AdditionalInfo> (ItemType (),nullptr,this,queryGenerator,flagsFunction,dataFunction,setDataFunction),parent)37         : QueryTreeModelBase(new QueryTreeNode<ItemType, AdditionalInfo>(ItemType(), nullptr, this,
38                                                          queryGenerator, flagsFunction,
39                                                          dataFunction, setDataFunction),
40                              parent)
41     {
42     }
43 
44     explicit QueryTreeModel(const QueryGenerator &queryGenerator,
45                             const FlagsFunction &flagsFunction,
46                             const DataFunction &dataFunction,
47                             const SetDataFunction &setDataFunction,
48                             const DropFunction &dropFunction,
49                             const DragFunction &dragFunction,
50                             const FetchAdditionalInfoFunction &fetchAdditionalInfoFunction,
51                             QObject *parent = nullptr)
QueryTreeModelBase(new QueryTreeNode<ItemType,AdditionalInfo> (ItemType (),nullptr,this,queryGenerator,flagsFunction,dataFunction,setDataFunction,dropFunction),parent)52         : QueryTreeModelBase(new QueryTreeNode<ItemType, AdditionalInfo>(ItemType(), nullptr, this,
53                                                          queryGenerator, flagsFunction,
54                                                          dataFunction, setDataFunction,
55                                                          dropFunction),
56                              parent),
57           m_dragFunction(dragFunction),
58           m_fetchAdditionalInfoFunction(fetchAdditionalInfoFunction)
59     {
60     }
61 
62 protected:
createMimeData(const QModelIndexList & indexes)63     QMimeData *createMimeData(const QModelIndexList &indexes) const override
64     {
65         if (m_dragFunction) {
66             QList<ItemType> items;
67             std::transform(indexes.begin(), indexes.end(),
68                            std::back_inserter(items),
69                            [this](const QModelIndex &index) {
70                                return itemAtIndex(index);
71                            });
72             return m_dragFunction(items);
73         } else {
74             return nullptr;
75         }
76     }
77 
78 
fetchAdditionalInfo(const QModelIndex & index)79     void fetchAdditionalInfo(const QModelIndex &index) override
80     {
81         if (m_fetchAdditionalInfoFunction) {
82             auto theNode = node(index);
83             if (!theNode->hasAdditionalInfo())
84                 theNode->setAdditionalInfo(m_fetchAdditionalInfoFunction(index, theNode->item()));
85         }
86     }
87 
itemAtIndex(const QModelIndex & index)88     ItemType itemAtIndex(const QModelIndex &index) const
89     {
90         return node(index)->item();
91     }
92 
node(const QModelIndex & index)93     NodeType *node(const QModelIndex &index) const
94     {
95         return static_cast<NodeType *>(nodeFromIndex(index));
96     }
97 
98 private:
99     DragFunction m_dragFunction;
100     FetchAdditionalInfoFunction m_fetchAdditionalInfoFunction;
101 };
102 
103 }
104 
105 #endif // PRESENTATION_QUERYTREEMODEL_H
106