1 /***************************************************************************
2 * Copyright 2007 Alexander Dymo <adymo@kdevelop.org> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU Library General Public License as *
6 * published by the Free Software Foundation; either version 2 of the *
7 * License, or (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU Library General Public *
15 * License along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
19 #include "aggregatemodel.h"
21 #include <QStandardItem>
22 #include <QStandardItemModel>
28 struct AggregateModelPrivate
{
30 /*Instance of this class is used as an internal pointer to the aggregator items
31 in the model to differentiate between aggregators and non-aggregators.*/
32 class AggregateInternalData
{
35 AggregateModelPrivate()
37 internal
= new AggregateInternalData();
39 ~AggregateModelPrivate()
44 QList
<QStandardItemModel
*> modelList
;
45 QMap
<QStandardItemModel
*, QString
> modelNames
;
46 AggregateInternalData
*internal
;
51 AggregateModel::AggregateModel(QObject
*parent
)
52 :QAbstractItemModel(parent
)
54 d
= new AggregateModelPrivate();
57 AggregateModel::~AggregateModel()
62 void AggregateModel::addModel(const QString
&name
, QStandardItemModel
*model
)
64 d
->modelList
<< model
;
65 d
->modelNames
[model
] = name
;
69 void AggregateModel::removeModel(QStandardItemModel
*model
)
71 d
->modelList
.removeAll(model
);
72 d
->modelNames
.remove(model
);
78 // reimplemented methods from QAbstractItemModel
80 Qt::ItemFlags
AggregateModel::flags(const QModelIndex
&index
) const
84 return Qt::ItemIsEnabled
& Qt::ItemIsSelectable
;
87 QVariant
AggregateModel::headerData(int section
, Qt::Orientation orientation
, int role
) const
89 //there's nothing to return here because aggregated models will have different headers
90 //so we just use empty headers for aggregate model.
94 int AggregateModel::columnCount(const QModelIndex
&parent
) const
96 //only 1 column is supported atm
100 int AggregateModel::rowCount(const QModelIndex
&parent
) const
102 if (!parent
.isValid())
104 //toplevel items represent aggregated models
105 return d
->modelList
.count();
109 //Qt model guideline - only 1st column has children
110 if (parent
.column() != 0)
113 //find out if the parent is an aggregator
114 if (parent
.internalPointer() == d
->internal
)
116 //return the number of toplevel rows in the source model
117 return d
->modelList
[parent
.row()]->rowCount(QModelIndex());
121 //we have a standard item in the source model - just map it into our model
122 QStandardItem
*item
= static_cast<QStandardItem
*>(parent
.internalPointer());
123 return item
->rowCount();
128 QVariant
AggregateModel::data(const QModelIndex
&index
, int role
) const
130 if (!index
.isValid() || (role
!= Qt::DisplayRole
))
133 if (!index
.parent().isValid())
136 return d
->modelNames
[d
->modelList
[index
.row()]];
140 //we have a standard item in the source model - just map it into our model
141 QStandardItem
*item
= static_cast<QStandardItem
*>(index
.internalPointer());
142 return item
->data(role
);
146 QModelIndex
AggregateModel::parent(const QModelIndex
&index
) const
148 if (!index
.isValid())
149 return QModelIndex();
151 if (index
.internalPointer() == d
->internal
)
153 //this is aggregator item, it has no parents
154 return QModelIndex();
157 //this is just an item from the model
158 QStandardItem
*item
= static_cast<QStandardItem
*>(index
.internalPointer());
162 //we need to find the aggregator item that owns this index
163 //first find the model for this index
164 QStandardItemModel
*model
= item
->model();
165 //next find the row number of the aggregator item
166 int row
= d
->modelList
.indexOf(model
);
167 parent
= createIndex(row
, 0, d
->internal
);
171 //we have a standard item in the source model - just map it into our model
172 parent
= createIndex(item
->parent()->row(), 0, item
->parent());
177 QModelIndex
AggregateModel::index(int row
, int column
, const QModelIndex
&parent
) const
179 if (row
< 0 || column
< 0)
180 return QModelIndex();
182 if (!parent
.isValid())
184 if (column
> 1 || row
>= d
->modelList
.count())
185 return QModelIndex();
186 //this is an aggregator item
187 return createIndex(row
, column
, d
->internal
);
189 else if (parent
.internalPointer() == d
->internal
)
191 //the parent is an aggregator
192 //find the model that holds the items
193 QStandardItemModel
*model
= d
->modelList
[parent
.row()];
194 //this is the first level of items
195 QStandardItem
*item
= model
->item(row
, column
);
197 return createIndex(row
, column
, item
);
199 return QModelIndex();
203 //we have a standard item in the source model - just map it into our model
204 QStandardItem
*parentItem
= static_cast<QStandardItem
*>(parent
.internalPointer());
205 return createIndex(row
, column
, parentItem
->child(row
, column
));
211 #include "aggregatemodel.moc"