1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
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. *
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. *
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_
24 * @file NodeBasedModel.h
25 * @brief A Qt model based on nodes.
26 * @author James Hogan <james@albanarts.com>
31 #include <QAbstractItemModel>
37 /// A node in the model.
38 class DefaultModelNode
43 * Constructors + destructor.
46 /// Primary constructor.
47 DefaultModelNode(DefaultModelNode
* parent
)
54 virtual ~DefaultModelNode()
63 DefaultModelNode
* getParent()
68 /// Get a child node by index.
69 DefaultModelNode
* getChild(int index
)
71 if (unlikely(index
< 0 || index
>= getChildCount()))
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
)
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
];
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
)
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
)
163 /// Get data associated with the node.
164 virtual QVariant
getData(int role
, int column
)
171 /// Get the number of children.
172 virtual int getChildCount() const
179 /// Get a child node by index.
180 virtual DefaultModelNode
* _getChild(int index
)
193 DefaultModelNode
* m_parent
;
196 QVector
<DefaultModelNode
*> m_children
;
201 /// A Qt model based on nodes.
202 template <class NODE
= DefaultModelNode
>
203 class NodeBasedModel
: public QAbstractItemModel
215 * Constructors + destructor.
218 /// Default constructor.
219 NodeBasedModel(QObject
* parent
= 0)
220 : QAbstractItemModel(parent
)
226 virtual ~NodeBasedModel()
235 /// Get the root node.
241 /// Set the root node.
242 void setRootNode(Node
* root
)
248 Node
* itemFromIndex(const QModelIndex
&index
) const
252 return reinterpret_cast<Node
*>(index
.internalPointer());
260 QModelIndex
index(int row
, int column
, const QModelIndex
& parent
) const
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
);
276 return QModelIndex();
278 DefaultModelNode
* parentNode
= node
->getParent();
281 return QModelIndex();
283 DefaultModelNode
* grandParentNode
= parentNode
->getParent();
284 if (0 == grandParentNode
)
286 return QModelIndex();
288 int row
= grandParentNode
->getChildIndex(parentNode
);
290 return createIndex(row
, child
.column(), parentNode
);
292 int rowCount(const QModelIndex
&parent
) const
294 Node
* parentNode
= itemFromIndex(parent
);
299 return parentNode
->getChildCount();
301 virtual int columnCount(const QModelIndex
&parent
) const
306 QVariant
data(const QModelIndex
&index
, int role
) const
308 Node
* item
= itemFromIndex(index
);
313 return item
->getData(role
, index
.column());
315 virtual QVariant
headerData(int section
, Qt::Orientation orientation
, int role
) const
318 Q_UNUSED(orientation
)
333 #endif // _NodeBasedModel_h_