/**************************************************************************** ** Copyright (C) 2001-2006 Klarälvdalens Datakonsult AB. All rights reserved. ** ** This file is part of the KD Gantt library. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid commercial KD Gantt licenses may use this file in ** accordance with the KD Gantt Commercial License Agreement provided with ** the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.kdab.net/kdgantt for ** information about KD Gantt Commercial License Agreements. ** ** Contact info@kdab.net if any conditions of this ** licensing are not clear to you. ** **********************************************************************/ #include "kdganttforwardingproxymodel.h" #include using namespace KDGantt; typedef QAbstractProxyModel BASE; /*! Constructor. Creates a new ForwardingProxyModel with * parent \a parent */ ForwardingProxyModel::ForwardingProxyModel( QObject* parent ) : BASE( parent ) { } ForwardingProxyModel::~ForwardingProxyModel() { } /*! Converts indexes in the source model to indexes in the proxy model */ QModelIndex ForwardingProxyModel::mapFromSource ( const QModelIndex & sourceIndex ) const { if ( !sourceIndex.isValid() ) return QModelIndex(); assert( sourceIndex.model() == sourceModel() ); // Create an index that preserves the internal pointer from the source; // this way KDDataConverterProxyModel preserves the structure of the source model return createIndex( sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer() ); } namespace { // Think this is ugly? Well, it's not from me, it comes from QProxyModel struct KDPrivateModelIndex { int r, c; void *p; const QAbstractItemModel *m; }; } /*! Converts indexes in the proxy model to indexes in the source model */ QModelIndex ForwardingProxyModel::mapToSource ( const QModelIndex & proxyIndex ) const { if ( !proxyIndex.isValid() ) return QModelIndex(); assert( proxyIndex.model() == this ); // So here we need to create a source index which holds that internal pointer. // No way to pass it to sourceModel()->index... so we have to do the ugly way: QModelIndex sourceIndex; KDPrivateModelIndex* hack = reinterpret_cast(&sourceIndex); hack->r = proxyIndex.row(); hack->c = proxyIndex.column(); hack->p = proxyIndex.internalPointer(); hack->m = sourceModel(); assert( sourceIndex.isValid() ); return sourceIndex; } /*! Sets the model to be used as the source model for this proxy. * The proxy does not take ownership of the model. * \see QAbstractProxyModel::setSourceModel */ void ForwardingProxyModel::setSourceModel( QAbstractItemModel* model ) { if ( sourceModel() ) sourceModel()->disconnect( this ); BASE::setSourceModel( model ); if(!model) return; connect( model, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) ); connect( model, SIGNAL(modelReset()), this, SLOT(sourceModelReset()) ); connect( model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(sourceLayoutAboutToBeChanged()) ); connect( model, SIGNAL(layoutChanged()), this, SLOT(sourceLayoutChanged()) ); connect( model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(sourceDataChanged(QModelIndex,QModelIndex)) ); connect( model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(sourceColumnsAboutToBeInserted(QModelIndex,int,int)) ); connect( model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(sourceColumnsInserted(QModelIndex,int,int)) ); connect( model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(sourceColumnsAboutToBeRemoved(QModelIndex,int,int)) ); connect( model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(sourceColumnsRemoved(QModelIndex,int,int)) ); connect( model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(sourceRowsAboutToBeInserted(QModelIndex,int,int)) ); connect( model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(sourceRowsInserted(QModelIndex,int,int)) ); connect( model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int)) ); connect( model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(sourceRowsRemoved(QModelIndex,int,int)) ); } /*! Called when the source model is about to be reset. * \sa QAbstractItemModel::modelAboutToBeReset() */ void ForwardingProxyModel::sourceModelAboutToBeReset() { // The matching signal is emitted be reset() } /*! Called when the source model is reset * \sa QAbstractItemModel::modelReset() */ void ForwardingProxyModel::sourceModelReset() { //qDebug() << "ForwardingProxyModel::sourceModelReset()"; reset(); } /*! Called just before the layout of the source model is changed. * \sa QAbstractItemModel::layoutAboutToBeChanged() */ void ForwardingProxyModel::sourceLayoutAboutToBeChanged() { //qDebug() << "ForwardingProxyModel::sourceLayoutAboutToBeChanged()"; emit layoutAboutToBeChanged(); } /*! Called when the layout of the source model has changed. * \sa QAbstractItemModel::layoutChanged() */ void ForwardingProxyModel::sourceLayoutChanged() { //qDebug() << "ForwardingProxyModel::sourceLayoutChanged()"; reset(); } /*! Called when the data in an existing item in the source model changes. * \sa QAbstractItemModel::dataChanged() */ void ForwardingProxyModel::sourceDataChanged( const QModelIndex& from, const QModelIndex& to ) { //qDebug() << "ForwardingProxyModel::sourceDataChanged("<rowCount( mapToSource( idx ) ); } /*! \see QAbstractItemModel::columnCount */ int ForwardingProxyModel::columnCount( const QModelIndex& idx ) const { return sourceModel()->columnCount( mapToSource( idx ) ); } /*! \see QAbstractItemModel::index */ QModelIndex ForwardingProxyModel::index( int row, int column, const QModelIndex& parent ) const { return mapFromSource( sourceModel()->index( row, column, mapToSource( parent ) ) ); } /*! \see QAbstractItemModel::parent */ QModelIndex ForwardingProxyModel::parent( const QModelIndex& idx ) const { return mapFromSource( sourceModel()->parent( mapToSource( idx ) ) ); } /*! \see QAbstractItemModel::setData */ bool ForwardingProxyModel::setData( const QModelIndex& index, const QVariant& value, int role ) { //qDebug() << "ForwardingProxyModel::setData( " << index<setData( mapToSource( index ), value, role ); }