/* Copyright (C) 2010 Klarlvdalens Datakonsult AB, a KDAB Group company, info@kdab.net, author Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef AKONADI_ENTITYFETCHWATCHER_H #define AKONADI_ENTITYFETCHWATCHER_H #include class QAbstractItemModel; class QModelIndex; namespace AkonadiFuture { /** * @short A class that encapsulates logic to wait for an entity to be completely loaded into a model. * * @author Tobias Koenig */ class EntityFetchWatcher : public QObject { Q_OBJECT public: /** * Creates a new entity fetch watcher. * * @param index The model index of the entity to wait for. * @param model The model to work on. * @param parent The parent object. */ EntityFetchWatcher( const QModelIndex &index, const QAbstractItemModel *model, QObject *parent = 0 ); /** * Destroys the entity fetch watcher. */ ~EntityFetchWatcher(); /** * Starts watching the collection. */ void start(); Q_SIGNALS: /** * This signal is emitted when the entity at the watched @p index has been loaded completely into * the model. */ void entityFetched( const QModelIndex &index ); private: //@cond PRIVATE class Private; Private* const d; Q_PRIVATE_SLOT( d, void dataChanged( const QModelIndex&, const QModelIndex& ) ) //@endcond }; } #endif /* Copyright (C) 2010 Klarlvdalens Datakonsult AB, a KDAB Group company, info@kdab.net, author Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "entityfetchwatcher.h" #include #include #include #include using namespace AkonadiFuture; class EntityFetchWatcher::Private { public: Private( EntityFetchWatcher *qq, const QModelIndex &index, const QAbstractItemModel *model ) : q( qq ), mIndex( index ), mModel( model ) { } void dataChanged( const QModelIndex &index, const QModelIndex& ) { if ( index != mIndex ) return; qDebug() << "dataChanged our index"; if ( mIndex.data( Akonadi::EntityTreeModel::FetchStateRole ).toInt() == Akonadi::EntityTreeModel::IdleState ) { qDebug() << "our index is idle"; q->disconnect( mModel, SIGNAL( dataChanged( const QModelIndex&, const QModelIndex& ) ), q, SLOT( dataChanged( const QModelIndex&, const QModelIndex& ) ) ); emit q->entityFetched( mIndex ); q->deleteLater(); } else { qDebug() << "our index is busy"; } } EntityFetchWatcher *q; QPersistentModelIndex mIndex; const QAbstractItemModel *mModel; }; EntityFetchWatcher::EntityFetchWatcher( const QModelIndex &index, const QAbstractItemModel *model, QObject *parent ) : QObject( parent ), d( new Private( this, index, model ) ) { Q_ASSERT( d->mIndex.model() == d->mModel ); // make sure we work on the right indexes/model qDebug("EntityFetchWatcher::EntityFetchWatcher(%p)", this); } EntityFetchWatcher::~EntityFetchWatcher() { qDebug("EntityFetchWatcher::~EntityFetchWatcher(%p)", this); delete d; } void EntityFetchWatcher::start() { const Akonadi::Collection collection = d->mIndex.data( Akonadi::EntityTreeModel::CollectionRole ).value(); Q_ASSERT( collection.isValid() ); if ( collection.statistics().count() == 0 ) { // no reason to wait, this collection does not contain any items emit entityFetched( d->mIndex ); deleteLater(); return; } // check if the loading has been finished already if ( d->mIndex.data( Akonadi::EntityTreeModel::FetchStateRole ).toInt() == Akonadi::EntityTreeModel::IdleState ) { emit entityFetched( d->mIndex ); deleteLater(); return; } // start our work connect( d->mModel, SIGNAL( dataChanged( const QModelIndex&, const QModelIndex& ) ), this, SLOT( dataChanged( const QModelIndex&, const QModelIndex& ) ) ); } #include "entityfetchwatcher.moc"