File indexing completed on 2024-05-12 04:20:41
0001 /* 0002 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 0003 * 0004 * This file is part of the KGantt library. 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "kganttforwardingproxymodel.h" 0010 0011 #include <cassert> 0012 #include <QStringList> 0013 0014 using namespace KGantt; 0015 0016 typedef QAbstractProxyModel BASE; 0017 0018 0019 ForwardingProxyModel::ForwardingProxyModel( QObject* parent ) 0020 : BASE( parent ) 0021 { 0022 } 0023 0024 ForwardingProxyModel::~ForwardingProxyModel() 0025 { 0026 } 0027 0028 0029 QModelIndex ForwardingProxyModel::mapFromSource( const QModelIndex & sourceIndex ) const 0030 { 0031 if ( !sourceIndex.isValid() ) 0032 return QModelIndex(); 0033 assert( sourceIndex.model() == sourceModel() ); 0034 0035 // Create an index that preserves the internal pointer from the source; 0036 // this way KDDataConverterProxyModel preserves the structure of the source model 0037 return createIndex( sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer() ); 0038 } 0039 #ifdef __GNUC__ 0040 #if __GNUC__ > 3 0041 #define ATTRIBUTE __attribute__((__may_alias__)) 0042 #endif 0043 #else 0044 #define ATTRIBUTE 0045 #endif 0046 namespace { 0047 // Think this is ugly? Well, it's not from me, it comes from QProxyModel 0048 struct ATTRIBUTE KDPrivateModelIndex { 0049 int r, c; 0050 void *p; 0051 const QAbstractItemModel *m; 0052 }; 0053 } 0054 0055 0056 QModelIndex ForwardingProxyModel::mapToSource( const QModelIndex & proxyIndex ) const 0057 { 0058 if ( !proxyIndex.isValid() ) 0059 return QModelIndex(); 0060 assert( proxyIndex.model() == this ); 0061 // So here we need to create a source index which holds that internal pointer. 0062 // No way to pass it to sourceModel()->index... so we have to do the ugly way: 0063 QModelIndex sourceIndex; 0064 KDPrivateModelIndex* hack = reinterpret_cast<KDPrivateModelIndex*>(&sourceIndex); 0065 hack->r = proxyIndex.row(); 0066 hack->c = proxyIndex.column(); 0067 hack->p = proxyIndex.internalPointer(); 0068 hack->m = sourceModel(); 0069 assert( sourceIndex.isValid() ); 0070 return sourceIndex; 0071 } 0072 0073 0074 void ForwardingProxyModel::setSourceModel( QAbstractItemModel* model ) 0075 { 0076 if ( sourceModel() ) sourceModel()->disconnect( this ); 0077 BASE::setSourceModel( model ); 0078 0079 if (!model) return; 0080 0081 connect( model, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) ); 0082 connect( model, SIGNAL(modelReset()), this, SLOT(sourceModelReset()) ); 0083 connect( model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(sourceLayoutAboutToBeChanged()) ); 0084 connect( model, SIGNAL(layoutChanged()), this, SLOT(sourceLayoutChanged()) ); 0085 0086 connect( model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0087 this, SLOT(sourceDataChanged(QModelIndex,QModelIndex)) ); 0088 0089 0090 connect( model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), 0091 this, SLOT(sourceColumnsAboutToBeInserted(QModelIndex,int,int)) ); 0092 connect( model, SIGNAL(columnsInserted(QModelIndex,int,int)), 0093 this, SLOT(sourceColumnsInserted(QModelIndex,int,int)) ); 0094 connect( model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), 0095 this, SLOT(sourceColumnsAboutToBeRemoved(QModelIndex,int,int)) ); 0096 connect( model, SIGNAL(columnsRemoved(QModelIndex,int,int)), 0097 this, SLOT(sourceColumnsRemoved(QModelIndex,int,int)) ); 0098 0099 connect( model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), 0100 this, SLOT(sourceRowsAboutToBeInserted(QModelIndex,int,int)) ); 0101 connect( model, SIGNAL(rowsInserted(QModelIndex,int,int)), 0102 this, SLOT(sourceRowsInserted(QModelIndex,int,int)) ); 0103 connect( model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), 0104 this, SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int)) ); 0105 connect( model, SIGNAL(rowsRemoved(QModelIndex,int,int)), 0106 this, SLOT(sourceRowsRemoved(QModelIndex,int,int)) ); 0107 } 0108 0109 0110 void ForwardingProxyModel::sourceModelAboutToBeReset() 0111 { 0112 // The matching signal is emitted be reset() 0113 } 0114 0115 0116 void ForwardingProxyModel::sourceModelReset() 0117 { 0118 //qDebug() << "ForwardingProxyModel::sourceModelReset()"; 0119 beginResetModel(); 0120 endResetModel(); 0121 } 0122 0123 0124 0125 void ForwardingProxyModel::sourceLayoutAboutToBeChanged() 0126 { 0127 //qDebug() << "ForwardingProxyModel::sourceLayoutAboutToBeChanged()"; 0128 Q_EMIT layoutAboutToBeChanged(); 0129 } 0130 0131 0132 void ForwardingProxyModel::sourceLayoutChanged() 0133 { 0134 //qDebug() << "ForwardingProxyModel::sourceLayoutChanged()"; 0135 beginResetModel(); 0136 endResetModel(); 0137 } 0138 0139 0140 void ForwardingProxyModel::sourceDataChanged( const QModelIndex& from, const QModelIndex& to ) 0141 { 0142 //qDebug() << "ForwardingProxyModel::sourceDataChanged("<<from<<to<<")"; 0143 Q_EMIT dataChanged( mapFromSource( from ), mapFromSource( to ) ); 0144 } 0145 0146 0147 void ForwardingProxyModel::sourceColumnsAboutToBeInserted( const QModelIndex& parentIdx, 0148 int start, 0149 int end ) 0150 { 0151 beginInsertColumns( mapFromSource( parentIdx ), start, end ); 0152 } 0153 0154 0155 void ForwardingProxyModel::sourceColumnsInserted( const QModelIndex& parentIdx, int start, int end ) 0156 { 0157 Q_UNUSED( parentIdx ); 0158 Q_UNUSED( start ); 0159 Q_UNUSED( end ); 0160 endInsertColumns(); 0161 } 0162 0163 0164 void ForwardingProxyModel::sourceColumnsAboutToBeRemoved( const QModelIndex& parentIdx, 0165 int start, 0166 int end ) 0167 { 0168 beginRemoveColumns( mapFromSource( parentIdx ), start, end ); 0169 } 0170 0171 0172 void ForwardingProxyModel::sourceColumnsRemoved( const QModelIndex& parentIdx, int start, int end ) 0173 { 0174 Q_UNUSED( parentIdx ); 0175 Q_UNUSED( start ); 0176 Q_UNUSED( end ); 0177 endRemoveColumns(); 0178 } 0179 0180 0181 void ForwardingProxyModel::sourceRowsAboutToBeInserted( const QModelIndex & parentIdx, int start, int end ) 0182 { 0183 beginInsertRows( mapFromSource( parentIdx ), start, end ); 0184 } 0185 0186 0187 void ForwardingProxyModel::sourceRowsInserted( const QModelIndex& parentIdx, int start, int end ) 0188 { 0189 Q_UNUSED( parentIdx ); 0190 Q_UNUSED( start ); 0191 Q_UNUSED( end ); 0192 endInsertRows(); 0193 } 0194 0195 0196 void ForwardingProxyModel::sourceRowsAboutToBeRemoved( const QModelIndex & parentIdx, int start, int end ) 0197 { 0198 beginRemoveRows( mapFromSource( parentIdx ), start, end ); 0199 } 0200 0201 0202 void ForwardingProxyModel::sourceRowsRemoved( const QModelIndex& parentIdx, int start, int end ) 0203 { 0204 Q_UNUSED( parentIdx ); 0205 Q_UNUSED( start ); 0206 Q_UNUSED( end ); 0207 endRemoveRows(); 0208 } 0209 0210 0211 int ForwardingProxyModel::rowCount( const QModelIndex& idx ) const 0212 { 0213 return sourceModel()->rowCount( mapToSource( idx ) ); 0214 } 0215 0216 0217 int ForwardingProxyModel::columnCount( const QModelIndex& idx ) const 0218 { 0219 return sourceModel()->columnCount( mapToSource( idx ) ); 0220 } 0221 0222 0223 QModelIndex ForwardingProxyModel::index( int row, int column, const QModelIndex& parent ) const 0224 { 0225 return mapFromSource( sourceModel()->index( row, column, mapToSource( parent ) ) ); 0226 } 0227 0228 0229 QModelIndex ForwardingProxyModel::parent( const QModelIndex& idx ) const 0230 { 0231 return mapFromSource( sourceModel()->parent( mapToSource( idx ) ) ); 0232 } 0233 0234 0235 bool ForwardingProxyModel::setData( const QModelIndex& index, const QVariant& value, int role ) 0236 { 0237 //qDebug() << "ForwardingProxyModel::setData( " << index<<value<< role<<")"; 0238 return sourceModel()->setData( mapToSource( index ), value, role ); 0239 } 0240 0241 QMimeData *ForwardingProxyModel::mimeData(const QModelIndexList &indexes) const 0242 { 0243 QModelIndexList source_indexes; 0244 for (int i = 0; i < indexes.count(); ++i) 0245 source_indexes << mapToSource(indexes.at(i)); 0246 return sourceModel()->mimeData(source_indexes); 0247 } 0248 0249 bool ForwardingProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) 0250 { 0251 if ((row == -1) && (column == -1)) 0252 return sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent)); 0253 int source_destination_row = -1; 0254 int source_destination_column = -1; 0255 QModelIndex source_parent; 0256 if (row == rowCount(parent)) { 0257 source_parent = mapToSource(parent); 0258 source_destination_row = sourceModel()->rowCount(source_parent); 0259 } else { 0260 QModelIndex proxy_index = index(row, column, parent); 0261 QModelIndex source_index = mapToSource(proxy_index); 0262 source_destination_row = source_index.row(); 0263 source_destination_column = source_index.column(); 0264 source_parent = source_index.parent(); 0265 } 0266 return sourceModel()->dropMimeData(data, action, source_destination_row, source_destination_column, source_parent); 0267 } 0268 0269 QStringList ForwardingProxyModel::mimeTypes() const 0270 { 0271 return sourceModel()->mimeTypes(); 0272 } 0273 0274 Qt::DropActions ForwardingProxyModel::supportedDropActions() const 0275 { 0276 return sourceModel()->supportedDropActions(); 0277 } 0278 0279 #include "moc_kganttforwardingproxymodel.cpp" 0280