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 newPendingParents.append(child);
00175 }
00176 }
00177 m_pendingParents += newPendingParents;
00178 if (!m_pendingParents.isEmpty())
00179 processPendingParents();
00180
00181 }
00182
00183 void KDescendantsProxyModelPrivate::updateInternalIndexes(int start, int offset)
00184 {
00185
00186 QHash<int, QPersistentModelIndex> updates;
00187 {
00188 Mapping::right_const_iterator it = const_cast<const Mapping&>(m_mapping).rightLowerBound(start);
00189 const Mapping::right_const_iterator end = m_mapping.rightConstEnd();
00190
00191 while (it != end)
00192 {
00193 updates.insert(it.key() + offset, *it);
00194 ++it;
00195 }
00196 }
00197
00198 {
00199 QHash<int, QPersistentModelIndex>::const_iterator it = updates.constBegin();
00200 const QHash<int, QPersistentModelIndex>::const_iterator end = updates.constEnd();
00201
00202 for ( ; it != end; ++it)
00203 {
00204 m_mapping.insert(it.value(), it.key());
00205 }
00206 }
00207
00208 }
00209
00210 KDescendantsProxyModel::KDescendantsProxyModel(QObject *parent)
00211 : QAbstractProxyModel(parent), d_ptr(new KDescendantsProxyModelPrivate(this))
00212 {
00213 }
00214
00215 KDescendantsProxyModel::~KDescendantsProxyModel()
00216 {
00217 delete d_ptr;
00218 }
00219
00220 void KDescendantsProxyModel::setRootIndex(const QModelIndex &index)
00221 {
00222 Q_UNUSED(index)
00223 }
00224
00225 QModelIndexList KDescendantsProxyModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const
00226 {
00227 return QAbstractProxyModel::match(start, role, value, hits, flags);
00228 }
00229
00230 void KDescendantsProxyModel::setDisplayAncestorData( bool display )
00231 {
00232 Q_D(KDescendantsProxyModel);
00233 d->m_displayAncestorData = display;
00234 }
00235
00236 bool KDescendantsProxyModel::displayAncestorData() const
00237 {
00238 Q_D(const KDescendantsProxyModel );
00239 return d->m_displayAncestorData;
00240 }
00241
00242 void KDescendantsProxyModel::setAncestorSeparator( const QString &separator )
00243 {
00244 Q_D(KDescendantsProxyModel);
00245 d->m_ancestorSeparator = separator;
00246 }
00247
00248 QString KDescendantsProxyModel::ancestorSeparator() const
00249 {
00250 Q_D(const KDescendantsProxyModel );
00251 return d->m_ancestorSeparator;
00252 }
00253
00254
00255 void KDescendantsProxyModel::setSourceModel(QAbstractItemModel *_sourceModel)
00256 {
00257 beginResetModel();
00258
00259 if (_sourceModel) {
00260 disconnect(_sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
00261 this, SLOT(sourceRowsAboutToBeInserted(const QModelIndex &, int, int)));
00262 disconnect(_sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
00263 this, SLOT(sourceRowsInserted(const QModelIndex &, int, int)));
00264 disconnect(_sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
00265 this, SLOT(sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)));
00266 disconnect(_sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
00267 this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int)));
00268
00269
00270
00271
00272 disconnect(_sourceModel, SIGNAL(modelAboutToBeReset()),
00273 this, SLOT(sourceModelAboutToBeReset()));
00274 disconnect(_sourceModel, SIGNAL(modelReset()),
00275 this, SLOT(sourceModelReset()));
00276 disconnect(_sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
00277 this, SLOT(sourceDataChanged(const QModelIndex &, const QModelIndex &)));
00278 disconnect(_sourceModel, SIGNAL(layoutAboutToBeChanged()),
00279 this, SLOT(sourceLayoutAboutToBeChanged()));
00280 disconnect(_sourceModel, SIGNAL(layoutChanged()),
00281 this, SLOT(sourceLayoutChanged()));
00282 disconnect(_sourceModel, SIGNAL(destroyed()),
00283 this, SLOT(sourceModelDestroyed()));
00284 }
00285
00286 QAbstractProxyModel::setSourceModel(_sourceModel);
00287
00288 if (_sourceModel) {
00289 connect(_sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
00290 SLOT(sourceRowsAboutToBeInserted(const QModelIndex &, int, int)));
00291 connect(_sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
00292 SLOT(sourceRowsInserted(const QModelIndex &, int, int)));
00293 connect(_sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
00294 SLOT(sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)));
00295 connect(_sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
00296 SLOT(sourceRowsRemoved(const QModelIndex &, int, int)));
00297
00298
00299
00300
00301 connect(_sourceModel, SIGNAL(modelAboutToBeReset()),
00302 SLOT(sourceModelAboutToBeReset()));
00303 connect(_sourceModel, SIGNAL(modelReset()),
00304 SLOT(sourceModelReset()));
00305 connect(_sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
00306 SLOT(sourceDataChanged(const QModelIndex &, const QModelIndex &)));
00307 connect(_sourceModel, SIGNAL(layoutAboutToBeChanged()),
00308 SLOT(sourceLayoutAboutToBeChanged()));
00309 connect(_sourceModel, SIGNAL(layoutChanged()),
00310 SLOT(sourceLayoutChanged()));
00311 connect(_sourceModel, SIGNAL(destroyed()),
00312 SLOT(sourceModelDestroyed()));
00313 }
00314
00315 endResetModel();
00316 }
00317
00318 QModelIndex KDescendantsProxyModel::parent(const QModelIndex &index) const
00319 {
00320 Q_UNUSED(index)
00321 return QModelIndex();
00322 }
00323
00324 bool KDescendantsProxyModel::hasChildren(const QModelIndex &parent) const
00325 {
00326 Q_D(const KDescendantsProxyModel);
00327 return !(d->m_mapping.isEmpty() || parent.isValid());
00328 }
00329
00330 int KDescendantsProxyModel::rowCount(const QModelIndex &parent) const
00331 {
00332 Q_D(const KDescendantsProxyModel);
00333 if (d->m_pendingParents.contains(parent) || parent.isValid() || !sourceModel())
00334 return 0;
00335
00336 if (d->m_mapping.isEmpty() && sourceModel()->hasChildren())
00337 {
00338 const_cast<KDescendantsProxyModelPrivate*>(d)->synchronousMappingRefresh();
00339 }
00340 return d->m_rowCount;
00341 }
00342
00343 QModelIndex KDescendantsProxyModel::index(int row, int column, const QModelIndex &parent) const
00344 {
00345 if (parent.isValid())
00346 return QModelIndex();
00347
00348 if (!hasIndex(row, column, parent))
00349 return QModelIndex();
00350
00351 return createIndex(row, column);
00352 }
00353
00354 QModelIndex KDescendantsProxyModel::mapToSource(const QModelIndex &proxyIndex) const
00355 {
00356 Q_D(const KDescendantsProxyModel);
00357 if (d->m_mapping.isEmpty() || !proxyIndex.isValid() || !sourceModel())
00358 return QModelIndex();
00359
00360 const Mapping::right_const_iterator result = d->m_mapping.rightLowerBound(proxyIndex.row());
00361 Q_ASSERT(result != d->m_mapping.rightEnd());
00362
00363 const int proxyLastRow = result.key();
00364 const QModelIndex sourceLastChild = result.value();
00365 Q_ASSERT(sourceLastChild.isValid());
00366
00367
00368
00369
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 int verticalDistance = proxyLastRow - proxyIndex.row();
00397
00398
00399
00400 QModelIndex ancestor = sourceLastChild;
00401 while (ancestor.isValid())
00402 {
00403 const int ancestorRow = ancestor.row();
00404 if (verticalDistance <= ancestorRow)
00405 {
00406 return ancestor.sibling(ancestorRow - verticalDistance, proxyIndex.column());
00407 }
00408 verticalDistance -= (ancestorRow + 1);
00409 ancestor = ancestor.parent();
00410 }
00411 Q_ASSERT(!"Didn't find target row.");
00412 return QModelIndex();
00413 }
00414
00415 QModelIndex KDescendantsProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
00416 {
00417 Q_D(const KDescendantsProxyModel);
00418
00419 if (!sourceModel())
00420 return QModelIndex();
00421
00422 if (d->m_mapping.isEmpty())
00423 return QModelIndex();
00424
00425
00426 {
00427
00428
00429 Mapping::right_const_iterator it = d->m_mapping.rightConstBegin();
00430 const Mapping::right_const_iterator end = d->m_mapping.rightConstEnd();
00431 const QModelIndex sourceParent = sourceIndex.parent();
00432 Mapping::right_const_iterator result = end;
00433
00434 for ( ; it != end; ++it )
00435 {
00436 QModelIndex index = it.value();
00437 bool found_block = false;
00438 while (index.isValid())
00439 {
00440 const QModelIndex ancestor = index.parent();
00441 if (ancestor == sourceParent && index.row() >= sourceIndex.row())
00442 {
00443 found_block = true;
00444 if (result == end || it.key() < result.key())
00445 {
00446 result = it;
00447 break;
00448 }
00449 }
00450 index = ancestor;
00451 }
00452 if (found_block && !index.isValid())
00453
00454
00455 break;
00456 }
00457 Q_ASSERT(result != end);
00458 const QModelIndex sourceLastChild = result.value();
00459 int proxyRow = result.key();
00460 QModelIndex index = sourceLastChild;
00461 while (index.isValid())
00462 {
00463 const QModelIndex ancestor = index.parent();
00464 if (ancestor == sourceParent)
00465 {
00466 return createIndex(proxyRow - (index.row() - sourceIndex.row()), sourceIndex.column());
00467 }
00468 proxyRow -= (index.row() + 1);
00469 index = ancestor;
00470 }
00471 Q_ASSERT(!"Didn't find valid proxy mapping.");
00472 return QModelIndex();
00473 }
00474
00475 }
00476
00477 int KDescendantsProxyModel::columnCount(const QModelIndex &parent) const
00478 {
00479 if (parent.isValid() || !sourceModel())
00480 return 0;
00481
00482 return sourceModel()->columnCount();
00483 }
00484
00485 QVariant KDescendantsProxyModel::data(const QModelIndex &index, int role) const
00486 {
00487 Q_D(const KDescendantsProxyModel );
00488
00489 if (!sourceModel())
00490 return QVariant();
00491
00492 if (!index.isValid())
00493 return sourceModel()->data(index, role);
00494
00495 QModelIndex sourceIndex = mapToSource( index );
00496
00497 if ((d->m_displayAncestorData) && ( role == Qt::DisplayRole ) )
00498 {
00499 if (!sourceIndex.isValid())
00500 {
00501 return QVariant();
00502 }
00503 QString displayData = sourceIndex.data().toString();
00504 sourceIndex = sourceIndex.parent();
00505 while (sourceIndex.isValid())
00506 {
00507 displayData.prepend(d->m_ancestorSeparator);
00508 displayData.prepend(sourceIndex.data().toString());
00509 sourceIndex = sourceIndex.parent();
00510 }
00511 return displayData;
00512 } else {
00513 return sourceIndex.data(role);
00514 }
00515 }
00516
00517 QVariant KDescendantsProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
00518 {
00519 if (!sourceModel() || columnCount() <= section)
00520 return QVariant();
00521
00522 return QAbstractProxyModel::headerData(section, orientation, role);
00523 }
00524
00525 Qt::ItemFlags KDescendantsProxyModel::flags(const QModelIndex &index) const
00526 {
00527 if (!index.isValid() || !sourceModel())
00528 return QAbstractProxyModel::flags(index);
00529
00530 const QModelIndex srcIndex = mapToSource(index);
00531 Q_ASSERT(srcIndex.isValid());
00532 return sourceModel()->flags(srcIndex);
00533 }
00534
00535 void KDescendantsProxyModelPrivate::sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
00536 {
00537 Q_Q(KDescendantsProxyModel);
00538
00539 if (!q->sourceModel()->hasChildren(parent))
00540 {
00541
00542 return;
00543 }
00544
00545 int proxyStart = -1;
00546
00547 const int rowCount = q->sourceModel()->rowCount(parent);
00548
00549 if (rowCount > start)
00550 {
00551 const QModelIndex belowStart = q->sourceModel()->index(start, 0, parent);
00552 proxyStart = q->mapFromSource(belowStart).row();
00553 } else if (rowCount == 0)
00554 {
00555 proxyStart = q->mapFromSource(parent).row() + 1;
00556 } else {
00557 Q_ASSERT(rowCount == start);
00558 static const int column = 0;
00559 QModelIndex idx = q->sourceModel()->index(rowCount - 1, column, parent);
00560 while (q->sourceModel()->hasChildren(idx))
00561 {
00562 idx = q->sourceModel()->index(q->sourceModel()->rowCount(idx) - 1, column, idx);
00563 }
00564
00565 proxyStart = q->mapFromSource(idx).row() + 1;
00566 }
00567 const int proxyEnd = proxyStart + (end - start);
00568
00569 m_insertPair = qMakePair(proxyStart, proxyEnd);
00570 q->beginInsertRows(QModelIndex(), proxyStart, proxyEnd);
00571 }
00572
00573 void KDescendantsProxyModelPrivate::sourceRowsInserted(const QModelIndex &parent, int start, int end)
00574 {
00575 Q_Q(KDescendantsProxyModel);
00576
00577 const QModelIndex sourceStart = q->sourceModel()->index(start, 0, parent);
00578 Q_ASSERT(sourceStart.isValid());
00579
00580 const int rowCount = q->sourceModel()->rowCount(parent);
00581 Q_ASSERT(rowCount > 0);
00582
00583 const int difference = end - start + 1;
00584
00585 if (rowCount == difference)
00586 {
00587
00588 m_pendingParents.append(parent);
00589 scheduleProcessPendingParents();
00590 return;
00591 }
00592
00593 const int proxyStart = m_insertPair.first;
00594
00595 Q_ASSERT(proxyStart >= 0);
00596
00597 updateInternalIndexes(proxyStart, difference);
00598
00599 if (rowCount - 1 == end)
00600 {
00601
00602
00603
00604
00605
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 Q_ASSERT(!m_mapping.isEmpty());
00633 static const int column = 0;
00634 const QModelIndex oldIndex = q->sourceModel()->index(rowCount - 1 - difference, column, parent);
00635 Q_ASSERT(m_mapping.leftContains(oldIndex));
00636
00637
00638 const int proxyRow = m_mapping.takeLeft(oldIndex);
00639 const QModelIndex newIndex = q->sourceModel()->index(rowCount - 1, column, parent);
00640
00641
00642 m_mapping.insert(newIndex, proxyRow + difference);
00643 }
00644
00645 for (int row = start; row <= end; ++row)
00646 {
00647 static const int column = 0;
00648 const QModelIndex idx = q->sourceModel()->index(row, column, parent);
00649 Q_ASSERT(idx.isValid());
00650 if (q->sourceModel()->hasChildren(idx))
00651 m_pendingParents.append(idx);
00652 }
00653
00654 m_rowCount += difference;
00655
00656 scheduleProcessPendingParents();
00657 q->endInsertRows();
00658 }
00659
00660 void KDescendantsProxyModelPrivate::sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
00661 {
00662 Q_Q(KDescendantsProxyModel);
00663
00664 const int proxyStart = q->mapFromSource(q->sourceModel()->index(start, 0, parent)).row();
00665
00666 static const int column = 0;
00667 QModelIndex idx = q->sourceModel()->index(end, column, parent);
00668 while (q->sourceModel()->hasChildren(idx))
00669 {
00670 idx = q->sourceModel()->index(q->sourceModel()->rowCount(idx) - 1, column, idx);
00671 }
00672 const int proxyEnd = q->mapFromSource(idx).row();
00673
00674 m_removePair = qMakePair(proxyStart, proxyEnd);
00675
00676 q->beginRemoveRows(QModelIndex(), proxyStart, proxyEnd);
00677 }
00678
00679 void KDescendantsProxyModelPrivate::sourceRowsRemoved(const QModelIndex &parent, int start, int end)
00680 {
00681 Q_Q(KDescendantsProxyModel);
00682 Q_UNUSED(end)
00683
00684 const int rowCount = q->sourceModel()->rowCount(parent);
00685
00686
00687 const int proxyStart = m_removePair.first;
00688 const int proxyEnd = m_removePair.second;
00689
00690 const int difference = proxyEnd - proxyStart + 1;
00691 {
00692 Mapping::right_iterator it = m_mapping.rightLowerBound(proxyStart);
00693 const Mapping::right_iterator endIt = m_mapping.rightUpperBound(proxyEnd);
00694
00695 if (endIt != m_mapping.rightEnd())
00696 while (it != endIt)
00697 it = m_mapping.eraseRight(it);
00698 else
00699 while (it != m_mapping.rightUpperBound(proxyEnd))
00700 it = m_mapping.eraseRight(it);
00701 }
00702
00703 m_removePair = qMakePair(-1, -1);
00704 m_rowCount -= difference;
00705 Q_ASSERT(m_rowCount >= 0);
00706
00707 updateInternalIndexes(proxyStart, -1 * difference);
00708
00709 if (rowCount == start && rowCount != 0)
00710 {
00711 static const int column = 0;
00712 const QModelIndex newIndex = q->sourceModel()->index(rowCount - 1, column, parent);
00713 m_mapping.insert(newIndex, proxyStart - 1);
00714 }
00715
00716 q->endRemoveRows();
00717 }
00718
00719 void KDescendantsProxyModelPrivate::sourceRowsAboutToBeMoved(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destStart)
00720 {
00721 Q_UNUSED(srcParent)
00722 Q_UNUSED(srcStart)
00723 Q_UNUSED(srcEnd)
00724 Q_UNUSED(destParent)
00725 Q_UNUSED(destStart)
00726 Q_Q(KDescendantsProxyModel);
00727 q->beginResetModel();
00728 }
00729
00730 void KDescendantsProxyModelPrivate::sourceRowsMoved(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destStart)
00731 {
00732 Q_UNUSED(srcParent)
00733 Q_UNUSED(srcStart)
00734 Q_UNUSED(srcEnd)
00735 Q_UNUSED(destParent)
00736 Q_UNUSED(destStart)
00737 Q_Q(KDescendantsProxyModel);
00738 resetInternalData();
00739 q->endResetModel();
00740 }
00741
00742 void KDescendantsProxyModelPrivate::sourceModelAboutToBeReset()
00743 {
00744 Q_Q(KDescendantsProxyModel);
00745 q->beginResetModel();
00746 }
00747
00748 void KDescendantsProxyModelPrivate::sourceModelReset()
00749 {
00750 Q_Q(KDescendantsProxyModel);
00751 resetInternalData();
00752 if (q->sourceModel()->hasChildren())
00753 {
00754 m_pendingParents.append(QModelIndex());
00755 scheduleProcessPendingParents();
00756 }
00757 q->endResetModel();
00758 }
00759
00760 void KDescendantsProxyModelPrivate::sourceLayoutAboutToBeChanged()
00761 {
00762 Q_Q(KDescendantsProxyModel);
00763
00764 if (m_ignoreNextLayoutChanged) {
00765 m_ignoreNextLayoutChanged = false;
00766 return;
00767 }
00768
00769 if (m_mapping.isEmpty())
00770 return;
00771
00772 QPersistentModelIndex srcPersistentIndex;
00773 foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
00774 m_proxyIndexes << proxyPersistentIndex;
00775 Q_ASSERT(proxyPersistentIndex.isValid());
00776 srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
00777 Q_ASSERT(srcPersistentIndex.isValid());
00778 m_layoutChangePersistentIndexes << srcPersistentIndex;
00779 }
00780
00781 q->layoutAboutToBeChanged();
00782 }
00783
00784 void KDescendantsProxyModelPrivate::sourceLayoutChanged()
00785 {
00786 Q_Q(KDescendantsProxyModel);
00787
00788 if (m_ignoreNextLayoutAboutToBeChanged) {
00789 m_ignoreNextLayoutAboutToBeChanged = false;
00790 return;
00791 }
00792
00793 if (m_mapping.isEmpty())
00794 return;
00795
00796 m_rowCount = 0;
00797
00798 synchronousMappingRefresh();
00799
00800 for (int i = 0; i < m_proxyIndexes.size(); ++i) {
00801 q->changePersistentIndex(m_proxyIndexes.at(i), q->mapFromSource(m_layoutChangePersistentIndexes.at(i)));
00802 }
00803
00804 m_layoutChangePersistentIndexes.clear();
00805 m_proxyIndexes.clear();
00806
00807 q->layoutChanged();
00808 }
00809
00810 void KDescendantsProxyModelPrivate::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
00811 {
00812 Q_Q(KDescendantsProxyModel);
00813
00814 const int topRow = topLeft.row();
00815 const int bottomRow = bottomRight.row();
00816
00817 for(int i = topRow; i <= bottomRow; ++i)
00818 {
00819 const QModelIndex sourceTopLeft = q->sourceModel()->index(i, topLeft.column(), topLeft.parent());
00820 const QModelIndex proxyTopLeft = q->mapFromSource(sourceTopLeft);
00821
00822
00823 const QModelIndex sourceBottomRight = q->sourceModel()->index(i, bottomRight.column(), bottomRight.parent());
00824 const QModelIndex proxyBottomRight = q->mapFromSource(sourceBottomRight);
00825 emit q->dataChanged(proxyTopLeft, proxyBottomRight);
00826 }
00827 }
00828
00829 void KDescendantsProxyModelPrivate::sourceModelDestroyed()
00830 {
00831 Q_Q(KDescendantsProxyModel);
00832 resetInternalData();
00833 q->endResetModel();
00834 }
00835
00836 QMimeData* KDescendantsProxyModel::mimeData( const QModelIndexList & indexes ) const
00837 {
00838 if (!sourceModel())
00839 return QAbstractProxyModel::mimeData(indexes);
00840 Q_ASSERT(sourceModel());
00841 QModelIndexList sourceIndexes;
00842 foreach(const QModelIndex& index, indexes)
00843 sourceIndexes << mapToSource(index);
00844 return sourceModel()->mimeData(sourceIndexes);
00845 }
00846
00847 QStringList KDescendantsProxyModel::mimeTypes() const
00848 {
00849 if (!sourceModel())
00850 return QAbstractProxyModel::mimeTypes();
00851 Q_ASSERT(sourceModel());
00852 return sourceModel()->mimeTypes();
00853 }
00854
00855 Qt::DropActions KDescendantsProxyModel::supportedDropActions() const
00856 {
00857 if (!sourceModel())
00858 return QAbstractProxyModel::supportedDropActions();
00859 return sourceModel()->supportedDropActions();
00860 }
00861
00862 #include "moc_kdescendantsproxymodel_p.cpp"