+void SelectionModelSynchronizer::mappedCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
+ Q_UNUSED(previous);
+ QItemSelectionModel *selectionModel = qobject_cast<QItemSelectionModel *>(sender());
+ Q_ASSERT(selectionModel);
+ QModelIndex newSourceCurrent = mapToSource(current, selectionModel);
+ if(newSourceCurrent.isValid() && newSourceCurrent != currentIndex())
+ setCurrentIndex(newSourceCurrent);
+}
+
+void SelectionModelSynchronizer::mappedSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
+ Q_UNUSED(selected);
+ Q_UNUSED(deselected);
+ QItemSelectionModel *selectionModel = qobject_cast<QItemSelectionModel *>(sender());
+ Q_ASSERT(selectionModel);
+ QItemSelection newSourceSelection = mapSelectionToSource(selectionModel->selection(), selectionModel);
+ QItemSelection currentContainsSelection = newSourceSelection;
+ currentContainsSelection.merge(currentSelection(), QItemSelectionModel::Deselect);
+ if(!currentContainsSelection.isEmpty())
+ setCurrentSelection(newSourceSelection);
+}
+
+QModelIndex SelectionModelSynchronizer::mapToSource(const QModelIndex &index, QItemSelectionModel *selectionModel) {
+ Q_ASSERT(selectionModel);
+
+ QModelIndex sourceIndex = index;
+ const QAbstractItemModel *baseModel = selectionModel->model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ sourceIndex = proxyModel->mapToSource(sourceIndex);
+ baseModel = proxyModel->sourceModel();
+ if(baseModel == model())
+ break;
+ }
+ return sourceIndex;
+}
+
+QItemSelection SelectionModelSynchronizer::mapSelectionToSource(const QItemSelection &selection, QItemSelectionModel *selectionModel) {
+ Q_ASSERT(selectionModel);
+
+ QItemSelection sourceSelection = selection;
+ const QAbstractItemModel *baseModel = selectionModel->model();
+ const QAbstractProxyModel *proxyModel = 0;
+ while((proxyModel = qobject_cast<const QAbstractProxyModel *>(baseModel)) != 0) {
+ sourceSelection = proxyModel->mapSelectionToSource(sourceSelection);
+ baseModel = proxyModel->sourceModel();
+ if(baseModel == model())
+ break;
+ }
+ return sourceSelection;
+}
+
+void SelectionModelSynchronizer::setCurrentIndex(const QModelIndex &index) {
+ _selectionModel.setCurrentIndex(index, QItemSelectionModel::Current);
+}
+void SelectionModelSynchronizer::setCurrentSelection(const QItemSelection &selection) {
+ _selectionModel.select(selection, QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
+}
+
+void SelectionModelSynchronizer::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) {
+ Q_UNUSED(previous);
+ emit setCurrentIndex(current, QItemSelectionModel::Current);