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 "protocolhelper.h"
00025 #include "entity_p.h"
00026
00027 #include <kdebug.h>
00028
00029 #include <QtCore/QHash>
00030 #include <QtCore/QStringList>
00031 #include <QtCore/QTimer>
00032
00033 using namespace Akonadi;
00034
00035 class Akonadi::CollectionFetchJobPrivate : public JobPrivate
00036 {
00037 public:
00038 CollectionFetchJobPrivate( CollectionFetchJob *parent )
00039 : JobPrivate( parent ),
00040 mUnsubscribed( false )
00041 {
00042 }
00043
00044 Q_DECLARE_PUBLIC( CollectionFetchJob )
00045
00046 CollectionFetchJob::Type mType;
00047 Collection mBase;
00048 Collection::List mBaseList;
00049 Collection::List mCollections;
00050 QString mResource;
00051 Collection::List mPendingCollections;
00052 QTimer *mEmitTimer;
00053 bool mUnsubscribed;
00054
00055 void timeout()
00056 {
00057 Q_Q( CollectionFetchJob );
00058
00059 mEmitTimer->stop();
00060 if ( !mPendingCollections.isEmpty() ) {
00061 emit q->collectionsReceived( mPendingCollections );
00062 mPendingCollections.clear();
00063 }
00064 }
00065 };
00066
00067 CollectionFetchJob::CollectionFetchJob( const Collection &collection, Type type, QObject *parent )
00068 : Job( new CollectionFetchJobPrivate( this ), parent )
00069 {
00070 Q_D( CollectionFetchJob );
00071
00072 Q_ASSERT( collection.isValid() );
00073 d->mBase = collection;
00074 d->mType = type;
00075
00076 d->mEmitTimer = new QTimer( this );
00077 d->mEmitTimer->setSingleShot( true );
00078 d->mEmitTimer->setInterval( 100 );
00079 connect( d->mEmitTimer, SIGNAL(timeout()), this, SLOT(timeout()) );
00080 connect( this, SIGNAL(result(KJob*)), this, SLOT(timeout()) );
00081 }
00082
00083 CollectionFetchJob::CollectionFetchJob( const Collection::List & cols, QObject * parent )
00084 : Job( new CollectionFetchJobPrivate( this ), parent )
00085 {
00086 Q_D( CollectionFetchJob );
00087
00088 Q_ASSERT( !cols.isEmpty() );
00089 d->mBaseList = cols;
00090
00091 d->mEmitTimer = new QTimer( this );
00092 d->mEmitTimer->setSingleShot( true );
00093 d->mEmitTimer->setInterval( 100 );
00094 connect( d->mEmitTimer, SIGNAL(timeout()), this, SLOT(timeout()) );
00095 connect( this, SIGNAL(result(KJob*)), this, SLOT(timeout()) );
00096 }
00097
00098 CollectionFetchJob::~CollectionFetchJob()
00099 {
00100 }
00101
00102 Collection::List CollectionFetchJob::collections() const
00103 {
00104 Q_D( const CollectionFetchJob );
00105
00106 return d->mCollections;
00107 }
00108
00109 void CollectionFetchJob::doStart()
00110 {
00111 Q_D( CollectionFetchJob );
00112
00113 if ( !d->mBaseList.isEmpty() ) {
00114 foreach ( const Collection &col, d->mBaseList ) {
00115 new CollectionFetchJob( col, CollectionFetchJob::Base, this );
00116 }
00117 return;
00118 }
00119
00120 QByteArray command = d->newTag();
00121 if ( d->mUnsubscribed )
00122 command += " X-AKLIST ";
00123 else
00124 command += " X-AKLSUB ";
00125 command += QByteArray::number( d->mBase.id() );
00126 command += ' ';
00127 switch ( d->mType ) {
00128 case Base:
00129 command += "0 (";
00130 break;
00131 case FirstLevel:
00132 command += "1 (";
00133 break;
00134 case Recursive:
00135 command += "INF (";
00136 break;
00137 default:
00138 Q_ASSERT( false );
00139 }
00140
00141 if ( !d->mResource.isEmpty() ) {
00142 command += "RESOURCE \"";
00143 command += d->mResource.toUtf8();
00144 command += '"';
00145 }
00146
00147 command += ")\n";
00148 d->writeData( command );
00149 }
00150
00151 void CollectionFetchJob::doHandleResponse( const QByteArray & tag, const QByteArray & data )
00152 {
00153 Q_D( CollectionFetchJob );
00154
00155 if ( tag == "*" ) {
00156 Collection collection;
00157 ProtocolHelper::parseCollection( data, collection );
00158 if ( !collection.isValid() )
00159 return;
00160
00161 collection.d_ptr->resetChangeLog();
00162 d->mCollections.append( collection );
00163 d->mPendingCollections.append( collection );
00164 if ( !d->mEmitTimer->isActive() )
00165 d->mEmitTimer->start();
00166 return;
00167 }
00168 kDebug( 5250 ) << "Unhandled server response" << tag << data;
00169 }
00170
00171 void CollectionFetchJob::setResource(const QString & resource)
00172 {
00173 Q_D( CollectionFetchJob );
00174
00175 d->mResource = resource;
00176 }
00177
00178 void CollectionFetchJob::slotResult(KJob * job)
00179 {
00180 Q_D( CollectionFetchJob );
00181
00182 CollectionFetchJob *list = dynamic_cast<CollectionFetchJob*>( job );
00183 Q_ASSERT( job );
00184 d->mCollections += list->collections();
00185 Job::slotResult( job );
00186 if ( !job->error() && !hasSubjobs() )
00187 emitResult();
00188 }
00189
00190 void CollectionFetchJob::includeUnsubscribed(bool include)
00191 {
00192 Q_D( CollectionFetchJob );
00193
00194 d->mUnsubscribed = include;
00195 }
00196
00197 #include "collectionfetchjob.moc"