Basic openoffice.org control, and listening for new presentation documents, still...
[kworship.git] / include / NodeBasedModel.h
blobdd9862fc6d2314b7e55f18e1a434589ecbacb186
1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
5 * KWorship 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) any later version. *
9 * *
10 * KWorship 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 KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
20 #ifndef _NodeBasedModel_h_
21 #define _NodeBasedModel_h_
23 /**
24 * @file NodeBasedModel.h
25 * @brief A Qt model based on nodes.
26 * @author James Hogan <james@albanarts.com>
29 #include "compiler.h"
31 #include <QAbstractItemModel>
32 #include <QVector>
33 #include <QVariant>
35 #include <cassert>
37 /// A node in the model.
38 class DefaultModelNode
40 public:
43 * Constructors + destructor.
46 /// Primary constructor.
47 DefaultModelNode(DefaultModelNode* parent)
48 : m_parent(parent)
49 , m_children()
53 /// Destructor.
54 virtual ~DefaultModelNode()
59 * Main interface
62 /// Get the parent.
63 DefaultModelNode* getParent()
65 return m_parent;
68 /// Get a child node by index.
69 DefaultModelNode* getChild(int index)
71 if (unlikely(index < 0 || index >= getChildCount()))
73 return 0;
76 if (index >= m_children.size())
78 int prevSize = m_children.size();
79 int newSize = getChildCount();
80 m_children.resize(newSize);
81 for (int i = prevSize; i < newSize; ++i)
83 m_children[i] = 0;
86 if (0 == m_children[index])
88 m_children[index] = _getChild(index);
90 return m_children[index];
93 /// Get the number of cached children.
94 int getNumCachedChildren() const
96 return m_children.size();
99 /// Get a cached child node by index (even if it is 0).
100 DefaultModelNode* getCachedChild(int index)
102 if (index >= 0 && index < m_children.size())
104 return m_children[index];
106 else
108 return 0;
112 /// Notify that children have been added.
113 void childrenAdded(int first, int last)
115 if (first > m_children.size())
117 first = m_children.size();
119 m_children.insert(first, last - first + 1, 0);
122 /// Notify that children have been removed.
123 void childrenRemoved(int first, int last)
125 int cacheSize = m_children.size();
126 if (first < cacheSize)
128 if (last >= cacheSize)
130 last = cacheSize - 1;
132 for (int i = first; i <= last; ++i)
134 delete m_children[i];
136 m_children.remove(first, last - first + 1);
140 /// Clear the cache of child nodes.
141 void clearChildCache()
143 foreach (DefaultModelNode* node, m_children)
145 delete node;
147 m_children.clear();
150 /// Get the index of a certain child.
151 int getChildIndex(DefaultModelNode* node) const
153 for (int i = 0; i < m_children.size(); ++i)
155 if (m_children[i] == node)
157 return i;
160 return -1;
163 /// Get data associated with the node.
164 virtual QVariant getData(int role, int column)
166 Q_UNUSED(role)
167 Q_UNUSED(column)
168 return QVariant();
171 /// Get the number of children.
172 virtual int getChildCount() const
174 return 0;
177 protected:
179 /// Get a child node by index.
180 virtual DefaultModelNode* _getChild(int index)
182 Q_UNUSED(index)
183 return 0;
186 private:
189 * Variables
192 /// Parent node.
193 DefaultModelNode* m_parent;
195 /// Child nodes.
196 QVector<DefaultModelNode*> m_children;
201 /// A Qt model based on nodes.
202 template <class NODE = DefaultModelNode>
203 class NodeBasedModel : public QAbstractItemModel
205 public:
208 * Types
211 /// Node type.
212 typedef NODE Node;
215 * Constructors + destructor.
218 /// Default constructor.
219 NodeBasedModel(QObject* parent = 0)
220 : QAbstractItemModel(parent)
221 , m_root(0)
225 /// Destructor.
226 virtual ~NodeBasedModel()
228 delete m_root;
232 * Main interface
235 /// Get the root node.
236 Node* getRootNode()
238 return m_root;
241 /// Set the root node.
242 void setRootNode(Node* root)
244 delete m_root;
245 m_root = root;
246 reset();
248 Node* itemFromIndex(const QModelIndex &index) const
250 if (index.isValid())
252 return reinterpret_cast<Node*>(index.internalPointer());
254 else
256 return m_root;
260 QModelIndex index(int row, int column, const QModelIndex& parent) const
262 if (0 == m_root)
264 return QModelIndex();
266 Node* parentNode = itemFromIndex(parent);
267 assert(0 != parentNode);
268 return createIndex(row, column, parentNode->getChild(row));
271 QModelIndex parent(const QModelIndex &child) const
273 Node* node = itemFromIndex(child);
274 if (0 == node)
276 return QModelIndex();
278 DefaultModelNode* parentNode = node->getParent();
279 if (0 == parentNode)
281 return QModelIndex();
283 DefaultModelNode* grandParentNode = parentNode->getParent();
284 if (0 == grandParentNode)
286 return QModelIndex();
288 int row = grandParentNode->getChildIndex(parentNode);
289 assert(row != -1);
290 return createIndex(row, child.column(), parentNode);
292 int rowCount(const QModelIndex &parent) const
294 Node* parentNode = itemFromIndex(parent);
295 if (0 == parentNode)
297 return 0;
299 return parentNode->getChildCount();
301 virtual int columnCount(const QModelIndex &parent) const
303 Q_UNUSED(parent)
304 return 1;
306 QVariant data(const QModelIndex &index, int role) const
308 Node* item = itemFromIndex(index);
309 if (0 == item)
311 return QVariant();
313 return item->getData(role, index.column());
315 virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const
317 Q_UNUSED(section)
318 Q_UNUSED(orientation)
319 Q_UNUSED(role)
320 return QVariant();
323 private:
326 * Variables
329 /// Root item.
330 Node* m_root;
333 #endif // _NodeBasedModel_h_