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>
52 #include <klocalizedstring.h>
55 #include <QtCore/QDebug>
56 #include <QtCore/QDir>
57 #include <QtCore/QHash>
58 #include <QtCore/QSettings>
59 #include <QtCore/QTimer>
60 #include <QApplication>
61 #include <QtDBus/QtDBus>
67 using namespace Akonadi;
72 Q_CLASSINFO(
"D-Bus Interface",
"org.kde.dfaure" )
79 mItemSyncFetchScope( 0 ),
80 mItemTransactionMode(
ItemSync::SingleTransaction ),
81 mCollectionSyncer( 0 ),
82 mHierarchicalRid( false ),
83 mUnemittedProgress( 0 ),
84 mAutomaticProgressReporting( true )
86 Internal::setClientType( Internal::Resource );
87 mStatusMessage = defaultReadyMessage();
88 mProgressEmissionCompressor.setInterval( 1000 );
89 mProgressEmissionCompressor.setSingleShot(
true );
92 ~ResourceBasePrivate()
94 delete mItemSyncFetchScope;
102 if ( !DBusConnectionPool::threadConnection().registerService( serviceId ) ) {
103 QString reason = DBusConnectionPool::threadConnection().lastError().message();
104 if ( reason.isEmpty() ) {
105 reason = QString::fromLatin1(
"this service is probably running already." );
107 kError() <<
"Unable to register service" << serviceId <<
"at D-Bus:" << reason;
109 if ( QThread::currentThread() == QCoreApplication::instance()->thread() )
110 QCoreApplication::instance()->exit(1);
113 AgentBasePrivate::delayedInit();
117 virtual void changeProcessed()
119 if ( m_recursiveMover ) {
120 m_recursiveMover->changeProcessed();
121 QTimer::singleShot( 0, m_recursiveMover, SLOT(replayNext()) );
125 mChangeRecorder->changeProcessed();
126 if ( !mChangeRecorder->isEmpty() )
127 scheduler->scheduleChangeReplay();
128 scheduler->taskDone();
131 void slotAbortRequested();
133 void slotDeliveryDone( KJob* job );
134 void slotCollectionSyncDone( KJob *job );
135 void slotLocalListDone( KJob *job );
136 void slotSynchronizeCollection(
const Collection &col );
137 void slotCollectionListDone( KJob *job );
138 void slotSynchronizeCollectionAttributes(
const Collection &col );
139 void slotCollectionListForAttributesDone( KJob *job );
140 void slotCollectionAttributesSyncDone( KJob *job );
142 void slotItemSyncDone( KJob *job );
144 void slotPercent( KJob* job,
unsigned long percent );
145 void slotDelayedEmitProgress();
146 void slotDeleteResourceCollection();
147 void slotDeleteResourceCollectionDone( KJob *job );
148 void slotCollectionDeletionDone( KJob *job );
153 void slotPrepareItemRetrievalResult( KJob* job );
155 void changeCommittedResult( KJob* job );
158 void slotRecursiveMoveReplayResult( KJob *job );
160 void slotSessionReconnected()
167 void createItemSyncInstanceIfMissing()
170 Q_ASSERT_X( scheduler->currentTask().type == ResourceScheduler::SyncCollection,
171 "createItemSyncInstance",
"Calling items retrieval methods although no item retrieval is in progress" );
172 if ( !mItemSyncer ) {
173 mItemSyncer =
new ItemSync( q->currentCollection() );
175 if ( mItemSyncFetchScope )
176 mItemSyncer->setFetchScope( *mItemSyncFetchScope );
177 mItemSyncer->setProperty(
"collection", QVariant::fromValue( q->currentCollection() ) );
178 connect( mItemSyncer, SIGNAL(percent(KJob*,ulong)), q, SLOT(slotPercent(KJob*,ulong)) );
179 connect( mItemSyncer, SIGNAL(result(KJob*)), q, SLOT(slotItemSyncDone(KJob*)) );
181 Q_ASSERT( mItemSyncer );
186 Q_SCRIPTABLE QString dumpNotificationListToString()
const
188 return mChangeRecorder->dumpNotificationListToString();
192 Q_SCRIPTABLE QString dumpToString()
const
196 QMetaObject::invokeMethod( const_cast<ResourceBase *>(q),
"dumpResourceToString", Qt::DirectConnection, Q_RETURN_ARG(QString, retVal) );
197 return scheduler->dumpToString() + QLatin1Char(
'\n') + retVal;
200 Q_SCRIPTABLE
void dump()
205 Q_SCRIPTABLE
void clear()
210 Q_SCRIPTABLE
void dumpMemoryInfo()
const
215 QTextStream stream( stdout );
216 stream << dumpMemoryInfoToString();
219 Q_SCRIPTABLE QString dumpMemoryInfoToString()
const
223 #if defined __GLIBC__
226 QTextStream stream( &str );
227 stream <<
"Total non-mmapped bytes (arena): " << mi.arena <<
'\n'
228 <<
"# of free chunks (ordblks): " << mi.ordblks <<
'\n'
229 <<
"# of free fastbin blocks (smblks>: " << mi.smblks <<
'\n'
230 <<
"# of mapped regions (hblks): " << mi.hblks <<
'\n'
231 <<
"Bytes in mapped regions (hblkhd): " << mi.hblkhd <<
'\n'
232 <<
"Max. total allocated space (usmblks): " << mi.usmblks <<
'\n'
233 <<
"Free bytes held in fastbins (fsmblks):" << mi.fsmblks <<
'\n'
234 <<
"Total allocated space (uordblks): " << mi.uordblks <<
'\n'
235 <<
"Total free space (fordblks): " << mi.fordblks <<
'\n'
236 <<
"Topmost releasable block (keepcost): " << mi.keepcost <<
'\n';
238 str = QLatin1String(
"mallinfo() not supported" );
251 if ( collection.
remoteId().isEmpty() ) {
255 AgentBasePrivate::itemAdded( item, collection );
258 void itemChanged(
const Akonadi::Item& item,
const QSet< QByteArray >& partIdentifiers)
264 AgentBasePrivate::itemChanged( item, partIdentifiers );
267 void itemsFlagsChanged(
const Item::List& items,
const QSet< QByteArray >& addedFlags,
268 const QSet< QByteArray >& removedFlags)
270 if (addedFlags.isEmpty() && removedFlags.isEmpty() ) {
281 if ( validItems.isEmpty() ) {
286 AgentBasePrivate::itemsFlagsChanged( validItems, addedFlags, removedFlags );
292 if ( item.
remoteId().isEmpty() || destination.
remoteId().isEmpty() || destination == source ) {
296 AgentBasePrivate::itemMoved( item, source, destination );
301 if ( destination.
remoteId().isEmpty() || destination == source ) {
312 if ( validItems.isEmpty() ) {
317 AgentBasePrivate::itemsMoved( validItems, source, destination );
326 AgentBasePrivate::itemRemoved( item );
337 if ( validItems.isEmpty() ) {
342 AgentBasePrivate::itemsRemoved( validItems );
347 if ( parent.
remoteId().isEmpty() ) {
351 AgentBasePrivate::collectionAdded( collection, parent );
356 if ( collection.
remoteId().isEmpty() ) {
360 AgentBasePrivate::collectionChanged( collection );
363 void collectionChanged(
const Akonadi::Collection& collection,
const QSet< QByteArray >& partIdentifiers)
365 if ( collection.
remoteId().isEmpty() ) {
369 AgentBasePrivate::collectionChanged( collection, partIdentifiers );
375 if ( destination.
remoteId().isEmpty() || source == destination ) {
382 if ( source.
resource() == q_ptr->identifier() ) {
383 AgentBasePrivate::collectionRemoved( collection );
384 }
else if ( destination.
resource() == q_ptr->identifier() ) {
385 scheduler->taskDone();
388 scheduler->scheduleMoveReplay( collection, mover );
394 if ( collection.
remoteId().isEmpty() ) {
400 AgentBasePrivate::collectionMoved( collection, source, destination );
405 if ( collection.
remoteId().isEmpty() ) {
409 AgentBasePrivate::collectionRemoved( collection );
416 ResourceScheduler *scheduler;
421 bool mHierarchicalRid;
422 QTimer mProgressEmissionCompressor;
423 int mUnemittedProgress;
424 QMap<Akonadi::Collection::Id, QVariantMap> mUnemittedAdvancedStatus;
425 bool mAutomaticProgressReporting;
426 QPointer<RecursiveMover> m_recursiveMover;
430 :
AgentBase( new ResourceBasePrivate( this ), id )
434 new Akonadi__ResourceAdaptor(
this );
436 d->scheduler =
new ResourceScheduler(
this );
438 d->mChangeRecorder->setChangeRecordingEnabled(
true );
439 d->mChangeRecorder->setCollectionMoveTranslationEnabled(
false );
440 connect( d->mChangeRecorder, SIGNAL(changesAdded()),
441 d->scheduler, SLOT(scheduleChangeReplay()) );
443 d->mChangeRecorder->setResourceMonitored( d->mId.toLatin1() );
444 d->mChangeRecorder->fetchCollection(
true );
446 connect( d->scheduler, SIGNAL(executeFullSync()),
448 connect( d->scheduler, SIGNAL(executeCollectionTreeSync()),
454 connect( d->scheduler, SIGNAL(executeItemFetch(
Akonadi::Item,QSet<QByteArray>)),
456 connect( d->scheduler, SIGNAL(executeResourceCollectionDeletion()),
457 SLOT(slotDeleteResourceCollection()) );
460 connect( d->scheduler, SIGNAL(
status(
int,QString)),
461 SIGNAL(
status(
int,QString)) );
462 connect( d->scheduler, SIGNAL(executeChangeReplay()),
463 d->mChangeRecorder, SLOT(replayNext()) );
464 connect( d->scheduler, SIGNAL(executeRecursiveMoveReplay(
RecursiveMover*)),
466 connect( d->scheduler, SIGNAL(fullSyncComplete()), SIGNAL(
synchronized()) );
468 connect( d->mChangeRecorder, SIGNAL(nothingToReplay()), d->scheduler, SLOT(
taskDone()) );
471 connect(
this, SIGNAL(
abortRequested()),
this, SLOT(slotAbortRequested()) );
472 connect(
this, SIGNAL(
synchronized()), d->scheduler, SLOT(
taskDone()) );
477 connect( &d->mProgressEmissionCompressor, SIGNAL(timeout()),
478 this, SLOT(slotDelayedEmitProgress()) );
480 d->scheduler->setOnline( d->mOnline );
481 if ( !d->mChangeRecorder->isEmpty() )
482 d->scheduler->scheduleChangeReplay();
484 DBusConnectionPool::threadConnection().registerObject( QLatin1String(
"/Debug" ), d, QDBusConnection::ExportScriptableSlots );
488 connect( d->mChangeRecorder->session(), SIGNAL(reconnected()), SLOT(slotSessionReconnected()) );
497 d_func()->scheduler->scheduleFullSync();
510 QString ResourceBase::parseArguments(
int argc,
char **argv )
514 kDebug() <<
"Not enough arguments passed...";
518 for (
int i = 1; i < argc - 1; ++i ) {
519 if ( QLatin1String( argv[ i ] ) == QLatin1String(
"--identifier" ) )
520 identifier = QLatin1String( argv[ i + 1 ] );
523 if ( identifier.isEmpty() ) {
524 kDebug() <<
"Identifier argument missing";
528 const QFileInfo fi( QString::fromLocal8Bit( argv[0] ) );
530 const QByteArray catalog = fi.baseName().toLatin1();
533 ki18nc(
"@title application name",
"Akonadi Resource" ), KDEPIMLIBS_VERSION,
534 ki18nc(
"@title application description",
"Akonadi Resource" ) );
536 KCmdLineOptions options;
537 options.add(
"identifier <argument>",
538 ki18nc(
"@label commandline option",
"Resource identifier" ) );
539 KCmdLineArgs::addCmdLineOptions( options );
546 QApplication::setQuitOnLastWindowClosed(
false );
547 KGlobal::locale()->insertCatalog( QLatin1String(
"libakonadi" ) );
548 int rv = kapp->exec();
553 void ResourceBasePrivate::slotAbortRequested()
557 scheduler->cancelQueues();
558 QMetaObject::invokeMethod( q,
"abortActivity" );
564 Q_ASSERT( d->scheduler->currentTask().type == ResourceScheduler::FetchItem );
566 d->scheduler->currentTask().sendDBusReplies( i18nc(
"@info",
"Invalid item retrieved" ) );
567 d->scheduler->taskDone();
572 QSet<QByteArray> requestedParts = d->scheduler->currentTask().itemParts;
573 foreach (
const QByteArray &part, requestedParts ) {
575 kWarning() <<
"Item does not provide part" << part;
582 connect( job, SIGNAL(result(KJob*)), SLOT(slotDeliveryDone(KJob*)) );
585 void ResourceBasePrivate::slotDeliveryDone(KJob * job)
588 Q_ASSERT( scheduler->currentTask().type == ResourceScheduler::FetchItem );
589 if ( job->error() ) {
590 emit q->error( i18nc(
"@info",
"Error while creating item: %1", job->errorString() ) );
592 scheduler->currentTask().sendDBusReplies( job->error() ? job->errorString() : QString() );
593 scheduler->taskDone();
599 Q_ASSERT( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionAttributes );
602 d->scheduler->taskDone();
607 connect( job, SIGNAL(result(KJob*)), SLOT(slotCollectionAttributesSyncDone(KJob*)) );
610 void ResourceBasePrivate::slotCollectionAttributesSyncDone(KJob * job)
613 Q_ASSERT( scheduler->currentTask().type == ResourceScheduler::SyncCollectionAttributes );
614 if ( job->error() ) {
615 emit q->error( i18nc(
"@info",
"Error while updating collection: %1", job->errorString() ) );
617 emit q->attributesSynchronized( scheduler->currentTask().collection.id() );
618 scheduler->taskDone();
621 void ResourceBasePrivate::slotDeleteResourceCollection()
627 connect( job, SIGNAL(result(KJob*)), q, SLOT(slotDeleteResourceCollectionDone(KJob*)) );
630 void ResourceBasePrivate::slotDeleteResourceCollectionDone( KJob *job )
633 if ( job->error() ) {
634 emit q->error( job->errorString() );
635 scheduler->taskDone();
641 connect( job, SIGNAL(result(KJob*)), q, SLOT(slotCollectionDeletionDone(KJob*)) );
644 scheduler->taskDone();
649 void ResourceBasePrivate::slotCollectionDeletionDone( KJob *job )
652 if ( job->error() ) {
653 emit q->error( job->errorString() );
656 scheduler->taskDone();
663 connect( job, SIGNAL(result(KJob*)), scheduler, SLOT(taskDone()) );
674 job->d_func()->setClean();
677 connect( job, SIGNAL(finished(KJob*)),
this, SLOT(changeCommittedResult(KJob*)) );
683 connect( job, SIGNAL(result(KJob*)), SLOT(changeCommittedResult(KJob*)) );
686 void ResourceBasePrivate::changeCommittedResult( KJob *job )
689 if ( qobject_cast<CollectionModifyJob*>( job ) ) {
690 if ( job->error() ) {
691 emit q->error( i18nc(
"@info",
"Updating local collection failed: %1.", job->errorText() ) );
693 mChangeRecorder->d_ptr->invalidateCache( static_cast<CollectionModifyJob*>( job )->collection() );
702 bool ResourceBase::requestItemDelivery( qint64 uid,
const QString &remoteId,
703 const QString &mimeType,
const QStringList &parts )
705 return requestItemDeliveryV2( uid, remoteId, mimeType, parts ).isEmpty();
708 QString ResourceBase::requestItemDeliveryV2(qint64 uid,
const QString &remoteId,
const QString &mimeType,
const QStringList &_parts)
712 const QString errorMsg = i18nc(
"@info",
"Cannot fetch item in offline mode." );
713 emit
error( errorMsg );
717 setDelayedReply(
true );
723 QSet<QByteArray> parts;
724 Q_FOREACH(
const QString &str, _parts )
725 parts.insert( str.toLatin1() );
727 d->scheduler->scheduleItemFetch( item, parts, message() );
736 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
737 d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
738 "ResourceBase::collectionsRetrieved()",
739 "Calling collectionsRetrieved() although no collection retrieval is in progress" );
740 if ( !d->mCollectionSyncer ) {
742 d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
743 connect( d->mCollectionSyncer, SIGNAL(
percent(KJob*,ulong)), SLOT(slotPercent(KJob*,ulong)) );
744 connect( d->mCollectionSyncer, SIGNAL(result(KJob*)), SLOT(slotCollectionSyncDone(KJob*)) );
746 d->mCollectionSyncer->setRemoteCollections( collections );
753 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
754 d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
755 "ResourceBase::collectionsRetrievedIncremental()",
756 "Calling collectionsRetrievedIncremental() although no collection retrieval is in progress" );
757 if ( !d->mCollectionSyncer ) {
759 d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
760 connect( d->mCollectionSyncer, SIGNAL(
percent(KJob*,ulong)), SLOT(slotPercent(KJob*,ulong)) );
761 connect( d->mCollectionSyncer, SIGNAL(result(KJob*)), SLOT(slotCollectionSyncDone(KJob*)) );
763 d->mCollectionSyncer->setRemoteCollections( changedCollections, removedCollections );
769 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
770 d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
771 "ResourceBase::setCollectionStreamingEnabled()",
772 "Calling setCollectionStreamingEnabled() although no collection retrieval is in progress" );
773 if ( !d->mCollectionSyncer ) {
775 d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
776 connect( d->mCollectionSyncer, SIGNAL(
percent(KJob*,ulong)), SLOT(slotPercent(KJob*,ulong)) );
777 connect( d->mCollectionSyncer, SIGNAL(result(KJob*)), SLOT(slotCollectionSyncDone(KJob*)) );
779 d->mCollectionSyncer->setStreamingEnabled( enable );
785 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
786 d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
787 "ResourceBase::collectionsRetrievalDone()",
788 "Calling collectionsRetrievalDone() although no collection retrieval is in progress" );
790 if ( d->mCollectionSyncer ) {
791 d->mCollectionSyncer->retrievalDone();
796 d->scheduler->taskDone();
800 void ResourceBasePrivate::slotCollectionSyncDone( KJob * job )
803 mCollectionSyncer = 0;
804 if ( job->error() ) {
806 emit q->error( job->errorString() );
808 if ( scheduler->currentTask().type == ResourceScheduler::SyncAll ) {
810 list->
setFetchScope( q->changeRecorder()->collectionFetchScope() );
812 q->connect( list, SIGNAL(result(KJob*)), q, SLOT(slotLocalListDone(KJob*)) );
814 }
else if ( scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ) {
815 scheduler->scheduleCollectionTreeSyncCompletion();
818 scheduler->taskDone();
821 void ResourceBasePrivate::slotLocalListDone( KJob * job )
824 if ( job->error() ) {
825 emit q->error( job->errorString() );
829 scheduler->scheduleSync( col );
831 scheduler->scheduleFullSyncCompletion();
833 scheduler->taskDone();
836 void ResourceBasePrivate::slotSynchronizeCollection(
const Collection &col )
844 if ( !contentTypes.isEmpty() || col.
isVirtual() ) {
845 if ( mAutomaticProgressReporting ) {
851 scheduler->taskDone();
854 void ResourceBasePrivate::slotSynchronizeCollectionAttributes(
const Collection &col )
857 QMetaObject::invokeMethod( q,
"retrieveCollectionAttributes", Q_ARG(
Akonadi::Collection, col ) );
860 void ResourceBasePrivate::slotPrepareItemRetrieval(
const Akonadi::Item &item )
868 const QSet<QByteArray> attributes = q->changeRecorder()->itemFetchScope().attributes();
869 foreach (
const QByteArray &attribute, attributes )
872 q->connect( fetch, SIGNAL(result(KJob*)), SLOT(slotPrepareItemRetrievalResult(KJob*)) );
875 void ResourceBasePrivate::slotPrepareItemRetrievalResult( KJob* job )
878 Q_ASSERT_X( scheduler->currentTask().type == ResourceScheduler::FetchItem,
879 "ResourceBasePrivate::slotPrepareItemRetrievalResult()",
880 "Preparing item retrieval although no item retrieval is in progress" );
881 if ( job->error() ) {
882 q->cancelTask( job->errorText() );
886 if ( fetch->
items().count() != 1 ) {
887 q->cancelTask( i18n(
"The requested item no longer exists" ) );
890 const Item item = fetch->
items().first();
891 const QSet<QByteArray> parts = scheduler->currentTask().itemParts;
892 if ( !q->retrieveItem( item, parts ) )
896 void ResourceBasePrivate::slotRecursiveMoveReplay(
RecursiveMover *mover )
900 Q_ASSERT( !m_recursiveMover );
901 m_recursiveMover = mover;
902 connect( mover, SIGNAL(result(KJob*)), q, SLOT(slotRecursiveMoveReplayResult(KJob*)) );
906 void ResourceBasePrivate::slotRecursiveMoveReplayResult( KJob *job )
909 m_recursiveMover = 0;
911 if ( job->error() ) {
923 if ( d->mItemSyncer ) {
924 d->mItemSyncer->deliveryDone();
928 d->scheduler->taskDone();
935 d->scheduler->scheduleResourceCollectionDeletion();
941 d->scheduler->scheduleCacheInvalidation( collection );
947 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollection ,
948 "ResourceBase::currentCollection()",
949 "Trying to access current collection although no item retrieval is in progress" );
950 return d->currentCollection;
956 Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::FetchItem ,
957 "ResourceBase::currentItem()",
958 "Trying to access current item although no item retrieval is in progress" );
959 return d->scheduler->currentTask().item;
964 d_func()->scheduler->scheduleCollectionTreeSync();
970 switch ( d->scheduler->currentTask().type ) {
971 case ResourceScheduler::FetchItem:
974 case ResourceScheduler::ChangeReplay:
975 d->changeProcessed();
977 case ResourceScheduler::SyncCollectionTree:
978 case ResourceScheduler::SyncAll:
979 if ( d->mCollectionSyncer )
980 d->mCollectionSyncer->rollback();
982 d->scheduler->taskDone();
984 case ResourceScheduler::SyncCollection:
985 if ( d->mItemSyncer ) {
986 d->mItemSyncer->rollback();
988 d->scheduler->taskDone();
992 d->scheduler->taskDone();
1006 d->scheduler->deferTask();
1011 d_func()->scheduler->setOnline( state );
1024 job->setProperty(
"recursive", recursive );
1025 connect( job, SIGNAL(result(KJob*)), SLOT(slotCollectionListDone(KJob*)) );
1028 void ResourceBasePrivate::slotCollectionListDone( KJob *job )
1030 if ( !job->error() ) {
1032 if ( !list.isEmpty() ) {
1033 if ( job->property(
"recursive" ).toBool() ) {
1034 Q_FOREACH (
const Collection &collection, list ) {
1035 scheduler->scheduleSync( collection );
1038 scheduler->scheduleSync( list.first() );
1050 connect( job, SIGNAL(result(KJob*)), SLOT(slotCollectionListForAttributesDone(KJob*)) );
1053 void ResourceBasePrivate::slotCollectionListForAttributesDone( KJob *job )
1055 if ( !job->error() ) {
1057 if ( !list.isEmpty() ) {
1059 scheduler->scheduleAttributesSync( col );
1070 if ( d->mItemSyncer ) {
1071 d->mItemSyncer->setTotalItems( amount );
1078 d->createItemSyncInstanceIfMissing();
1079 if ( d->mItemSyncer ) {
1080 d->mItemSyncer->setStreamingEnabled( enable );
1087 d->createItemSyncInstanceIfMissing();
1088 if ( d->mItemSyncer ) {
1089 d->mItemSyncer->setFullSyncItems( items );
1097 d->createItemSyncInstanceIfMissing();
1098 if ( d->mItemSyncer ) {
1099 d->mItemSyncer->setIncrementalSyncItems( changedItems, removedItems );
1103 void ResourceBasePrivate::slotItemSyncDone( KJob *job )
1108 emit q->error( job->errorString() );
1110 scheduler->taskDone();
1114 void ResourceBasePrivate::slotDelayedEmitProgress()
1117 if ( mAutomaticProgressReporting ) {
1118 emit q->percent( mUnemittedProgress );
1120 Q_FOREACH(
const QVariantMap &statusMap, mUnemittedAdvancedStatus ) {
1121 emit q->advancedStatus( statusMap );
1124 mUnemittedProgress = 0;
1125 mUnemittedAdvancedStatus.clear();
1128 void ResourceBasePrivate::slotPercent( KJob *job,
unsigned long percent )
1134 QVariantMap statusMap;
1135 statusMap.insert( QLatin1String(
"key" ), QString::fromLatin1(
"collectionSyncProgress" ) );
1136 statusMap.insert( QLatin1String(
"collectionId" ), collection.
id() );
1137 statusMap.insert( QLatin1String(
"percent" ), static_cast<unsigned int>( percent ) );
1139 mUnemittedAdvancedStatus[collection.
id()] = statusMap;
1142 if ( percent == 100 ) {
1143 mProgressEmissionCompressor.stop();
1144 slotDelayedEmitProgress();
1145 }
else if ( !mProgressEmissionCompressor.isActive() ) {
1146 mProgressEmissionCompressor.start();
1153 d->mHierarchicalRid = enable;
1159 d->scheduler->scheduleCustomTask( receiver, method, argument, priority );
1165 d->scheduler->taskDone();
1181 d->mItemTransactionMode = mode;
1187 if ( !d->mItemSyncFetchScope )
1189 *(d->mItemSyncFetchScope) = fetchScope;
1195 d->mAutomaticProgressReporting = enabled;
1201 return d->dumpNotificationListToString();
1207 return d->dumpToString();
1213 return d->dumpMemoryInfo();
1219 return d->dumpMemoryInfoToString();
1222 #include "resourcebase.moc"
1223 #include "moc_resourcebase.cpp"