• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

akonadi

resourcebase.cpp

00001 /*
00002     Copyright (c) 2006 Till Adam <adam@kde.org>
00003     Copyright (c) 2007 Volker Krause <vkrause@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or modify it
00006     under the terms of the GNU Library General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or (at your
00008     option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful, but WITHOUT
00011     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013     License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to the
00017     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00018     02110-1301, USA.
00019 */
00020 
00021 #include "resourcebase.h"
00022 #include "agentbase_p.h"
00023 
00024 #include "resourceadaptor.h"
00025 #include "collectiondeletejob.h"
00026 #include "collectionsync_p.h"
00027 #include "itemsync.h"
00028 #include "resourcescheduler_p.h"
00029 #include "tracerinterface.h"
00030 #include "xdgbasedirs_p.h"
00031 
00032 #include "changerecorder.h"
00033 #include "collectionfetchjob.h"
00034 #include "collectionfetchscope.h"
00035 #include "collectionmodifyjob.h"
00036 #include "itemfetchjob.h"
00037 #include "itemfetchscope.h"
00038 #include "itemmodifyjob.h"
00039 #include "itemmodifyjob_p.h"
00040 #include "session.h"
00041 #include "resourceselectjob_p.h"
00042 #include "monitor_p.h"
00043 
00044 #include <kaboutdata.h>
00045 #include <kcmdlineargs.h>
00046 #include <kdebug.h>
00047 #include <klocale.h>
00048 
00049 #include <QtCore/QDebug>
00050 #include <QtCore/QDir>
00051 #include <QtCore/QHash>
00052 #include <QtCore/QSettings>
00053 #include <QtCore/QTimer>
00054 #include <QtGui/QApplication>
00055 #include <QtDBus/QtDBus>
00056 
00057 using namespace Akonadi;
00058 
00059 class Akonadi::ResourceBasePrivate : public AgentBasePrivate
00060 {
00061   public:
00062     ResourceBasePrivate( ResourceBase *parent )
00063       : AgentBasePrivate( parent ),
00064         scheduler( 0 ),
00065         mItemSyncer( 0 ),
00066         mCollectionSyncer( 0 ),
00067         mHierarchicalRid( false )
00068     {
00069       mStatusMessage = defaultReadyMessage();
00070     }
00071 
00072     Q_DECLARE_PUBLIC( ResourceBase )
00073 
00074     void delayedInit()
00075     {
00076       if ( !QDBusConnection::sessionBus().registerService( QLatin1String( "org.freedesktop.Akonadi.Resource." ) + mId ) )
00077         kFatal() << "Unable to register service at D-Bus: " << QDBusConnection::sessionBus().lastError().message();
00078       AgentBasePrivate::delayedInit();
00079     }
00080 
00081     virtual void changeProcessed()
00082     {
00083       mMonitor->changeProcessed();
00084       if ( !mMonitor->isEmpty() )
00085         scheduler->scheduleChangeReplay();
00086       scheduler->taskDone();
00087     }
00088 
00089     void slotDeliveryDone( KJob* job );
00090     void slotCollectionSyncDone( KJob *job );
00091     void slotLocalListDone( KJob *job );
00092     void slotSynchronizeCollection( const Collection &col );
00093     void slotCollectionListDone( KJob *job );
00094 
00095     void slotItemSyncDone( KJob *job );
00096 
00097     void slotPercent( KJob* job, unsigned long percent );
00098     void slotDeleteResourceCollection();
00099     void slotDeleteResourceCollectionDone( KJob *job );
00100     void slotCollectionDeletionDone( KJob *job );
00101 
00102     void slotPrepareItemRetrieval( const Akonadi::Item &item );
00103     void slotPrepareItemRetrievalResult( KJob* job );
00104 
00105     void changeCommittedResult( KJob* job );
00106 
00107     // synchronize states
00108     Collection currentCollection;
00109 
00110     ResourceScheduler *scheduler;
00111     ItemSync *mItemSyncer;
00112     CollectionSync *mCollectionSyncer;
00113     bool mHierarchicalRid;
00114 };
00115 
00116 ResourceBase::ResourceBase( const QString & id )
00117   : AgentBase( new ResourceBasePrivate( this ), id )
00118 {
00119   Q_D( ResourceBase );
00120 
00121   new ResourceAdaptor( this );
00122 
00123   d->scheduler = new ResourceScheduler( this );
00124 
00125   d->mMonitor->setChangeRecordingEnabled( true );
00126   connect( d->mMonitor, SIGNAL( changesAdded() ),
00127            d->scheduler, SLOT( scheduleChangeReplay() ) );
00128 
00129   d->mMonitor->setResourceMonitored( d->mId.toLatin1() );
00130 
00131   connect( d->scheduler, SIGNAL( executeFullSync() ),
00132            SLOT( retrieveCollections() ) );
00133   connect( d->scheduler, SIGNAL( executeCollectionTreeSync() ),
00134            SLOT( retrieveCollections() ) );
00135   connect( d->scheduler, SIGNAL( executeCollectionSync( const Akonadi::Collection& ) ),
00136            SLOT( slotSynchronizeCollection( const Akonadi::Collection& ) ) );
00137   connect( d->scheduler, SIGNAL( executeItemFetch( const Akonadi::Item&, const QSet<QByteArray>& ) ),
00138            SLOT( slotPrepareItemRetrieval(Akonadi::Item)) );
00139   connect( d->scheduler, SIGNAL( executeResourceCollectionDeletion() ),
00140            SLOT( slotDeleteResourceCollection() ) );
00141   connect( d->scheduler, SIGNAL( status( int, const QString& ) ),
00142            SIGNAL( status( int, const QString& ) ) );
00143   connect( d->scheduler, SIGNAL( executeChangeReplay() ),
00144            d->mMonitor, SLOT( replayNext() ) );
00145   connect( d->scheduler, SIGNAL( fullSyncComplete() ), SIGNAL( synchronized() ) );
00146   connect( d->mMonitor, SIGNAL( nothingToReplay() ), d->scheduler, SLOT( taskDone() ) );
00147   connect( d->mMonitor, SIGNAL(collectionRemoved(Akonadi::Collection)),
00148            d->scheduler, SLOT(collectionRemoved(Akonadi::Collection)) );
00149   connect( this, SIGNAL( synchronized() ), d->scheduler, SLOT( taskDone() ) );
00150   connect( this, SIGNAL( agentNameChanged( const QString& ) ),
00151            this, SIGNAL( nameChanged( const QString& ) ) );
00152 
00153   d->scheduler->setOnline( d->mOnline );
00154   if ( !d->mMonitor->isEmpty() )
00155     d->scheduler->scheduleChangeReplay();
00156 
00157   new ResourceSelectJob( identifier() );
00158 }
00159 
00160 ResourceBase::~ResourceBase()
00161 {
00162 }
00163 
00164 void ResourceBase::synchronize()
00165 {
00166   d_func()->scheduler->scheduleFullSync();
00167 }
00168 
00169 void ResourceBase::setName( const QString &name )
00170 {
00171   AgentBase::setAgentName( name );
00172 }
00173 
00174 QString ResourceBase::name() const
00175 {
00176   return AgentBase::agentName();
00177 }
00178 
00179 QString ResourceBase::parseArguments( int argc, char **argv )
00180 {
00181   QString identifier;
00182   if ( argc < 3 ) {
00183     kDebug() << "Not enough arguments passed...";
00184     exit( 1 );
00185   }
00186 
00187   for ( int i = 1; i < argc - 1; ++i ) {
00188     if ( QLatin1String( argv[ i ] ) == QLatin1String( "--identifier" ) )
00189       identifier = QLatin1String( argv[ i + 1 ] );
00190   }
00191 
00192   if ( identifier.isEmpty() ) {
00193     kDebug() << "Identifier argument missing";
00194     exit( 1 );
00195   }
00196 
00197   QByteArray catalog;
00198   char *p = strrchr( argv[0], '/' );
00199   if ( p )
00200     catalog = QByteArray( p + 1 );
00201   else
00202     catalog = QByteArray( argv[0] );
00203 
00204   KCmdLineArgs::init( argc, argv, identifier.toLatin1(), catalog,
00205                       ki18nc("@title, application name", "Akonadi Resource"), "0.1",
00206                       ki18nc("@title, application description", "Akonadi Resource") );
00207 
00208   KCmdLineOptions options;
00209   options.add( "identifier <argument>",
00210                ki18nc("@label, commandline option", "Resource identifier") );
00211   KCmdLineArgs::addCmdLineOptions( options );
00212 
00213   return identifier;
00214 }
00215 
00216 int ResourceBase::init( ResourceBase *r )
00217 {
00218   QApplication::setQuitOnLastWindowClosed( false );
00219   int rv = kapp->exec();
00220   delete r;
00221   return rv;
00222 }
00223 
00224 void ResourceBase::itemRetrieved( const Item &item )
00225 {
00226   Q_D( ResourceBase );
00227   Q_ASSERT( d->scheduler->currentTask().type == ResourceScheduler::FetchItem );
00228   if ( !item.isValid() ) {
00229     QDBusMessage reply( d->scheduler->currentTask().dbusMsg );
00230     reply << false;
00231     QDBusConnection::sessionBus().send( reply );
00232     d->scheduler->taskDone();
00233     return;
00234   }
00235 
00236   Item i( item );
00237   QSet<QByteArray> requestedParts = d->scheduler->currentTask().itemParts;
00238   foreach ( const QByteArray &part, requestedParts ) {
00239     if ( !item.loadedPayloadParts().contains( part ) ) {
00240       kWarning() << "Item does not provide part" << part;
00241     }
00242   }
00243 
00244   ItemModifyJob *job = new ItemModifyJob( i );
00245   // FIXME: remove once the item with which we call retrieveItem() has a revision number
00246   job->disableRevisionCheck();
00247   connect( job, SIGNAL( result( KJob* ) ), SLOT( slotDeliveryDone( KJob* ) ) );
00248 }
00249 
00250 void ResourceBasePrivate::slotDeliveryDone(KJob * job)
00251 {
00252   Q_Q( ResourceBase );
00253   Q_ASSERT( scheduler->currentTask().type == ResourceScheduler::FetchItem );
00254   QDBusMessage reply( scheduler->currentTask().dbusMsg );
00255   if ( job->error() ) {
00256     emit q->error( QLatin1String( "Error while creating item: " ) + job->errorString() );
00257     reply << false;
00258   } else {
00259     reply << true;
00260   }
00261   QDBusConnection::sessionBus().send( reply );
00262   scheduler->taskDone();
00263 }
00264 
00265 void ResourceBasePrivate::slotDeleteResourceCollection()
00266 {
00267   Q_Q( ResourceBase );
00268 
00269   CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::FirstLevel );
00270   job->fetchScope().setResource( q->identifier() );
00271   connect( job, SIGNAL( result( KJob* ) ), q, SLOT( slotDeleteResourceCollectionDone( KJob* ) ) );
00272 }
00273 
00274 void ResourceBasePrivate::slotDeleteResourceCollectionDone( KJob *job )
00275 {
00276   Q_Q( ResourceBase );
00277   if ( job->error() ) {
00278     emit q->error( job->errorString() );
00279     scheduler->taskDone();
00280   } else {
00281     const CollectionFetchJob *fetchJob = static_cast<const CollectionFetchJob*>( job );
00282 
00283     if ( !fetchJob->collections().isEmpty() ) {
00284       CollectionDeleteJob *job = new CollectionDeleteJob( fetchJob->collections().first() );
00285       connect( job, SIGNAL( result( KJob* ) ), q, SLOT( slotCollectionDeletionDone( KJob* ) ) );
00286     } else {
00287       // there is no resource collection, so just ignore the request
00288       scheduler->taskDone();
00289     }
00290   }
00291 }
00292 
00293 void ResourceBasePrivate::slotCollectionDeletionDone( KJob *job )
00294 {
00295   Q_Q( ResourceBase );
00296   if ( job->error() ) {
00297     emit q->error( job->errorString() );
00298   }
00299 
00300   scheduler->taskDone();
00301 }
00302 
00303 void ResourceBase::changeCommitted( const Item& item )
00304 {
00305   Q_D( ResourceBase );
00306   ItemModifyJob *job = new ItemModifyJob( item );
00307   job->d_func()->setClean();
00308   job->disableRevisionCheck(); // TODO: remove, but where/how do we handle the error?
00309   job->ignorePayload(); // we only want to reset the dirty flag and update the remote id
00310   d->changeProcessed();
00311 }
00312 
00313 void ResourceBase::changeCommitted( const Collection &collection )
00314 {
00315   CollectionModifyJob *job = new CollectionModifyJob( collection );
00316   connect( job, SIGNAL(result(KJob*)), SLOT(changeCommittedResult(KJob*)) );
00317 }
00318 
00319 void ResourceBasePrivate::changeCommittedResult( KJob *job )
00320 {
00321   Q_Q( ResourceBase );
00322   if ( job->error() )
00323     emit q->error( i18nc( "@info", "Updating local collection failed: %1.", job->errorText() ) );
00324   mMonitor->d_ptr->invalidateCache( static_cast<CollectionModifyJob*>( job )->collection() );
00325   changeProcessed();
00326 }
00327 
00328 bool ResourceBase::requestItemDelivery( qint64 uid, const QString & remoteId,
00329                                         const QString &mimeType, const QStringList &_parts )
00330 {
00331   Q_D( ResourceBase );
00332   if ( !isOnline() ) {
00333     emit error( i18nc( "@info", "Cannot fetch item in offline mode." ) );
00334     return false;
00335   }
00336 
00337   setDelayedReply( true );
00338   // FIXME: we need at least the revision number too
00339   Item item( uid );
00340   item.setMimeType( mimeType );
00341   item.setRemoteId( remoteId );
00342 
00343   QSet<QByteArray> parts;
00344   Q_FOREACH( const QString &str, _parts )
00345     parts.insert( str.toLatin1() );
00346 
00347   d->scheduler->scheduleItemFetch( item, parts, message().createReply() );
00348 
00349   return true;
00350 }
00351 
00352 void ResourceBase::collectionsRetrieved( const Collection::List & collections )
00353 {
00354   Q_D( ResourceBase );
00355   Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
00356               d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
00357               "ResourceBase::collectionsRetrieved()",
00358               "Calling collectionsRetrieved() although no collection retrieval is in progress" );
00359   if ( !d->mCollectionSyncer ) {
00360     d->mCollectionSyncer = new CollectionSync( identifier() );
00361     d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
00362     connect( d->mCollectionSyncer, SIGNAL( percent( KJob*, unsigned long ) ), SLOT( slotPercent( KJob*, unsigned long ) ) );
00363     connect( d->mCollectionSyncer, SIGNAL( result( KJob* ) ), SLOT( slotCollectionSyncDone( KJob* ) ) );
00364   }
00365   d->mCollectionSyncer->setRemoteCollections( collections );
00366 }
00367 
00368 void ResourceBase::collectionsRetrievedIncremental( const Collection::List & changedCollections,
00369                                                     const Collection::List & removedCollections )
00370 {
00371   Q_D( ResourceBase );
00372   Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
00373               d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
00374               "ResourceBase::collectionsRetrievedIncremental()",
00375               "Calling collectionsRetrievedIncremental() although no collection retrieval is in progress" );
00376   if ( !d->mCollectionSyncer ) {
00377     d->mCollectionSyncer = new CollectionSync( identifier() );
00378     d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
00379     connect( d->mCollectionSyncer, SIGNAL( percent( KJob*, unsigned long ) ), SLOT( slotPercent( KJob*, unsigned long ) ) );
00380     connect( d->mCollectionSyncer, SIGNAL( result( KJob* ) ), SLOT( slotCollectionSyncDone( KJob* ) ) );
00381   }
00382   d->mCollectionSyncer->setRemoteCollections( changedCollections, removedCollections );
00383 }
00384 
00385 void ResourceBase::setCollectionStreamingEnabled( bool enable )
00386 {
00387   Q_D( ResourceBase );
00388   Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
00389               d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
00390               "ResourceBase::setCollectionStreamingEnabled()",
00391               "Calling setCollectionStreamingEnabled() although no collection retrieval is in progress" );
00392   if ( !d->mCollectionSyncer ) {
00393     d->mCollectionSyncer = new CollectionSync( identifier() );
00394     d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
00395     connect( d->mCollectionSyncer, SIGNAL( percent( KJob*, unsigned long ) ), SLOT( slotPercent( KJob*, unsigned long ) ) );
00396     connect( d->mCollectionSyncer, SIGNAL( result( KJob* ) ), SLOT( slotCollectionSyncDone( KJob* ) ) );
00397   }
00398   d->mCollectionSyncer->setStreamingEnabled( enable );
00399 }
00400 
00401 void ResourceBase::collectionsRetrievalDone()
00402 {
00403   Q_D( ResourceBase );
00404   Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
00405               d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
00406               "ResourceBase::collectionsRetrievalDone()",
00407               "Calling collectionsRetrievalDone() although no collection retrieval is in progress" );
00408   // streaming enabled, so finalize the sync
00409   if ( d->mCollectionSyncer ) {
00410     d->mCollectionSyncer->retrievalDone();
00411   }
00412   // user did the sync himself, we are done now
00413   else {
00414     // FIXME: we need the same special case for SyncAll as in slotCollectionSyncDone here!
00415     d->scheduler->taskDone();
00416   }
00417 }
00418 
00419 void ResourceBasePrivate::slotCollectionSyncDone( KJob * job )
00420 {
00421   Q_Q( ResourceBase );
00422   mCollectionSyncer = 0;
00423   if ( job->error() ) {
00424     emit q->error( job->errorString() );
00425   } else {
00426     if ( scheduler->currentTask().type == ResourceScheduler::SyncAll ) {
00427       CollectionFetchJob *list = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive );
00428       list->fetchScope().setResource( mId );
00429       list->fetchScope().setAncestorRetrieval( q->changeRecorder()->collectionFetchScope().ancestorRetrieval() );
00430       q->connect( list, SIGNAL( result( KJob* ) ), q, SLOT( slotLocalListDone( KJob* ) ) );
00431       return;
00432     }
00433   }
00434   scheduler->taskDone();
00435 }
00436 
00437 void ResourceBasePrivate::slotLocalListDone( KJob * job )
00438 {
00439   Q_Q( ResourceBase );
00440   if ( job->error() ) {
00441     emit q->error( job->errorString() );
00442   } else {
00443     Collection::List cols = static_cast<CollectionFetchJob*>( job )->collections();
00444     foreach ( const Collection &col, cols ) {
00445       scheduler->scheduleSync( col );
00446     }
00447     scheduler->scheduleFullSyncCompletion();
00448   }
00449   scheduler->taskDone();
00450 }
00451 
00452 void ResourceBasePrivate::slotSynchronizeCollection( const Collection &col )
00453 {
00454   Q_Q( ResourceBase );
00455   currentCollection = col;
00456   // check if this collection actually can contain anything
00457   QStringList contentTypes = currentCollection.contentMimeTypes();
00458   contentTypes.removeAll( Collection::mimeType() );
00459   if ( !contentTypes.isEmpty() || (col.rights() & (Collection::CanLinkItem)) ) { // HACK to check for virtual collections
00460     emit q->status( AgentBase::Running, i18nc( "@info:status", "Syncing collection '%1'", currentCollection.name() ) );
00461     q->retrieveItems( currentCollection );
00462     return;
00463   }
00464   scheduler->taskDone();
00465 }
00466 
00467 void ResourceBasePrivate::slotPrepareItemRetrieval( const Akonadi::Item &item )
00468 {
00469   Q_Q( ResourceBase );
00470   ItemFetchJob *fetch = new ItemFetchJob( item, this );
00471   fetch->fetchScope().setAncestorRetrieval( q->changeRecorder()->itemFetchScope().ancestorRetrieval() );
00472   fetch->fetchScope().setCacheOnly( true );
00473   q->connect( fetch, SIGNAL(result(KJob*)), SLOT(slotPrepareItemRetrievalResult(KJob*)) );
00474 }
00475 
00476 void ResourceBasePrivate::slotPrepareItemRetrievalResult( KJob* job )
00477 {
00478   Q_Q( ResourceBase );
00479   Q_ASSERT_X( scheduler->currentTask().type == ResourceScheduler::FetchItem,
00480             "ResourceBasePrivate::slotPrepareItemRetrievalResult()",
00481             "Preparing item retrieval although no item retrieval is in progress" );
00482   if ( job->error() ) {
00483     q->cancelTask( job->errorText() );
00484     return;
00485   }
00486   ItemFetchJob *fetch = qobject_cast<ItemFetchJob*>( job );
00487   if ( fetch->items().count() != 1 ) {
00488     q->cancelTask( QLatin1String("The requested item does no longer exist") );
00489     return;
00490   }
00491   const Item item = fetch->items().first();
00492   const QSet<QByteArray> parts = scheduler->currentTask().itemParts;
00493   if ( !q->retrieveItem( item, parts ) )
00494     q->cancelTask();
00495 }
00496 
00497 void ResourceBase::itemsRetrievalDone()
00498 {
00499   Q_D( ResourceBase );
00500   // streaming enabled, so finalize the sync
00501   if ( d->mItemSyncer ) {
00502     d->mItemSyncer->deliveryDone();
00503   }
00504   // user did the sync himself, we are done now
00505   else {
00506     d->scheduler->taskDone();
00507   }
00508 }
00509 
00510 void ResourceBase::clearCache()
00511 {
00512   Q_D( ResourceBase );
00513   d->scheduler->scheduleResourceCollectionDeletion();
00514 }
00515 
00516 Collection ResourceBase::currentCollection() const
00517 {
00518   Q_D( const ResourceBase );
00519   Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollection ,
00520               "ResourceBase::currentCollection()",
00521               "Trying to access current collection although no item retrieval is in progress" );
00522   return d->currentCollection;
00523 }
00524 
00525 Item ResourceBase::currentItem() const
00526 {
00527   Q_D( const ResourceBase );
00528   Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::FetchItem ,
00529               "ResourceBase::currentItem()",
00530               "Trying to access current item although no item retrieval is in progress" );
00531   return d->scheduler->currentTask().item;
00532 }
00533 
00534 void ResourceBase::synchronizeCollectionTree()
00535 {
00536   d_func()->scheduler->scheduleCollectionTreeSync();
00537 }
00538 
00539 void ResourceBase::cancelTask()
00540 {
00541   Q_D( ResourceBase );
00542   switch ( d->scheduler->currentTask().type ) {
00543     case ResourceScheduler::FetchItem:
00544       itemRetrieved( Item() ); // sends the error reply and
00545       break;
00546     case ResourceScheduler::ChangeReplay:
00547       d->changeProcessed();
00548       break;
00549     default:
00550       d->scheduler->taskDone();
00551   }
00552 }
00553 
00554 void ResourceBase::cancelTask( const QString &msg )
00555 {
00556   cancelTask();
00557 
00558   emit error( msg );
00559 }
00560 
00561 void ResourceBase::deferTask()
00562 {
00563   Q_D( ResourceBase );
00564   d->scheduler->deferTask();
00565 }
00566 
00567 void ResourceBase::doSetOnline( bool state )
00568 {
00569   d_func()->scheduler->setOnline( state );
00570 }
00571 
00572 void ResourceBase::synchronizeCollection( qint64 collectionId )
00573 {
00574   CollectionFetchJob* job = new CollectionFetchJob( Collection( collectionId ), CollectionFetchJob::Base );
00575   job->fetchScope().setResource( identifier() );
00576   job->fetchScope().setAncestorRetrieval( changeRecorder()->collectionFetchScope().ancestorRetrieval() );
00577   connect( job, SIGNAL( result( KJob* ) ), SLOT( slotCollectionListDone( KJob* ) ) );
00578 }
00579 
00580 void ResourceBasePrivate::slotCollectionListDone( KJob *job )
00581 {
00582   if ( !job->error() ) {
00583     Collection::List list = static_cast<CollectionFetchJob*>( job )->collections();
00584     if ( !list.isEmpty() ) {
00585       Collection col = list.first();
00586       scheduler->scheduleSync( col );
00587     }
00588   }
00589   // TODO: error handling
00590 }
00591 
00592 void ResourceBase::setTotalItems( int amount )
00593 {
00594   kDebug() << amount;
00595   Q_D( ResourceBase );
00596   setItemStreamingEnabled( true );
00597   d->mItemSyncer->setTotalItems( amount );
00598 }
00599 
00600 void ResourceBase::setItemStreamingEnabled( bool enable )
00601 {
00602   Q_D( ResourceBase );
00603   Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollection,
00604               "ResourceBase::setItemStreamingEnabled()",
00605               "Calling setItemStreamingEnabled() although no item retrieval is in progress" );
00606   if ( !d->mItemSyncer ) {
00607     d->mItemSyncer = new ItemSync( currentCollection() );
00608     connect( d->mItemSyncer, SIGNAL( percent( KJob*, unsigned long ) ), SLOT( slotPercent( KJob*, unsigned long ) ) );
00609     connect( d->mItemSyncer, SIGNAL( result( KJob* ) ), SLOT( slotItemSyncDone( KJob* ) ) );
00610   }
00611   d->mItemSyncer->setStreamingEnabled( enable );
00612 }
00613 
00614 void ResourceBase::itemsRetrieved( const Item::List &items )
00615 {
00616   Q_D( ResourceBase );
00617   Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollection,
00618               "ResourceBase::itemsRetrieved()",
00619               "Calling itemsRetrieved() although no item retrieval is in progress" );
00620   if ( !d->mItemSyncer ) {
00621     d->mItemSyncer = new ItemSync( currentCollection() );
00622     connect( d->mItemSyncer, SIGNAL( percent( KJob*, unsigned long ) ), SLOT( slotPercent( KJob*, unsigned long ) ) );
00623     connect( d->mItemSyncer, SIGNAL( result( KJob* ) ), SLOT( slotItemSyncDone( KJob* ) ) );
00624   }
00625   d->mItemSyncer->setFullSyncItems( items );
00626 }
00627 
00628 void ResourceBase::itemsRetrievedIncremental( const Item::List &changedItems, const Item::List &removedItems )
00629 {
00630   Q_D( ResourceBase );
00631   Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollection,
00632               "ResourceBase::itemsRetrievedIncremental()",
00633               "Calling itemsRetrievedIncremental() although no item retrieval is in progress" );
00634   if ( !d->mItemSyncer ) {
00635     d->mItemSyncer = new ItemSync( currentCollection() );
00636     connect( d->mItemSyncer, SIGNAL( percent( KJob*, unsigned long ) ), SLOT( slotPercent( KJob*, unsigned long ) ) );
00637     connect( d->mItemSyncer, SIGNAL( result( KJob* ) ), SLOT( slotItemSyncDone( KJob* ) ) );
00638   }
00639   d->mItemSyncer->setIncrementalSyncItems( changedItems, removedItems );
00640 }
00641 
00642 void ResourceBasePrivate::slotItemSyncDone( KJob *job )
00643 {
00644   mItemSyncer = 0;
00645   Q_Q( ResourceBase );
00646   if ( job->error() ) {
00647     emit q->error( job->errorString() );
00648   }
00649   scheduler->taskDone();
00650 }
00651 
00652 void ResourceBasePrivate::slotPercent( KJob *job, unsigned long percent )
00653 {
00654   Q_Q( ResourceBase );
00655   Q_UNUSED( job );
00656   emit q->percent( percent );
00657 }
00658 
00659 void ResourceBase::setHierarchicalRemoteIdentifiersEnabled( bool enable )
00660 {
00661   Q_D( ResourceBase );
00662   d->mHierarchicalRid = enable;
00663 }
00664 
00665 void ResourceBase::scheduleCustomTask( QObject *receiver, const char *method, const QVariant &argument, SchedulePriority priority )
00666 {
00667   Q_D( ResourceBase );
00668   d->scheduler->scheduleCustomTask( receiver, method, argument, priority );
00669 }
00670 
00671 void ResourceBase::taskDone()
00672 {
00673   Q_D( ResourceBase );
00674   d->scheduler->taskDone();
00675 }
00676 
00677 #include "resourcebase.moc"

akonadi

Skip menu "akonadi"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal