00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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();
00309 job->ignorePayload();
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
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
00409 if ( d->mCollectionSyncer ) {
00410 d->mCollectionSyncer->retrievalDone();
00411 }
00412
00413 else {
00414
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
00457 QStringList contentTypes = currentCollection.contentMimeTypes();
00458 contentTypes.removeAll( Collection::mimeType() );
00459 if ( !contentTypes.isEmpty() || (col.rights() & (Collection::CanLinkItem)) ) {
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
00501 if ( d->mItemSyncer ) {
00502 d->mItemSyncer->deliveryDone();
00503 }
00504
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() );
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
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"