Akonadi Contacts

leafextensionproxymodel.cpp
1 /*
2  This file is part of Akonadi Contact.
3 
4  SPDX-FileCopyrightText: 2010 KDAB
5  SPDX-FileContributor: Tobias Koenig <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #include "leafextensionproxymodel_p.h"
11 
12 #include <QSet>
13 
14 using namespace Akonadi;
15 
16 class Q_DECL_HIDDEN LeafExtensionProxyModel::Private
17 {
18 public:
19  Private(LeafExtensionProxyModel *qq)
20  : q(qq)
21  {
22  }
23 
24  void sourceRowsInserted(const QModelIndex &parentIndex, int start, int end);
25  void sourceRowsRemoved(const QModelIndex &parentIndex, int start, int end);
26 
27  LeafExtensionProxyModel *const q;
28  QMap<qint64, QModelIndex> mParentIndexes;
29  QSet<QModelIndex> mOwnIndexes;
30  qint64 mUniqueKeyCounter = 0;
31 };
32 
33 void LeafExtensionProxyModel::Private::sourceRowsInserted(const QModelIndex &parentIndex, int start, int end)
34 {
35  // iterate over all of our stored parent indexes
37  while (it.hasNext()) {
38  it.next();
39  if (it.value().parent() == parentIndex) {
40  if (it.value().row() >= start) {
41  const QModelIndex newIndex = q->QSortFilterProxyModel::index(it.value().row() + (end - start) + 1, it.value().column(), parentIndex);
42  it.setValue(newIndex);
43  }
44  }
45  }
46 }
47 
48 void LeafExtensionProxyModel::Private::sourceRowsRemoved(const QModelIndex &parentIndex, int start, int end)
49 {
50  // iterate over all of our stored parent indexes
52  while (it.hasNext()) {
53  it.next();
54  if (it.value().parent() == parentIndex) {
55  if (it.value().row() >= start && it.value().row() <= end) {
56  it.remove();
57  } else if (it.value().row() > end) {
58  const QModelIndex newIndex = q->index(it.value().row() - (end - start) - 1, it.value().column(), parentIndex);
59  it.setValue(newIndex);
60  }
61  }
62  }
63 }
64 
65 LeafExtensionProxyModel::LeafExtensionProxyModel(QObject *parent)
66  : QSortFilterProxyModel(parent)
67  , d(new Private(this))
68 {
69 }
70 
71 LeafExtensionProxyModel::~LeafExtensionProxyModel()
72 {
73  delete d;
74 }
75 
76 QModelIndex LeafExtensionProxyModel::index(int row, int column, const QModelIndex &parent) const
77 {
78  if (row < 0 || column < 0) {
79  return QModelIndex();
80  }
81 
82  if (parent.isValid()) {
83  const QModelIndex sourceParent = mapToSource(parent);
84  const QModelIndex sourceIndex = sourceModel()->index(row, column, sourceParent);
85  if (!sourceIndex.isValid()) {
86  qint64 key = -1;
87  QMapIterator<qint64, QModelIndex> it(d->mParentIndexes);
88  while (it.hasNext()) {
89  it.next();
90  if (it.value() == parent) {
91  key = it.key();
92  break;
93  }
94  }
95 
96  if (key == -1) {
97  key = ++(d->mUniqueKeyCounter);
98  d->mParentIndexes.insert(key, parent);
99  }
100 
101  const QModelIndex index = createIndex(row, column, static_cast<quint32>(key));
102  d->mOwnIndexes.insert(index);
103 
104  return index;
105  }
106  }
107 
108  return QSortFilterProxyModel::index(row, column, parent);
109 }
110 
111 QModelIndex LeafExtensionProxyModel::parent(const QModelIndex &index) const
112 {
113  if (d->mOwnIndexes.contains(index)) {
114  return d->mParentIndexes.value(index.internalId());
115  }
116 
117  return QSortFilterProxyModel::parent(index);
118 }
119 
120 int LeafExtensionProxyModel::rowCount(const QModelIndex &index) const
121 {
122  if (d->mOwnIndexes.contains(index)) {
123  return 0;
124  }
125 
126  const QModelIndex sourceIndex = mapToSource(index);
127  if (sourceModel()->rowCount(sourceIndex) == 0) {
128  return leafRowCount(index);
129  }
130 
131  return QSortFilterProxyModel::rowCount(index);
132 }
133 
134 int LeafExtensionProxyModel::columnCount(const QModelIndex &index) const
135 {
136  if (d->mOwnIndexes.contains(index)) {
137  return 1;
138  }
139 
141 }
142 
143 QVariant LeafExtensionProxyModel::data(const QModelIndex &index, int role) const
144 {
145  if (d->mOwnIndexes.contains(index)) {
146  return leafData(index.parent(), index.row(), index.column(), role);
147  }
148 
149  return QSortFilterProxyModel::data(index, role);
150 }
151 
152 Qt::ItemFlags LeafExtensionProxyModel::flags(const QModelIndex &index) const
153 {
154  if (d->mOwnIndexes.contains(index)) {
156  }
157 
158  return QSortFilterProxyModel::flags(index);
159 }
160 
161 bool LeafExtensionProxyModel::setData(const QModelIndex &index, const QVariant &data, int role)
162 {
163  if (d->mOwnIndexes.contains(index)) {
164  return false;
165  }
166 
167  return QSortFilterProxyModel::setData(index, data, role);
168 }
169 
170 bool LeafExtensionProxyModel::hasChildren(const QModelIndex &parent) const
171 {
172  if (d->mOwnIndexes.contains(parent)) {
173  return false; // extensible in the future?
174  }
175 
176  const QModelIndex sourceParent = mapToSource(parent);
177  if (sourceModel() && sourceModel()->rowCount(sourceParent) == 0) {
178  return leafRowCount(parent) != 0;
179  }
180 
181  return QSortFilterProxyModel::hasChildren(parent);
182 }
183 
184 QModelIndex LeafExtensionProxyModel::buddy(const QModelIndex &index) const
185 {
186  if (d->mOwnIndexes.contains(index)) {
187  return index;
188  }
189 
190  return QSortFilterProxyModel::buddy(index);
191 }
192 
193 void LeafExtensionProxyModel::fetchMore(const QModelIndex &index)
194 {
195  if (d->mOwnIndexes.contains(index)) {
196  return;
197  }
198 
200 }
201 
202 void LeafExtensionProxyModel::setSourceModel(QAbstractItemModel *_sourceModel)
203 {
204  if (_sourceModel == sourceModel()) {
205  return;
206  }
207 
208  beginResetModel();
209 
210  disconnect(this, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(sourceRowsInserted(QModelIndex, int, int)));
211  disconnect(this, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(sourceRowsRemoved(QModelIndex, int, int)));
212 
214 
215  connect(this, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(sourceRowsInserted(QModelIndex, int, int)));
216  connect(this, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(sourceRowsRemoved(QModelIndex, int, int)));
217 
218  endResetModel();
219 }
220 
221 #include "moc_leafextensionproxymodel_p.cpp"
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual Qt::ItemFlags flags(const QModelIndex &index) const const override
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
quintptr internalId() const const
virtual int rowCount(const QModelIndex &parent) const const override
bool isValid() const const
int row() const const
virtual int columnCount(const QModelIndex &parent) const const override
QModelIndex parent() const const
virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override
virtual bool hasChildren(const QModelIndex &parent) const const override
virtual QModelIndex buddy(const QModelIndex &index) const const override
virtual void fetchMore(const QModelIndex &parent) override
int column() const const
QObject * parent() const const
virtual QVariant data(const QModelIndex &index, int role) const const override
typedef ItemFlags
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Wed Jun 23 2021 23:09:25 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.