akonadi
itemfetchjob.cpp
00001 /* 00002 Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 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 mValuePool( 0 ) 00045 { 00046 mCollection = Collection::root(); 00047 } 00048 00049 ~ItemFetchJobPrivate() 00050 { 00051 delete mValuePool; 00052 } 00053 00054 void init() 00055 { 00056 Q_Q( ItemFetchJob ); 00057 mEmitTimer = new QTimer( q ); 00058 mEmitTimer->setSingleShot( true ); 00059 mEmitTimer->setInterval( 100 ); 00060 q->connect( mEmitTimer, SIGNAL(timeout()), q, SLOT(timeout()) ); 00061 q->connect( q, SIGNAL(result(KJob*)), q, SLOT(timeout()) ); 00062 } 00063 00064 void timeout() 00065 { 00066 Q_Q( ItemFetchJob ); 00067 00068 mEmitTimer->stop(); // in case we are called by result() 00069 if ( !mPendingItems.isEmpty() ) { 00070 if ( !q->error() ) 00071 emit q->itemsReceived( mPendingItems ); 00072 mPendingItems.clear(); 00073 } 00074 } 00075 00076 void startFetchJob(); 00077 void selectDone( KJob * job ); 00078 00079 Q_DECLARE_PUBLIC( ItemFetchJob ) 00080 00081 Collection mCollection; 00082 Item::List mRequestedItems; 00083 Item::List mResultItems; 00084 ItemFetchScope mFetchScope; 00085 Item::List mPendingItems; // items pending for emitting itemsReceived() 00086 QTimer* mEmitTimer; 00087 ProtocolHelperValuePool *mValuePool; 00088 }; 00089 00090 void ItemFetchJobPrivate::startFetchJob() 00091 { 00092 Q_Q( ItemFetchJob ); 00093 QByteArray command = newTag(); 00094 if ( mRequestedItems.isEmpty() ) { 00095 command += " " AKONADI_CMD_ITEMFETCH " 1:*"; 00096 } else { 00097 try { 00098 command += ProtocolHelper::entitySetToByteArray( mRequestedItems, AKONADI_CMD_ITEMFETCH ); 00099 } catch ( const Exception &e ) { 00100 q->setError( Job::Unknown ); 00101 q->setErrorText( QString::fromUtf8( e.what() ) ); 00102 q->emitResult(); 00103 return; 00104 } 00105 } 00106 00107 command += ProtocolHelper::itemFetchScopeToByteArray( mFetchScope ); 00108 00109 writeData( command ); 00110 } 00111 00112 void ItemFetchJobPrivate::selectDone( KJob * job ) 00113 { 00114 if ( !job->error() ) 00115 // the collection is now selected, fetch the message(s) 00116 startFetchJob(); 00117 } 00118 00119 ItemFetchJob::ItemFetchJob( const Collection &collection, QObject * parent ) 00120 : Job( new ItemFetchJobPrivate( this ), parent ) 00121 { 00122 Q_D( ItemFetchJob ); 00123 00124 d->init(); 00125 d->mCollection = collection; 00126 d->mValuePool = new ProtocolHelperValuePool; // only worth it for lots of results 00127 } 00128 00129 ItemFetchJob::ItemFetchJob( const Item & item, QObject * parent) 00130 : Job( new ItemFetchJobPrivate( this ), parent ) 00131 { 00132 Q_D( ItemFetchJob ); 00133 00134 d->init(); 00135 d->mRequestedItems.append( item ); 00136 } 00137 00138 ItemFetchJob::ItemFetchJob(const Akonadi::Item::List& items, QObject* parent) 00139 : Job( new ItemFetchJobPrivate( this ), parent ) 00140 { 00141 Q_D( ItemFetchJob ); 00142 00143 d->init(); 00144 d->mRequestedItems = items; 00145 } 00146 00147 ItemFetchJob::ItemFetchJob(const QList<Akonadi::Item::Id>& items, QObject* parent) 00148 : Job( new ItemFetchJobPrivate( this ), parent ) 00149 { 00150 Q_D( ItemFetchJob ); 00151 00152 d->init(); 00153 foreach(Item::Id id, items) 00154 d->mRequestedItems.append(Item(id)); 00155 } 00156 00157 00158 ItemFetchJob::~ItemFetchJob() 00159 { 00160 } 00161 00162 void ItemFetchJob::doStart() 00163 { 00164 Q_D( ItemFetchJob ); 00165 00166 if ( d->mRequestedItems.isEmpty() ) { // collection content listing 00167 if ( d->mCollection == Collection::root() ) { 00168 setErrorText( i18n( "Cannot list root collection." ) ); 00169 setError( Unknown ); 00170 emitResult(); 00171 } 00172 CollectionSelectJob *job = new CollectionSelectJob( d->mCollection, this ); 00173 connect( job, SIGNAL(result(KJob*)), SLOT(selectDone(KJob*)) ); 00174 addSubjob( job ); 00175 } else 00176 d->startFetchJob(); 00177 } 00178 00179 void ItemFetchJob::doHandleResponse( const QByteArray & tag, const QByteArray & data ) 00180 { 00181 Q_D( ItemFetchJob ); 00182 00183 if ( tag == "*" ) { 00184 int begin = data.indexOf( "FETCH" ); 00185 if ( begin >= 0 ) { 00186 00187 // split fetch response into key/value pairs 00188 QList<QByteArray> fetchResponse; 00189 ImapParser::parseParenthesizedList( data, fetchResponse, begin + 6 ); 00190 00191 Item item; 00192 ProtocolHelper::parseItemFetchResult( fetchResponse, item, d->mValuePool ); 00193 if ( !item.isValid() ) 00194 return; 00195 00196 d->mResultItems.append( item ); 00197 d->mPendingItems.append( item ); 00198 if ( !d->mEmitTimer->isActive() ) 00199 d->mEmitTimer->start(); 00200 return; 00201 } 00202 } 00203 kDebug() << "Unhandled response: " << tag << data; 00204 } 00205 00206 Item::List ItemFetchJob::items() const 00207 { 00208 Q_D( const ItemFetchJob ); 00209 00210 return d->mResultItems; 00211 } 00212 00213 void ItemFetchJob::setFetchScope( ItemFetchScope &fetchScope ) 00214 { 00215 Q_D( ItemFetchJob ); 00216 00217 d->mFetchScope = fetchScope; 00218 } 00219 00220 void ItemFetchJob::setFetchScope( const ItemFetchScope &fetchScope ) 00221 { 00222 Q_D( ItemFetchJob ); 00223 00224 d->mFetchScope = fetchScope; 00225 } 00226 00227 ItemFetchScope &ItemFetchJob::fetchScope() 00228 { 00229 Q_D( ItemFetchJob ); 00230 00231 return d->mFetchScope; 00232 } 00233 00234 void ItemFetchJob::setCollection(const Akonadi::Collection& collection) 00235 { 00236 Q_D( ItemFetchJob ); 00237 00238 d->mCollection = collection; 00239 } 00240 00241 00242 #include "itemfetchjob.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Tue May 8 2012 00:00:44 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Tue May 8 2012 00:00:44 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.