00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "leafextensionproxymodel_p.h"
00024
00025 #include <QtCore/QSet>
00026
00027 using namespace Akonadi;
00028
00029 class LeafExtensionProxyModel::Private
00030 {
00031 public:
00032 Private( LeafExtensionProxyModel *qq )
00033 : q( qq ), mUniqueKeyCounter( 0 )
00034 {
00035 }
00036
00037 void sourceRowsInserted( const QModelIndex&, int, int );
00038 void sourceRowsRemoved( const QModelIndex&, int, int );
00039
00040 LeafExtensionProxyModel *q;
00041 QMap<qint64, QModelIndex> mParentIndexes;
00042 QSet<QModelIndex> mOwnIndexes;
00043 qint64 mUniqueKeyCounter;
00044 };
00045
00046 void LeafExtensionProxyModel::Private::sourceRowsInserted( const QModelIndex &parentIndex, int start, int end )
00047 {
00048
00049 QMutableMapIterator<qint64, QModelIndex> it( mParentIndexes );
00050 while ( it.hasNext() ) {
00051 it.next();
00052 if ( it.value().parent() == parentIndex ) {
00053 if ( it.value().row() >= start ) {
00054 const QModelIndex newIndex = q->QSortFilterProxyModel::index( it.value().row() + (end-start) + 1, it.value().column(), parentIndex );
00055 it.setValue( newIndex );
00056 }
00057 }
00058 }
00059 }
00060
00061 void LeafExtensionProxyModel::Private::sourceRowsRemoved( const QModelIndex &parentIndex, int start, int end )
00062 {
00063
00064 QMutableMapIterator<qint64, QModelIndex> it( mParentIndexes );
00065 while ( it.hasNext() ) {
00066 it.next();
00067 if ( it.value().parent() == parentIndex ) {
00068 if ( it.value().row() >= start && it.value().row() <= end ) {
00069 it.remove();
00070 } else if ( it.value().row() > end ) {
00071 const QModelIndex newIndex = q->index( it.value().row() - (end-start) - 1, it.value().column(), parentIndex );
00072 it.setValue( newIndex );
00073 }
00074 }
00075 }
00076 }
00077
00078 LeafExtensionProxyModel::LeafExtensionProxyModel( QObject *parent )
00079 : QSortFilterProxyModel( parent ), d( new Private( this ) )
00080 {
00081 }
00082
00083 LeafExtensionProxyModel::~LeafExtensionProxyModel()
00084 {
00085 delete d;
00086 }
00087
00088 QModelIndex LeafExtensionProxyModel::index( int row, int column, const QModelIndex &parent ) const
00089 {
00090 if ( row < 0 || column < 0 )
00091 return QModelIndex();
00092
00093 if ( parent.isValid() ) {
00094 const QModelIndex sourceParent = mapToSource( parent );
00095 const QModelIndex sourceIndex = sourceModel()->index( row, column, sourceParent );
00096 if ( !sourceIndex.isValid() ) {
00097
00098 qint64 key = -1;
00099 QMapIterator<qint64, QModelIndex> it( d->mParentIndexes );
00100 while ( it.hasNext() ) {
00101 it.next();
00102 if ( it.value() == parent ) {
00103 key = it.key();
00104 break;
00105 }
00106 }
00107
00108 if ( key == -1 ) {
00109 key = ++(d->mUniqueKeyCounter);
00110 d->mParentIndexes.insert( key, parent );
00111 }
00112
00113 const QModelIndex index = createIndex( row, column, static_cast<quint32>( key ) );
00114 d->mOwnIndexes.insert( index );
00115
00116 return index;
00117 }
00118 }
00119
00120 return QSortFilterProxyModel::index( row, column, parent );
00121 }
00122
00123 QModelIndex LeafExtensionProxyModel::parent( const QModelIndex &index ) const
00124 {
00125 if ( d->mOwnIndexes.contains( index ) )
00126 return d->mParentIndexes.value( index.internalId() );
00127
00128 return QSortFilterProxyModel::parent( index );
00129 }
00130
00131 int LeafExtensionProxyModel::rowCount( const QModelIndex &index ) const
00132 {
00133 if ( d->mOwnIndexes.contains( index ) )
00134 return 0;
00135
00136 const QModelIndex sourceIndex = mapToSource( index );
00137 if ( sourceModel()->rowCount( sourceIndex ) == 0 )
00138 return leafRowCount( index );
00139
00140 return QSortFilterProxyModel::rowCount( index );
00141 }
00142
00143 int LeafExtensionProxyModel::columnCount( const QModelIndex &index ) const
00144 {
00145 if ( d->mOwnIndexes.contains( index ) )
00146 return 1;
00147
00148 return QSortFilterProxyModel::columnCount( index );
00149 }
00150
00151 QVariant LeafExtensionProxyModel::data( const QModelIndex &index, int role ) const
00152 {
00153 if ( d->mOwnIndexes.contains( index ) )
00154 return leafData( index.parent(), index.row(), index.column(), role );
00155
00156 return QSortFilterProxyModel::data( index, role );
00157 }
00158
00159 Qt::ItemFlags LeafExtensionProxyModel::flags( const QModelIndex &index ) const
00160 {
00161 if ( d->mOwnIndexes.contains( index ) )
00162 return Qt::ItemIsEnabled|Qt::ItemIsSelectable;
00163
00164 return QSortFilterProxyModel::flags( index );
00165 }
00166
00167 bool LeafExtensionProxyModel::setData( const QModelIndex &index, const QVariant &data, int role )
00168 {
00169 if ( d->mOwnIndexes.contains( index ) )
00170 return false;
00171
00172 return QSortFilterProxyModel::setData( index, data, role );
00173 }
00174
00175 bool LeafExtensionProxyModel::hasChildren( const QModelIndex &parent ) const
00176 {
00177 if ( d->mOwnIndexes.contains( parent ) )
00178 return false;
00179
00180 const QModelIndex sourceParent = mapToSource( parent );
00181 if ( sourceModel() && sourceModel()->rowCount( sourceParent ) == 0 )
00182 return (leafRowCount( parent ) != 0);
00183
00184 return QSortFilterProxyModel::hasChildren( parent );
00185 }
00186
00187 QModelIndex LeafExtensionProxyModel::buddy( const QModelIndex &index ) const
00188 {
00189 if ( d->mOwnIndexes.contains( index ) )
00190 return index;
00191
00192 return QSortFilterProxyModel::buddy( index );
00193 }
00194
00195 void LeafExtensionProxyModel::fetchMore( const QModelIndex &index )
00196 {
00197 if ( d->mOwnIndexes.contains( index ) )
00198 return;
00199
00200 QSortFilterProxyModel::fetchMore( index );
00201 }
00202
00203 void LeafExtensionProxyModel::setSourceModel( QAbstractItemModel *_sourceModel )
00204 {
00205 if ( _sourceModel == sourceModel() )
00206 return;
00207
00208 beginResetModel();
00209
00210 disconnect( this, SIGNAL( rowsInserted( const QModelIndex&, int, int ) ),
00211 this, SLOT( sourceRowsInserted( const QModelIndex&, int, int ) ) );
00212 disconnect( this, SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ),
00213 this, SLOT( sourceRowsRemoved( const QModelIndex&, int, int ) ) );
00214
00215 QSortFilterProxyModel::setSourceModel( _sourceModel );
00216
00217 connect( this, SIGNAL( rowsInserted( const QModelIndex&, int, int ) ),
00218 this, SLOT( sourceRowsInserted( const QModelIndex&, int, int ) ) );
00219 connect( this, SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ),
00220 this, SLOT( sourceRowsRemoved( const QModelIndex&, int, int ) ) );
00221
00222 endResetModel();
00223 }
00224
00225 #include "leafextensionproxymodel_p.moc"