cmake: avoid de-duplication of user's CXXFLAGS
[quassel.git] / src / client / treemodel.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2022 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 <QAbstractItemModel>
26 #include <QLinkedList>  // needed for debug
27 #include <QList>
28 #include <QStringList>
29 #include <QVariant>
30
31 /*****************************************
32  *  general item used in the Tree Model
33  *****************************************/
34 class CLIENT_EXPORT AbstractTreeItem : public QObject
35 {
36     Q_OBJECT
37
38 public:
39     enum TreeItemFlag
40     {
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)
97             parent()->removeChildLater(this);
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
111     QVariant data(int column, int role) const override;
112     bool setData(int column, const QVariant& value, int role) override;
113
114     int columnCount() const override;
115
116 private:
117     QList<QVariant> _itemData;
118 };
119
120 /*****************************************
121  * PropertyMapItem
122  *****************************************/
123 class CLIENT_EXPORT PropertyMapItem : public AbstractTreeItem
124 {
125     Q_OBJECT
126
127 public:
128     PropertyMapItem(AbstractTreeItem* parent = nullptr);
129
130     virtual QStringList propertyOrder() const = 0;
131
132     QVariant data(int column, int role) const override;
133     bool setData(int column, const QVariant& value, int role) override;
134
135     virtual QString toolTip(int column) const { Q_UNUSED(column) return QString(); }
136     int columnCount() const override;
137 };
138
139 /*****************************************
140  * TreeModel
141  *****************************************/
142 class CLIENT_EXPORT TreeModel : public QAbstractItemModel
143 {
144     Q_OBJECT
145
146 public:
147     enum myRoles
148     {
149         SortRole = Qt::UserRole,
150         UserRole
151     };
152
153     TreeModel(const QList<QVariant>&, QObject* parent = nullptr);
154     ~TreeModel() override;
155
156     AbstractTreeItem* root() const;
157
158     QVariant data(const QModelIndex& index, int role) const override;
159     bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
160
161     Qt::ItemFlags flags(const QModelIndex& index) const override;
162     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
163
164     QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
165     QModelIndex indexByItem(AbstractTreeItem* item) const;
166
167     QModelIndex parent(const QModelIndex& index) const override;
168
169     int rowCount(const QModelIndex& parent = QModelIndex()) const override;
170     int columnCount(const QModelIndex& parent = QModelIndex()) const override;
171
172     virtual void clear();
173
174 private slots:
175     void itemDataChanged(int column = -1);
176
177     void beginAppendChilds(int firstRow, int lastRow);
178     void endAppendChilds();
179
180     void beginRemoveChilds(int firstRow, int lastRow);
181     void endRemoveChilds();
182
183 protected:
184     AbstractTreeItem* rootItem;
185
186 private:
187     void connectItem(AbstractTreeItem* item);
188
189     struct ChildStatus
190     {
191         QModelIndex parent;
192         int childCount;
193         int start;
194         int end;
195         inline ChildStatus(QModelIndex parent_, int cc_, int s_, int e_)
196             : parent(parent_)
197             , childCount(cc_)
198             , start(s_)
199             , end(e_){};
200     };
201     ChildStatus _childStatus;
202     int _aboutToRemoveOrInsert;
203
204 private slots:
205     void debug_rowsAboutToBeInserted(const QModelIndex& parent, int start, int end);
206     void debug_rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
207     void debug_rowsInserted(const QModelIndex& parent, int start, int end);
208     void debug_rowsRemoved(const QModelIndex& parent, int start, int end);
209     void debug_dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
210 };