akonadi
collectionfetchjob.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "collectionfetchjob.h"
00021
00022 #include "imapparser_p.h"
00023 #include "job_p.h"
00024 #include "protocol_p.h"
00025 #include "protocolhelper_p.h"
00026 #include "entity_p.h"
00027
00028 #include <kdebug.h>
00029
00030 #include <QtCore/QHash>
00031 #include <QtCore/QStringList>
00032 #include <QtCore/QTimer>
00033
00034 using namespace Akonadi;
00035
00036 class Akonadi::CollectionFetchJobPrivate : public JobPrivate
00037 {
00038 public:
00039 CollectionFetchJobPrivate( CollectionFetchJob *parent )
00040 : JobPrivate( parent ),
00041 mUnsubscribed( false ),
00042 mStatistics( false )
00043 {
00044 }
00045
00046 Q_DECLARE_PUBLIC( CollectionFetchJob )
00047
00048 CollectionFetchJob::Type mType;
00049 Collection mBase;
00050 Collection::List mBaseList;
00051 Collection::List mCollections;
00052 QString mResource;
00053 Collection::List mPendingCollections;
00054 QTimer *mEmitTimer;
00055 bool mUnsubscribed;
00056 bool mStatistics;
00057
00058 void timeout()
00059 {
00060 Q_Q( CollectionFetchJob );
00061
00062 mEmitTimer->stop();
00063 if ( !mPendingCollections.isEmpty() ) {
00064 emit q->collectionsReceived( mPendingCollections );
00065 mPendingCollections.clear();
00066 }
00067 }
00068 };
00069
00070 CollectionFetchJob::CollectionFetchJob( const Collection &collection, Type type, QObject *parent )
00071 : Job( new CollectionFetchJobPrivate( this ), parent )
00072 {
00073 Q_D( CollectionFetchJob );
00074
00075 d->mBase = collection;
00076 d->mType = type;
00077
00078 d->mEmitTimer = new QTimer( this );
00079 d->mEmitTimer->setSingleShot( true );
00080 d->mEmitTimer->setInterval( 100 );
00081 connect( d->mEmitTimer, SIGNAL(timeout()), this, SLOT(timeout()) );
00082 connect( this, SIGNAL(result(KJob*)), this, SLOT(timeout()) );
00083 }
00084
00085 CollectionFetchJob::CollectionFetchJob( const Collection::List & cols, QObject * parent )
00086 : Job( new CollectionFetchJobPrivate( this ), parent )
00087 {
00088 Q_D( CollectionFetchJob );
00089
00090 Q_ASSERT( !cols.isEmpty() );
00091 if ( cols.size() == 1 ) {
00092 d->mBase = cols.first();
00093 d->mType = CollectionFetchJob::Base;
00094 } else {
00095 d->mBaseList = cols;
00096 }
00097
00098 d->mEmitTimer = new QTimer( this );
00099 d->mEmitTimer->setSingleShot( true );
00100 d->mEmitTimer->setInterval( 100 );
00101 connect( d->mEmitTimer, SIGNAL(timeout()), this, SLOT(timeout()) );
00102 connect( this, SIGNAL(result(KJob*)), this, SLOT(timeout()) );
00103 }
00104
00105 CollectionFetchJob::~CollectionFetchJob()
00106 {
00107 }
00108
00109 Collection::List CollectionFetchJob::collections() const
00110 {
00111 Q_D( const CollectionFetchJob );
00112
00113 return d->mCollections;
00114 }
00115
00116 void CollectionFetchJob::doStart()
00117 {
00118 Q_D( CollectionFetchJob );
00119
00120 if ( !d->mBaseList.isEmpty() ) {
00121 foreach ( const Collection &col, d->mBaseList ) {
00122 new CollectionFetchJob( col, CollectionFetchJob::Base, this );
00123 }
00124 return;
00125 }
00126
00127 if ( !d->mBase.isValid() && d->mBase.remoteId().isEmpty() ) {
00128 setError( Unknown );
00129 setErrorText( QLatin1String( "Invalid collection given." ) );
00130 emitResult();
00131 return;
00132 }
00133
00134 QByteArray command = d->newTag();
00135 if ( !d->mBase.isValid() )
00136 command += " " AKONADI_CMD_RID;
00137 if ( d->mUnsubscribed )
00138 command += " X-AKLIST ";
00139 else
00140 command += " X-AKLSUB ";
00141 if ( d->mBase.isValid() )
00142 command += QByteArray::number( d->mBase.id() );
00143 else
00144 command += ImapParser::quote( d->mBase.remoteId().toUtf8() );
00145 command += ' ';
00146 switch ( d->mType ) {
00147 case Base:
00148 command += "0 (";
00149 break;
00150 case FirstLevel:
00151 command += "1 (";
00152 break;
00153 case Recursive:
00154 command += "INF (";
00155 break;
00156 default:
00157 Q_ASSERT( false );
00158 }
00159
00160 if ( !d->mResource.isEmpty() ) {
00161 command += "RESOURCE \"";
00162 command += d->mResource.toUtf8();
00163 command += '"';
00164 }
00165
00166 if ( d->mStatistics ) {
00167 command += ") (STATISTICS true";
00168 }
00169
00170 command += ")\n";
00171 d->writeData( command );
00172 }
00173
00174 void CollectionFetchJob::doHandleResponse( const QByteArray & tag, const QByteArray & data )
00175 {
00176 Q_D( CollectionFetchJob );
00177
00178 if ( tag == "*" ) {
00179 Collection collection;
00180 ProtocolHelper::parseCollection( data, collection );
00181 if ( !collection.isValid() )
00182 return;
00183
00184 collection.d_ptr->resetChangeLog();
00185 d->mCollections.append( collection );
00186 d->mPendingCollections.append( collection );
00187 if ( !d->mEmitTimer->isActive() )
00188 d->mEmitTimer->start();
00189 return;
00190 }
00191 kDebug( 5250 ) << "Unhandled server response" << tag << data;
00192 }
00193
00194 void CollectionFetchJob::setResource(const QString & resource)
00195 {
00196 Q_D( CollectionFetchJob );
00197
00198 d->mResource = resource;
00199 }
00200
00201 void CollectionFetchJob::slotResult(KJob * job)
00202 {
00203 Q_D( CollectionFetchJob );
00204
00205 CollectionFetchJob *list = dynamic_cast<CollectionFetchJob*>( job );
00206 Q_ASSERT( job );
00207 d->mCollections += list->collections();
00208 Job::slotResult( job );
00209 if ( !job->error() && !hasSubjobs() )
00210 emitResult();
00211 }
00212
00213 void CollectionFetchJob::includeUnsubscribed(bool include)
00214 {
00215 Q_D( CollectionFetchJob );
00216
00217 d->mUnsubscribed = include;
00218 }
00219
00220 void CollectionFetchJob::includeStatistics(bool include)
00221 {
00222 Q_D( CollectionFetchJob );
00223
00224 d->mStatistics = include;
00225 }
00226
00227 #include "collectionfetchjob.moc"