00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "kdescendantsproxymodel_p.h"
00024
00025 #include <QtCore/QStringList>
00026 #include <QtCore/QTimer>
00027
00028 #include "kdebug.h"
00029
00030 #define KDO(object) kDebug() << #object << object
00031
00032 #include "kbihash_p.h"
00033
00034 typedef KHash2Map<QPersistentModelIndex, int> Mapping;
00035
00036 class KDescendantsProxyModelPrivate
00037 {
00038 KDescendantsProxyModelPrivate(KDescendantsProxyModel * qq)
00039 : q_ptr(qq),
00040 m_rowCount(0),
00041 m_ignoreNextLayoutAboutToBeChanged(false),
00042 m_ignoreNextLayoutChanged(false),
00043 m_relayouting(false),
00044 m_displayAncestorData( false ),
00045 m_ancestorSeparator( QLatin1String( " / " ) )
00046 {
00047 }
00048
00049 Q_DECLARE_PUBLIC(KDescendantsProxyModel)
00050 KDescendantsProxyModel * const q_ptr;
00051
00052 mutable QVector<QPersistentModelIndex> m_pendingParents;
00053
00054 void scheduleProcessPendingParents() const;
00055 void processPendingParents();
00056
00057 void synchronousMappingRefresh();
00058
00059 void updateInternalIndexes(int start, int offset);
00060
00061 void resetInternalData();
00062
00063 void sourceRowsAboutToBeInserted(const QModelIndex &, int, int);
00064 void sourceRowsInserted(const QModelIndex &, int, int);
00065 void sourceRowsAboutToBeRemoved(const QModelIndex &, int, int);
00066 void sourceRowsRemoved(const QModelIndex &, int, int);
00067 void sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int);
00068 void sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
00069 void sourceModelAboutToBeReset();
00070 void sourceModelReset();
00071 void sourceLayoutAboutToBeChanged();
00072 void sourceLayoutChanged();
00073 void sourceDataChanged(const QModelIndex &, const QModelIndex &);
00074 void sourceModelDestroyed();
00075
00076 Mapping m_mapping;
00077 int m_rowCount;
00078 QPair<int, int> m_removePair;
00079 QPair<int, int> m_insertPair;
00080
00081 bool m_ignoreNextLayoutAboutToBeChanged;
00082 bool m_ignoreNextLayoutChanged;
00083 bool m_relayouting;
00084
00085 bool m_displayAncestorData;
00086 QString m_ancestorSeparator;
00087
00088 QList<QPersistentModelIndex> m_layoutChangePersistentIndexes;
00089 QModelIndexList m_proxyIndexes;
00090 };
00091
00092 void KDescendantsProxyModelPrivate::resetInternalData()
00093 {
00094 m_rowCount = 0;
00095 m_mapping.clear();
00096 m_layoutChangePersistentIndexes.clear();
00097 m_proxyIndexes.clear();
00098 }
00099
00100 void KDescendantsProxyModelPrivate::synchronousMappingRefresh()
00101 {
00102 m_rowCount = 0;
00103 m_mapping.clear();
00104 m_pendingParents.clear();
00105
00106 m_pendingParents.append(QModelIndex());
00107
00108 m_relayouting = true;
00109 while (!m_pendingParents.isEmpty())
00110 {
00111 processPendingParents();
00112 }
00113 m_relayouting = false;
00114 }
00115
00116 void KDescendantsProxyModelPrivate::scheduleProcessPendingParents() const
00117 {
00118 Q_Q(const KDescendantsProxyModel);
00119 const_cast<KDescendantsProxyModelPrivate*>(this)->processPendingParents();
00120 }
00121
00122 void KDescendantsProxyModelPrivate::processPendingParents()
00123 {
00124 Q_Q(KDescendantsProxyModel);
00125 const QVector<QPersistentModelIndex>::iterator begin = m_pendingParents.begin();
00126 QVector<QPersistentModelIndex>::iterator it = begin;
00127
00128
00129 static const int chunkSize = 30;
00130
00131 const QVector<QPersistentModelIndex>::iterator end =
00132 m_pendingParents.end();
00133
00134 QVector<QPersistentModelIndex> newPendingParents;
00135
00136 while (it != end && it != m_pendingParents.end()) {
00137 const QModelIndex sourceParent = *it;
00138 if (!sourceParent.isValid() && m_rowCount > 0)
00139 {
00140
00141 it = m_pendingParents.erase(it);
00142 continue;
00143 }
00144 const int rowCount = q->sourceModel()->rowCount(sourceParent);
00145
00146 Q_ASSERT(rowCount > 0);
00147 const QPersistentModelIndex sourceIndex = q->sourceModel()->index(rowCount - 1, 0, sourceParent);
00148
00149 Q_ASSERT(sourceIndex.isValid());
00150
00151 const QModelIndex proxyParent = q->mapFromSource(sourceParent);
00152
00153 Q_ASSERT(sourceParent.isValid() == proxyParent.isValid());
00154 const int proxyEndRow = proxyParent.row() + rowCount;
00155 const int proxyStartRow = proxyEndRow - rowCount + 1;
00156
00157 if (!m_relayouting)
00158 q->beginInsertRows(QModelIndex(), proxyStartRow, proxyEndRow);
00159
00160 updateInternalIndexes(proxyStartRow, rowCount);
00161 m_mapping.insert(sourceIndex, proxyEndRow);
00162 it = m_pendingParents.erase(it);
00163 m_rowCount += rowCount;
00164
00165 if (!m_relayouting)
00166 q->endInsertRows();
00167
00168 for (int sourceRow = 0; sourceRow < rowCount; ++sourceRow ) {
00169 static const int column = 0;
00170 const QModelIndex child = q->sourceModel()->index(sourceRow, column, sourceParent);
00171 Q_ASSERT(child.isValid());
00172
00173 if (q->sourceModel()->hasChildren(child))
00174 {
00175 Q_ASSERT(q->sourceModel()->rowCount(child) > 0);
00176 newPendingParents.append(child);
00177 }
00178 }
00179 }
00180 m_pendingParents += newPendingParents;
00181 if (!m_pendingParents.isEmpty())
00182 processPendingParents();
00183
00184 }
00185
00186 void KDescendantsProxyModelPrivate::updateInternalIndexes(int start, int offset)
00187 {
00188
00189 QHash<int, QPersistentModelIndex> updates;
00190 {
00191 Mapping::right_const_iterator it = const_cast<const Mapping&>(m_mapping).rightLowerBound(start);
00192 const Mapping::right_const_iterator end = m_mapping.rightConstEnd();
00193
00194 while (it != end)
00195 {
00196 updates.insert(it.key() + offset, *it);
00197 ++it;
00198 }
00199 }
00200
00201 {
00202 QHash<int, QPersistentModelIndex>::const_iterator it = updates.constBegin();
00203 const QHash<int, QPersistentModelIndex>::const_iterator end = updates.constEnd();
00204
00205 for ( ; it != end; ++it)
00206 {
00207 m_mapping.insert(it.value(), it.key());
00208 }
00209 }
00210
00211 }
00212
00213 KDescendantsProxyModel::KDescendantsProxyModel(QObject *parent)
00214 : QAbstractProxyModel(parent), d_ptr(new KDescendantsProxyModelPrivate(this))
00215 {
00216 }
00217
00218 KDescendantsProxyModel::~KDescendantsProxyModel()
00219 {
00220 delete d_ptr;
00221 }
00222
00223 void KDescendantsProxyModel::setRootIndex(const QModelIndex &index)
00224 {
00225 Q_UNUSED(index)
00226 }
00227
00228 QModelIndexList KDescendantsProxyModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const
00229 {
00230 return QAbstractProxyModel::match(start, role, value, hits, flags);
00231 }
00232
00233 void KDescendantsProxyModel::setDisplayAncestorData( bool display )
00234 {
00235 Q_D(KDescendantsProxyModel);
00236 d->m_displayAncestorData = display;
00237 }
00238
00239 bool KDescendantsProxyModel::displayAncestorData() const
00240 {
00241 Q_D(const KDescendantsProxyModel );
00242 return d->m_displayAncestorData;
00243 }
00244
00245 void KDescendantsProxyModel::setAncestorSeparator( const QString &separator )
00246 {
00247 Q_D(KDescendantsProxyModel);
00248 d->m_ancestorSeparator = separator;
00249 }
00250
00251 QString KDescendantsProxyModel::ancestorSeparator() const
00252 {
00253 Q_D(const KDescendantsProxyModel );
00254 return d->m_ancestorSeparator;
00255 }
00256
00257
00258 void KDescendantsProxyModel::setSourceModel(QAbstractItemModel *_sourceModel)
00259 {
00260 beginResetModel();
00261
00262 if (_sourceModel) {
00263 disconnect(_sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
00264 this, SLOT(sourceRowsAboutToBeInserted(const QModelIndex &, int, int)));
00265 disconnect(_sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
00266 this, SLOT(sourceRowsInserted(const QModelIndex &, int, int)));
00267 disconnect(_sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
00268 this, SLOT(sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)));
00269 disconnect(_sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
00270 this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int)));
00271
00272
00273
00274
00275 disconnect(_sourceModel, SIGNAL(modelAboutToBeReset()),
00276 this, SLOT(sourceModelAboutToBeReset()));
00277 disconnect(_sourceModel, SIGNAL(modelReset()),
00278 this, SLOT(sourceModelReset()));
00279 disconnect(_sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
00280 this, SLOT(sourceDataChanged(const QModelIndex &, const QModelIndex &)));
00281 disconnect(_sourceModel, SIGNAL(layoutAboutToBeChanged()),
00282 this, SLOT(sourceLayoutAboutToBeChanged()));
00283 disconnect(_sourceModel, SIGNAL(layoutChanged()),
00284 this, SLOT(sourceLayoutChanged()));
00285 disconnect(_sourceModel, SIGNAL(destroyed()),
00286 this, SLOT(sourceModelDestroyed()));
00287 }
00288
00289 QAbstractProxyModel::setSourceModel(_sourceModel);
00290
00291 if (_sourceModel) {
00292 connect(_sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
00293 SLOT(sourceRowsAboutToBeInserted(const QModelIndex &, int, int)));
00294 connect(_sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
00295 SLOT(sourceRowsInserted(const QModelIndex &, int, int)));
00296 connect(_sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
00297 SLOT(sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)));
00298 connect(_sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
00299 SLOT(sourceRowsRemoved(const QModelIndex &, int, int)));
00300
00301
00302
00303
00304 connect(_sourceModel, SIGNAL(modelAboutToBeReset()),
00305 SLOT(sourceModelAboutToBeReset()));
00306 connect(_sourceModel, SIGNAL(modelReset()),
00307 SLOT(sourceModelReset()));
00308 connect(_sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
00309 SLOT(sourceDataChanged(const QModelIndex &, const QModelIndex &)));
00310 connect(_sourceModel, SIGNAL(layoutAboutToBeChanged()),
00311 SLOT(sourceLayoutAboutToBeChanged()));
00312 connect(_sourceModel, SIGNAL(layoutChanged()),
00313 SLOT(sourceLayoutChanged()));
00314 connect(_sourceModel, SIGNAL(destroyed()),
00315 SLOT(sourceModelDestroyed()));
00316 }
00317
00318 endResetModel();
00319 }
00320
00321 QModelIndex KDescendantsProxyModel::parent(const QModelIndex &index) const
00322 {
00323 Q_UNUSED(index)
00324 return QModelIndex();
00325 }
00326
00327 bool KDescendantsProxyModel::hasChildren(const QModelIndex &parent) const
00328 {
00329 Q_D(const KDescendantsProxyModel);
00330 return !(d->m_mapping.isEmpty() || parent.isValid());
00331 }
00332
00333 int KDescendantsProxyModel::rowCount(const QModelIndex &parent) const
00334 {
00335 Q_D(const KDescendantsProxyModel);
00336 if (d->m_pendingParents.contains(parent) || parent.isValid() || !sourceModel())
00337 return 0;
00338
00339 if (d->m_mapping.isEmpty() && sourceModel()->hasChildren())
00340 {
00341 Q_ASSERT(sourceModel()->rowCount() > 0);
00342 const_cast<KDescendantsProxyModelPrivate*>(d)->synchronousMappingRefresh();
00343 }
00344 return d->m_rowCount;
00345 }
00346
00347 QModelIndex KDescendantsProxyModel::index(int row, int column, const QModelIndex &parent) const
00348 {
00349 if (parent.isValid())
00350 return QModelIndex();
00351
00352 if (!hasIndex(row, column, parent))
00353 return QModelIndex();
00354
00355 return createIndex(row, column);
00356 }
00357
00358 QModelIndex KDescendantsProxyModel::mapToSource(const QModelIndex &proxyIndex) const
00359 {
00360 Q_D(const KDescendantsProxyModel);
00361 if (d->m_mapping.isEmpty() || !proxyIndex.isValid() || !sourceModel())
00362 return QModelIndex();
00363
00364 const Mapping::right_const_iterator result = d->m_mapping.rightLowerBound(proxyIndex.row());
00365 Q_ASSERT(result != d->m_mapping.rightEnd());
00366
00367 const int proxyLastRow = result.key();
00368 const QModelIndex sourceLastChild = result.value();
00369 Q_ASSERT(sourceLastChild.isValid());
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 int verticalDistance = proxyLastRow - proxyIndex.row();
00401
00402
00403
00404 QModelIndex ancestor = sourceLastChild;
00405 while (ancestor.isValid())
00406 {
00407 const int ancestorRow = ancestor.row();
00408 if (verticalDistance <= ancestorRow)
00409 {
00410 return ancestor.sibling(ancestorRow - verticalDistance, proxyIndex.column());
00411 }
00412 verticalDistance -= (ancestorRow + 1);
00413 ancestor = ancestor.parent();
00414 }
00415 Q_ASSERT(!"Didn't find target row.");
00416 return QModelIndex();
00417 }
00418
00419 QModelIndex KDescendantsProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
00420 {
00421 Q_D(const KDescendantsProxyModel);
00422
00423 if (!sourceModel())
00424 return QModelIndex();
00425
00426 if (d->m_mapping.isEmpty())
00427 return QModelIndex();
00428
00429
00430 {
00431
00432
00433 Mapping::right_const_iterator it = d->m_mapping.rightConstBegin();
00434 const Mapping::right_const_iterator end = d->m_mapping.rightConstEnd();
00435 const QModelIndex sourceParent = sourceIndex.parent();
00436 Mapping::right_const_iterator result = end;
00437
00438 for ( ; it != end; ++it )
00439 {
00440 QModelIndex index = it.value();
00441 bool found_block = false;
00442 while (index.isValid())
00443 {
00444 const QModelIndex ancestor = index.parent();
00445 if (ancestor == sourceParent && index.row() >= sourceIndex.row())
00446 {
00447 found_block = true;
00448 if (result == end || it.key() < result.key())
00449 {
00450 result = it;
00451 break;
00452 }
00453 }
00454 index = ancestor;
00455 }
00456 if (found_block && !index.isValid())
00457
00458
00459 break;
00460 }
00461 Q_ASSERT(result != end);
00462 const QModelIndex sourceLastChild = result.value();
00463 int proxyRow = result.key();
00464 QModelIndex index = sourceLastChild;
00465 while (index.isValid())
00466 {
00467 const QModelIndex ancestor = index.parent();
00468 if (ancestor == sourceParent)
00469 {
00470 return createIndex(proxyRow - (index.row() - sourceIndex.row()), sourceIndex.column());
00471 }
00472 proxyRow -= (index.row() + 1);
00473 index = ancestor;
00474 }
00475 Q_ASSERT(!"Didn't find valid proxy mapping.");
00476 return QModelIndex();
00477 }
00478
00479 }
00480
00481 int KDescendantsProxyModel::columnCount(const QModelIndex &parent) const
00482 {
00483 if (parent.isValid() || !sourceModel())
00484 return 0;
00485
00486 return sourceModel()->columnCount();
00487 }
00488
00489 QVariant KDescendantsProxyModel::data(const QModelIndex &index, int role) const
00490 {
00491 Q_D(const KDescendantsProxyModel );
00492
00493 if (!sourceModel())
00494 return QVariant();
00495
00496 if (!index.isValid())
00497 return sourceModel()->data(index, role);
00498
00499 QModelIndex sourceIndex = mapToSource( index );
00500
00501 if ((d->m_displayAncestorData) && ( role == Qt::DisplayRole ) )
00502 {
00503 if (!sourceIndex.isValid())
00504 {
00505 return QVariant();
00506 }
00507 QString displayData = sourceIndex.data().toString();
00508 sourceIndex = sourceIndex.parent();
00509 while (sourceIndex.isValid())
00510 {
00511 displayData.prepend(d->m_ancestorSeparator);
00512 displayData.prepend(sourceIndex.data().toString());
00513 sourceIndex = sourceIndex.parent();
00514 }
00515 return displayData;
00516 } else {
00517 return sourceIndex.data(role);
00518 }
00519 }
00520
00521 QVariant KDescendantsProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
00522 {
00523 if (!sourceModel() || columnCount() <= section)
00524 return QVariant();
00525
00526 return QAbstractProxyModel::headerData(section, orientation, role);
00527 }
00528
00529 Qt::ItemFlags KDescendantsProxyModel::flags(const QModelIndex &index) const
00530 {
00531 if (!index.isValid() || !sourceModel())
00532 return QAbstractProxyModel::flags(index);
00533
00534 const QModelIndex srcIndex = mapToSource(index);
00535 Q_ASSERT(srcIndex.isValid());
00536 return sourceModel()->flags(srcIndex);
00537 }
00538
00539 void KDescendantsProxyModelPrivate::sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
00540 {
00541 Q_Q(KDescendantsProxyModel);
00542
00543 if (!q->sourceModel()->hasChildren(parent))
00544 {
00545 Q_ASSERT(q->sourceModel()->rowCount(parent) == 0);
00546
00547 return;
00548 }
00549
00550 int proxyStart = -1;
00551
00552 const int rowCount = q->sourceModel()->rowCount(parent);
00553
00554 if (rowCount > start)
00555 {
00556 const QModelIndex belowStart = q->sourceModel()->index(start, 0, parent);
00557 proxyStart = q->mapFromSource(belowStart).row();
00558 } else if (rowCount == 0)
00559 {
00560 proxyStart = q->mapFromSource(parent).row() + 1;
00561 } else {
00562 Q_ASSERT(rowCount == start);
00563 static const int column = 0;
00564 QModelIndex idx = q->sourceModel()->index(rowCount - 1, column, parent);
00565 while (q->sourceModel()->hasChildren(idx))
00566 {
00567 Q_ASSERT(q->sourceModel()->rowCount(idx) > 0);
00568 idx = q->sourceModel()->index(q->sourceModel()->rowCount(idx) - 1, column, idx);
00569 }
00570
00571 proxyStart = q->mapFromSource(idx).row() + 1;
00572 }
00573 const int proxyEnd = proxyStart + (end - start);
00574
00575 m_insertPair = qMakePair(proxyStart, proxyEnd);
00576 q->beginInsertRows(QModelIndex(), proxyStart, proxyEnd);
00577 }
00578
00579 void KDescendantsProxyModelPrivate::sourceRowsInserted(const QModelIndex &parent, int start, int end)
00580 {
00581 Q_Q(KDescendantsProxyModel);
00582
00583 const QModelIndex sourceStart = q->sourceModel()->index(start, 0, parent);
00584 Q_ASSERT(sourceStart.isValid());
00585
00586 const int rowCount = q->sourceModel()->rowCount(parent);
00587 Q_ASSERT(rowCount > 0);
00588
00589 const int difference = end - start + 1;
00590
00591 if (rowCount == difference)
00592 {
00593
00594 m_pendingParents.append(parent);
00595 scheduleProcessPendingParents();
00596 return;
00597 }
00598
00599 const int proxyStart = m_insertPair.first;
00600
00601 Q_ASSERT(proxyStart >= 0);
00602
00603 updateInternalIndexes(proxyStart, difference);
00604
00605 if (rowCount - 1 == end)
00606 {
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 Q_ASSERT(!m_mapping.isEmpty());
00639 static const int column = 0;
00640 const QModelIndex oldIndex = q->sourceModel()->index(rowCount - 1 - difference, column, parent);
00641 Q_ASSERT(m_mapping.leftContains(oldIndex));
00642
00643 const QModelIndex newIndex = q->sourceModel()->index(rowCount - 1, column, parent);
00644
00645 QModelIndex indexAbove = oldIndex;
00646
00647 if (start > 0) {
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 while (q->sourceModel()->hasChildren(indexAbove)) {
00658 Q_ASSERT(q->sourceModel()->rowCount(indexAbove) > 0);
00659 indexAbove = q->sourceModel()->index(q->sourceModel()->rowCount(indexAbove) - 1, column, indexAbove);
00660 }
00661 Q_ASSERT(q->sourceModel()->rowCount(indexAbove) == 0);
00662 }
00663
00664 Q_ASSERT(m_mapping.leftContains(indexAbove));
00665
00666 const int newProxyRow = m_mapping.leftToRight(indexAbove) + difference;
00667
00668
00669 m_mapping.removeLeft(oldIndex);
00670
00671
00672 m_mapping.insert(newIndex, newProxyRow);
00673 }
00674
00675 for (int row = start; row <= end; ++row)
00676 {
00677 static const int column = 0;
00678 const QModelIndex idx = q->sourceModel()->index(row, column, parent);
00679 Q_ASSERT(idx.isValid());
00680 if (q->sourceModel()->hasChildren(idx))
00681 {
00682 Q_ASSERT(q->sourceModel()->rowCount(idx) > 0);
00683 m_pendingParents.append(idx);
00684 }
00685 }
00686
00687 m_rowCount += difference;
00688
00689 q->endInsertRows();
00690 scheduleProcessPendingParents();
00691 }
00692
00693 void KDescendantsProxyModelPrivate::sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
00694 {
00695 Q_Q(KDescendantsProxyModel);
00696
00697 const int proxyStart = q->mapFromSource(q->sourceModel()->index(start, 0, parent)).row();
00698
00699 static const int column = 0;
00700 QModelIndex idx = q->sourceModel()->index(end, column, parent);
00701 while (q->sourceModel()->hasChildren(idx))
00702 {
00703 Q_ASSERT(q->sourceModel()->rowCount(idx) > 0);
00704 idx = q->sourceModel()->index(q->sourceModel()->rowCount(idx) - 1, column, idx);
00705 }
00706 const int proxyEnd = q->mapFromSource(idx).row();
00707
00708 m_removePair = qMakePair(proxyStart, proxyEnd);
00709
00710 q->beginRemoveRows(QModelIndex(), proxyStart, proxyEnd);
00711 }
00712
00713 void KDescendantsProxyModelPrivate::sourceRowsRemoved(const QModelIndex &parent, int start, int end)
00714 {
00715 Q_Q(KDescendantsProxyModel);
00716 Q_UNUSED(end)
00717
00718 const int rowCount = q->sourceModel()->rowCount(parent);
00719
00720
00721 const int proxyStart = m_removePair.first;
00722 const int proxyEnd = m_removePair.second;
00723
00724 const int difference = proxyEnd - proxyStart + 1;
00725 {
00726 Mapping::right_iterator it = m_mapping.rightLowerBound(proxyStart);
00727 const Mapping::right_iterator endIt = m_mapping.rightUpperBound(proxyEnd);
00728
00729 if (endIt != m_mapping.rightEnd())
00730 while (it != endIt)
00731 it = m_mapping.eraseRight(it);
00732 else
00733 while (it != m_mapping.rightUpperBound(proxyEnd))
00734 it = m_mapping.eraseRight(it);
00735 }
00736
00737 m_removePair = qMakePair(-1, -1);
00738 m_rowCount -= difference;
00739 Q_ASSERT(m_rowCount >= 0);
00740
00741 updateInternalIndexes(proxyStart, -1 * difference);
00742
00743 if (rowCount == start && rowCount != 0)
00744 {
00745 static const int column = 0;
00746 const QModelIndex newIndex = q->sourceModel()->index(rowCount - 1, column, parent);
00747 m_mapping.insert(newIndex, proxyStart - 1);
00748 }
00749
00750 q->endRemoveRows();
00751 }
00752
00753 void KDescendantsProxyModelPrivate::sourceRowsAboutToBeMoved(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destStart)
00754 {
00755 Q_UNUSED(srcParent)
00756 Q_UNUSED(srcStart)
00757 Q_UNUSED(srcEnd)
00758 Q_UNUSED(destParent)
00759 Q_UNUSED(destStart)
00760 Q_Q(KDescendantsProxyModel);
00761 q->beginResetModel();
00762 }
00763
00764 void KDescendantsProxyModelPrivate::sourceRowsMoved(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destStart)
00765 {
00766 Q_UNUSED(srcParent)
00767 Q_UNUSED(srcStart)
00768 Q_UNUSED(srcEnd)
00769 Q_UNUSED(destParent)
00770 Q_UNUSED(destStart)
00771 Q_Q(KDescendantsProxyModel);
00772 resetInternalData();
00773 q->endResetModel();
00774 }
00775
00776 void KDescendantsProxyModelPrivate::sourceModelAboutToBeReset()
00777 {
00778 Q_Q(KDescendantsProxyModel);
00779 q->beginResetModel();
00780 }
00781
00782 void KDescendantsProxyModelPrivate::sourceModelReset()
00783 {
00784 Q_Q(KDescendantsProxyModel);
00785 resetInternalData();
00786 if (q->sourceModel()->hasChildren())
00787 {
00788 Q_ASSERT(q->sourceModel()->rowCount() > 0);
00789 m_pendingParents.append(QModelIndex());
00790 scheduleProcessPendingParents();
00791 }
00792 q->endResetModel();
00793 }
00794
00795 void KDescendantsProxyModelPrivate::sourceLayoutAboutToBeChanged()
00796 {
00797 Q_Q(KDescendantsProxyModel);
00798
00799 if (m_ignoreNextLayoutChanged) {
00800 m_ignoreNextLayoutChanged = false;
00801 return;
00802 }
00803
00804 if (m_mapping.isEmpty())
00805 return;
00806
00807 QPersistentModelIndex srcPersistentIndex;
00808 foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
00809 m_proxyIndexes << proxyPersistentIndex;
00810 Q_ASSERT(proxyPersistentIndex.isValid());
00811 srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
00812 Q_ASSERT(srcPersistentIndex.isValid());
00813 m_layoutChangePersistentIndexes << srcPersistentIndex;
00814 }
00815
00816 q->layoutAboutToBeChanged();
00817 }
00818
00819 void KDescendantsProxyModelPrivate::sourceLayoutChanged()
00820 {
00821 Q_Q(KDescendantsProxyModel);
00822
00823 if (m_ignoreNextLayoutAboutToBeChanged) {
00824 m_ignoreNextLayoutAboutToBeChanged = false;
00825 return;
00826 }
00827
00828 if (m_mapping.isEmpty())
00829 return;
00830
00831 m_rowCount = 0;
00832
00833 synchronousMappingRefresh();
00834
00835 for (int i = 0; i < m_proxyIndexes.size(); ++i) {
00836 q->changePersistentIndex(m_proxyIndexes.at(i), q->mapFromSource(m_layoutChangePersistentIndexes.at(i)));
00837 }
00838
00839 m_layoutChangePersistentIndexes.clear();
00840 m_proxyIndexes.clear();
00841
00842 q->layoutChanged();
00843 }
00844
00845 void KDescendantsProxyModelPrivate::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
00846 {
00847 Q_Q(KDescendantsProxyModel);
00848
00849 const int topRow = topLeft.row();
00850 const int bottomRow = bottomRight.row();
00851
00852 for(int i = topRow; i <= bottomRow; ++i)
00853 {
00854 const QModelIndex sourceTopLeft = q->sourceModel()->index(i, topLeft.column(), topLeft.parent());
00855 const QModelIndex proxyTopLeft = q->mapFromSource(sourceTopLeft);
00856
00857
00858 const QModelIndex sourceBottomRight = q->sourceModel()->index(i, bottomRight.column(), bottomRight.parent());
00859 const QModelIndex proxyBottomRight = q->mapFromSource(sourceBottomRight);
00860 emit q->dataChanged(proxyTopLeft, proxyBottomRight);
00861 }
00862 }
00863
00864 void KDescendantsProxyModelPrivate::sourceModelDestroyed()
00865 {
00866 Q_Q(KDescendantsProxyModel);
00867 resetInternalData();
00868 q->endResetModel();
00869 }
00870
00871 QMimeData* KDescendantsProxyModel::mimeData( const QModelIndexList & indexes ) const
00872 {
00873 if (!sourceModel())
00874 return QAbstractProxyModel::mimeData(indexes);
00875 Q_ASSERT(sourceModel());
00876 QModelIndexList sourceIndexes;
00877 foreach(const QModelIndex& index, indexes)
00878 sourceIndexes << mapToSource(index);
00879 return sourceModel()->mimeData(sourceIndexes);
00880 }
00881
00882 QStringList KDescendantsProxyModel::mimeTypes() const
00883 {
00884 if (!sourceModel())
00885 return QAbstractProxyModel::mimeTypes();
00886 Q_ASSERT(sourceModel());
00887 return sourceModel()->mimeTypes();
00888 }
00889
00890 Qt::DropActions KDescendantsProxyModel::supportedDropActions() const
00891 {
00892 if (!sourceModel())
00893 return QAbstractProxyModel::supportedDropActions();
00894 return sourceModel()->supportedDropActions();
00895 }
00896
00897 #include "moc_kdescendantsproxymodel_p.cpp"