akonadi
itemfetchjob.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "itemfetchjob.h"
00021
00022 #include "attributefactory.h"
00023 #include "collection.h"
00024 #include "collectionselectjob_p.h"
00025 #include "imapparser_p.h"
00026 #include "itemfetchscope.h"
00027 #include "job_p.h"
00028 #include "protocol_p.h"
00029 #include "protocolhelper_p.h"
00030
00031 #include <kdebug.h>
00032 #include <KLocale>
00033
00034 #include <QtCore/QStringList>
00035 #include <QtCore/QTimer>
00036
00037 using namespace Akonadi;
00038
00039 class Akonadi::ItemFetchJobPrivate : public JobPrivate
00040 {
00041 public:
00042 ItemFetchJobPrivate( ItemFetchJob *parent )
00043 : JobPrivate( parent )
00044 {
00045 mCollection = Collection::root();
00046 }
00047
00048 void init()
00049 {
00050 Q_Q( ItemFetchJob );
00051 mEmitTimer = new QTimer( q );
00052 mEmitTimer->setSingleShot( true );
00053 mEmitTimer->setInterval( 100 );
00054 q->connect( mEmitTimer, SIGNAL(timeout()), q, SLOT(timeout()) );
00055 q->connect( q, SIGNAL(result(KJob*)), q, SLOT(timeout()) );
00056 }
00057
00058 void timeout()
00059 {
00060 Q_Q( ItemFetchJob );
00061
00062 mEmitTimer->stop();
00063 if ( !mPendingItems.isEmpty() ) {
00064 emit q->itemsReceived( mPendingItems );
00065 mPendingItems.clear();
00066 }
00067 }
00068
00069 void startFetchJob();
00070 void selectDone( KJob * job );
00071
00072 Q_DECLARE_PUBLIC( ItemFetchJob )
00073
00074 Collection mCollection;
00075 Item::List mRequestedItems;
00076 Item::List mResultItems;
00077 ItemFetchScope mFetchScope;
00078 Item::List mPendingItems;
00079 QTimer* mEmitTimer;
00080 };
00081
00082 void ItemFetchJobPrivate::startFetchJob()
00083 {
00084 Q_Q( ItemFetchJob );
00085 QByteArray command = newTag();
00086 if ( mRequestedItems.isEmpty() ) {
00087 command += " " AKONADI_CMD_ITEMFETCH " 1:*";
00088 } else {
00089 try {
00090 command += ProtocolHelper::entitySetToByteArray( mRequestedItems, AKONADI_CMD_ITEMFETCH );
00091 } catch ( const Exception &e ) {
00092 q->setError( Job::Unknown );
00093 q->setErrorText( QString::fromUtf8( e.what() ) );
00094 q->emitResult();
00095 return;
00096 }
00097 }
00098
00099 command += ProtocolHelper::itemFetchScopeToByteArray( mFetchScope );
00100
00101 writeData( command );
00102 }
00103
00104 void ItemFetchJobPrivate::selectDone( KJob * job )
00105 {
00106 if ( !job->error() )
00107
00108 startFetchJob();
00109 }
00110
00111 ItemFetchJob::ItemFetchJob( const Collection &collection, QObject * parent )
00112 : Job( new ItemFetchJobPrivate( this ), parent )
00113 {
00114 Q_D( ItemFetchJob );
00115
00116 d->init();
00117 d->mCollection = collection;
00118 }
00119
00120 ItemFetchJob::ItemFetchJob( const Item & item, QObject * parent)
00121 : Job( new ItemFetchJobPrivate( this ), parent )
00122 {
00123 Q_D( ItemFetchJob );
00124
00125 d->init();
00126 d->mRequestedItems.append( item );
00127 }
00128
00129 ItemFetchJob::ItemFetchJob(const Akonadi::Item::List& items, QObject* parent)
00130 : Job( new ItemFetchJobPrivate( this ), parent )
00131 {
00132 Q_D( ItemFetchJob );
00133
00134 d->init();
00135 d->mRequestedItems = items;
00136 }
00137
00138
00139 ItemFetchJob::~ItemFetchJob()
00140 {
00141 }
00142
00143 void ItemFetchJob::doStart()
00144 {
00145 Q_D( ItemFetchJob );
00146
00147 if ( d->mRequestedItems.isEmpty() ) {
00148 if ( d->mCollection == Collection::root() ) {
00149 setErrorText( i18n("Cannot list root collection.") );
00150 setError( Unknown );
00151 emitResult();
00152 }
00153 CollectionSelectJob *job = new CollectionSelectJob( d->mCollection, this );
00154 connect( job, SIGNAL(result(KJob*)), SLOT(selectDone(KJob*)) );
00155 addSubjob( job );
00156 } else
00157 d->startFetchJob();
00158 }
00159
00160 void ItemFetchJob::doHandleResponse( const QByteArray & tag, const QByteArray & data )
00161 {
00162 Q_D( ItemFetchJob );
00163
00164 if ( tag == "*" ) {
00165 int begin = data.indexOf( "FETCH" );
00166 if ( begin >= 0 ) {
00167
00168
00169 QList<QByteArray> fetchResponse;
00170 ImapParser::parseParenthesizedList( data, fetchResponse, begin + 6 );
00171
00172 Item item;
00173 ProtocolHelper::parseItemFetchResult( fetchResponse, item );
00174 if ( !item.isValid() )
00175 return;
00176
00177 d->mResultItems.append( item );
00178 d->mPendingItems.append( item );
00179 if ( !d->mEmitTimer->isActive() )
00180 d->mEmitTimer->start();
00181 return;
00182 }
00183 }
00184 kDebug() << "Unhandled response: " << tag << data;
00185 }
00186
00187 Item::List ItemFetchJob::items() const
00188 {
00189 Q_D( const ItemFetchJob );
00190
00191 return d->mResultItems;
00192 }
00193
00194 void ItemFetchJob::setFetchScope( ItemFetchScope &fetchScope )
00195 {
00196 Q_D( ItemFetchJob );
00197
00198 d->mFetchScope = fetchScope;
00199 }
00200
00201 void ItemFetchJob::setFetchScope( const ItemFetchScope &fetchScope )
00202 {
00203 Q_D( ItemFetchJob );
00204
00205 d->mFetchScope = fetchScope;
00206 }
00207
00208 ItemFetchScope &ItemFetchJob::fetchScope()
00209 {
00210 Q_D( ItemFetchJob );
00211
00212 return d->mFetchScope;
00213 }
00214
00215 void ItemFetchJob::setCollection(const Akonadi::Collection& collection)
00216 {
00217 Q_D( ItemFetchJob );
00218
00219 d->mCollection = collection;
00220 }
00221
00222
00223 #include "itemfetchjob.moc"