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 if ( !q->error() )
00065 emit q->itemsReceived( mPendingItems );
00066 mPendingItems.clear();
00067 }
00068 }
00069
00070 void startFetchJob();
00071 void selectDone( KJob * job );
00072
00073 Q_DECLARE_PUBLIC( ItemFetchJob )
00074
00075 Collection mCollection;
00076 Item::List mRequestedItems;
00077 Item::List mResultItems;
00078 ItemFetchScope mFetchScope;
00079 Item::List mPendingItems;
00080 QTimer* mEmitTimer;
00081 };
00082
00083 void ItemFetchJobPrivate::startFetchJob()
00084 {
00085 Q_Q( ItemFetchJob );
00086 QByteArray command = newTag();
00087 if ( mRequestedItems.isEmpty() ) {
00088 command += " " AKONADI_CMD_ITEMFETCH " 1:*";
00089 } else {
00090 try {
00091 command += ProtocolHelper::entitySetToByteArray( mRequestedItems, AKONADI_CMD_ITEMFETCH );
00092 } catch ( const Exception &e ) {
00093 q->setError( Job::Unknown );
00094 q->setErrorText( QString::fromUtf8( e.what() ) );
00095 q->emitResult();
00096 return;
00097 }
00098 }
00099
00100 command += ProtocolHelper::itemFetchScopeToByteArray( mFetchScope );
00101
00102 writeData( command );
00103 }
00104
00105 void ItemFetchJobPrivate::selectDone( KJob * job )
00106 {
00107 if ( !job->error() )
00108
00109 startFetchJob();
00110 }
00111
00112 ItemFetchJob::ItemFetchJob( const Collection &collection, QObject * parent )
00113 : Job( new ItemFetchJobPrivate( this ), parent )
00114 {
00115 Q_D( ItemFetchJob );
00116
00117 d->init();
00118 d->mCollection = collection;
00119 }
00120
00121 ItemFetchJob::ItemFetchJob( const Item & item, QObject * parent)
00122 : Job( new ItemFetchJobPrivate( this ), parent )
00123 {
00124 Q_D( ItemFetchJob );
00125
00126 d->init();
00127 d->mRequestedItems.append( item );
00128 }
00129
00130 ItemFetchJob::ItemFetchJob(const Akonadi::Item::List& items, QObject* parent)
00131 : Job( new ItemFetchJobPrivate( this ), parent )
00132 {
00133 Q_D( ItemFetchJob );
00134
00135 d->init();
00136 d->mRequestedItems = items;
00137 }
00138
00139
00140 ItemFetchJob::~ItemFetchJob()
00141 {
00142 }
00143
00144 void ItemFetchJob::doStart()
00145 {
00146 Q_D( ItemFetchJob );
00147
00148 if ( d->mRequestedItems.isEmpty() ) {
00149 if ( d->mCollection == Collection::root() ) {
00150 setErrorText( i18n( "Cannot list root collection." ) );
00151 setError( Unknown );
00152 emitResult();
00153 }
00154 CollectionSelectJob *job = new CollectionSelectJob( d->mCollection, this );
00155 connect( job, SIGNAL( result( KJob* ) ), SLOT( selectDone( KJob* ) ) );
00156 addSubjob( job );
00157 } else
00158 d->startFetchJob();
00159 }
00160
00161 void ItemFetchJob::doHandleResponse( const QByteArray & tag, const QByteArray & data )
00162 {
00163 Q_D( ItemFetchJob );
00164
00165 if ( tag == "*" ) {
00166 int begin = data.indexOf( "FETCH" );
00167 if ( begin >= 0 ) {
00168
00169
00170 QList<QByteArray> fetchResponse;
00171 ImapParser::parseParenthesizedList( data, fetchResponse, begin + 6 );
00172
00173 Item item;
00174 ProtocolHelper::parseItemFetchResult( fetchResponse, item );
00175 if ( !item.isValid() )
00176 return;
00177
00178 d->mResultItems.append( item );
00179 d->mPendingItems.append( item );
00180 if ( !d->mEmitTimer->isActive() )
00181 d->mEmitTimer->start();
00182 return;
00183 }
00184 }
00185 kDebug() << "Unhandled response: " << tag << data;
00186 }
00187
00188 Item::List ItemFetchJob::items() const
00189 {
00190 Q_D( const ItemFetchJob );
00191
00192 return d->mResultItems;
00193 }
00194
00195 void ItemFetchJob::setFetchScope( ItemFetchScope &fetchScope )
00196 {
00197 Q_D( ItemFetchJob );
00198
00199 d->mFetchScope = fetchScope;
00200 }
00201
00202 void ItemFetchJob::setFetchScope( const ItemFetchScope &fetchScope )
00203 {
00204 Q_D( ItemFetchJob );
00205
00206 d->mFetchScope = fetchScope;
00207 }
00208
00209 ItemFetchScope &ItemFetchJob::fetchScope()
00210 {
00211 Q_D( ItemFetchJob );
00212
00213 return d->mFetchScope;
00214 }
00215
00216 void ItemFetchJob::setCollection(const Akonadi::Collection& collection)
00217 {
00218 Q_D( ItemFetchJob );
00219
00220 d->mCollection = collection;
00221 }
00222
00223
00224 #include "itemfetchjob.moc"