#include <QItemSelectionModel>
#include <QAbstractItemModel>
#include <QAbstractProxyModel>
+#include <QLinkedList>
#include <QDebug>
MappedSelectionModel::MappedSelectionModel(QAbstractItemModel *model)
: QItemSelectionModel(model)
{
- _isProxyModel = (bool)proxyModel();
- connect(this, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
- this, SLOT(_currentChanged(QModelIndex, QModelIndex)));
- connect(this, SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
- this, SLOT(_selectionChanged(QItemSelection, QItemSelection)));
-}
-
-MappedSelectionModel::~MappedSelectionModel() {
-}
-
-const QAbstractItemModel *MappedSelectionModel::baseModel() const {
- if(isProxyModel())
- return proxyModel()->sourceModel();
- else
- return model();
-}
-
-const QAbstractProxyModel *MappedSelectionModel::proxyModel() const {
- return qobject_cast<const QAbstractProxyModel *>(model());
}
QModelIndex MappedSelectionModel::mapFromSource(const QModelIndex &sourceIndex) {
- if(isProxyModel())
- return proxyModel()->mapFromSource(sourceIndex);
- else
- return sourceIndex;
-}
+ QModelIndex proxyIndex = sourceIndex;
+ QLinkedList<const QAbstractProxyModel *> proxies;
+ const QAbstractItemModel *baseModel = model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ proxies.push_back(proxyModel);
+ baseModel = proxyModel->sourceModel();
+ if(baseModel == sourceIndex.model())
+ break;
+ }
-QItemSelection MappedSelectionModel::mapFromSource(const QItemSelection &sourceSelection) {
- if(isProxyModel()) {
- QItemSelection mappedSelection;
- foreach(QItemSelectionRange range, sourceSelection) {
- QModelIndex topleft = mapFromSource(range.topLeft());
- QModelIndex bottomright = mapFromSource(range.bottomRight());
- if(topleft.isValid() && bottomright.isValid())
- mappedSelection << QItemSelectionRange(topleft, bottomright);
- else
- Q_ASSERT(!topleft.isValid() && !bottomright.isValid());
- }
- return mappedSelection;
- } else {
- return sourceSelection;
+ while(!proxies.isEmpty()) {
+ proxyModel = proxies.takeLast();
+ proxyIndex = proxyModel->mapFromSource(proxyIndex);
}
-}
-
-QModelIndex MappedSelectionModel::mapToSource(const QModelIndex &proxyIndex) {
- if(isProxyModel())
- return proxyModel()->mapToSource(proxyIndex);
- else
- return proxyIndex;
+ return proxyIndex;
}
-QItemSelection MappedSelectionModel::mapToSource(const QItemSelection &proxySelection) {
- if(isProxyModel()) {
- QItemSelection mappedSelection;
- foreach(QItemSelectionRange range, proxySelection) {
- mappedSelection << QItemSelectionRange(mapToSource(range.topLeft()), mapToSource(range.bottomRight()));
- }
- return mappedSelection;
- } else {
- return proxySelection;
+QItemSelection MappedSelectionModel::mapSelectionFromSource(const QItemSelection &sourceSelection) {
+ if(sourceSelection.isEmpty())
+ return sourceSelection;
+
+ QItemSelection proxySelection = sourceSelection;
+ QLinkedList<const QAbstractProxyModel *> proxies;
+ const QAbstractItemModel *baseModel = model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ proxies.push_back(proxyModel);
+ baseModel = proxyModel->sourceModel();
+ if(baseModel == sourceSelection.first().model())
+ break;
}
-}
-
-void MappedSelectionModel::mappedSelect(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) {
- QModelIndex mappedIndex = mapFromSource(index);
- if(!isSelected(mappedIndex))
- select(mappedIndex, command);
-}
-void MappedSelectionModel::mappedSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) {
- QItemSelection mappedSelection = mapFromSource(selection);
- if(mappedSelection != QItemSelectionModel::selection())
- select(mappedSelection, command);
+ while(!proxies.isEmpty()) {
+ proxyModel = proxies.takeLast();
+ proxySelection = proxyModel->mapSelectionFromSource(proxySelection);
+ }
+ return proxySelection;
}
-
+
void MappedSelectionModel::mappedSetCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) {
- QModelIndex mappedIndex = mapFromSource(index);
- if(mappedIndex == currentIndex())
- return;
-
- if(mappedIndex.isValid())
- setCurrentIndex(mappedIndex, command);
- else if(hasSelection())
- setCurrentIndex(currentIndex(), QItemSelectionModel::Clear);
+ setCurrentIndex(mapFromSource(index), command);
}
-
-void MappedSelectionModel::_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
- Q_UNUSED(previous)
- emit mappedCurrentChanged(mapToSource(current));
+void MappedSelectionModel::mappedSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) {
+ select(mapSelectionFromSource(selection), command);
}
-void MappedSelectionModel::_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
- Q_UNUSED(selected)
- Q_UNUSED(deselected)
- emit mappedSelectionChanged(mapToSource(QItemSelectionModel::selection()));
-}
-