diff --git a/akonadi/partfetcher.cpp b/akonadi/partfetcher.cpp index 3881c1c8b..62f9af93b 100755 --- a/akonadi/partfetcher.cpp +++ b/akonadi/partfetcher.cpp @@ -1,166 +1,174 @@ /* Copyright (c) 2009 Stephen Kelly 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 "partfetcher.h" #include "entitytreemodel.h" #include "session.h" #include "itemfetchjob.h" #include "itemfetchscope.h" using namespace Akonadi; namespace Akonadi { class PartFetcherPrivate { - PartFetcherPrivate( PartFetcher *partFetcher ) - : q_ptr( partFetcher ) + PartFetcherPrivate( PartFetcher *partFetcher, const QModelIndex &index, const QByteArray &partName ) + : m_persistentIndex( index ), m_partName( partName ), q_ptr( partFetcher ) { - } - void itemsFetched( const Akonadi::Item::List &list ); - void fetchJobDone( KJob *job ); + void fetchJobDone( KJob* ); void modelDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight ); QPersistentModelIndex m_persistentIndex; QByteArray m_partName; + Item m_item; Q_DECLARE_PUBLIC( PartFetcher ) PartFetcher *q_ptr; - }; } -void PartFetcherPrivate::itemsFetched( const Akonadi::Item::List &list ) +void PartFetcherPrivate::fetchJobDone( KJob *job ) { - Q_Q(PartFetcher); + Q_Q( PartFetcher ); + if ( job->error() ) { + q->setError( KJob::UserDefinedError ); + q->setErrorText( QLatin1String( "Unable to fetch item for index" ) ); + q->emitResult(); + return; + } + + ItemFetchJob *fetchJob = qobject_cast( job ); + + const Item::List list = fetchJob->items(); Q_ASSERT( list.size() == 1 ); // If m_persistentIndex comes from a selection proxy model, it could become // invalid if the user clicks around a lot. - if( !m_persistentIndex.isValid() ) - { - emit q->invalidated(); - q->reset(); + if ( !m_persistentIndex.isValid() ) { + q->setError( KJob::UserDefinedError ); + q->setErrorText( QLatin1String( "Index is no longer available" ) ); + q->emitResult(); return; } - QSet loadedParts = m_persistentIndex.data( EntityTreeModel::LoadedPartsRole ).value >(); + const QSet loadedParts = m_persistentIndex.data( EntityTreeModel::LoadedPartsRole ).value >(); Q_ASSERT( !loadedParts.contains( m_partName ) ); Item item = m_persistentIndex.data( EntityTreeModel::ItemRole ).value(); item.merge( list.at( 0 ) ); QAbstractItemModel *model = const_cast( m_persistentIndex.model() ); Q_ASSERT( model ); QVariant itemVariant = QVariant::fromValue( item ); model->setData( m_persistentIndex, itemVariant, EntityTreeModel::ItemRole ); - emit q->partFetched( m_persistentIndex, item, m_partName ); -} + m_item = item; -void PartFetcherPrivate::fetchJobDone( KJob *job ) -{ - Q_Q( PartFetcher ); - if ( job->error() ) - { - emit q->invalidated(); - } - q->reset(); + emit q->emitResult(); } -PartFetcher::PartFetcher( QObject *parent ) - : QObject( parent ), d_ptr( new PartFetcherPrivate( this ) ) +PartFetcher::PartFetcher( const QModelIndex &index, const QByteArray &partName, QObject *parent ) + : KJob( parent ), d_ptr( new PartFetcherPrivate( this, index, partName ) ) { - } -bool PartFetcher::fetchPart( const QModelIndex &idx, const QByteArray &partName ) +void PartFetcher::start() { Q_D( PartFetcher ); - Q_ASSERT( idx.isValid() ); - - if ( d->m_persistentIndex.isValid() || !d->m_partName.isEmpty() ) - // One PartFetcher can only handle one fetch operation at a time. - return false; + const QModelIndex index = d->m_persistentIndex; - QSet loadedParts = idx.data( EntityTreeModel::LoadedPartsRole ).value >(); + const QSet loadedParts = index.data( EntityTreeModel::LoadedPartsRole ).value >(); - if ( loadedParts.contains( partName ) ) - { - Item item = idx.data( EntityTreeModel::ItemRole ).value(); - emit partFetched( idx, item, partName ); - reset(); - return true; + if ( loadedParts.contains( d->m_partName ) ) { + d->m_item = d->m_persistentIndex.data( EntityTreeModel::ItemRole ).value(); + emitResult(); + return; } - QSet availableParts = idx.data( EntityTreeModel::AvailablePartsRole ).value >(); - - if ( !availableParts.contains( partName ) ) - { - return false; + const QSet availableParts = index.data( EntityTreeModel::AvailablePartsRole ).value >(); + if ( !availableParts.contains( d->m_partName ) ) { + setError( UserDefinedError ); + setErrorText( QString::fromLatin1( "Payload part '%1' is not available for this index" ) + .arg( QString::fromLatin1( d->m_partName ) ) ); + emitResult(); + return; } - Akonadi::Session *session = qobject_cast( qvariant_cast( idx.data( EntityTreeModel::SessionRole ) ) ); + Akonadi::Session *session = qobject_cast( qvariant_cast( index.data( EntityTreeModel::SessionRole ) ) ); - if (!session) - return false; - - Akonadi::Item item = idx.data( EntityTreeModel::ItemRole ).value(); + if ( !session ) { + setError( UserDefinedError ); + setErrorText( QLatin1String( "No session available for this index" ) ); + emitResult(); + return; + } - if (!item.isValid()) - return false; + const Akonadi::Item item = index.data( EntityTreeModel::ItemRole ).value(); - d->m_persistentIndex = idx; - d->m_partName = partName; + if ( !item.isValid() ) { + setError( UserDefinedError ); + setErrorText( QLatin1String( "No item available for this index" ) ); + emitResult(); + return; + } ItemFetchScope scope; - scope.fetchPayloadPart( partName ); + scope.fetchPayloadPart( d->m_partName ); ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob( item, session ); itemFetchJob->setFetchScope( scope ); - connect( itemFetchJob, SIGNAL( itemsReceived( const Akonadi::Item::List& ) ), - this, SLOT( itemsFetched( const Akonadi::Item::List& ) ) ); connect( itemFetchJob, SIGNAL( result( KJob* ) ), this, SLOT( fetchJobDone( KJob* ) ) ); +} - return true; +QModelIndex PartFetcher::index() const +{ + Q_D( const PartFetcher ); + return d->m_persistentIndex; } -void PartFetcher::reset() +QByteArray PartFetcher::partName() const { - Q_D( PartFetcher ); + Q_D( const PartFetcher ); + + return d->m_partName; +} + +Item PartFetcher::item() const +{ + Q_D( const PartFetcher ); - d->m_persistentIndex = QModelIndex(); - d->m_partName.clear(); + return d->m_item; } #include "partfetcher.moc" diff --git a/akonadi/partfetcher.h b/akonadi/partfetcher.h index e8ac4921c..ca896ae81 100755 --- a/akonadi/partfetcher.h +++ b/akonadi/partfetcher.h @@ -1,91 +1,118 @@ /* Copyright (c) 2009 Stephen Kelly 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_PART_FETCHER_H #define AKONADI_PART_FETCHER_H -#include +#include #include "akonadi_export.h" class QModelIndex; namespace Akonadi { class Item; class PartFetcherPrivate; /** * @short Convenience class for getting payload parts from an Akonadi Model. * * This class can be used to retrieve individual payload parts from an EntityTreeModel, - * and fetch them asyncronously from the Akonadi storage if necessary. + * and fetch them asynchronously from the Akonadi storage if necessary. * * The requested part is emitted though the partFetched signal. * + * Example: + * + * @code + * + * const QModelIndex index = view->selectionModel()->currentIndex(); + * + * PartFetcher *fetcher = new PartFetcher( index, Akonadi::MessagePart::Envelope ); + * connect( fetcher, SIGNAL( result( KJob* ) ), SLOT( fetchResult( KJob* ) ) ); + * fetcher->start(); + * + * ... + * + * MyClass::fetchResult( KJob *job ) + * { + * if ( job->error() ) { + * qDebug() << job->errorText(); + * return; + * } + * + * PartFetcher *fetcher = qobject_cast( job ); + * + * const Item item = fetcher->item(); + * // do something with the item + * } + * + * @endcode + * * @author Stephen Kelly * @since 4.4 */ -class AKONADI_EXPORT PartFetcher : public QObject +class AKONADI_EXPORT PartFetcher : public KJob { Q_OBJECT public: /** * Creates a new part fetcher. * + * @param index The index of the item to fetch the part from. + * @param partName The name of the payload part to fetch. * @param parent The parent object. */ - explicit PartFetcher( QObject *parent = 0 ); + explicit PartFetcher( const QModelIndex &index, const QByteArray &partName, QObject *parent = 0 ); /** - * Fetches the part called @p partName from the item at @p index + * Starts the fetch operation. */ - bool fetchPart( const QModelIndex &index, const QByteArray &partName ); + virtual void start(); /** - * @internal - * - * TODO: move to private class. + * Returns the index of the item the part was fetched from. */ - void reset(); + QModelIndex index() const; - Q_SIGNALS: /** - * This signal is emitted whenever the requested part has been fetched successfully. - * - * @param index The index of the item the part was fetched from. - * @param item The item the part was fetched from. - * @param partName The name of the part that has been fetched. + * Returns the name of the part that has been fetched. + */ + QByteArray partName() const; + + /** + * Returns the item that contains the fetched payload part. */ - void partFetched( const QModelIndex &index, const Item &item, const QByteArray &partName ); - void invalidated(); + Item item() const; private: + //@cond PRIVATE Q_DECLARE_PRIVATE( Akonadi::PartFetcher ) PartFetcherPrivate *d_ptr; - Q_PRIVATE_SLOT( d_func(), void itemsFetched( const Akonadi::Item::List & ) ) Q_PRIVATE_SLOT( d_func(), void fetchJobDone( KJob *job ) ) + //@endcond }; } #endif