akonadi
flatcollectionproxymodel.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "flatcollectionproxymodel_p.h"
00021
00022 #include <kdebug.h>
00023
00024 using namespace Akonadi;
00025
00029 class FlatCollectionProxyModel::Private
00030 {
00031 public:
00032 Private( FlatCollectionProxyModel* parent ) : q( parent ) {}
00033
00034
00035 static int totalCount( QAbstractItemModel *model, const QModelIndex &index )
00036 {
00037 Q_ASSERT( model );
00038 const int rows = model->rowCount( index );
00039 int count = rows;
00040 for ( int i = 0; i < rows; ++i ) {
00041 QModelIndex current = model->index( i, 0, index );
00042 if ( current.isValid() )
00043 count += totalCount( model, current );
00044 }
00045 return count;
00046 }
00047
00048
00049 static QModelIndex findSourceIndex( QAbstractItemModel *model, int _row, int col, const QModelIndex &parent = QModelIndex() )
00050 {
00051 int row = _row;
00052 Q_ASSERT( model );
00053 for ( int i = 0; i <= row; ++i ) {
00054 QModelIndex current = model->index( i, col, parent );
00055 if ( i == row )
00056 return current;
00057 const int childCount = totalCount( model, current );
00058 if ( childCount >= ( row - i ) )
00059 return findSourceIndex( model, row - i - 1, col, current );
00060 else
00061 row -= childCount;
00062 }
00063 Q_ASSERT( false );
00064 return QModelIndex();
00065 }
00066
00067 void sourceDataChanged( const QModelIndex &sourceTopLeft, const QModelIndex &sourceBottomRight )
00068 {
00069 if ( sourceTopLeft != sourceBottomRight ) {
00070 emit q->dataChanged( q->mapFromSource( sourceTopLeft ), q->mapFromSource( sourceBottomRight ) );
00071 } else {
00072 const QModelIndex proxyIndex = q->mapFromSource( sourceTopLeft );
00073 emit q->dataChanged( proxyIndex, proxyIndex );
00074 }
00075 }
00076
00077 FlatCollectionProxyModel *q;
00078 };
00079
00080 FlatCollectionProxyModel::FlatCollectionProxyModel(QObject * parent) :
00081 QAbstractProxyModel( parent ),
00082 d( new Private( this ) )
00083 {
00084 }
00085
00086 FlatCollectionProxyModel::~FlatCollectionProxyModel()
00087 {
00088 delete d;
00089 }
00090
00091 void FlatCollectionProxyModel::setSourceModel(QAbstractItemModel * sourceModel)
00092 {
00093 QAbstractProxyModel::setSourceModel( sourceModel );
00094 connect( sourceModel, SIGNAL(modelReset()), SIGNAL(modelReset()) );
00095 connect( sourceModel, SIGNAL(layoutChanged()), SIGNAL(layoutChanged()) );
00096 connect( sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
00097 SLOT(sourceDataChanged(QModelIndex,QModelIndex)) );
00098 }
00099
00100 int FlatCollectionProxyModel::rowCount(const QModelIndex & parent) const
00101 {
00102 if ( parent.isValid() )
00103 return 0;
00104 return d->totalCount( sourceModel(), mapToSource( parent ) );
00105 }
00106
00107 int FlatCollectionProxyModel::columnCount(const QModelIndex & parent) const
00108 {
00109 return sourceModel()->columnCount( mapToSource( parent ) );
00110 }
00111
00112 QModelIndex FlatCollectionProxyModel::index(int row, int column, const QModelIndex & parent) const
00113 {
00114 Q_UNUSED( parent );
00115 return createIndex( row, column );
00116 }
00117
00118 QModelIndex FlatCollectionProxyModel::parent(const QModelIndex & index) const
00119 {
00120 Q_UNUSED( index );
00121 return QModelIndex();
00122 }
00123
00124 QModelIndex FlatCollectionProxyModel::mapToSource(const QModelIndex & proxyIndex) const
00125 {
00126 if ( !proxyIndex.isValid() )
00127 return QModelIndex();
00128 return d->findSourceIndex( sourceModel(), proxyIndex.row(), proxyIndex.column() );
00129 }
00130
00131 QModelIndex FlatCollectionProxyModel::mapFromSource(const QModelIndex & sourceIndex) const
00132 {
00133 if ( !sourceIndex.isValid() )
00134 return QModelIndex();
00135 int row = 0;
00136 QModelIndex current = sourceIndex;
00137 while ( current.parent() != QModelIndex() ) {
00138 row += current.row() + 1;
00139 for ( int i = current.row() - 1; i >= 0; --i )
00140 row += d->totalCount( sourceModel(), sourceModel()->index( i, 0, current.parent() ) );
00141 current = current.parent();
00142 }
00143 row += current.row();
00144 for ( int i = current.row() - 1; i >= 0; --i )
00145 row += d->totalCount( sourceModel(), sourceModel()->index( i, 0 ) );
00146 return createIndex( row, sourceIndex.column() );
00147 }
00148
00149 QVariant FlatCollectionProxyModel::data(const QModelIndex & index, int role) const
00150 {
00151 if ( role == Qt::DisplayRole ) {
00152 QModelIndex sourceIndex = mapToSource( index );
00153 QString name = sourceIndex.data( role ).toString();
00154 sourceIndex = sourceIndex.parent();
00155 while ( sourceIndex.isValid() ) {
00156 name.prepend( sourceIndex.data( role ).toString() + QLatin1String( "/" ) );
00157 sourceIndex = sourceIndex.parent();
00158 }
00159 return name;
00160 }
00161 return QAbstractProxyModel::data( index, role );
00162 }
00163
00164 #include "flatcollectionproxymodel_p.moc"