modernize: Pass arguments by value and move in constructors
[quassel.git] / src / client / treemodel.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2018 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #pragma once
22
23 #include "client-export.h"
24
25 #include <QList>
26 #include <QStringList>
27 #include <QVariant>
28 #include <QAbstractItemModel>
29
30 #include <QLinkedList> // needed for debug
31
32 /*****************************************
33  *  general item used in the Tree Model
34  *****************************************/
35 class CLIENT_EXPORT AbstractTreeItem : public QObject
36 {
37     Q_OBJECT
38
39 public:
40     enum TreeItemFlag {
41         NoTreeItemFlag = 0x00,
42         DeleteOnLastChildRemoved = 0x01
43     };
44     Q_DECLARE_FLAGS(TreeItemFlags, TreeItemFlag)
45
46     AbstractTreeItem(AbstractTreeItem *parent = nullptr);
47
48     bool newChild(AbstractTreeItem *child);
49     bool newChilds(const QList<AbstractTreeItem *> &items);
50
51     bool removeChild(int row);
52     inline bool removeChild(AbstractTreeItem *child) { return removeChild(child->row()); }
53     void removeAllChilds();
54
55     bool reParent(AbstractTreeItem *newParent);
56
57     AbstractTreeItem *child(int row) const;
58
59     int childCount(int column = 0) const;
60
61     virtual int columnCount() const = 0;
62
63     virtual QVariant data(int column, int role) const = 0;
64     virtual bool setData(int column, const QVariant &value, int role) = 0;
65
66     virtual inline Qt::ItemFlags flags() const { return _flags; }
67     virtual inline void setFlags(Qt::ItemFlags flags) { _flags = flags; }
68
69     inline AbstractTreeItem::TreeItemFlags treeItemFlags() const { return _treeItemFlags; }
70     inline void setTreeItemFlags(AbstractTreeItem::TreeItemFlags flags) { _treeItemFlags = flags; }
71     int row() const;
72     inline AbstractTreeItem *parent() const { return qobject_cast<AbstractTreeItem *>(QObject::parent()); }
73
74     void dumpChildList();
75
76 signals:
77     void dataChanged(int column = -1);
78
79     void beginAppendChilds(int firstRow, int lastRow);
80     void endAppendChilds();
81
82     void beginRemoveChilds(int firstRow, int lastRow);
83     void endRemoveChilds();
84
85 protected:
86     void customEvent(QEvent *event) override;
87
88 private:
89     QList<AbstractTreeItem *> _childItems;
90     Qt::ItemFlags _flags;
91     TreeItemFlags _treeItemFlags;
92
93     void removeChildLater(AbstractTreeItem *child);
94     inline void checkForDeletion()
95     {
96         if (treeItemFlags() & DeleteOnLastChildRemoved && childCount() == 0) parent()->removeChildLater(this);
97     }
98 };
99
100
101 /*****************************************
102  * SimpleTreeItem
103  *****************************************/
104 class CLIENT_EXPORT SimpleTreeItem : public AbstractTreeItem
105 {
106     Q_OBJECT
107
108 public:
109     SimpleTreeItem(QList<QVariant> data, AbstractTreeItem *parent = nullptr);
110     ~SimpleTreeItem() override;
111
112     QVariant data(int column, int role) const override;
113     bool setData(int column, const QVariant &value, int role) override;
114
115     int columnCount() const override;
116
117 private:
118     QList<QVariant> _itemData;
119 };
120
121
122 /*****************************************
123  * PropertyMapItem
124  *****************************************/
125 class CLIENT_EXPORT PropertyMapItem : public AbstractTreeItem
126 {
127     Q_OBJECT
128
129 public:
130     PropertyMapItem(AbstractTreeItem *parent = nullptr);
131
132     virtual QStringList propertyOrder() const = 0;
133
134     QVariant data(int column, int role) const override;
135     bool setData(int column, const QVariant &value, int role) override;
136
137     virtual QString toolTip(int column) const { Q_UNUSED(column) return QString(); }
138     int columnCount() const override;
139 };
140
141
142 /*****************************************
143  * TreeModel
144  *****************************************/
145 class CLIENT_EXPORT TreeModel : public QAbstractItemModel
146 {
147     Q_OBJECT
148
149 public:
150     enum myRoles {
151         SortRole = Qt::UserRole,
152         UserRole
153     };
154
155     TreeModel(const QList<QVariant> &, QObject *parent = nullptr);
156     ~TreeModel() override;
157
158     AbstractTreeItem *root() const;
159
160     QVariant data(const QModelIndex &index, int role) const override;
161     bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
162
163     Qt::ItemFlags flags(const QModelIndex &index) const override;
164     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
165
166     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
167     QModelIndex indexByItem(AbstractTreeItem *item) const;
168
169     QModelIndex parent(const QModelIndex &index) const override;
170
171     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
172     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
173
174     virtual void clear();
175
176 private slots:
177     void itemDataChanged(int column = -1);
178
179     void beginAppendChilds(int firstRow, int lastRow);
180     void endAppendChilds();
181
182     void beginRemoveChilds(int firstRow, int lastRow);
183     void endRemoveChilds();
184
185 protected:
186     AbstractTreeItem *rootItem;
187
188 private:
189     void connectItem(AbstractTreeItem *item);
190
191     struct ChildStatus {
192         QModelIndex parent;
193         int childCount;
194         int start;
195         int end;
196         inline ChildStatus(QModelIndex parent_, int cc_, int s_, int e_) : parent(parent_), childCount(cc_), start(s_), end(e_) {};
197     };
198     ChildStatus _childStatus;
199     int _aboutToRemoveOrInsert;
200
201 private slots:
202     void debug_rowsAboutToBeInserted(const QModelIndex &parent, int start, int end);
203     void debug_rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
204     void debug_rowsInserted(const QModelIndex &parent, int start, int end);
205     void debug_rowsRemoved(const QModelIndex &parent, int start, int end);
206     void debug_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
207 };