/* Copyright (C) 2010 Klarlvdalens Datakonsult AB, a KDAB Group company, info@kdab.net, author Tobias Koenig <tokoe@kdab.com> 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 <QtCore/QObject>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 <tokoe@kde.org> */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 <tokoe@kdab.com> 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 <akonadi/collectionstatistics.h>#include <akonadi/entitytreemodel.h>#include <QtCore/QAbstractItemModel>#include <QtCore/QTimer>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<Akonadi::Collection>(); 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"