File indexing completed on 2024-05-19 15:09:23
0001 /* 0002 SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "columnproxymodel.h" 0008 0009 ColumnProxyModel::ColumnProxyModel(QObject *parent) 0010 : QAbstractListModel(parent) 0011 , m_column(0) 0012 , m_sourceModel(nullptr) 0013 { 0014 } 0015 0016 void ColumnProxyModel::setSourceModel(QAbstractItemModel *sourceModel) 0017 { 0018 if (sourceModel == m_sourceModel) { 0019 return; 0020 } 0021 0022 beginResetModel(); 0023 if (m_sourceModel) { 0024 disconnect(m_sourceModel, &QObject::destroyed, this, &ColumnProxyModel::sourceDestroyed); 0025 0026 disconnect(m_sourceModel, &QAbstractItemModel::dataChanged, this, &ColumnProxyModel::considerDataChanged); 0027 disconnect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeInserted, this, &ColumnProxyModel::considerRowsAboutToBeInserted); 0028 disconnect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeMoved, this, &ColumnProxyModel::considerRowsAboutToBeMoved); 0029 disconnect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ColumnProxyModel::considerRowsAboutToBeRemoved); 0030 disconnect(m_sourceModel, &QAbstractItemModel::rowsInserted, this, &ColumnProxyModel::considerRowsInserted); 0031 disconnect(m_sourceModel, &QAbstractItemModel::rowsMoved, this, &ColumnProxyModel::considerRowsMoved); 0032 disconnect(m_sourceModel, &QAbstractItemModel::rowsRemoved, this, &ColumnProxyModel::considerRowsRemoved); 0033 0034 // TODO: QAbstractItemModel::modelAboutToBeReset and QAbstractItemModel::modelReset are private signals 0035 // we can connect to them, but can't emit them 0036 disconnect(m_sourceModel, SIGNAL(modelAboutToBeReset()), this, SIGNAL(modelAboutToBeReset())); 0037 disconnect(m_sourceModel, SIGNAL(modelReset()), this, SIGNAL(modelReset())); 0038 0039 disconnect(m_sourceModel, &QAbstractItemModel::headerDataChanged, this, &QAbstractItemModel::headerDataChanged); 0040 disconnect(m_sourceModel, &QAbstractItemModel::layoutAboutToBeChanged, this, &QAbstractItemModel::layoutAboutToBeChanged); 0041 disconnect(m_sourceModel, &QAbstractItemModel::layoutChanged, this, &QAbstractItemModel::layoutChanged); 0042 } 0043 m_sourceModel = sourceModel; 0044 if (m_sourceModel) { 0045 connect(m_sourceModel, &QObject::destroyed, this, &ColumnProxyModel::sourceDestroyed); 0046 0047 connect(m_sourceModel, &QAbstractItemModel::dataChanged, this, &ColumnProxyModel::considerDataChanged); 0048 connect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeInserted, this, &ColumnProxyModel::considerRowsAboutToBeInserted); 0049 connect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeMoved, this, &ColumnProxyModel::considerRowsAboutToBeMoved); 0050 connect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ColumnProxyModel::considerRowsAboutToBeRemoved); 0051 connect(m_sourceModel, &QAbstractItemModel::rowsInserted, this, &ColumnProxyModel::considerRowsInserted); 0052 connect(m_sourceModel, &QAbstractItemModel::rowsMoved, this, &ColumnProxyModel::considerRowsMoved); 0053 connect(m_sourceModel, &QAbstractItemModel::rowsRemoved, this, &ColumnProxyModel::considerRowsRemoved); 0054 0055 // TODO: QAbstractItemModel::modelAboutToBeReset and QAbstractItemModel::modelReset are private signals 0056 // we can connect to them, but can't emit them 0057 connect(m_sourceModel, SIGNAL(modelAboutToBeReset()), this, SIGNAL(modelAboutToBeReset())); 0058 connect(m_sourceModel, SIGNAL(modelReset()), this, SIGNAL(modelReset())); 0059 0060 connect(m_sourceModel, &QAbstractItemModel::headerDataChanged, this, &QAbstractItemModel::headerDataChanged); 0061 connect(m_sourceModel, &QAbstractItemModel::layoutAboutToBeChanged, this, &QAbstractItemModel::layoutAboutToBeChanged); 0062 connect(m_sourceModel, &QAbstractItemModel::layoutChanged, this, &QAbstractItemModel::layoutChanged); 0063 } 0064 endResetModel(); 0065 } 0066 0067 void ColumnProxyModel::setColumn(int col) 0068 { 0069 beginResetModel(); 0070 m_column = col; 0071 endResetModel(); 0072 } 0073 0074 int ColumnProxyModel::column() const 0075 { 0076 return m_column; 0077 } 0078 0079 QModelIndex ColumnProxyModel::rootIndex() const 0080 { 0081 return m_index; 0082 } 0083 0084 void ColumnProxyModel::setRootIndex(const QModelIndex &index) 0085 { 0086 if (index == m_index) { 0087 return; 0088 } 0089 0090 if (index.isValid()) { 0091 setSourceModel(const_cast<QAbstractItemModel *>(index.model())); 0092 } 0093 beginResetModel(); 0094 m_index = index; 0095 endResetModel(); 0096 0097 Q_EMIT rootIndexChanged(); 0098 } 0099 0100 QModelIndex ColumnProxyModel::indexFromModel(QAbstractItemModel *model, int row, int column, const QModelIndex &parent) 0101 { 0102 return model ? model->index(row, column, parent) : QModelIndex(); 0103 } 0104 0105 QVariant ColumnProxyModel::data(const QModelIndex &index, int role) const 0106 { 0107 return m_sourceModel ? m_sourceModel->data(sourceIndex(index), role) : QVariant(); 0108 } 0109 0110 QVariant ColumnProxyModel::headerData(int section, Qt::Orientation orientation, int role) const 0111 { 0112 return m_sourceModel ? m_sourceModel->headerData(section, orientation, role) : QVariant(); 0113 } 0114 0115 QModelIndex ColumnProxyModel::sourceIndex(const QModelIndex &proxyIndex) const 0116 { 0117 return m_sourceModel ? m_sourceModel->index(proxyIndex.row(), m_column, m_index) : QModelIndex(); 0118 } 0119 0120 int ColumnProxyModel::rowCount(const QModelIndex &parent) const 0121 { 0122 return (!m_sourceModel || parent.isValid()) ? 0 : m_sourceModel->rowCount(m_index); 0123 } 0124 0125 QModelIndex ColumnProxyModel::proxyIndex(const QModelIndex &sourceIndex) const 0126 { 0127 if (sourceIndex.parent() == m_index) { 0128 return index(sourceIndex.row(), sourceIndex.column(), QModelIndex()); 0129 } 0130 0131 return QModelIndex(); 0132 } 0133 0134 void ColumnProxyModel::sourceDestroyed(QObject *source) 0135 { 0136 Q_ASSERT(source == m_sourceModel); 0137 0138 beginResetModel(); 0139 m_sourceModel = nullptr; 0140 endResetModel(); 0141 } 0142 0143 QModelIndex ColumnProxyModel::indexAt(int row, const QModelIndex &parent) const 0144 { 0145 return m_sourceModel ? m_sourceModel->index(row, m_column, parent) : QModelIndex(); 0146 } 0147 0148 ///////////////// 0149 0150 void ColumnProxyModel::considerDataChanged(const QModelIndex &idxA, const QModelIndex &idxB) 0151 { 0152 if (idxA.parent() == m_index && idxB.parent() == m_index) { 0153 Q_EMIT dataChanged(proxyIndex(idxA), proxyIndex(idxB)); 0154 } 0155 } 0156 0157 void ColumnProxyModel::considerRowsAboutToBeInserted(const QModelIndex &parent, int rA, int rB) 0158 { 0159 if (parent == m_index) { 0160 beginInsertRows(QModelIndex(), rA, rB); 0161 } 0162 } 0163 0164 void ColumnProxyModel::considerRowsAboutToBeMoved(const QModelIndex &sourceParent, int rA, int rB, const QModelIndex &destParent, int rD) 0165 { 0166 if (sourceParent == m_index && destParent == m_index) { 0167 beginMoveRows(QModelIndex(), rA, rB, QModelIndex(), rD); 0168 } else if (sourceParent == m_index) { 0169 beginRemoveRows(sourceParent, rA, rB); 0170 } else if (destParent == m_index) { 0171 beginInsertRows(destParent, rD, rD + (rB - rA)); 0172 } 0173 } 0174 0175 void ColumnProxyModel::considerRowsAboutToBeRemoved(const QModelIndex &parent, int rA, int rB) 0176 { 0177 if (parent == m_index) { 0178 beginRemoveRows(QModelIndex(), rA, rB); 0179 } 0180 } 0181 0182 void ColumnProxyModel::considerRowsInserted(const QModelIndex &parent, int, int) 0183 { 0184 if (parent == m_index) { 0185 endInsertRows(); 0186 } 0187 } 0188 0189 void ColumnProxyModel::considerRowsMoved(const QModelIndex &sourceParent, int, int, const QModelIndex &destParent, int) 0190 { 0191 if (sourceParent == m_index && destParent == m_index) { 0192 endMoveRows(); 0193 } else if (sourceParent == m_index) { 0194 endRemoveRows(); 0195 } else if (destParent == m_index) { 0196 endInsertRows(); 0197 } 0198 } 0199 0200 void ColumnProxyModel::considerRowsRemoved(const QModelIndex &parent, int, int) 0201 { 0202 if (parent == m_index) { 0203 endInsertRows(); 0204 } 0205 } 0206 0207 QHash<int, QByteArray> ColumnProxyModel::roleNames() const 0208 { 0209 return m_sourceModel ? m_sourceModel->roleNames() : QHash<int, QByteArray>(); 0210 } 0211 0212 bool ColumnProxyModel::setData(const QModelIndex &index, const QVariant &value, int role) 0213 { 0214 return m_sourceModel && m_sourceModel->setData(sourceIndex(index), value, role); 0215 } 0216 0217 #include "moc_columnproxymodel.cpp"