1 /**************************************************************************
2 ** This file is part of LiteIDE
3 **
4 ** Copyright (c) 2011-2017 LiteIDE. All rights reserved.
5 **
6 ** This library is free software; you can redistribute it and/or
7 ** modify it under the terms of the GNU Lesser General Public
8 ** License as published by the Free Software Foundation; either
9 ** version 2.1 of the License, or (at your option) any later version.
10 **
11 ** This library is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** Lesser General Public License for more details.
15 **
16 ** In addition, as a special exception, that plugins developed for LiteIDE,
17 ** are allowed to remain closed sourced and can be distributed under any license .
18 ** These rights are included in the file LGPL_EXCEPTION.txt in this package.
19 **
20 **************************************************************************/
21 // Module: multiindexmodel.cpp
22 // Creator: visualfc <visualfc@gmail.com>
23
24 #include "multiindexmodel.h"
25
26 /****************************************************************************
27 **
28 ** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
29 ** Contact: http://www.qt-project.org/legal
30 **
31 ** This file is part of the QtGui module of the Qt Toolkit.
32 **
33 ** $QT_BEGIN_LICENSE:LGPL$
34 ** Commercial License Usage
35 ** Licensees holding valid commercial Qt licenses may use this file in
36 ** accordance with the commercial license agreement provided with the
37 ** Software or, alternatively, in accordance with the terms contained in
38 ** a written agreement between you and Digia. For licensing terms and
39 ** conditions see http://qt.digia.com/licensing. For further information
40 ** use the contact form at http://qt.digia.com/contact-us.
41 **
42 ** GNU Lesser General Public License Usage
43 ** Alternatively, this file may be used under the terms of the GNU Lesser
44 ** General Public License version 2.1 as published by the Free Software
45 ** Foundation and appearing in the file LICENSE.LGPL included in the
46 ** packaging of this file. Please review the following information to
47 ** ensure the GNU Lesser General Public License version 2.1 requirements
48 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
49 **
50 ** In addition, as a special exception, Digia gives you certain additional
51 ** rights. These rights are described in the Digia Qt LGPL Exception
52 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
53 **
54 ** GNU General Public License Usage
55 ** Alternatively, this file may be used under the terms of the GNU
56 ** General Public License version 3.0 as published by the Free Software
57 ** Foundation and appearing in the file LICENSE.GPL included in the
58 ** packaging of this file. Please review the following information to
59 ** ensure the GNU General Public License version 3.0 requirements will be
60 ** met: http://www.gnu.org/copyleft/gpl.html.
61 **
62 **
63 ** $QT_END_LICENSE$
64 **
65 ****************************************************************************/
66
67 #include "multiindexmodel_p.h"
68
69 #include <QTime>
70 #include <QDebug>
71
72
73 class MultiIndexModelLessThan
74 {
75 public:
MultiIndexModelLessThan(int column,const QModelIndex & parent,const QAbstractItemModel * source,const MultiIndexModel * proxy)76 inline MultiIndexModelLessThan(int column, const QModelIndex &parent,
77 const QAbstractItemModel *source,
78 const MultiIndexModel *proxy)
79 : sort_column(column), source_parent(parent), source_model(source), proxy_model(proxy) {}
80
operator ()(int r1,int r2) const81 inline bool operator()(int r1, int r2) const
82 {
83 QModelIndex i1 = source_model->index(r1, sort_column, source_parent);
84 QModelIndex i2 = source_model->index(r2, sort_column, source_parent);
85 return proxy_model->lessThan(source_model,i1, i2);
86 }
87
88 private:
89 int sort_column;
90 QModelIndex source_parent;
91 const QAbstractItemModel *source_model;
92 const MultiIndexModel *proxy_model;
93 };
94
95 class MultiIndexModelGreaterThan
96 {
97 public:
MultiIndexModelGreaterThan(int column,const QModelIndex & parent,const QAbstractItemModel * source,const MultiIndexModel * proxy)98 inline MultiIndexModelGreaterThan(int column, const QModelIndex &parent,
99 const QAbstractItemModel *source,
100 const MultiIndexModel *proxy)
101 : sort_column(column), source_parent(parent),
102 source_model(source), proxy_model(proxy) {}
103
operator ()(int r1,int r2) const104 inline bool operator()(int r1, int r2) const
105 {
106 QModelIndex i1 = source_model->index(r1, sort_column, source_parent);
107 QModelIndex i2 = source_model->index(r2, sort_column, source_parent);
108 return proxy_model->lessThan(source_model,i2, i1);
109 }
110
111 private:
112 int sort_column;
113 QModelIndex source_parent;
114 const QAbstractItemModel *source_model;
115 const MultiIndexModel *proxy_model;
116 };
117
store_persistent_indexes(const QModelIndexList & persistentList)118 QModelIndexPairList MultiIndexModelPrivate::store_persistent_indexes(const QModelIndexList &persistentList)
119 {
120 Q_Q(MultiIndexModel);
121 QModelIndexPairList source_indexes;
122 foreach (QModelIndex proxy_index, persistentList) {
123 SourceModelIndex index = q->mapToSourceEx(proxy_index);
124 source_indexes.append(qMakePair(proxy_index, QPersistentModelIndex(index.index)));
125 }
126 return source_indexes;
127 }
128
update_persistent_indexes(const QModelIndexPairList & source_indexes)129 void MultiIndexModelPrivate::update_persistent_indexes(const QModelIndexPairList &source_indexes)
130 {
131 Q_Q(MultiIndexModel);
132 QModelIndexList from, to;
133 for (int i = 0; i < source_indexes.count(); ++i) {
134 QModelIndex source_index = source_indexes.at(i).second;
135 QModelIndex old_proxy_index = source_indexes.at(i).first;
136 if (source_index.isValid()) {
137 QAbstractItemModel *model = (QAbstractItemModel *)source_index.model();
138 createMapping(model,source_index.parent(),false);
139 //createMapping(model,source_index,true);
140 QModelIndex proxy_index = q->mapFromSourceEx(model,source_index);
141 from << old_proxy_index;
142 to << proxy_index;
143 } else {
144 from << old_proxy_index;
145 to << QModelIndex();
146 }
147 }
148 q->changePersistentIndexList(from, to);
149 }
150
151
sort_source_rows(QAbstractItemModel * model,QVector<int> & source_rows,const QModelIndex & source_parent) const152 void MultiIndexModelPrivate::sort_source_rows(QAbstractItemModel *model,
153 QVector<int> &source_rows, const QModelIndex &source_parent) const
154 {
155 Q_Q(const MultiIndexModel);
156 if (source_sort_column >= 0) {
157 if (sort_order == Qt::AscendingOrder) {
158 MultiIndexModelLessThan lt(source_sort_column, source_parent, model, q);
159 qStableSort(source_rows.begin(), source_rows.end(), lt);
160 } else {
161 MultiIndexModelGreaterThan gt(source_sort_column, source_parent, model, q);
162 qStableSort(source_rows.begin(), source_rows.end(), gt);
163 }
164 } else { // restore the source model order
165 qStableSort(source_rows.begin(), source_rows.end());
166 }
167 }
168
169
170 /*!
171 \since 4.8
172 \class MultiIndexModel
173 \brief The MultiIndexModel class proxies its source model unmodified
174
175 \ingroup model-view
176
177 MultiIndexModel can be used to forward the structure of a source model exactly, with no sorting, filtering or other transformation.
178 This is similar in concept to an identity matrix where A.I = A.
179
180 Because it does no sorting or filtering, this class is most suitable to proxy models which transform the data() of the source model.
181 For example, a proxy model could be created to define the font used, or the background colour, or the tooltip etc. This removes the
182 need to implement all data handling in the same class that creates the structure of the model, and can also be used to create
183 re-usable components.
184
185 This also provides a way to change the data in the case where a source model is supplied by a third party which can not be modified.
186
187 \snippet doc/src/snippets/code/src_gui_itemviews_MultiIndexModel.cpp 0
188
189 \sa QAbstractProxyModel, {Model/View Programming}, QAbstractItemModel
190
191 */
192
193 /*!
194 Constructs an identity model with the given \a parent.
195 */
MultiIndexModel(QObject * parent)196 MultiIndexModel::MultiIndexModel(QObject* parent)
197 : AbstractMultiProxyModel(*new MultiIndexModelPrivate, parent)
198 {
199
200 }
201
202 /*! \internal
203 */
MultiIndexModel(MultiIndexModelPrivate & dd,QObject * parent)204 MultiIndexModel::MultiIndexModel(MultiIndexModelPrivate &dd, QObject* parent)
205 : AbstractMultiProxyModel(dd, parent)
206 {
207
208 }
209
lessThan(const QAbstractItemModel *,const QModelIndex & left,const QModelIndex & right) const210 bool MultiIndexModel::lessThan(const QAbstractItemModel */*sourceModel*/, const QModelIndex &left, const QModelIndex &right) const
211 {
212 Q_D(const MultiIndexModel);
213 QVariant l = (left.model() ? left.model()->data(left, d->sort_role) : QVariant());
214 QVariant r = (right.model() ? right.model()->data(right, d->sort_role) : QVariant());
215 switch (l.userType()) {
216 case QVariant::Invalid:
217 return (r.type() != QVariant::Invalid);
218 case QVariant::Int:
219 return l.toInt() < r.toInt();
220 case QVariant::UInt:
221 return l.toUInt() < r.toUInt();
222 case QVariant::LongLong:
223 return l.toLongLong() < r.toLongLong();
224 case QVariant::ULongLong:
225 return l.toULongLong() < r.toULongLong();
226 case QMetaType::Float:
227 return l.toFloat() < r.toFloat();
228 case QVariant::Double:
229 return l.toDouble() < r.toDouble();
230 case QVariant::Char:
231 return l.toChar() < r.toChar();
232 case QVariant::Date:
233 return l.toDate() < r.toDate();
234 case QVariant::Time:
235 return l.toTime() < r.toTime();
236 case QVariant::DateTime:
237 return l.toDateTime() < r.toDateTime();
238 case QVariant::String:
239 default:
240 if (d->sort_localeaware)
241 return l.toString().localeAwareCompare(r.toString()) < 0;
242 else
243 return l.toString().compare(r.toString(), d->sort_casesensitivity) < 0;
244 }
245 return false;
246 }
247
filterAcceptsRow(const QAbstractItemModel *,int,const QModelIndex &) const248 bool MultiIndexModel::filterAcceptsRow(const QAbstractItemModel */*sourceModel*/, int /*source_row*/, const QModelIndex &/*source_parent*/) const
249 {
250 return true;
251 }
252
253 /*!
254 Destroys this identity model.
255 */
~MultiIndexModel()256 MultiIndexModel::~MultiIndexModel()
257 {
258 Q_D(MultiIndexModel);
259 d->clearMapping();
260 }
261
262 /*!
263 \reimp
264 */
columnCount(const QModelIndex & parent) const265 int MultiIndexModel::columnCount(const QModelIndex& parent) const
266 {
267 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
268 Q_D(const MultiIndexModel);
269 if (d->indexList.isEmpty()) {
270 return 0;
271 }
272 SourceModelIndex source = mapToSourceEx(parent);
273 if (source.model == 0) {
274 return d->indexList[0].model->columnCount();
275 }
276 return source.model->columnCount(source.index);
277 }
278
279 /*!
280 \reimp
281 */
dropMimeData(const QMimeData * data,Qt::DropAction action,int row,int column,const QModelIndex & parent)282 bool MultiIndexModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
283 {
284 //Q_ASSERT(parent.isValid() ? parent.model() == this : true);
285 // Q_D(MultiIndexModel);
286 SourceModelIndex source = mapToSourceEx(parent);
287 return source.model->dropMimeData(data, action, row, column,source.index);
288 }
289
createMapping(QAbstractItemModel * model,const QModelIndex & parent,bool forceUpdate,const QString &) const290 QMap<QModelIndex,Mapping*>::iterator MultiIndexModelPrivate::createMapping(QAbstractItemModel *model, const QModelIndex &parent, bool forceUpdate, const QString &/*context*/) const
291 {
292 Q_Q(const MultiIndexModel);
293 QMap<QModelIndex,Mapping*>::iterator it = modelMapping[model].find(parent);
294 if (it == modelMapping[model].end()) {
295 Mapping *m = new Mapping;
296 m->rowCount = 0;
297 m->sourceParent = parent;
298 m->sourceModel = model;
299 it = modelMapping[model].insert(parent,m);
300 forceUpdate = true;
301 }
302 if (forceUpdate) {
303 Mapping *m = it.value();
304 int rowCount = model->rowCount(parent);
305
306 //qDebug() << context << parent.data() << rowCount;
307 QVector<int> rows;
308 rows.reserve(rowCount);
309 for (int i = 0; i < rowCount; ++i) {
310 if (q->filterAcceptsRow(model,i, parent))
311 rows.append(i);
312 }
313 // for (int i = 0; i < rowCount; i++) {
314 // rows[i] = i;
315 // }
316 sort_source_rows(model,rows,parent);
317 m->rowCount = rowCount;
318 m->source_rows.swap(rows);
319 m->proxy_rows.resize(rowCount);
320 this->build_source_to_proxy_mapping(m->source_rows,m->proxy_rows);
321 }
322 return it;
323 }
324
build_source_to_proxy_mapping(const QVector<int> & proxy_to_source,QVector<int> & source_to_proxy) const325 void MultiIndexModelPrivate::build_source_to_proxy_mapping(
326 const QVector<int> &proxy_to_source, QVector<int> &source_to_proxy) const
327 {
328 source_to_proxy.fill(-1);
329 int proxy_count = proxy_to_source.size();
330 for (int i = 0; i < proxy_count; ++i)
331 source_to_proxy[proxy_to_source.at(i)] = i;
332 }
333
findOrCreateMapping(QAbstractItemModel * model,const QModelIndex & parent) const334 QMap<QModelIndex,Mapping*>::iterator MultiIndexModelPrivate::findOrCreateMapping(QAbstractItemModel *model, const QModelIndex &parent) const
335 {
336 QMap<QModelIndex,Mapping*>::iterator it = modelMapping[model].find(parent);
337 if (it == modelMapping[model].end()) {
338 it = createMapping(model,parent,true);
339 }
340 if (parent.isValid()) {
341 QModelIndex source_grand_parent = parent.parent();
342 findOrCreateMapping(model,source_grand_parent);
343 }
344 return it;
345 }
346
clearMapping()347 void MultiIndexModelPrivate::clearMapping()
348 {
349 //Q_Q(MultiIndexModel);
350 QMutableMapIterator<QAbstractItemModel*, QMap<QModelIndex,Mapping*> > i(modelMapping);
351 while (i.hasNext()) {
352 i.next();
353 qDeleteAll(i.value());
354 }
355 modelMapping.clear();
356 }
357
deleteMapping(QAbstractItemModel * model)358 void MultiIndexModelPrivate::deleteMapping(QAbstractItemModel *model)
359 {
360 QMutableMapIterator<QAbstractItemModel*, QMap<QModelIndex,Mapping*> > i(modelMapping);
361 while (i.hasNext()) {
362 i.next();
363 if (i.key() == model) {
364 qDeleteAll(i.value());
365 i.remove();
366 break;
367 }
368 }
369 }
370
371 /*!
372 \reimp
373 */
index(int row,int column,const QModelIndex & parent) const374 QModelIndex MultiIndexModel::index(int row, int column, const QModelIndex& parent) const
375 {
376 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
377 if (!hasIndex(row,column,parent)) {
378 return QModelIndex();
379 }
380 Q_D(const MultiIndexModel);
381 if (!parent.isValid()) {
382 if (row < d->indexList.size()) {
383 return createIndex(row,column);
384 }
385 return QModelIndex();
386 }
387 SourceModelIndex sourceParent = mapToSourceEx(parent);
388
389 QMap<QModelIndex,Mapping*>::iterator it = d->createMapping(sourceParent.model,sourceParent.index,false,"index");
390 // static int check = 1;
391 // if (sourceParent.index.data() == "DataBase" && check) {
392 // check = 0;
393 // qDebug() << "index" << it.value()->source_rows << it.value()->proxy_rows;
394 // }
395 // QMap<QModelIndex,Mapping*>::iterator it = d->modelMapping[sourceParent.model].find(sourceParent.index);
396 // if (it == d->modelMapping[sourceParent.model].end()) {
397 // it = d->createMapping(sourceParent.model,sourceParent.index);
398 // } else {
399 // qDebug() << it.value()->proxy_rows;
400 // }
401
402 return createIndex(row,column,it.value());
403 }
404
405 /*!
406 \reimp
407 */
insertColumns(int column,int count,const QModelIndex & parent)408 bool MultiIndexModel::insertColumns(int column, int count, const QModelIndex& parent)
409 {
410 //Q_ASSERT(parent.isValid() ? parent.model() == this : true);
411 //Q_D(MultiIndexModel);
412 SourceModelIndex source = mapToSourceEx(parent);
413 return source.model->insertColumns(column, count, source.index);
414 }
415
416 /*!
417 \reimp
418 */
insertRows(int row,int count,const QModelIndex & parent)419 bool MultiIndexModel::insertRows(int row, int count, const QModelIndex& parent)
420 {
421 //Q_ASSERT(parent.isValid() ? parent.model() == this : true);
422 //Q_D(MultiIndexModel);
423 SourceModelIndex source = mapToSourceEx(parent);
424 return source.model->insertRows(row, count, source.index);
425 }
426
427
428
429 /*!
430 \reimp
431 */
mapSelectionFromSource(const QItemSelection & selection) const432 QItemSelection MultiIndexModel::mapSelectionFromSource(const QItemSelection& selection) const
433 {
434 Q_D(const MultiIndexModel);
435 QItemSelection proxySelection;
436
437 qDebug() << "mapSelectionFromSource";
438
439 if (d->indexList.isEmpty())
440 return proxySelection;
441
442 QItemSelection::const_iterator it = selection.constBegin();
443 const QItemSelection::const_iterator end = selection.constEnd();
444 for ( ; it != end; ++it) {
445 const QItemSelectionRange range(mapFromSource(it->topLeft()), mapFromSource(it->bottomRight()));
446 proxySelection.append(range);
447 }
448
449 return proxySelection;
450 }
451
452 /*!
453 \reimp
454 */
mapSelectionToSource(const QItemSelection & selection) const455 QItemSelection MultiIndexModel::mapSelectionToSource(const QItemSelection& selection) const
456 {
457 Q_D(const MultiIndexModel);
458 QItemSelection sourceSelection;
459
460 qDebug() << "mapSelectionToSource";
461
462 if (d->indexList.isEmpty())
463 return sourceSelection;
464
465 QItemSelection::const_iterator it = selection.constBegin();
466 const QItemSelection::const_iterator end = selection.constEnd();
467 for ( ; it != end; ++it) {
468 //Q_ASSERT(it->model() == this);
469 const QItemSelectionRange range(mapToSource(it->topLeft()), mapToSource(it->bottomRight()));
470 sourceSelection.append(range);
471 }
472
473 return sourceSelection;
474 }
475
476 class MyModel : public QAbstractProxyModel
477 {
478 friend class MultiIndexModel;
479 };
480
481
482 /*!
483 \reimp
484 */
mapToSource(const QModelIndex & proxyIndex) const485 QModelIndex MultiIndexModel::mapToSource(const QModelIndex& proxyIndex) const
486 {
487 return mapToSourceEx(proxyIndex).index;
488 }
489
mapToSourceEx(const QModelIndex & proxyIndex) const490 SourceModelIndex MultiIndexModel::mapToSourceEx(const QModelIndex &proxyIndex) const
491 {
492 Q_D(const MultiIndexModel);
493 if (!proxyIndex.isValid())
494 return SourceModelIndex();
495
496 Q_ASSERT(proxyIndex.model() == this);
497
498 Mapping *m = (Mapping*)proxyIndex.internalPointer();
499 if (m == 0) {
500 SourceModelIndex si = d->indexList[proxyIndex.row()];
501 si.index = si.index.sibling(si.index.row(),proxyIndex.column());
502 return si;
503 }
504 if (m->source_rows.size() <= proxyIndex.row()) {
505 return SourceModelIndex();
506 }
507
508 int source_row = m->source_rows.at(proxyIndex.row());
509 //qDebug() << source_row;
510 QModelIndex index = m->sourceModel->index(source_row,proxyIndex.column(),m->sourceParent);
511 return SourceModelIndex(m->sourceModel,index);
512 }
513
514 /*!
515 \reimp
516 */
mapFromSource(const QModelIndex & sourceIndex) const517 QModelIndex MultiIndexModel::mapFromSource(const QModelIndex& sourceIndex) const
518 {
519 //Q_D(const MultiIndexModel);
520 if (!sourceIndex.isValid())
521 return QModelIndex();
522 QAbstractItemModel *model = (QAbstractItemModel *)sourceIndex.model();
523 return mapFromSourceEx(model,sourceIndex);
524 }
525
mapFromSourceEx(QAbstractItemModel * sourceModel,const QModelIndex & sourceIndex) const526 QModelIndex MultiIndexModel::mapFromSourceEx(QAbstractItemModel *sourceModel, const QModelIndex &sourceIndex) const
527 {
528 Q_D(const MultiIndexModel);
529 if (sourceModel == 0) {
530 return QModelIndex();
531 }
532 int row = d->isRootIndexRow(sourceModel,sourceIndex);
533 if (row >= 0) {
534 int column = sourceIndex.column();
535 if (column < 0) {
536 column = 0;
537 }
538 //d->createMapping(sourceModel,d->indexList[row].index);
539 return createIndex(row,column);
540 }
541
542 if (!sourceIndex.isValid()) {
543 return QModelIndex();
544 }
545
546 QModelIndex parent = sourceModel->parent(sourceIndex);
547
548 QMap<QModelIndex,Mapping*>::iterator it = d->createMapping(sourceModel,parent,false,"map");// d->modelMapping[sourceModel].find(parent);
549 // if (it == d->modelMapping[sourceModel].end()) {
550 // it = d->createMapping(sourceModel,parent);
551 // }
552 Mapping *m = it.value();
553
554 if (m->proxy_rows.size() <= sourceIndex.row()) {
555 return QModelIndex();
556 }
557
558 int proxy_row = m->proxy_rows.at(sourceIndex.row());
559 // qDebug() << sourceIndex.data() << proxy_row;
560 return createIndex(proxy_row,sourceIndex.column(),m);
561 //return QModelIndex();
562 }
563
hasChildren(const QModelIndex & parent) const564 bool MultiIndexModel::hasChildren(const QModelIndex &parent) const
565 {
566 Q_D(const MultiIndexModel);
567 if (!parent.isValid()) {
568 return !d->indexList.isEmpty();
569 }
570
571 SourceModelIndex source = mapToSourceEx(parent);
572 if (source.model == 0) {
573 return false;
574 }
575 // //if (parent.isValid() && !source.index.isValid())
576 // // return false;
577 if (!source.model->hasChildren(source.index))
578 return false;
579
580 if (source.model->canFetchMore(source.index))
581 return true; //we assume we might have children that can be fetched
582
583 return true;
584 // Mapping *m = d->createMapping(source.model,source.index,false,"hasChildren").value();
585 // return m->source_rows.count() != 0;
586 }
587
buddy(const QModelIndex & index) const588 QModelIndex MultiIndexModel::buddy(const QModelIndex &index) const
589 {
590 Q_D(const MultiIndexModel);
591 if (!d->indexValid(index))
592 return QModelIndex();
593
594 SourceModelIndex source = mapToSourceEx(index);
595 QModelIndex source_buddy = source.model->buddy(source.index);
596 if (source.index == source_buddy)
597 return index;
598 return mapFromSourceEx(source.model,source_buddy);
599 }
600
601
602 /*!
603 \reimp
604 */
match(const QModelIndex & start,int role,const QVariant & value,int hits,Qt::MatchFlags flags) const605 QModelIndexList MultiIndexModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const
606 {
607 Q_D(const MultiIndexModel);
608 Q_ASSERT(start.isValid() ? start.model() == this : true);
609 if (d->indexList.isEmpty())
610 return QModelIndexList();
611
612 SourceModelIndex source = mapToSourceEx(start);
613 const QModelIndexList sourceList = source.model->match(source.index, role, value, hits, flags);
614 QModelIndexList::const_iterator it = sourceList.constBegin();
615 const QModelIndexList::const_iterator end = sourceList.constEnd();
616 QModelIndexList proxyList;
617 for ( ; it != end; ++it)
618 proxyList.append(mapFromSourceEx(source.model,*it));
619 return proxyList;
620 }
621
622 /*!
623 \reimp
624 */
parent(const QModelIndex & child) const625 QModelIndex MultiIndexModel::parent(const QModelIndex& child) const
626 {
627 Q_ASSERT(child.isValid() ? child.model() == this : true);
628 //Q_D(const MultiIndexModel);
629 if (!child.isValid()) {
630 return QModelIndex();
631 }
632 // SourceModelIndex index = this->mapToSourceEx(child);
633 // if (index.model == 0) {
634 // return QModelIndex();
635 // }
636 // return mapFromSourceEx(index.model,index.index.parent());
637 Mapping *m = (Mapping*)child.internalPointer();
638 if (m == 0) {
639 return QModelIndex();
640 }
641 // if (m->sourceModel != child.model()) {
642 // qDebug() << "error parent" << child;
643 // }
644 //qDebug() << m->sourceParent.data().toString();
645 return mapFromSourceEx(m->sourceModel,m->sourceParent);
646 // const QModelIndex sourceIndex = mapToSource(child);
647 // foreach (QModelIndex index, d->indexList) {
648 // if (index == sourceIndex) {
649 // return QModelIndex();
650 // }
651 // }
652 // const QModelIndex sourceParent = sourceIndex.parent();
653 // return mapFromSource(sourceParent);
654 }
655
656 /*
657 QModelIndex MultiProxyModel::parent(const QModelIndex &child) const
658 {
659 Q_D(const MultiProxyModel);
660 if (!d->indexValid(child))
661 return QModelIndex();
662 IndexMap::const_iterator it = d->index_to_iterator(child);
663 Q_ASSERT(it != d->source_index_mapping.constEnd());
664 QModelIndex source_parent = it.key();
665 QModelIndex proxy_parent = mapFromSource(source_parent);
666 return proxy_parent;
667 }
668 */
669
670 /*!
671 \reimp
672 */
removeColumns(int column,int count,const QModelIndex & parent)673 bool MultiIndexModel::removeColumns(int column, int count, const QModelIndex& parent)
674 {
675 //Q_ASSERT(parent.isValid() ? parent.model() == this : true);
676 //Q_D(MultiIndexModel);
677 SourceModelIndex source = mapToSourceEx(parent);
678 return source.model->removeColumns(column, count, source.index);
679 }
680
681 /*!
682 \reimp
683 */
removeRows(int row,int count,const QModelIndex & parent)684 bool MultiIndexModel::removeRows(int row, int count, const QModelIndex& parent)
685 {
686 // Q_ASSERT(parent.isValid() ? parent.model() == this : true);
687 //Q_D(MultiIndexModel);
688 SourceModelIndex source = mapToSourceEx(parent);
689 return source.model->removeRows(row, count, source.index);
690 }
691
692 /*!
693 \reimp
694 */
rowCount(const QModelIndex & parent) const695 int MultiIndexModel::rowCount(const QModelIndex& parent) const
696 {
697 Q_D(const MultiIndexModel);
698 if (!parent.isValid()) {
699 return d->indexList.size();
700 }
701 //qDebug() << parent.isValid() << parent.data().toString();
702 //Q_ASSERT(parent.isValid() ? parent.model() == this : true);
703 SourceModelIndex source = mapToSourceEx(parent);
704 //return source.model->rowCount(source.index);
705 QMap<QModelIndex,Mapping*>::iterator it = d->createMapping(source.model,source.index,false,"rowCount");
706 return it.value()->source_rows.count();
707 //qDebug() << source.model->rowCount(source.index);
708 // return source.model->rowCount(source.index);
709 // QMap<QModelIndex,Mapping*>::iterator it = d->createMapping(source.model,source.index);
710 // qDebug() << parent.column() << parent << source.index << source.index.data() << it.value()->source_rows;
711 // return it.value()->source_rows.count();
712 //qDebug() << source_parent.isValid();
713 // int rows = d->model->rowCount(source_parent);
714 // qDebug() << "rowCount" << rows << source_parent.data().toString();
715 // return rows;
716 // QModelIndex source_parent = mapToSource(parent);
717 // qDebug() << source_parent.isValid();
718 // if (parent.isValid() && !source_parent.isValid())
719 // return 0;
720 // QMap<QModelIndex,Mapping*>::iterator it = d->findOrCreateMapping(source_parent);
721 // return it.value()->source_rows.count();
722 }
723
724 /*!
725 \reimp
726 */
addSourceModel(QAbstractItemModel * sourceModel,const QModelIndex & sourceIndex)727 bool MultiIndexModel::addSourceModel(QAbstractItemModel* sourceModel, const QModelIndex &sourceIndex)
728 {
729 Q_D(MultiIndexModel);
730 if (!sourceModel || d->containsModel(sourceModel) ) {
731 return false;
732 }
733
734 int n = d->indexList.size();
735
736 this->beginInsertRows(QModelIndex(),n,n);
737
738 AbstractMultiProxyModel::addSourceModel(sourceModel,sourceIndex);
739
740 //beginResetModel();
741
742 connect(sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
743 d_func(),SLOT(_q_sourceRowsAboutToBeInserted(const QModelIndex &, int, int)));
744 connect(sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
745 d_func(),SLOT(_q_sourceRowsInserted(const QModelIndex &, int, int)));
746 connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
747 d_func(),SLOT(_q_sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)));
748 connect(sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
749 d_func(),SLOT(_q_sourceRowsRemoved(const QModelIndex &, int, int)));
750 connect(sourceModel, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
751 d_func(),SLOT(_q_sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
752 connect(sourceModel, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
753 d_func(),SLOT(_q_sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
754 connect(sourceModel, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)),
755 d_func(),SLOT(_q_sourceColumnsAboutToBeInserted(const QModelIndex &, int, int)));
756 connect(sourceModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)),
757 d_func(),SLOT(_q_sourceColumnsInserted(const QModelIndex &, int, int)));
758 connect(sourceModel, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)),
759 d_func(),SLOT(_q_sourceColumnsAboutToBeRemoved(const QModelIndex &, int, int)));
760 connect(sourceModel, SIGNAL(columnsRemoved(const QModelIndex &, int, int)),
761 d_func(),SLOT(_q_sourceColumnsRemoved(const QModelIndex &, int, int)));
762 connect(sourceModel, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
763 d_func(),SLOT(_q_sourceColumnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
764 connect(sourceModel, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
765 d_func(),SLOT(_q_sourceColumnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
766 connect(sourceModel, SIGNAL(modelAboutToBeReset()),
767 d_func(),SLOT(_q_sourceModelAboutToBeReset()));
768 connect(sourceModel, SIGNAL(modelReset()),
769 d_func(),SLOT(_q_sourceModelReset()));
770 connect(sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
771 d_func(),SLOT(_q_sourceDataChanged(const QModelIndex &, const QModelIndex &)));
772 connect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
773 d_func(),SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int)));
774 connect(sourceModel, SIGNAL(layoutAboutToBeChanged()),
775 d_func(),SLOT(_q_sourceLayoutAboutToBeChanged()));
776 connect(sourceModel, SIGNAL(layoutChanged()),
777 d_func(),SLOT(_q_sourceLayoutChanged()));
778
779 //endResetModel();
780 this->endInsertRows();
781
782 return true;
783 }
784
removeSourceModel(QAbstractItemModel * sourceModel)785 bool MultiIndexModel::removeSourceModel(QAbstractItemModel *sourceModel)
786 {
787 Q_D(MultiIndexModel);
788 bool b = AbstractMultiProxyModel::removeSourceModel(sourceModel);
789 if (b) {
790 d->deleteMapping(sourceModel);
791 }
792 return b;
793 }
794
removeAllSourceModel()795 void MultiIndexModel::removeAllSourceModel()
796 {
797 Q_D(MultiIndexModel);
798 AbstractMultiProxyModel::removeAllSourceModel();
799 d->clearMapping();
800 }
801
sort(int column,Qt::SortOrder order)802 void MultiIndexModel::sort(int column, Qt::SortOrder order)
803 {
804 Q_D(MultiIndexModel);
805 d->sort_order = order;
806 d->source_sort_column = column;
807 }
808
setSortRole(int role)809 void MultiIndexModel::setSortRole(int role)
810 {
811 Q_D(MultiIndexModel);
812 d->sort_role = role;
813 }
814
sortCaseSensitivity() const815 Qt::CaseSensitivity MultiIndexModel::sortCaseSensitivity() const
816 {
817 Q_D(const MultiIndexModel);
818 return d->sort_casesensitivity;
819 }
820
setSortCaseSensitivity(Qt::CaseSensitivity cs)821 void MultiIndexModel::setSortCaseSensitivity(Qt::CaseSensitivity cs)
822 {
823 Q_D(MultiIndexModel);
824 d->sort_casesensitivity = cs;
825 }
826
isSortLocaleAware() const827 bool MultiIndexModel::isSortLocaleAware() const
828 {
829 Q_D(const MultiIndexModel);
830 return d->sort_localeaware;
831 }
832
setSortLocaleAware(bool on)833 void MultiIndexModel::setSortLocaleAware(bool on)
834 {
835 Q_D(MultiIndexModel);
836 d->sort_localeaware = on;
837 }
838
sortRole() const839 int MultiIndexModel::sortRole() const
840 {
841 Q_D(const MultiIndexModel);
842 return d->sort_role;
843 }
844
_q_sourceColumnsAboutToBeInserted(const QModelIndex & parent,int start,int end)845 void MultiIndexModelPrivate::_q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
846 {
847 //Q_ASSERT(parent.isValid() ? parent.model() == model : true);
848 Q_Q(MultiIndexModel);
849 QAbstractItemModel *model = (QAbstractItemModel*)sender();
850 q->beginInsertColumns(q->mapFromSourceEx(model,parent), start, end);
851 }
852
_q_sourceColumnsAboutToBeMoved(const QModelIndex & sourceParent,int sourceStart,int sourceEnd,const QModelIndex & destParent,int dest)853 void MultiIndexModelPrivate::_q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
854 {
855 //Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
856 //Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
857 Q_Q(MultiIndexModel);
858 QAbstractItemModel *model = (QAbstractItemModel*)sender();
859 q->beginMoveColumns(q->mapFromSourceEx(model,sourceParent), sourceStart, sourceEnd, q->mapFromSourceEx(model,destParent), dest);
860 }
861
_q_sourceColumnsAboutToBeRemoved(const QModelIndex & parent,int start,int end)862 void MultiIndexModelPrivate::_q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
863 {
864 //Q_ASSERT(parent.isValid() ? parent.model() == model : true);
865 Q_Q(MultiIndexModel);
866 QAbstractItemModel *model = (QAbstractItemModel*)sender();
867 q->beginRemoveColumns(q->mapFromSourceEx(model,parent), start, end);
868 }
869
_q_sourceColumnsInserted(const QModelIndex & parent,int start,int end)870 void MultiIndexModelPrivate::_q_sourceColumnsInserted(const QModelIndex &parent, int start, int end)
871 {
872 //Q_ASSERT(parent.isValid() ? parent.model() == model : true);
873 Q_Q(MultiIndexModel);
874 Q_UNUSED(parent)
875 Q_UNUSED(start)
876 Q_UNUSED(end)
877 q->endInsertColumns();
878 }
879
_q_sourceColumnsMoved(const QModelIndex & sourceParent,int sourceStart,int sourceEnd,const QModelIndex & destParent,int dest)880 void MultiIndexModelPrivate::_q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
881 {
882 //Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
883 //Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
884 Q_Q(MultiIndexModel);
885 Q_UNUSED(sourceParent)
886 Q_UNUSED(sourceStart)
887 Q_UNUSED(sourceEnd)
888 Q_UNUSED(destParent)
889 Q_UNUSED(dest)
890
891 q->endMoveColumns();
892 }
893
_q_sourceColumnsRemoved(const QModelIndex & parent,int start,int end)894 void MultiIndexModelPrivate::_q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end)
895 {
896 //Q_ASSERT(parent.isValid() ? parent.model() == model : true);
897 Q_Q(MultiIndexModel);
898 Q_UNUSED(parent)
899 Q_UNUSED(start)
900 Q_UNUSED(end)
901 q->endRemoveColumns();
902 }
903
_q_sourceDataChanged(const QModelIndex & topLeft,const QModelIndex & bottomRight)904 void MultiIndexModelPrivate::_q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
905 {
906 //Q_ASSERT(topLeft.isValid() ? topLeft.model() == model : true);
907 //Q_ASSERT(bottomRight.isValid() ? bottomRight.model() == model : true);
908 Q_Q(MultiIndexModel);
909
910 QAbstractItemModel *model = (QAbstractItemModel*)sender();
911 q->dataChanged(q->mapFromSourceEx(model,topLeft), q->mapFromSourceEx(model,bottomRight));
912 }
913
_q_sourceHeaderDataChanged(Qt::Orientation orientation,int first,int last)914 void MultiIndexModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last)
915 {
916 Q_Q(MultiIndexModel);
917 q->headerDataChanged(orientation, first, last);
918 }
919
_q_sourceLayoutAboutToBeChanged()920 void MultiIndexModelPrivate::_q_sourceLayoutAboutToBeChanged()
921 {
922 // if (ignoreNextLayoutAboutToBeChanged)
923 // return;
924
925 // Q_Q(MultiIndexModel);
926
927 // foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
928 // proxyIndexes << proxyPersistentIndex;
929 // Q_ASSERT(proxyPersistentIndex.isValid());
930 // const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
931 // Q_ASSERT(srcPersistentIndex.isValid());
932 // layoutChangePersistentIndexes << srcPersistentIndex;
933 // }
934
935 // q->layoutAboutToBeChanged();
936 Q_Q(MultiIndexModel);
937 saved_persistent_indexes.clear();
938 emit q->layoutAboutToBeChanged();
939 QModelIndexList persistentList = q->persistentIndexList();
940 if (persistentList.isEmpty())
941 return;
942
943 // QAbstractItemModel *model = (QAbstractItemModel*)sender();
944 // qDebug() << "begin changed" << model;
945 saved_persistent_indexes = store_persistent_indexes(persistentList);
946 }
947
_q_sourceLayoutChanged()948 void MultiIndexModelPrivate::_q_sourceLayoutChanged()
949 {
950 Q_Q(MultiIndexModel);
951
952
953 QAbstractItemModel *model = (QAbstractItemModel*)sender();
954
955 // qDebug() << "changed" << model;
956
957 qDeleteAll(modelMapping[model]);
958 modelMapping[model].clear();
959 //modelMapping.remove(model);
960 update_persistent_indexes(saved_persistent_indexes);
961 saved_persistent_indexes.clear();
962 //// if (dynamic_sortfilter && update_source_sort_column()) {
963 //// //update_source_sort_column might have created wrong mapping so we have to clear it again
964 // // qDeleteAll(sourceMapping);
965 //// sourceMapping.clear();
966 //// }
967
968 // emit q->layoutChanged();
969 // if (ignoreNextLayoutChanged)
970 // return;
971
972 // Q_Q(MultiIndexModel);
973
974 // for (int i = 0; i < proxyIndexes.size(); ++i) {
975 // q->changePersistentIndex(proxyIndexes.at(i), q->mapFromSource(layoutChangePersistentIndexes.at(i)));
976 // }
977
978 // layoutChangePersistentIndexes.clear();
979 // proxyIndexes.clear();
980
981 q->layoutChanged();
982 }
983
_q_sourceModelAboutToBeReset()984 void MultiIndexModelPrivate::_q_sourceModelAboutToBeReset()
985 {
986 Q_Q(MultiIndexModel);
987 q->beginResetModel();
988 }
989
_q_sourceModelReset()990 void MultiIndexModelPrivate::_q_sourceModelReset()
991 {
992 Q_Q(MultiIndexModel);
993
994 q->endResetModel();
995 }
996
sort(QAbstractItemModel * sourceModel)997 void MultiIndexModelPrivate::sort(QAbstractItemModel *sourceModel )
998 {
999 Q_Q(MultiIndexModel);
1000 emit q->layoutAboutToBeChanged();
1001 QModelIndexPairList source_indexes = store_persistent_indexes(q->persistentIndexList());
1002 QMap<QModelIndex,Mapping*>::const_iterator it = modelMapping[sourceModel].constBegin();
1003 for (; it != modelMapping[sourceModel].constEnd(); ++it) {
1004 QModelIndex source_parent = it.key();
1005 Mapping *m = it.value();
1006 sort_source_rows(m->sourceModel, m->source_rows, source_parent);
1007 build_source_to_proxy_mapping(m->source_rows, m->proxy_rows);
1008 }
1009 update_persistent_indexes(source_indexes);
1010 emit q->layoutChanged();
1011 }
1012
_q_sourceRowsAboutToBeInserted(const QModelIndex & parent,int,int)1013 void MultiIndexModelPrivate::_q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int /*start*/, int /*end*/)
1014 {
1015 //Q_ASSERT(parent.isValid() ? parent.model() == model : true);
1016 //Q_Q(MultiIndexModel);
1017 QAbstractItemModel *model = (QAbstractItemModel *)sender();
1018 QMap<QModelIndex,Mapping*>::iterator it = modelMapping[model].find(parent);
1019 if (it == modelMapping[model].end()) {
1020 //this->createMapping(model,parent,false,"insert");
1021 }
1022 }
1023
_q_sourceRowsAboutToBeMoved(const QModelIndex & sourceParent,int sourceStart,int sourceEnd,const QModelIndex & destParent,int dest)1024 void MultiIndexModelPrivate::_q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
1025 {
1026 //Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
1027 //Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
1028 Q_Q(MultiIndexModel);
1029 QAbstractItemModel *model = (QAbstractItemModel *)sender();
1030
1031 q->beginMoveRows(q->mapFromSourceEx(model,sourceParent), sourceStart, sourceEnd, q->mapFromSourceEx(model,destParent), dest);
1032 }
1033
_q_sourceRowsInserted(const QModelIndex & parent,int start,int end)1034 void MultiIndexModelPrivate::_q_sourceRowsInserted(const QModelIndex &parent, int start, int end)
1035 {
1036 //Q_ASSERT(parent.isValid() ? parent.model() == model : true);
1037 Q_Q(MultiIndexModel);
1038 Q_UNUSED(parent)
1039 Q_UNUSED(start)
1040 Q_UNUSED(end)
1041
1042 QAbstractItemModel *model = (QAbstractItemModel *)sender();
1043 QMap<QModelIndex,Mapping*>::iterator it = modelMapping[model].find(parent);
1044 if (it != modelMapping[model].end()) {
1045 this->createMapping(model,parent,true,"insert");
1046 Mapping *m = it.value();
1047 QModelIndex proxyIndex = q->mapFromSourceEx(model,parent);
1048 QVector<int> all(end-start+1);
1049 for (int i = start; i <= end; i++) {
1050 all[i-start] = m->proxy_rows.at(i);
1051 //qDebug() << m->sourceModel->index(i,0,parent).data();
1052 }
1053 qStableSort(all);
1054
1055 if (all.last()-all.first()+1 == all.size()) {
1056 q->beginInsertRows(proxyIndex,all.first(),all.last());
1057 q->endInsertRows();
1058 } else {
1059 foreach (int n, all) {
1060 q->beginInsertRows(proxyIndex, n, n);
1061 q->endInsertRows();
1062 }
1063 }
1064 }
1065 }
1066
_q_sourceRowsMoved(const QModelIndex & sourceParent,int sourceStart,int sourceEnd,const QModelIndex & destParent,int dest)1067 void MultiIndexModelPrivate::_q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
1068 {
1069 //Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
1070 //Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
1071 Q_Q(MultiIndexModel);
1072 Q_UNUSED(sourceParent)
1073 Q_UNUSED(sourceStart)
1074 Q_UNUSED(sourceEnd)
1075 Q_UNUSED(destParent)
1076 Q_UNUSED(dest)
1077
1078 //todo
1079 q->endMoveRows();
1080 }
1081
_q_sourceRowsAboutToBeRemoved(const QModelIndex & parent,int start,int end)1082 void MultiIndexModelPrivate::_q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
1083 {
1084 //Q_ASSERT(parent.isValid() ? parent.model() == model : true);
1085 Q_Q(MultiIndexModel);
1086
1087 QAbstractItemModel *model = (QAbstractItemModel *)sender();
1088 QMap<QModelIndex,Mapping*>::iterator it = modelMapping[model].find(parent);
1089 if (it != modelMapping[model].end()) {
1090 Mapping *m = it.value();
1091
1092 int n1 = m->proxy_rows.at(start);
1093 int n2 = m->proxy_rows.at(end);
1094 if (n1 > n2) {
1095 qSwap(n1,n2);
1096 }
1097 for (int i = start; i < end+1; i++) {
1098 QModelIndex child = m->sourceModel->index(i,0,m->sourceParent);
1099 QMap<QModelIndex,Mapping*>::iterator childIt = modelMapping[model].find(child);
1100 if (childIt != modelMapping[model].end()) {
1101 Mapping *cm = childIt.value();
1102 cm->sourceParent = QModelIndex();
1103 modelMapping[model].remove(child);
1104 removeMappingList.append(cm);
1105 }
1106 }
1107 q->beginRemoveRows(q->mapFromSourceEx(model,parent), n1,n2);
1108 }
1109 }
1110
_q_sourceRowsRemoved(const QModelIndex & parent,int start,int end)1111 void MultiIndexModelPrivate::_q_sourceRowsRemoved(const QModelIndex &parent, int start, int end)
1112 {
1113 //Q_ASSERT(parent.isValid() ? parent.model() == model : true);
1114 Q_Q(MultiIndexModel);
1115 Q_UNUSED(parent)
1116 Q_UNUSED(start)
1117 Q_UNUSED(end)
1118
1119 //update
1120 QAbstractItemModel *model = (QAbstractItemModel *)sender();
1121 QMap<QModelIndex,Mapping*>::iterator it = modelMapping[model].find(parent);
1122 if (it != modelMapping[model].end()) {
1123 this->createMapping(model,parent,true);
1124 q->endRemoveRows();
1125 }
1126 }
1127
1128
1129 #include "moc_multiindexmodel.cpp"
1130 //lite_memory_check_begin
1131 #if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG)
1132 #define _CRTDBG_MAP_ALLOC
1133 #include <stdlib.h>
1134 #include <crtdbg.h>
1135 #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
1136 #define new DEBUG_NEW
1137 #endif
1138 //lite_memory_check_end
1139
1140