kdganttforwardingproxymodel.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.  All rights reserved.
00003 **
00004 ** This file is part of the KD Chart library.
00005 **
00006 ** Licensees holding valid commercial KD Chart licenses may use this file in
00007 ** accordance with the KD Chart Commercial License Agreement provided with
00008 ** the Software.
00009 **
00010 **
00011 ** This file may be distributed and/or modified under the terms of the
00012 ** GNU General Public License version 2 and version 3 as published by the
00013 ** Free Software Foundation and appearing in the file LICENSE.GPL included.
00014 **
00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 **
00018 ** Contact info@kdab.com if any conditions of this licensing are not
00019 ** clear to you.
00020 **
00021 **********************************************************************/
00022 
00023 #include "kdganttforwardingproxymodel.h"
00024 
00025 #include <cassert>
00026 #include <QStringList>
00027 
00028 using namespace KDGantt;
00029 
00030 typedef QAbstractProxyModel BASE;
00031 
00035 ForwardingProxyModel::ForwardingProxyModel( QObject* parent )
00036     : BASE( parent )
00037 {
00038 }
00039 
00040 ForwardingProxyModel::~ForwardingProxyModel()
00041 {
00042 }
00043 
00045 QModelIndex ForwardingProxyModel::mapFromSource ( const QModelIndex & sourceIndex ) const
00046 {
00047     if ( !sourceIndex.isValid() )
00048         return QModelIndex();
00049     assert( sourceIndex.model() == sourceModel() );
00050 
00051     // Create an index that preserves the internal pointer from the source;
00052     // this way KDDataConverterProxyModel preserves the structure of the source model
00053     return createIndex( sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer() );
00054 }
00055 
00056 namespace {
00057     // Think this is ugly? Well, it's not from me, it comes from QProxyModel
00058     struct KDPrivateModelIndex {
00059         int r, c;
00060         void *p;
00061         const QAbstractItemModel *m;
00062     };
00063 }
00064 
00066 QModelIndex ForwardingProxyModel::mapToSource ( const QModelIndex & proxyIndex ) const
00067 {
00068     if ( !proxyIndex.isValid() )
00069         return QModelIndex();
00070     assert( proxyIndex.model() == this );
00071     // So here we need to create a source index which holds that internal pointer.
00072     // No way to pass it to sourceModel()->index... so we have to do the ugly way:
00073     QModelIndex sourceIndex;
00074     KDPrivateModelIndex* hack = reinterpret_cast<KDPrivateModelIndex*>(&sourceIndex);
00075     hack->r = proxyIndex.row();
00076     hack->c = proxyIndex.column();
00077     hack->p = proxyIndex.internalPointer();
00078     hack->m = sourceModel();
00079     assert( sourceIndex.isValid() );
00080     return sourceIndex;
00081 }
00082 
00087 void ForwardingProxyModel::setSourceModel( QAbstractItemModel* model )
00088 {
00089     if ( sourceModel() ) sourceModel()->disconnect( this );
00090     BASE::setSourceModel( model );
00091 
00092     if(!model) return;
00093 
00094     connect( model, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) );
00095     connect( model, SIGNAL(modelReset()), this, SLOT(sourceModelReset()) );
00096     connect( model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(sourceLayoutAboutToBeChanged()) );
00097     connect( model, SIGNAL(layoutChanged()), this, SLOT(sourceLayoutChanged()) );
00098 
00099     connect( model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)),
00100              this, SLOT(sourceDataChanged(const QModelIndex&,const QModelIndex&)) );
00101 
00102 
00103     connect( model,  SIGNAL(columnsAboutToBeInserted(const QModelIndex&, int,int)),
00104              this, SLOT(sourceColumnsAboutToBeInserted(const QModelIndex&,int,int)) );
00105     connect( model,  SIGNAL(columnsInserted(const QModelIndex&, int,int)),
00106              this, SLOT(sourceColumnsInserted(const QModelIndex&,int,int)) );
00107     connect( model,  SIGNAL(columnsAboutToBeRemoved(const QModelIndex&, int,int)),
00108              this, SLOT(sourceColumnsAboutToBeRemoved(const QModelIndex&,int,int)) );
00109     connect( model,  SIGNAL(columnsRemoved(const QModelIndex&, int,int)),
00110              this, SLOT(sourceColumnsRemoved(const QModelIndex&,int,int)) );
00111 
00112     connect( model,  SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int,int)),
00113              this, SLOT(sourceRowsAboutToBeInserted(const QModelIndex&,int,int)) );
00114     connect( model,  SIGNAL(rowsInserted(const QModelIndex&, int,int)),
00115              this, SLOT(sourceRowsInserted(const QModelIndex&,int,int)) );
00116     connect( model,  SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int,int)),
00117              this, SLOT(sourceRowsAboutToBeRemoved(const QModelIndex&,int,int)) );
00118     connect( model,  SIGNAL(rowsRemoved(const QModelIndex&, int,int)),
00119              this, SLOT(sourceRowsRemoved(const QModelIndex&,int,int)) );
00120 }
00121 
00125 void ForwardingProxyModel::sourceModelAboutToBeReset()
00126 {
00127     // The matching signal is emitted be reset()
00128 }
00129 
00133 void ForwardingProxyModel::sourceModelReset()
00134 {
00135   //qDebug() << "ForwardingProxyModel::sourceModelReset()";
00136     reset();
00137 }
00138 
00143 void ForwardingProxyModel::sourceLayoutAboutToBeChanged()
00144 {
00145   //qDebug() << "ForwardingProxyModel::sourceLayoutAboutToBeChanged()";
00146     emit layoutAboutToBeChanged();
00147 }
00148 
00152 void ForwardingProxyModel::sourceLayoutChanged()
00153 {
00154   //qDebug() << "ForwardingProxyModel::sourceLayoutChanged()";
00155     reset();
00156 }
00157 
00161 void ForwardingProxyModel::sourceDataChanged( const QModelIndex& from, const QModelIndex& to )
00162 {
00163   //qDebug() << "ForwardingProxyModel::sourceDataChanged("<<from<<to<<")";
00164     emit dataChanged( mapFromSource( from ), mapFromSource( to ) );
00165 }
00166 
00170 void ForwardingProxyModel::sourceColumnsAboutToBeInserted( const QModelIndex& parentIdx,
00171                                                                     int start,
00172                                                                     int end )
00173 {
00174     beginInsertColumns( mapFromSource( parentIdx ), start, end );
00175 }
00176 
00180 void ForwardingProxyModel::sourceColumnsInserted( const QModelIndex& parentIdx, int start, int end )
00181 {
00182     Q_UNUSED( parentIdx );
00183     Q_UNUSED( start );
00184     Q_UNUSED( end );
00185     endInsertColumns();
00186 }
00187 
00191 void ForwardingProxyModel::sourceColumnsAboutToBeRemoved( const QModelIndex& parentIdx,
00192                                                                     int start,
00193                                                                     int end )
00194 {
00195     beginRemoveColumns( mapFromSource( parentIdx ), start, end );
00196 }
00197 
00201 void ForwardingProxyModel::sourceColumnsRemoved( const QModelIndex& parentIdx, int start, int end )
00202 {
00203     Q_UNUSED( parentIdx );
00204     Q_UNUSED( start );
00205     Q_UNUSED( end );
00206     endRemoveColumns();
00207 }
00208 
00212 void ForwardingProxyModel::sourceRowsAboutToBeInserted( const QModelIndex & parentIdx, int start, int end )
00213 {
00214     beginInsertRows( mapFromSource( parentIdx ), start, end );
00215 }
00216 
00220 void ForwardingProxyModel::sourceRowsInserted( const QModelIndex& parentIdx, int start, int end )
00221 {
00222     Q_UNUSED( parentIdx );
00223     Q_UNUSED( start );
00224     Q_UNUSED( end );
00225     endInsertRows();
00226 }
00227 
00231 void ForwardingProxyModel::sourceRowsAboutToBeRemoved( const QModelIndex & parentIdx, int start, int end )
00232 {
00233     beginRemoveRows( mapFromSource( parentIdx ), start, end );
00234 }
00235 
00239 void ForwardingProxyModel::sourceRowsRemoved( const QModelIndex& parentIdx, int start, int end )
00240 {
00241     Q_UNUSED( parentIdx );
00242     Q_UNUSED( start );
00243     Q_UNUSED( end );
00244     endRemoveRows();
00245 }
00246 
00248 int ForwardingProxyModel::rowCount( const QModelIndex& idx ) const
00249 {
00250     return sourceModel()->rowCount( mapToSource( idx ) );
00251 }
00252 
00254 int ForwardingProxyModel::columnCount( const QModelIndex& idx ) const
00255 {
00256     return sourceModel()->columnCount( mapToSource( idx ) );
00257 }
00258 
00260 QModelIndex ForwardingProxyModel::index( int row, int column, const QModelIndex& parent ) const
00261 {
00262     return mapFromSource( sourceModel()->index( row, column, mapToSource( parent ) ) );
00263 }
00264 
00266 QModelIndex ForwardingProxyModel::parent( const QModelIndex& idx ) const
00267 {
00268     return mapFromSource( sourceModel()->parent( mapToSource( idx ) ) );
00269 }
00270 
00272 bool ForwardingProxyModel::setData( const QModelIndex& index, const QVariant& value, int role )
00273 {
00274   //qDebug() << "ForwardingProxyModel::setData( " << index<<value<< role<<")";
00275     return sourceModel()->setData( mapToSource( index ), value, role );
00276 }
00277 
00278 QMimeData *ForwardingProxyModel::mimeData(const QModelIndexList &indexes) const
00279 {
00280     QModelIndexList source_indexes;
00281     for (int i = 0; i < indexes.count(); ++i)
00282         source_indexes << mapToSource(indexes.at(i));
00283     return sourceModel()->mimeData(source_indexes);
00284 }
00285 
00286 bool ForwardingProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
00287 {
00288     if ((row == -1) && (column == -1))
00289         return sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent));
00290     int source_destination_row = -1;
00291     int source_destination_column = -1;
00292     QModelIndex source_parent;
00293     if (row == rowCount(parent)) {
00294         source_parent = mapToSource(parent);
00295         source_destination_row = sourceModel()->rowCount(source_parent);
00296     } else {
00297         QModelIndex proxy_index = index(row, column, parent);
00298         QModelIndex source_index = mapToSource(proxy_index);
00299         source_destination_row = source_index.row();
00300         source_destination_column = source_index.column();
00301         source_parent = source_index.parent();
00302     }
00303     return sourceModel()->dropMimeData(data, action, source_destination_row, source_destination_column, source_parent);
00304 }
00305 
00306 QStringList ForwardingProxyModel::mimeTypes() const
00307 {
00308     return sourceModel()->mimeTypes();
00309 }
00310 
00311 Qt::DropActions ForwardingProxyModel::supportedDropActions() const
00312 {
00313     return sourceModel()->supportedDropActions();
00314 }
00315         
00316 #include "moc_kdganttforwardingproxymodel.cpp"
00317