File indexing completed on 2024-05-05 03:56:41
0001 /* 0002 SPDX-FileCopyrightText: 2010 Stephen Kelly <steveire@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "kcheckableproxymodel.h" 0008 0009 #include <QItemSelectionModel> 0010 0011 class KCheckableProxyModelPrivate 0012 { 0013 Q_DECLARE_PUBLIC(KCheckableProxyModel) 0014 KCheckableProxyModel *q_ptr; 0015 0016 KCheckableProxyModelPrivate(KCheckableProxyModel *checkableModel) 0017 : q_ptr(checkableModel) 0018 { 0019 } 0020 0021 QItemSelectionModel *m_itemSelectionModel = nullptr; 0022 0023 void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); 0024 }; 0025 0026 KCheckableProxyModel::KCheckableProxyModel(QObject *parent) 0027 : QIdentityProxyModel(parent) 0028 , d_ptr(new KCheckableProxyModelPrivate(this)) 0029 { 0030 } 0031 0032 KCheckableProxyModel::~KCheckableProxyModel() = default; 0033 0034 void KCheckableProxyModel::setSelectionModel(QItemSelectionModel *itemSelectionModel) 0035 { 0036 Q_D(KCheckableProxyModel); 0037 d->m_itemSelectionModel = itemSelectionModel; 0038 Q_ASSERT(sourceModel() ? d->m_itemSelectionModel->model() == sourceModel() : true); 0039 connect(itemSelectionModel, &QItemSelectionModel::selectionChanged, this, [d](const QItemSelection &selected, const QItemSelection &deselected) { 0040 d->selectionChanged(selected, deselected); 0041 }); 0042 } 0043 0044 QItemSelectionModel *KCheckableProxyModel::selectionModel() const 0045 { 0046 Q_D(const KCheckableProxyModel); 0047 return d->m_itemSelectionModel; 0048 } 0049 0050 Qt::ItemFlags KCheckableProxyModel::flags(const QModelIndex &index) const 0051 { 0052 if (!index.isValid() || index.column() != 0) { 0053 return QIdentityProxyModel::flags(index); 0054 } 0055 return QIdentityProxyModel::flags(index) | Qt::ItemIsUserCheckable; 0056 } 0057 0058 QVariant KCheckableProxyModel::data(const QModelIndex &index, int role) const 0059 { 0060 Q_D(const KCheckableProxyModel); 0061 0062 if (role == Qt::CheckStateRole) { 0063 if (index.column() != 0) { 0064 return QVariant(); 0065 } 0066 if (!d->m_itemSelectionModel) { 0067 return Qt::Unchecked; 0068 } 0069 0070 return d->m_itemSelectionModel->selection().contains(mapToSource(index)) ? Qt::Checked : Qt::Unchecked; 0071 } 0072 return QIdentityProxyModel::data(index, role); 0073 } 0074 0075 bool KCheckableProxyModel::setData(const QModelIndex &index, const QVariant &value, int role) 0076 { 0077 Q_D(KCheckableProxyModel); 0078 if (role == Qt::CheckStateRole) { 0079 if (index.column() != 0) { 0080 return false; 0081 } 0082 if (!d->m_itemSelectionModel) { 0083 return false; 0084 } 0085 0086 Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt()); 0087 const QModelIndex srcIndex = mapToSource(index); 0088 bool result = select(QItemSelection(srcIndex, srcIndex), state == Qt::Checked ? QItemSelectionModel::Select : QItemSelectionModel::Deselect); 0089 Q_EMIT dataChanged(index, index); 0090 return result; 0091 } 0092 return QIdentityProxyModel::setData(index, value, role); 0093 } 0094 0095 void KCheckableProxyModel::setSourceModel(QAbstractItemModel *sourceModel) 0096 { 0097 QIdentityProxyModel::setSourceModel(sourceModel); 0098 Q_ASSERT(d_ptr->m_itemSelectionModel ? d_ptr->m_itemSelectionModel->model() == sourceModel : true); 0099 } 0100 0101 void KCheckableProxyModelPrivate::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) 0102 { 0103 Q_Q(KCheckableProxyModel); 0104 const auto lstSelected = q->mapSelectionFromSource(selected); 0105 for (const QItemSelectionRange &range : lstSelected) { 0106 Q_EMIT q->dataChanged(range.topLeft(), range.bottomRight()); 0107 } 0108 const auto lstDeselected = q->mapSelectionFromSource(deselected); 0109 for (const QItemSelectionRange &range : lstDeselected) { 0110 Q_EMIT q->dataChanged(range.topLeft(), range.bottomRight()); 0111 } 0112 } 0113 0114 bool KCheckableProxyModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) 0115 { 0116 Q_D(KCheckableProxyModel); 0117 d->m_itemSelectionModel->select(selection, command); 0118 return true; 0119 } 0120 0121 QHash<int, QByteArray> KCheckableProxyModel::roleNames() const 0122 { 0123 auto roles = QIdentityProxyModel::roleNames(); 0124 roles[Qt::CheckStateRole] = QByteArrayLiteral("checkState"); 0125 return roles; 0126 } 0127 0128 #include "moc_kcheckableproxymodel.cpp"