1/***************************************************************************
2 * Copyright (C) 2005-2014 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#ifndef TREEMODEL_H
22#define TREEMODEL_H
23
24#include <QList>
25#include <QStringList>
26#include <QVariant>
27#include <QAbstractItemModel>
28
29#include <QLinkedList> // needed for debug
30
31/*****************************************
32 * general item used in the Tree Model
33 *****************************************/
34class AbstractTreeItem : public QObject
35{
36 Q_OBJECT
37
38public:
39 enum TreeItemFlag {
40 NoTreeItemFlag = 0x00,
41 DeleteOnLastChildRemoved = 0x01
42 };
43 Q_DECLARE_FLAGS(TreeItemFlags, TreeItemFlag)
44
45 AbstractTreeItem(AbstractTreeItem *parent = 0);
46
47 bool newChild(AbstractTreeItem *child);
48 bool newChilds(const QList<AbstractTreeItem *> &items);
49
50 bool removeChild(int row);
51 inline bool removeChild(AbstractTreeItem *child) { return removeChild(child->row()); }
52 void removeAllChilds();
53
54 bool reParent(AbstractTreeItem *newParent);
55
56 AbstractTreeItem *child(int row) const;
57
58 int childCount(int column = 0) const;
59
60 virtual int columnCount() const = 0;
61
62 virtual QVariant data(int column, int role) const = 0;
63 virtual bool setData(int column, const QVariant &value, int role) = 0;
64
65 virtual inline Qt::ItemFlags flags() const { return _flags; }
66 virtual inline void setFlags(Qt::ItemFlags flags) { _flags = flags; }
67
68 inline AbstractTreeItem::TreeItemFlags treeItemFlags() const { return _treeItemFlags; }
69 inline void setTreeItemFlags(AbstractTreeItem::TreeItemFlags flags) { _treeItemFlags = flags; }
70 int row() const;
71 inline AbstractTreeItem *parent() const { return qobject_cast<AbstractTreeItem *>(QObject::parent()); }
72
73 void dumpChildList();
74
75signals:
76 void dataChanged(int column = -1);
77
78 void beginAppendChilds(int firstRow, int lastRow);
79 void endAppendChilds();
80
81 void beginRemoveChilds(int firstRow, int lastRow);
82 void endRemoveChilds();
83
84protected:
85 void customEvent(QEvent *event);
86
87private:
88 QList<AbstractTreeItem *> _childItems;
89 Qt::ItemFlags _flags;
90 TreeItemFlags _treeItemFlags;
91
92 void removeChildLater(AbstractTreeItem *child);
93 inline void checkForDeletion()
94 {
95 if (treeItemFlags() & DeleteOnLastChildRemoved && childCount() == 0) parent()->removeChildLater(this);
96 }
97};
98
99
100/*****************************************
101 * SimpleTreeItem
102 *****************************************/
103class SimpleTreeItem : public AbstractTreeItem
104{
105 Q_OBJECT
106
107public:
108 SimpleTreeItem(const QList<QVariant> &data, AbstractTreeItem *parent = 0);
109 virtual ~SimpleTreeItem();
110
111 virtual QVariant data(int column, int role) const;
112 virtual bool setData(int column, const QVariant &value, int role);
113
114 virtual int columnCount() const;
115
116private:
117 QList<QVariant> _itemData;
118};
119
120
121/*****************************************
122 * PropertyMapItem
123 *****************************************/
124class PropertyMapItem : public AbstractTreeItem
125{
126 Q_OBJECT
127
128public:
129 PropertyMapItem(const QStringList &propertyOrder, AbstractTreeItem *parent = 0);
130 PropertyMapItem(AbstractTreeItem *parent = 0);
131
132 virtual ~PropertyMapItem();
133
134 virtual QVariant data(int column, int role) const;
135 virtual bool setData(int column, const QVariant &value, int role);
136
137 virtual QString toolTip(int column) const { Q_UNUSED(column) return QString(); }
138 virtual int columnCount() const;
139
140 void appendProperty(const QString &property);
141
142private:
143 QStringList _propertyOrder;
144};
145
146
147/*****************************************
148 * TreeModel
149 *****************************************/
150class TreeModel : public QAbstractItemModel
151{
152 Q_OBJECT
153
154public:
155 enum myRoles {
156 SortRole = Qt::UserRole,
157 UserRole
158 };
159
160 TreeModel(const QList<QVariant> &, QObject *parent = 0);
161 virtual ~TreeModel();
162
163 virtual QVariant data(const QModelIndex &index, int role) const;
164 virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
165
166 virtual Qt::ItemFlags flags(const QModelIndex &index) const;
167 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
168
169 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
170 QModelIndex indexByItem(AbstractTreeItem *item) const;
171
172 QModelIndex parent(const QModelIndex &index) const;
173
174 int rowCount(const QModelIndex &parent = QModelIndex()) const;
175 int columnCount(const QModelIndex &parent = QModelIndex()) const;
176
177 virtual void clear();
178
179private slots:
180 void itemDataChanged(int column = -1);
181
182 void beginAppendChilds(int firstRow, int lastRow);
183 void endAppendChilds();
184
185 void beginRemoveChilds(int firstRow, int lastRow);
186 void endRemoveChilds();
187
188protected:
189 AbstractTreeItem *rootItem;
190
191private:
192 void connectItem(AbstractTreeItem *item);
193
194 struct ChildStatus {
195 QModelIndex parent;
196 int childCount;
197 int start;
198 int end;
199 inline ChildStatus(QModelIndex parent_, int cc_, int s_, int e_) : parent(parent_), childCount(cc_), start(s_), end(e_) {};
200 };
201 ChildStatus _childStatus;
202 int _aboutToRemoveOrInsert;
203
204private 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};
211
212
213#endif
214