2
Copyright (c) 2009 Stephen Kelly <steveire@gmail.com>
4
This library is free software; you can redistribute it and/or modify it
5
under the terms of the GNU Library General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or (at your
7
option) any later version.
9
This library is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12
License for more details.
14
You should have received a copy of the GNU Library General Public License
15
along with this library; see the file COPYING.LIB. If not, write to the
16
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
#include "dynamictreemodel.h"
30
DynamicTreeModel::DynamicTreeModel(QObject *parent)
31
: AbstractItemModel(parent),
36
QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &parent) const
39
// return QModelIndex();
42
if ( column < 0 || row < 0 )
45
QList<QList<qint64> > childIdColumns = m_childItems.value(parent.internalId());
48
if (childIdColumns.size() == 0)
51
if (column >= childIdColumns.size())
54
QList<qint64> rowIds = childIdColumns.at(column);
56
if ( row >= rowIds.size())
59
qint64 id = rowIds.at(row);
61
return createIndex(row, column, reinterpret_cast<void *>(id));
65
qint64 DynamicTreeModel::findParentId(qint64 searchId) const
70
QHashIterator<qint64, QList<QList<qint64> > > i(m_childItems);
74
QListIterator<QList<qint64> > j(i.value());
77
QList<qint64> l = j.next();
78
if (l.contains(searchId))
87
QModelIndex DynamicTreeModel::parent(const QModelIndex &index) const
92
qint64 searchId = index.internalId();
93
qint64 parentId = findParentId(searchId);
94
// Will never happen for valid index, but what the hey...
98
qint64 grandParentId = findParentId(parentId);
99
if (grandParentId < 0)
103
QList<qint64> childList = m_childItems.value(grandParentId).at(column);
105
int row = childList.indexOf(parentId);
107
return createIndex(row, column, reinterpret_cast<void *>(parentId));
111
int DynamicTreeModel::rowCount(const QModelIndex &index ) const
113
QList<QList<qint64> > cols = m_childItems.value(index.internalId());
115
if (cols.size() == 0 )
118
if (index.column() > 0)
121
return cols.at(0).size();
124
int DynamicTreeModel::columnCount(const QModelIndex &index ) const
127
return m_childItems.value(index.internalId()).size();
130
QVariant DynamicTreeModel::data(const QModelIndex &index, int role) const
132
if (!index.isValid())
135
if (Qt::DisplayRole == role)
137
return m_items.value(index.internalId());
143
ModelChangeCommand::ModelChangeCommand( DynamicTreeModel *model, QObject *parent )
144
: QObject(parent), m_model(model), m_numCols(1)
149
QModelIndex ModelChangeCommand::findIndex(QList<int> rows)
152
QModelIndex parent = QModelIndex();
153
QListIterator<int> i(rows);
156
parent = m_model->index(i.next(), col, parent);
157
Q_ASSERT(parent.isValid());
162
ModelInsertCommand::ModelInsertCommand(DynamicTreeModel *model, QObject *parent )
163
: ModelChangeCommand(model, parent)
168
void ModelInsertCommand::doCommand()
170
QModelIndex parent = findIndex(m_rowNumbers);
171
m_model->beginInsertRows(parent, m_startRow, m_endRow);
172
qint64 parentId = parent.internalId();
173
for (int row = m_startRow; row <= m_endRow; row++)
175
for(int col = 0; col < m_numCols; col++ )
177
if (m_model->m_childItems[parentId].size() <= col)
179
m_model->m_childItems[parentId].append(QList<qint64>());
181
// QString name = QUuid::createUuid().toString();
182
qint64 id = m_model->newId();
183
QString name = QString::number(id);
185
m_model->m_items.insert(id, name);
186
m_model->m_childItems[parentId][col].insert(row, id);
190
m_model->endInsertRows();
193
ModelInsertWithDescendantsCommand::ModelInsertWithDescendantsCommand(DynamicTreeModel *model, QObject *parent)
194
: ModelInsertCommand(model, parent)
199
void ModelInsertWithDescendantsCommand::setNumDescendants(QList<QPair<int, int > > descs)
204
void ModelInsertWithDescendantsCommand::doCommand()
206
QModelIndex idx = findIndex(m_rowNumbers);
208
QPair<int, int> firstPair = m_descs.value(0);
209
QModelIndex parent = m_model->index(firstPair.first, 0, idx);
210
int row = m_model->rowCount(parent);
211
m_model->beginInsertRows(parent, row, row + firstPair.second - 1);
213
qint64 parentId = parent.internalId();
214
QListIterator<QPair<int, int> > i(m_descs);
217
QPair<int, int> pair = i.next();
218
for(int col = 0; col < m_numCols; col++ )
220
if (m_model->m_childItems[parentId].size() <= col)
222
m_model->m_childItems[parentId].append(QList<qint64>());
224
for (int i = 0; i < pair.second; i++)
226
qint64 id = m_model->newId();
227
QString name = QString::number(id);
229
m_model->m_items.insert(id, name);
230
m_model->m_childItems[parentId][col].append(id);
233
parentId = m_model->m_childItems[parentId][0].at(pair.first);
235
m_model->endInsertRows();
239
ModelRemoveCommand::ModelRemoveCommand(DynamicTreeModel *model, QObject *parent )
240
: ModelChangeCommand(model, parent)
245
void ModelRemoveCommand::doCommand()
247
QModelIndex parent = findIndex(m_rowNumbers);
248
m_model->beginRemoveRows(parent, m_startRow, m_endRow);
249
qint64 parentId = parent.internalId();
250
for(int col = 0; col < m_numCols; col++ )
252
QList<qint64> childItems = m_model->m_childItems.value(parentId).value(col);
253
for (int row = m_startRow; row <= m_endRow; row++)
255
qint64 item = childItems[row];
257
m_model->m_childItems[parentId][col].removeOne(item);
260
m_model->endRemoveRows();
263
void ModelRemoveCommand::purgeItem(qint64 parent)
265
QList<QList<qint64> > childItemRows = m_model->m_childItems.value(parent);
267
if (childItemRows.size() > 0)
269
for (int col = 0; col < m_numCols; col++)
271
QList<qint64> childItems = childItemRows[col];
272
foreach(qint64 item, childItems)
275
m_model->m_childItems[parent][col].removeOne(item);
279
m_model->m_items.remove(parent);
283
ModelDataChangeCommand::ModelDataChangeCommand(DynamicTreeModel *model, QObject *parent)
284
: ModelChangeCommand(model, parent), m_startColumn(0)
289
void ModelDataChangeCommand::doCommand()
291
QModelIndex parent = findIndex(m_rowNumbers);
292
QModelIndex topLeft = m_model->index(m_startRow, m_startColumn, parent);
293
QModelIndex bottomRight = m_model->index(m_endRow, m_numCols - 1, parent);
295
QList<QList<qint64> > childItems = m_model->m_childItems[parent.internalId()];
298
for (int col = m_startColumn; col < m_startColumn + m_numCols; col++)
300
for (int row = m_startRow; row < m_endRow; row++ )
302
QString name = QUuid::createUuid().toString();
303
m_model->m_items[childItems[col][row]] = name;
306
m_model->dataChanged(topLeft, bottomRight);
310
ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent)
311
: ModelChangeCommand(model, parent)
316
void ModelMoveCommand::doCommand()
318
QModelIndex srcParent = findIndex(m_rowNumbers);
319
QModelIndex destParent = findIndex(m_destRowNumbers);
321
m_model->beginMoveRows(srcParent, m_startRow, m_endRow, destParent, m_destRow);
323
QList<qint64> l = m_model->m_childItems.value(srcParent.internalId())[0].mid(m_startRow, m_endRow - m_startRow + 1 );
325
for (int i = m_startRow; i <= m_endRow ; i++)
327
m_model->m_childItems[srcParent.internalId()][0].removeAt(m_startRow);
330
if (m_destRow < m_startRow)
334
if (srcParent == destParent)
335
d = m_destRow - (m_endRow - m_startRow + 1);
337
d = m_destRow - (m_endRow - m_startRow) + 1;
340
foreach(const qint64 id, l)
342
m_model->m_childItems[destParent.internalId()][0].insert(d++, id);
345
m_model->endMoveRows();