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 Akonadi::LeafExtensionProxyModelPrivate
17 {
18 public:
19  explicit LeafExtensionProxyModelPrivate(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 LeafExtensionProxyModelPrivate::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 LeafExtensionProxyModelPrivate::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 LeafExtensionProxyModelPrivate(this))
68 {
69 }
70 
71 LeafExtensionProxyModel::~LeafExtensionProxyModel() = default;
72 
73 QModelIndex LeafExtensionProxyModel::index(int row, int column, const QModelIndex &parent) const
74 {
75  if (row < 0 || column < 0) {
76  return {};
77  }
78 
79  if (parent.isValid()) {
80  const QModelIndex sourceParent = mapToSource(parent);
81  const QModelIndex sourceIndex = sourceModel()->index(row, column, sourceParent);
82  if (!sourceIndex.isValid()) {
83  qint64 key = -1;
84  QMapIterator<qint64, QModelIndex> it(d->mParentIndexes);
85  while (it.hasNext()) {
86  it.next();
87  if (it.value() == parent) {
88  key = it.key();
89  break;
90  }
91  }
92 
93  if (key == -1) {
94  key = ++(d->mUniqueKeyCounter);
95  d->mParentIndexes.insert(key, parent);
96  }
97 
98  const QModelIndex index = createIndex(row, column, static_cast<quint32>(key));
99  d->mOwnIndexes.insert(index);
100 
101  return index;
102  }
103  }
104 
105  return QSortFilterProxyModel::index(row, column, parent);
106 }
107 
108 QModelIndex LeafExtensionProxyModel::parent(const QModelIndex &index) const
109 {
110  if (d->mOwnIndexes.contains(index)) {
111  return d->mParentIndexes.value(index.internalId());
112  }
113 
114  return QSortFilterProxyModel::parent(index);
115 }
116 
117 int LeafExtensionProxyModel::rowCount(const QModelIndex &index) const
118 {
119  if (d->mOwnIndexes.contains(index)) {
120  return 0;
121  }
122 
123  const QModelIndex sourceIndex = mapToSource(index);
124  if (sourceModel()->rowCount(sourceIndex) == 0) {
125  return leafRowCount(index);
126  }
127 
128  return QSortFilterProxyModel::rowCount(index);
129 }
130 
131 int LeafExtensionProxyModel::columnCount(const QModelIndex &index) const
132 {
133  if (d->mOwnIndexes.contains(index)) {
134  return 1;
135  }
136 
138 }
139 
140 QVariant LeafExtensionProxyModel::data(const QModelIndex &index, int role) const
141 {
142  if (d->mOwnIndexes.contains(index)) {
143  return leafData(index.parent(), index.row(), index.column(), role);
144  }
145 
146  return QSortFilterProxyModel::data(index, role);
147 }
148 
149 Qt::ItemFlags LeafExtensionProxyModel::flags(const QModelIndex &index) const
150 {
151  if (d->mOwnIndexes.contains(index)) {
153  }
154 
155  return QSortFilterProxyModel::flags(index);
156 }
157 
158 bool LeafExtensionProxyModel::setData(const QModelIndex &index, const QVariant &data, int role)
159 {
160  if (d->mOwnIndexes.contains(index)) {
161  return false;
162  }
163 
164  return QSortFilterProxyModel::setData(index, data, role);
165 }
166 
167 bool LeafExtensionProxyModel::hasChildren(const QModelIndex &parent) const
168 {
169  if (d->mOwnIndexes.contains(parent)) {
170  return false; // extensible in the future?
171  }
172 
173  const QModelIndex sourceParent = mapToSource(parent);
174  if (sourceModel() && sourceModel()->rowCount(sourceParent) == 0) {
175  return leafRowCount(parent) != 0;
176  }
177 
178  return QSortFilterProxyModel::hasChildren(parent);
179 }
180 
181 QModelIndex LeafExtensionProxyModel::buddy(const QModelIndex &index) const
182 {
183  if (d->mOwnIndexes.contains(index)) {
184  return index;
185  }
186 
187  return QSortFilterProxyModel::buddy(index);
188 }
189 
190 void LeafExtensionProxyModel::fetchMore(const QModelIndex &index)
191 {
192  if (d->mOwnIndexes.contains(index)) {
193  return;
194  }
195 
197 }
198 
199 void LeafExtensionProxyModel::setSourceModel(QAbstractItemModel *_sourceModel)
200 {
201  if (_sourceModel == sourceModel()) {
202  return;
203  }
204 
205  beginResetModel();
206 
207  disconnect(this, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(sourceRowsInserted(QModelIndex, int, int)));
208  disconnect(this, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(sourceRowsRemoved(QModelIndex, int, int)));
209 
211 
212  connect(this, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(sourceRowsInserted(QModelIndex, int, int)));
213  connect(this, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(sourceRowsRemoved(QModelIndex, int, int)));
214 
215  endResetModel();
216 }
217 
218 #include "moc_leafextensionproxymodel_p.cpp"
quintptr internalId() const const
int column() const const
Q_SCRIPTABLE Q_NOREPLY void start()
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override
typedef ItemFlags
virtual Qt::ItemFlags flags(const QModelIndex &index) const const override
virtual int columnCount(const QModelIndex &parent) const const override
virtual bool hasChildren(const QModelIndex &parent) const const override
virtual int rowCount(const QModelIndex &parent) const const override
bool isValid() const const
int row() const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual QModelIndex buddy(const QModelIndex &index) const const override
virtual QVariant data(const QModelIndex &index, int role) const const override
QModelIndex parent() const const
virtual void fetchMore(const QModelIndex &parent) override
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sat Apr 1 2023 04:09:05 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.