1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
/*
SPDX-FileCopyrightText: 2007 Alexander Dymo <adymo@kdevelop.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "aggregatemodel.h"
#include <QStandardItem>
#include <QStandardItemModel>
namespace Sublime {
class AggregateModelPrivate
{
public:
/*Instance of this class is used as an internal pointer to the aggregator items
in the model to differentiate between aggregators and non-aggregators.*/
class AggregateInternalData {
};
AggregateModelPrivate()
{
internal = new AggregateInternalData();
}
~AggregateModelPrivate()
{
delete internal;
}
QList<QStandardItemModel*> modelList;
QMap<QStandardItemModel*, QString> modelNames;
AggregateInternalData *internal;
};
AggregateModel::AggregateModel(QObject *parent)
:QAbstractItemModel(parent)
,d_ptr(new AggregateModelPrivate())
{
}
AggregateModel::~AggregateModel() = default;
void AggregateModel::addModel(const QString &name, QStandardItemModel *model)
{
Q_D(AggregateModel);
beginResetModel();
d->modelList << model;
d->modelNames[model] = name;
endResetModel();
}
void AggregateModel::removeModel(QStandardItemModel *model)
{
Q_D(AggregateModel);
beginResetModel();
d->modelList.removeAll(model);
d->modelNames.remove(model);
endResetModel();
}
// reimplemented methods from QAbstractItemModel
Qt::ItemFlags AggregateModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::NoItemFlags;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant AggregateModel::headerData(int section, Qt::Orientation orientation, int role) const
{
Q_UNUSED(section);
Q_UNUSED(orientation);
Q_UNUSED(role);
//there's nothing to return here because aggregated models will have different headers
//so we just use empty headers for aggregate model.
return QString();
}
int AggregateModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
//only 1 column is supported atm
return 1;
}
int AggregateModel::rowCount(const QModelIndex &parent) const
{
Q_D(const AggregateModel);
if (!parent.isValid())
{
//toplevel items represent aggregated models
return d->modelList.count();
}
else
{
//Qt model guideline - only 1st column has children
if (parent.column() != 0)
return 0;
//find out if the parent is an aggregator
if (parent.internalPointer() == d->internal)
{
//return the number of toplevel rows in the source model
return d->modelList[parent.row()]->rowCount(QModelIndex());
}
else
{
//we have a standard item in the source model - just map it into our model
auto *item = static_cast<QStandardItem*>(parent.internalPointer());
return item->rowCount();
}
}
}
QVariant AggregateModel::data(const QModelIndex &index, int role) const
{
Q_D(const AggregateModel);
if (!index.isValid() || (role != Qt::DisplayRole))
return QVariant();
if (!index.parent().isValid())
{
//aggregator item
return d->modelNames[d->modelList[index.row()]];
}
else
{
//we have a standard item in the source model - just map it into our model
auto *item = static_cast<QStandardItem*>(index.internalPointer());
return item->data(role);
}
}
QModelIndex AggregateModel::parent(const QModelIndex &index) const
{
Q_D(const AggregateModel);
if (!index.isValid())
return QModelIndex();
if (index.internalPointer() == d->internal)
{
//this is aggregator item, it has no parents
return QModelIndex();
}
//this is just an item from the model
auto *item = static_cast<QStandardItem*>(index.internalPointer());
QModelIndex parent;
if (!item->parent())
{
//we need to find the aggregator item that owns this index
//first find the model for this index
QStandardItemModel *model = item->model();
//next find the row number of the aggregator item
int row = d->modelList.indexOf(model);
parent = createIndex(row, 0, d->internal);
}
else
{
//we have a standard item in the source model - just map it into our model
parent = createIndex(item->parent()->row(), 0, item->parent());
}
return parent;
}
QModelIndex AggregateModel::index(int row, int column, const QModelIndex &parent) const
{
Q_D(const AggregateModel);
if (row < 0 || column < 0)
return QModelIndex();
if (!parent.isValid())
{
if (column > 1 || row >= d->modelList.count())
return QModelIndex();
//this is an aggregator item
return createIndex(row, column, d->internal);
}
else if (parent.internalPointer() == d->internal)
{
//the parent is an aggregator
//find the model that holds the items
QStandardItemModel *model = d->modelList[parent.row()];
//this is the first level of items
QStandardItem *item = model->item(row, column);
if (item)
return createIndex(row, column, item);
else
return QModelIndex();
}
else
{
//we have a standard item in the source model - just map it into our model
auto *parentItem = static_cast<QStandardItem*>(parent.internalPointer());
return createIndex(row, column, parentItem->child(row, column));
}
}
}
#include "moc_aggregatemodel.cpp"
|