Merge pull request #105 from merlin1991/qdatastream
[quassel.git] / src / client / treemodel.h
1 /***************************************************************************
2  *   Copyright (C) 2005-2015 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  *****************************************/
34 class AbstractTreeItem : public QObject
35 {
36     Q_OBJECT
37
38 public:
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
75 signals:
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
84 protected:
85     void customEvent(QEvent *event);
86
87 private:
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  *****************************************/
103 class SimpleTreeItem : public AbstractTreeItem
104 {
105     Q_OBJECT
106
107 public:
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
116 private:
117     QList<QVariant> _itemData;
118 };
119
120
121 /*****************************************
122  * PropertyMapItem
123  *****************************************/
124 class PropertyMapItem : public AbstractTreeItem
125 {
126     Q_OBJECT
127
128 public:
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
142 private:
143     QStringList _propertyOrder;
144 };
145
146
147 /*****************************************
148  * TreeModel
149  *****************************************/
150 class TreeModel : public QAbstractItemModel
151 {
152     Q_OBJECT
153
154 public:
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
179 private 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
188 protected:
189     AbstractTreeItem *rootItem;
190
191 private:
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
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 };
211
212
213 #endif