File indexing completed on 2024-05-19 04:56:07
0001 /** 0002 * \file proxyitemselectionmodel.cpp 0003 * Item selection model to share selection with proxy model. 0004 * 0005 * This is a stripped down version of KLinkItemSelectionModel from kitemmodels. 0006 * Copyright (C) 2010 Klarälvdalens Datakonsult AB, 0007 * a KDAB Group company, info@kdab.net, 0008 * author Stephen Kelly <stephen@kdab.com> 0009 * Copyright (c) 2016 Ableton AG <info@ableton.com> 0010 * Author Stephen Kelly <stephen.kelly@ableton.com> 0011 * Copyright (C) 2018 Urs Fleisch 0012 * 0013 * This library is free software; you can redistribute it and/or modify it 0014 * under the terms of the GNU Library General Public License as published by 0015 * the Free Software Foundation; either version 2 of the License, or (at your 0016 * option) any later version. 0017 0018 * This library is distributed in the hope that it will be useful, but WITHOUT 0019 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0020 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0021 * License for more details. 0022 0023 * You should have received a copy of the GNU Library General Public License 0024 * along with this library; see the file COPYING.LIB. If not, write to the 0025 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0026 * 02110-1301, USA. 0027 */ 0028 0029 #include "proxyitemselectionmodel.h" 0030 #include <QAbstractProxyModel> 0031 0032 ProxyItemSelectionModel::ProxyItemSelectionModel( 0033 QAbstractItemModel* proxyModel, QItemSelectionModel* sourceSelectionModel, 0034 QObject* parent) 0035 : QItemSelectionModel(proxyModel, parent), 0036 m_proxySelectionModel(sourceSelectionModel), m_ignoreCurrentChanged(false) 0037 { 0038 connect(this, &QItemSelectionModel::currentChanged, 0039 this, &ProxyItemSelectionModel::onCurrentChanged); 0040 #if QT_VERSION >= 0x050500 0041 connect(this, &QItemSelectionModel::modelChanged, 0042 this, &ProxyItemSelectionModel::onModelChanged); 0043 #endif 0044 0045 connect(m_proxySelectionModel, 0046 &QItemSelectionModel::selectionChanged, 0047 this, &ProxyItemSelectionModel::onSelectionChanged); 0048 connect(m_proxySelectionModel, 0049 &QItemSelectionModel::currentChanged, 0050 this, &ProxyItemSelectionModel::onProxyCurrentChanged); 0051 #if QT_VERSION >= 0x050500 0052 connect(m_proxySelectionModel, &QItemSelectionModel::modelChanged, 0053 this, &ProxyItemSelectionModel::onModelChanged); 0054 #endif 0055 onModelChanged(); 0056 } 0057 0058 void ProxyItemSelectionModel::select( 0059 const QModelIndex& index, QItemSelectionModel::SelectionFlags command) 0060 { 0061 if (m_ignoreCurrentChanged) { 0062 return; 0063 } 0064 QItemSelection itemSelection(index, index); 0065 QItemSelectionModel::select(itemSelection, command); 0066 if (index.isValid()) { 0067 m_proxySelectionModel->select( 0068 mapSelectionFromProxy(itemSelection), command); 0069 } else { 0070 m_proxySelectionModel->clearSelection(); 0071 } 0072 } 0073 0074 void ProxyItemSelectionModel::select( 0075 const QItemSelection& selection, 0076 QItemSelectionModel::SelectionFlags command) 0077 { 0078 m_ignoreCurrentChanged = true; 0079 QItemSelection itemSelection = selection; 0080 QItemSelectionModel::select(itemSelection, command); 0081 m_proxySelectionModel->select(mapSelectionFromProxy(itemSelection), command); 0082 m_ignoreCurrentChanged = false; 0083 } 0084 0085 void ProxyItemSelectionModel::onCurrentChanged(const QModelIndex& current) 0086 { 0087 const QItemSelection selection = 0088 mapSelectionFromProxy(QItemSelection(current, current)); 0089 if (selection.isEmpty()) { 0090 return; 0091 } 0092 m_proxySelectionModel->setCurrentIndex(selection.indexes().first(), 0093 QItemSelectionModel::NoUpdate); 0094 } 0095 0096 void ProxyItemSelectionModel::onSelectionChanged(const QItemSelection& selected, 0097 const QItemSelection& deselected) 0098 { 0099 QItemSelectionModel::select(mapSelectionFromModel(deselected), 0100 QItemSelectionModel::Deselect); 0101 QItemSelectionModel::select(mapSelectionFromModel(selected), 0102 QItemSelectionModel::Select); 0103 } 0104 0105 void ProxyItemSelectionModel::onProxyCurrentChanged(const QModelIndex& current) 0106 { 0107 const QItemSelection selection = 0108 mapSelectionFromModel(QItemSelection(current, current)); 0109 if (selection.isEmpty()) { 0110 return; 0111 } 0112 setCurrentIndex(selection.indexes().first(), QItemSelectionModel::NoUpdate); 0113 } 0114 0115 void ProxyItemSelectionModel::onModelChanged() 0116 { 0117 if (!model() || !m_proxySelectionModel || !m_proxySelectionModel->model()) { 0118 return; 0119 } 0120 QItemSelectionModel::select( 0121 mapSelectionFromModel(m_proxySelectionModel->selection()), 0122 QItemSelectionModel::ClearAndSelect); 0123 } 0124 0125 QItemSelection ProxyItemSelectionModel::mapSelectionFromProxy( 0126 const QItemSelection& selection) const 0127 { 0128 if (selection.isEmpty() || !model()) { 0129 return QItemSelection(); 0130 } 0131 0132 Q_ASSERT(qobject_cast<const QAbstractProxyModel*>(model())); 0133 return static_cast<const QAbstractProxyModel*>(model()) 0134 ->mapSelectionToSource(selection); 0135 } 0136 0137 QItemSelection ProxyItemSelectionModel::mapSelectionFromModel( 0138 const QItemSelection& selection) const 0139 { 0140 if (selection.isEmpty() || !model()) { 0141 return QItemSelection(); 0142 } 0143 0144 Q_ASSERT(qobject_cast<const QAbstractProxyModel*>(model())); 0145 return static_cast<const QAbstractProxyModel*>(model()) 0146 ->mapSelectionFromSource(selection); 0147 }