21 #include "resourcebase.h"
22 #include "agentbase_p.h"
24 #include "resourceadaptor.h"
25 #include "collectiondeletejob.h"
26 #include "collectionsync_p.h"
27 #include "dbusconnectionpool.h"
29 #include "kdepimlibs-version.h"
30 #include "resourcescheduler_p.h"
31 #include "tracerinterface.h"
32 #include "xdgbasedirs_p.h"
34 #include "changerecorder.h"
35 #include "collectionfetchjob.h"
36 #include "collectionfetchscope.h"
37 #include "collectionmodifyjob.h"
38 #include "invalidatecachejob_p.h"
39 #include "itemfetchjob.h"
40 #include "itemfetchscope.h"
41 #include "itemmodifyjob.h"
42 #include "itemmodifyjob_p.h"
44 #include "resourceselectjob_p.h"
45 #include "monitor_p.h"
46 #include "servermanager_p.h"
47 #include "recursivemover_p.h"
49 #include <kaboutdata.h>
50 #include <kcmdlineargs.h>
54 #include <QtCore/QDebug>
55 #include <QtCore/QDir>
56 #include <QtCore/QHash>
57 #include <QtCore/QSettings>
58 #include <QtCore/QTimer>
59 #include <QApplication>
60 #include <QtDBus/QtDBus>
62 using namespace Akonadi;
67 Q_CLASSINFO(
"D-Bus Interface",
"org.kde.dfaure" )
74 mItemSyncFetchScope( 0 ),
75 mItemTransactionMode(
ItemSync::SingleTransaction ),
76 mCollectionSyncer( 0 ),
77 mHierarchicalRid( false ),
78 mUnemittedProgress( 0 ),
79 mAutomaticProgressReporting( true )
81 Internal::setClientType( Internal::Resource );
82 mStatusMessage = defaultReadyMessage();
83 mProgressEmissionCompressor.setInterval( 1000 );
84 mProgressEmissionCompressor.setSingleShot(
true );
87 ~ResourceBasePrivate()
89 delete mItemSyncFetchScope;
97 if ( !DBusConnectionPool::threadConnection().registerService( serviceId ) ) {
98 QString reason = DBusConnectionPool::threadConnection().lastError().message();
99 if ( reason.isEmpty() ) {
100 reason = QString::fromLatin1(
"this service is probably running already." );
102 kError() <<
"Unable to register service" << serviceId <<
"at D-Bus:" << reason;
104 if ( QThread::currentThread() == QCoreApplication::instance()->thread() )
105 QCoreApplication::instance()->exit(1);
108 AgentBasePrivate::delayedInit();
112 virtual void changeProcessed()
114 if ( m_recursiveMover ) {
115 m_recursiveMover->changeProcessed();
116 QTimer::singleShot( 0, m_recursiveMover, SLOT(replayNext()) );
120 mChangeRecorder->changeProcessed();
121 if ( !mChangeRecorder->isEmpty() )
122 scheduler->scheduleChangeReplay();
123 scheduler->taskDone();
126 void slotAbortRequested();
128 void slotDeliveryDone( KJob* job );
129 void slotCollectionSyncDone( KJob *job );
130 void slotLocalListDone( KJob *job );
131 void slotSynchronizeCollection(
const Collection &col );
132 void slotCollectionListDone( KJob *job );
133 void slotSynchronizeCollectionAttributes(
const Collection &col );
134 void slotCollectionListForAttributesDone( KJob *job );
135 void slotCollectionAttributesSyncDone( KJob *job );
137 void slotItemSyncDone( KJob *job );
139 void slotPercent( KJob* job,
unsigned long percent );
140 void slotDelayedEmitProgress();
141 void slotDeleteResourceCollection();
142 void slotDeleteResourceCollectionDone( KJob *job );
143 void slotCollectionDeletionDone( KJob *job );
147 void slotPrepareItemRetrieval(
const Akonadi::Item &item );
148 void slotPrepareItemRetrievalResult( KJob* job );
150 void changeCommittedResult( KJob* job );
153 void slotRecursiveMoveReplayResult( KJob *job );
155 void slotSessionReconnected()
162 void createItemSyncInstanceIfMissing()
165 Q_ASSERT_X( scheduler->currentTask().type == ResourceScheduler::SyncCollection,
166 "createItemSyncInstance",
"Calling items retrieval methods although no item retrieval is in progress" );
167 if ( !mItemSyncer ) {
168 mItemSyncer =
new ItemSync( q->currentCollection() );
170 if ( mItemSyncFetchScope )
171 mItemSyncer->setFetchScope( *mItemSyncFetchScope );
172 mItemSyncer->setProperty(
"collection", QVariant::fromValue( q->currentCollection() ) );
173 connect( mItemSyncer, SIGNAL(percent(KJob*,ulong)), q, SLOT(slotPercent(KJob*,ulong)) );
174 connect( mItemSyncer, SIGNAL(result(KJob*)), q, SLOT(slotItemSyncDone(KJob*)) );
176 Q_ASSERT( mItemSyncer );
181 Q_SCRIPTABLE QString dumpNotificationListToString()
const
183 return mChangeRecorder->dumpNotificationListToString();
187 Q_SCRIPTABLE QString dumpToString()
const
191 QMetaObject::invokeMethod( const_cast<ResourceBase *>(q),
"dumpResourceToString", Qt::DirectConnection, Q_RETURN_ARG(QString, retVal) );
192 return scheduler->dumpToString() + QLatin1Char(
'\n') + retVal;
195 Q_SCRIPTABLE
void dump()
200 Q_SCRIPTABLE
void clear()
213 if ( collection.
remoteId().isEmpty() ) {
217 AgentBasePrivate::itemAdded( item, collection );
220 void itemChanged(
const Akonadi::Item& item,
const QSet< QByteArray >& partIdentifiers)
222 if ( item.remoteId().isEmpty() ) {
226 AgentBasePrivate::itemChanged( item, partIdentifiers );
232 if ( item.remoteId().isEmpty() || destination.
remoteId().isEmpty() || destination == source ) {
236 AgentBasePrivate::itemMoved( item, source, destination );
239 void itemRemoved(
const Akonadi::Item& item)
241 if ( item.remoteId().isEmpty() ) {
245 AgentBasePrivate::itemRemoved( item );
250 if ( parent.
remoteId().isEmpty() ) {
254 AgentBasePrivate::collectionAdded( collection, parent );
259 if ( collection.
remoteId().isEmpty() ) {
263 AgentBasePrivate::collectionChanged( collection );
266 void collectionChanged(
const Akonadi::Collection& collection,
const QSet< QByteArray >& partIdentifiers)
268 if ( collection.
remoteId().isEmpty() ) {
272 AgentBasePrivate::collectionChanged( collection, partIdentifiers );
278 if ( destination.
remoteId().isEmpty() || source == destination ) {
285 if ( source.
resource() == q_ptr->identifier() ) {
286 AgentBasePrivate::collectionRemoved( collection );
287 }
else if ( destination.
resource() == q_ptr->identifier() ) {
288 scheduler->taskDone();
291 scheduler->scheduleMoveReplay( collection, mover );
297 if ( collection.
remoteId().isEmpty() ) {
303 AgentBasePrivate::collectionMoved( collection, source, destination );
308 if ( collection.
remoteId().isEmpty() ) {
312 AgentBasePrivate::collectionRemoved( collection );
319 ResourceScheduler *scheduler;
324 bool mHierarchicalRid;
325 QTimer mProgressEmissionCompressor;
326 int mUnemittedProgress;
327 QMap<Akonadi::Collection::Id, QVariantMap> mUnemittedAdvancedStatus;
328 bool mAutomaticProgressReporting;
329 QPointer<RecursiveMover> m_recursiveMover;
333 :
AgentBase( new ResourceBasePrivate( this ), id )
337 new Akonadi__ResourceAdaptor(
this );
339 d->scheduler =
new ResourceScheduler(
this );
341 d->mChangeRecorder->setChangeRecordingEnabled(
true );
342 d->mChangeRecorder->setCollectionMoveTranslationEnabled(
false );
343 connect( d->mChangeRecorder, SIGNAL(changesAdded()),
344 d->scheduler, SLOT(scheduleChangeReplay()) );
346 d->mChangeRecorder->setResourceMonitored( d->mId.toLatin1() );
347 d->mChangeRecorder->fetchCollection(
true );
349 connect( d->scheduler, SIGNAL(executeFullSync()),
351 connect( d->scheduler, SIGNAL(executeCollectionTreeSync()),
357 connect( d->scheduler, SIGNAL(executeItemFetch(Akonadi::Item,QSet<QByteArray>)),
358 SLOT(slotPrepareItemRetrieval(Akonadi::Item)) );
359 connect( d->scheduler, SIGNAL(executeResourceCollectionDeletion()),
360 SLOT(slotDeleteResourceCollection()) );
363 connect( d->scheduler, SIGNAL(
status(
int,QString)),
364 SIGNAL(
status(
int,QString)) );
365 connect( d->scheduler, SIGNAL(executeChangeReplay()),
366 d->mChangeRecorder, SLOT(replayNext()) );
367 connect( d->scheduler, SIGNAL(executeRecursiveMoveReplay(
RecursiveMover*)),
369 connect( d->scheduler, SIGNAL(fullSyncComplete()), SIGNAL(
synchronized()) );
371 connect( d->mChangeRecorder, SIGNAL(nothingToReplay()), d->scheduler, SLOT(
taskDone()) );
374 connect(
this, SIGNAL(
abortRequested()),
this, SLOT(slotAbortRequested()) );
375 connect(
this, SIGNAL(
synchronized()), d->scheduler, SLOT(
taskDone()) );
380 connect( &d->mProgressEmissionCompressor, SIGNAL(timeout()),
381 this, SLOT(slotDelayedEmitProgress()) );
383 d->scheduler->setOnline( d->mOnline );
384 if ( !d->mChangeRecorder->isEmpty() )
385 d->scheduler->scheduleChangeReplay();
387 DBusConnectionPool::threadConnection().registerObject( QLatin1String(
"/Debug" ), d, QDBusConnection::ExportScriptableSlots );
391 connect( d->mChangeRecorder->session(), SIGNAL(reconnected()), SLOT(slotSessionReconnected()) );
400 d_func()->scheduler->scheduleFullSync();
413 QString ResourceBase::parseArguments(
int argc,
char **argv )
417 kDebug() <<
"Not enough arguments passed...";
421 for (
int i = 1; i < argc - 1; ++i ) {
422 if ( QLatin1String( argv[ i ] ) == QLatin1String(
"--identifier" ) )
423 identifier = QLatin1String( argv[ i + 1 ] );
426 if ( identifier.isEmpty() ) {
427 kDebug() <<
"Identifier argument missing";
431 const QFileInfo fi( QString::fromLocal8Bit( argv[0] ) );
433 const QByteArray catalog = fi.baseName().toLatin1();
436 ki18nc(
"@title application name",
"Akonadi Resource" ), KDEPIMLIBS_VERSION,
437 ki18nc(
"@title application description",
"Akonadi Resource" ) );
439 KCmdLineOptions options;
440 options.add(
"identifier <argument>",
441 ki18nc(
"@label commandline option",
"Resource identifier" ) );
442 KCmdLineArgs::addCmdLineOptions( options );
449 QApplication::setQuitOnLastWindowClosed(
false );
450 KGlobal::locale()->insertCatalog( QLatin1String(
"libakonadi" ) );
451 int rv = kapp->exec();
456 void ResourceBasePrivate::slotAbortRequested()
460 scheduler->cancelQueues();
461 QMetaObject::invokeMethod( q,
"abortActivity" );
467 Q_ASSERT( d->scheduler->currentTask().type == ResourceScheduler::FetchItem );
468 if ( !item.isValid() ) {
469 d->scheduler->currentTask().sendDBusReplies( i18nc(
"@info",
"Invalid item retrieved" ) );
470 d->scheduler->taskDone();
475 QSet<QByteArray> requestedParts = d->scheduler->currentTask().itemParts;
476 foreach (
const QByteArray &part, requestedParts ) {
477 if ( !item.loadedPayloadParts().contains( part ) ) {
478 kWarning() <<
"Item does not provide part" << part;
485 connect( job, SIGNAL(result(KJob*)), SLOT(slotDeliveryDone(KJob*)) );
488 void ResourceBasePrivate::slotDeliveryDone(KJob * job)
491 Q_ASSERT( scheduler->currentTask().type == ResourceScheduler::FetchItem );
492 if ( job->error() ) {
493 emit q->error( i18nc(
"@info",
"Error while creating item: %1" ).arg( job->errorString() ) );
495 scheduler->currentTask().sendDBusReplies( job->error() ? job->errorString() : QString() );
496 scheduler->taskDone();
502 Q_ASSERT( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionAttributes );
505 d->scheduler->taskDone();
510 connect( job, SIGNAL(result(KJob*)), SLOT(slotCollectionAttributesSyncDone(KJob*)) );
513 void ResourceBasePrivate::slotCollectionAttributesSyncDone(KJob * job)
516 Q_ASSERT( scheduler->currentTask().type == ResourceScheduler::SyncCollectionAttributes );
517 if ( job->error() ) {
518 emit q->error( i18nc(
"@info",
"Error while updating collection: %1" ).arg( job->errorString() ) );
520 emit q->attributesSynchronized( scheduler->currentTask().collection.id() );
521 scheduler->taskDone();
524 void ResourceBasePrivate::slotDeleteResourceCollection()
530 connect( job, SIGNAL(result(KJob*)), q, SLOT(slotDeleteResourceCollectionDone(KJob*)) );
533 void ResourceBasePrivate::slotDeleteResourceCollectionDone( KJob *job )
536 if ( job->error() ) {
537 emit q->error( job->errorString() );
538 scheduler->taskDone();
544 connect( job, SIGNAL(result(KJob*)), q, SLOT(slotCollectionDeletionDone(KJob*)) );
547 scheduler->taskDone();
552 void ResourceBasePrivate::slotCollectionDeletionDone( KJob *job )
555 if ( job->error() ) {
556 emit q->error( job->errorString() );
559 scheduler->taskDone();
566 connect( job, SIGNAL(result(KJob*)), scheduler, SLOT(taskDone()) );
573 job->d_func()->setClean();
576 d->changeProcessed();
582 connect( job, SIGNAL(result(KJob*)), SLOT(changeCommittedResult(KJob*)) );
585 void ResourceBasePrivate::changeCommittedResult( KJob *job )
589 emit q->error( i18nc(
"@info",
"Updating local collection failed: %1.", job->errorText() ) );
590 mChangeRecorder->d_ptr->invalidateCache( static_cast<CollectionModifyJob*>( job )->collection() );
594 bool ResourceBase::requestItemDelivery( qint64 uid,
const QString &remoteId,
595 const QString &mimeType,
const QStringList &parts )
597 return requestItemDeliveryV2( uid, remoteId, mimeType, parts ).isEmpty();
600 QString ResourceBase::requestItemDeliveryV2(qint64 uid,
const QString &remoteId,
const QString &mimeType,
const QStringList &_parts)
604 const QString errorMsg = i18nc(
"@info",
"Cannot fetch item in offline mode." );
605 emit
error( errorMsg );
609 setDelayedReply(
true );
612 item.setMimeType( mimeType );
613 item.setRemoteId( remoteId );
615 QSet<QByteArray> parts;
616 Q_FOREACH(
const QString &str, _parts )
617 parts.insert( str.toLatin1() );
619 d->scheduler->scheduleItemFetch( item, parts, message() );
628 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
629 d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
630 "ResourceBase::collectionsRetrieved()",
631 "Calling collectionsRetrieved() although no collection retrieval is in progress" );
632 if ( !d->mCollectionSyncer ) {
634 d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
635 connect( d->mCollectionSyncer, SIGNAL(
percent(KJob*,ulong)), SLOT(slotPercent(KJob*,ulong)) );
636 connect( d->mCollectionSyncer, SIGNAL(result(KJob*)), SLOT(slotCollectionSyncDone(KJob*)) );
638 d->mCollectionSyncer->setRemoteCollections( collections );
645 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
646 d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
647 "ResourceBase::collectionsRetrievedIncremental()",
648 "Calling collectionsRetrievedIncremental() although no collection retrieval is in progress" );
649 if ( !d->mCollectionSyncer ) {
651 d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
652 connect( d->mCollectionSyncer, SIGNAL(
percent(KJob*,ulong)), SLOT(slotPercent(KJob*,ulong)) );
653 connect( d->mCollectionSyncer, SIGNAL(result(KJob*)), SLOT(slotCollectionSyncDone(KJob*)) );
655 d->mCollectionSyncer->setRemoteCollections( changedCollections, removedCollections );
661 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
662 d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
663 "ResourceBase::setCollectionStreamingEnabled()",
664 "Calling setCollectionStreamingEnabled() although no collection retrieval is in progress" );
665 if ( !d->mCollectionSyncer ) {
667 d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
668 connect( d->mCollectionSyncer, SIGNAL(
percent(KJob*,ulong)), SLOT(slotPercent(KJob*,ulong)) );
669 connect( d->mCollectionSyncer, SIGNAL(result(KJob*)), SLOT(slotCollectionSyncDone(KJob*)) );
671 d->mCollectionSyncer->setStreamingEnabled( enable );
677 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
678 d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
679 "ResourceBase::collectionsRetrievalDone()",
680 "Calling collectionsRetrievalDone() although no collection retrieval is in progress" );
682 if ( d->mCollectionSyncer ) {
683 d->mCollectionSyncer->retrievalDone();
688 d->scheduler->taskDone();
692 void ResourceBasePrivate::slotCollectionSyncDone( KJob * job )
695 mCollectionSyncer = 0;
696 if ( job->error() ) {
698 emit q->error( job->errorString() );
700 if ( scheduler->currentTask().type == ResourceScheduler::SyncAll ) {
702 list->
setFetchScope( q->changeRecorder()->collectionFetchScope() );
704 q->connect( list, SIGNAL(result(KJob*)), q, SLOT(slotLocalListDone(KJob*)) );
706 }
else if ( scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ) {
707 scheduler->scheduleCollectionTreeSyncCompletion();
710 scheduler->taskDone();
713 void ResourceBasePrivate::slotLocalListDone( KJob * job )
716 if ( job->error() ) {
717 emit q->error( job->errorString() );
721 scheduler->scheduleSync( col );
723 scheduler->scheduleFullSyncCompletion();
725 scheduler->taskDone();
728 void ResourceBasePrivate::slotSynchronizeCollection(
const Collection &col )
736 if ( mAutomaticProgressReporting ) {
742 scheduler->taskDone();
745 void ResourceBasePrivate::slotSynchronizeCollectionAttributes(
const Collection &col )
748 QMetaObject::invokeMethod( q,
"retrieveCollectionAttributes", Q_ARG(
Akonadi::Collection, col ) );
751 void ResourceBasePrivate::slotPrepareItemRetrieval(
const Akonadi::Item &item )
759 const QSet<QByteArray> attributes = q->changeRecorder()->itemFetchScope().attributes();
760 foreach (
const QByteArray &attribute, attributes )
763 q->connect( fetch, SIGNAL(result(KJob*)), SLOT(slotPrepareItemRetrievalResult(KJob*)) );
766 void ResourceBasePrivate::slotPrepareItemRetrievalResult( KJob* job )
769 Q_ASSERT_X( scheduler->currentTask().type == ResourceScheduler::FetchItem,
770 "ResourceBasePrivate::slotPrepareItemRetrievalResult()",
771 "Preparing item retrieval although no item retrieval is in progress" );
772 if ( job->error() ) {
773 q->cancelTask( job->errorText() );
777 if ( fetch->
items().count() != 1 ) {
778 q->cancelTask( i18n(
"The requested item no longer exists" ) );
781 const Item item = fetch->
items().first();
782 const QSet<QByteArray> parts = scheduler->currentTask().itemParts;
783 if ( !q->retrieveItem( item, parts ) )
787 void ResourceBasePrivate::slotRecursiveMoveReplay(
RecursiveMover *mover )
791 Q_ASSERT( !m_recursiveMover );
792 m_recursiveMover = mover;
793 connect( mover, SIGNAL(result(KJob*)), q, SLOT(slotRecursiveMoveReplayResult(KJob*)) );
797 void ResourceBasePrivate::slotRecursiveMoveReplayResult( KJob *job )
800 m_recursiveMover = 0;
802 if ( job->error() ) {
814 if ( d->mItemSyncer ) {
815 d->mItemSyncer->deliveryDone();
819 d->scheduler->taskDone();
826 d->scheduler->scheduleResourceCollectionDeletion();
832 d->scheduler->scheduleCacheInvalidation( collection );
838 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollection ,
839 "ResourceBase::currentCollection()",
840 "Trying to access current collection although no item retrieval is in progress" );
841 return d->currentCollection;
847 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::FetchItem ,
848 "ResourceBase::currentItem()",
849 "Trying to access current item although no item retrieval is in progress" );
850 return d->scheduler->currentTask().item;
855 d_func()->scheduler->scheduleCollectionTreeSync();
861 switch ( d->scheduler->currentTask().type ) {
862 case ResourceScheduler::FetchItem:
865 case ResourceScheduler::ChangeReplay:
866 d->changeProcessed();
868 case ResourceScheduler::SyncCollectionTree:
869 case ResourceScheduler::SyncAll:
870 if ( d->mCollectionSyncer )
871 d->mCollectionSyncer->rollback();
873 d->scheduler->taskDone();
875 case ResourceScheduler::SyncCollection:
876 if ( d->mItemSyncer ) {
877 d->mItemSyncer->rollback();
879 d->scheduler->taskDone();
883 d->scheduler->taskDone();
897 d->scheduler->deferTask();
902 d_func()->scheduler->setOnline( state );
915 job->setProperty(
"recursive", recursive );
916 connect( job, SIGNAL(result(KJob*)), SLOT(slotCollectionListDone(KJob*)) );
919 void ResourceBasePrivate::slotCollectionListDone( KJob *job )
921 if ( !job->error() ) {
923 if ( !list.isEmpty() ) {
924 if ( job->property(
"recursive" ).toBool() ) {
925 Q_FOREACH (
const Collection &collection, list ) {
926 scheduler->scheduleSync( collection );
929 scheduler->scheduleSync( list.first() );
941 connect( job, SIGNAL(result(KJob*)), SLOT(slotCollectionListForAttributesDone(KJob*)) );
944 void ResourceBasePrivate::slotCollectionListForAttributesDone( KJob *job )
946 if ( !job->error() ) {
948 if ( !list.isEmpty() ) {
950 scheduler->scheduleAttributesSync( col );
961 if ( d->mItemSyncer ) {
962 d->mItemSyncer->setTotalItems( amount );
969 d->createItemSyncInstanceIfMissing();
970 if ( d->mItemSyncer ) {
971 d->mItemSyncer->setStreamingEnabled( enable );
978 d->createItemSyncInstanceIfMissing();
979 if ( d->mItemSyncer ) {
980 d->mItemSyncer->setFullSyncItems( items );
985 const Item::List &removedItems )
988 d->createItemSyncInstanceIfMissing();
989 if ( d->mItemSyncer ) {
990 d->mItemSyncer->setIncrementalSyncItems( changedItems, removedItems );
994 void ResourceBasePrivate::slotItemSyncDone( KJob *job )
999 emit q->error( job->errorString() );
1001 scheduler->taskDone();
1005 void ResourceBasePrivate::slotDelayedEmitProgress()
1008 if ( mAutomaticProgressReporting ) {
1009 emit q->percent( mUnemittedProgress );
1011 Q_FOREACH(
const QVariantMap &statusMap, mUnemittedAdvancedStatus ) {
1012 emit q->advancedStatus( statusMap );
1015 mUnemittedProgress = 0;
1016 mUnemittedAdvancedStatus.clear();
1019 void ResourceBasePrivate::slotPercent( KJob *job,
unsigned long percent )
1025 QVariantMap statusMap;
1026 statusMap.insert( QLatin1String(
"key" ), QString::fromLatin1(
"collectionSyncProgress" ) );
1027 statusMap.insert( QLatin1String(
"collectionId" ), collection.
id() );
1028 statusMap.insert( QLatin1String(
"percent" ), static_cast<unsigned int>( percent ) );
1030 mUnemittedAdvancedStatus[collection.
id()] = statusMap;
1033 if ( percent == 100 ) {
1034 mProgressEmissionCompressor.stop();
1035 slotDelayedEmitProgress();
1036 }
else if ( !mProgressEmissionCompressor.isActive() ) {
1037 mProgressEmissionCompressor.start();
1044 d->mHierarchicalRid = enable;
1050 d->scheduler->scheduleCustomTask( receiver, method, argument, priority );
1056 d->scheduler->taskDone();
1072 d->mItemTransactionMode = mode;
1078 if ( !d->mItemSyncFetchScope )
1080 *(d->mItemSyncFetchScope) = fetchScope;
1086 d->mAutomaticProgressReporting = enabled;
1092 return d->dumpNotificationListToString();
1098 return d->dumpToString();
1101 #include "resourcebase.moc"
1102 #include "moc_resourcebase.cpp"
Job that modifies a collection in the Akonadi storage.
Helper class for expanding inter-resource collection moves inside ResourceBase.
void fetchAttribute(const QByteArray &type, bool fetch=true)
Sets whether the attribute of the given type should be fetched.
void retrieveCollectionAttributes(const Akonadi::Collection &collection)
Retrieve the attributes of a single collection from the backend.
void abortActivity()
Abort any activity in progress in the backend.
void disableRevisionCheck()
Disables the check of the revision number.
void percent(int progress)
This signal should be emitted whenever the progress of an action in the agent (e.g.
virtual void retrieveCollections()=0
Retrieve the collection tree from the remote server and supply it via collectionsRetrieved() or colle...
Collection::List collections() const
Returns the list of fetched collection.
void abortRequested()
Emitted when another application has remotely asked the agent to abort its current operation...
QString dumpNotificationListToString() const
Dump the contents of the current ChangeReplay.
QString name() const
Returns the i18n'ed name of the collection.
void attributesSynchronized(qlonglong collectionId)
Emitted when a collection attributes synchronization has been completed.
void collectionsRetrievalDone()
Call this method to indicate you finished synchronizing the collection tree.
void setAutomaticProgressReporting(bool enabled)
Enable or disable automatic progress reporting.
void setCollectionStreamingEnabled(bool enable)
Enable collection streaming, that is collections don't have to be delivered at once as result of a re...
void synchronizeCollectionAttributes(qint64 id)
This method is called whenever the collection with the given id shall have its attributes synchronize...
Only list direct sub-collections of the base collection.
CollectionFetchScope & fetchScope()
Returns the collection fetch scope.
void setResource(const QString &resource)
Sets a resource filter, that is only collections owned by the specified resource are retrieved...
Represents a collection of PIM items.
Job that fetches collections from the Akonadi storage.
void itemsRetrieved(const Item::List &items)
Call this method to supply the full collection listing from the remote server.
void agentNameChanged(const QString &name)
This signal is emitted whenever the name of the agent has changed.
static QString mimeType()
Returns the mimetype used for collections.
void setItemSynchronizationFetchScope(const ItemFetchScope &fetchScope)
Set the fetch scope applied for item synchronization.
void synchronizeCollectionTree()
Refetches the Collections.
void setTotalItems(int amount)
Call this method when you want to use the itemsRetrieved() method in streaming mode and indicate the ...
void nameChanged(const QString &name)
This signal is emitted whenever the name of the resource has changed.
Item::List items() const
Returns the fetched item.
The base class for all Akonadi agents and resources.
Only fetch the base collection.
Syncs between items known to a client (usually a resource) and the Akonadi storage.
void itemsRetrievalDone()
Call this method to indicate you finished synchronizing the current collection.
void deferTask()
Stops the execution of the current task and continues with the next one.
ItemFetchScope & fetchScope()
Returns the item fetch scope.
void setAgentName(const QString &name)
This method is used to set the name of the agent.
SchedulePriority
Describes the scheduling priority of a task that has been queued for execution.
void synchronize()
This method is called whenever the resource should start synchronize all data.
Can create links to existing items in this virtual collection.
void error(const QString &message)
This signal shall be used to report errors.
virtual int status() const
This method returns the current status code of the agent.
void clearCache()
Call this method to remove all items and collections of the resource from the server cache...
void collectionAttributesRetrieved(const Collection &collection)
Call this method from retrieveCollectionAttributes() once the result is available.
QString remoteId() const
Returns the remote id of the entity.
void collectionsRetrieved(const Collection::List &collections)
Call this to supply the full folder tree retrieved from the remote server.
static Collection root()
Returns the root collection.
Item currentItem() const
Returns the item that is currently retrieved.
Job that deletes a collection in the Akonadi storage.
void itemsRetrievedIncremental(const Item::List &changedItems, const Item::List &removedItems)
Call this method to supply incrementally retrieved items from the remote server.
static QString agentServiceName(ServiceAgentType agentType, const QString &identifier)
Returns the namespaced D-Bus service name for an agent of type agentType with agent identifier identi...
void doSetOnline(bool online)
Inherited from AgentBase.
Id id() const
Returns the unique identifier of the entity.
void collectionTreeSynchronized()
Emitted when a collection tree synchronization has been completed.
void setFetchScope(const CollectionFetchScope &fetchScope)
Sets the collection fetch scope.
Rights rights() const
Returns the rights the user has on the collection.
void synchronizeCollection(qint64 id)
This method is called whenever the collection with the given id shall be synchronized.
Specifies which parts of an item should be fetched from the Akonadi storage.
void setAncestorRetrieval(AncestorRetrieval ancestorDepth)
Sets how many levels of ancestor collections should be included in the retrieval. ...
void setItemTransactionMode(ItemSync::TransactionMode mode)
Set transaction mode for item sync'ing.
Helper job to invalidate item cache for an entire collection.
QString identifier() const
Returns the instance identifier of this agent.
void setIgnorePayload(bool ignore)
Sets whether the payload of the modified item shall be omitted from transmission to the Akonadi stora...
TransactionMode
Transaction mode used by ItemSync.
void changeCommitted(const Item &item)
Resets the dirty flag of the given item and updates the remote id.
ChangeRecorder * changeRecorder() const
Returns the Akonadi::ChangeRecorder object used for monitoring.
void setHierarchicalRemoteIdentifiersEnabled(bool enable)
Indicate the use of hierarchical remote identifiers.
bool isOnline() const
Returns whether the agent is currently online.
void itemRetrieved(const Item &item)
Call this method from retrieveItem() once the result is available.
void changeProcessed()
Marks the current change as processes and replays the next change if change recording is enabled (noo...
void setCollection(const Akonadi::Collection &collection, const Akonadi::Collection &parentCollection)
Set the collection that is actually moved.
Job that modifies an existing item in the Akonadi storage.
Job that fetches items from the Akonadi storage.
Job that selects a resource context for remote identifier based operations.
~ResourceBase()
Destroys the base resource.
QStringList contentMimeTypes() const
Returns a list of possible content mimetypes, e.g.
static int init(int argc, char **argv)
Use this method in the main function of your resource application to initialize your resource subclas...
void setItemStreamingEnabled(bool enable)
Enable item streaming.
QString name() const
Returns the name of the resource.
void taskDone()
Indicate that the current task is finished.
void cancelTask()
Stops the execution of the current task and continues with the next one.
Collection currentCollection() const
Returns the collection that is currently synchronized.
QString resource() const
Returns the identifier of the resource owning the collection.
The user canceld this job.
ResourceBase(const QString &id)
Creates a base resource.
The agent is working on something.
bool isValid() const
Returns whether the entity is valid.
void setTransactionMode(TransactionMode mode)
Set the transaction mode to use for this sync.
void collectionsRetrievedIncremental(const Collection::List &changedCollections, const Collection::List &removedCollections)
Call this to supply incrementally retrieved collections from the remote server.
static QString addNamespace(const QString &string)
Adds the multi-instance namespace to string if required (with '_' as separator).
void setName(const QString &name)
This method is used to set the name of the resource.
List all sub-collections.
QList< Collection > List
Describes a list of collections.
QString agentName() const
Returns the name of the agent.
The base class for all Akonadi resources.
QString dumpSchedulerToString() const
Dump the state of the scheduler.
void scheduleCustomTask(QObject *receiver, const char *method, const QVariant &argument, SchedulePriority priority=Append)
Schedules a custom task in the internal scheduler.
void setCacheOnly(bool cacheOnly)
Sets whether payload data should be requested from remote sources or just from the local cache...
void invalidateCache(const Collection &collection)
Call this method to invalidate all cached content in collection.