• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.12
  • kdepimlibs
  • akonadi
resourcebase.cpp
1 /*
2  Copyright (c) 2006 Till Adam <adam@kde.org>
3  Copyright (c) 2007 Volker Krause <vkrause@kde.org>
4 
5  This library is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or (at your
8  option) any later version.
9 
10  This library is distributed in the hope that it will be useful, but WITHOUT
11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13  License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to the
17  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  02110-1301, USA.
19 */
20 
21 #include "resourcebase.h"
22 #include "agentbase_p.h"
23 
24 #include "resourceadaptor.h"
25 #include "collectiondeletejob.h"
26 #include "collectionsync_p.h"
27 #include "dbusconnectionpool.h"
28 #include "itemsync.h"
29 #include "kdepimlibs-version.h"
30 #include "resourcescheduler_p.h"
31 #include "tracerinterface.h"
32 #include "xdgbasedirs_p.h"
33 
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"
43 #include "session.h"
44 #include "resourceselectjob_p.h"
45 #include "monitor_p.h"
46 #include "servermanager_p.h"
47 #include "recursivemover_p.h"
48 
49 #include <kaboutdata.h>
50 #include <kcmdlineargs.h>
51 #include <kdebug.h>
52 #include <klocalizedstring.h>
53 #include <kglobal.h>
54 
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>
62 
63 using namespace Akonadi;
64 
65 class Akonadi::ResourceBasePrivate : public AgentBasePrivate
66 {
67  Q_OBJECT
68  Q_CLASSINFO( "D-Bus Interface", "org.kde.dfaure" )
69 
70  public:
71  ResourceBasePrivate( ResourceBase *parent )
72  : AgentBasePrivate( parent ),
73  scheduler( 0 ),
74  mItemSyncer( 0 ),
75  mItemSyncFetchScope( 0 ),
76  mItemTransactionMode( ItemSync::SingleTransaction ),
77  mCollectionSyncer( 0 ),
78  mHierarchicalRid( false ),
79  mUnemittedProgress( 0 ),
80  mAutomaticProgressReporting( true )
81  {
82  Internal::setClientType( Internal::Resource );
83  mStatusMessage = defaultReadyMessage();
84  mProgressEmissionCompressor.setInterval( 1000 );
85  mProgressEmissionCompressor.setSingleShot( true );
86  }
87 
88  ~ResourceBasePrivate()
89  {
90  delete mItemSyncFetchScope;
91  }
92 
93  Q_DECLARE_PUBLIC( ResourceBase )
94 
95  void delayedInit()
96  {
97  const QString serviceId = ServerManager::agentServiceName( ServerManager::Resource, mId );
98  if ( !DBusConnectionPool::threadConnection().registerService( serviceId ) ) {
99  QString reason = DBusConnectionPool::threadConnection().lastError().message();
100  if ( reason.isEmpty() ) {
101  reason = QString::fromLatin1( "this service is probably running already." );
102  }
103  kError() << "Unable to register service" << serviceId << "at D-Bus:" << reason;
104 
105  if ( QThread::currentThread() == QCoreApplication::instance()->thread() )
106  QCoreApplication::instance()->exit(1);
107 
108  } else {
109  AgentBasePrivate::delayedInit();
110  }
111  }
112 
113  virtual void changeProcessed()
114  {
115  if ( m_recursiveMover ) {
116  m_recursiveMover->changeProcessed();
117  QTimer::singleShot( 0, m_recursiveMover, SLOT(replayNext()) );
118  return;
119  }
120 
121  mChangeRecorder->changeProcessed();
122  if ( !mChangeRecorder->isEmpty() )
123  scheduler->scheduleChangeReplay();
124  scheduler->taskDone();
125  }
126 
127  void slotAbortRequested();
128 
129  void slotDeliveryDone( KJob* job );
130  void slotCollectionSyncDone( KJob *job );
131  void slotLocalListDone( KJob *job );
132  void slotSynchronizeCollection( const Collection &col );
133  void slotCollectionListDone( KJob *job );
134  void slotSynchronizeCollectionAttributes( const Collection &col );
135  void slotCollectionListForAttributesDone( KJob *job );
136  void slotCollectionAttributesSyncDone( KJob *job );
137 
138  void slotItemSyncDone( KJob *job );
139 
140  void slotPercent( KJob* job, unsigned long percent );
141  void slotDelayedEmitProgress();
142  void slotDeleteResourceCollection();
143  void slotDeleteResourceCollectionDone( KJob *job );
144  void slotCollectionDeletionDone( KJob *job );
145 
146  void slotInvalidateCache( const Akonadi::Collection &collection );
147 
148  void slotPrepareItemRetrieval( const Akonadi::Item &item );
149  void slotPrepareItemRetrievalResult( KJob* job );
150 
151  void changeCommittedResult( KJob* job );
152 
153  void slotRecursiveMoveReplay( RecursiveMover *mover );
154  void slotRecursiveMoveReplayResult( KJob *job );
155 
156  void slotSessionReconnected()
157  {
158  Q_Q( ResourceBase );
159 
160  new ResourceSelectJob( q->identifier() );
161  }
162 
163  void createItemSyncInstanceIfMissing()
164  {
165  Q_Q( ResourceBase );
166  Q_ASSERT_X( scheduler->currentTask().type == ResourceScheduler::SyncCollection,
167  "createItemSyncInstance", "Calling items retrieval methods although no item retrieval is in progress" );
168  if ( !mItemSyncer ) {
169  mItemSyncer = new ItemSync( q->currentCollection() );
170  mItemSyncer->setTransactionMode( mItemTransactionMode );
171  if ( mItemSyncFetchScope )
172  mItemSyncer->setFetchScope( *mItemSyncFetchScope );
173  mItemSyncer->setProperty( "collection", QVariant::fromValue( q->currentCollection() ) );
174  connect( mItemSyncer, SIGNAL(percent(KJob*,ulong)), q, SLOT(slotPercent(KJob*,ulong)) );
175  connect( mItemSyncer, SIGNAL(result(KJob*)), q, SLOT(slotItemSyncDone(KJob*)) );
176  }
177  Q_ASSERT( mItemSyncer );
178  }
179 
180  public Q_SLOTS:
181  // Dump the state of the scheduler
182  Q_SCRIPTABLE QString dumpToString() const
183  {
184  Q_Q( const ResourceBase );
185  QString retVal;
186  QMetaObject::invokeMethod( const_cast<ResourceBase *>(q), "dumpResourceToString", Qt::DirectConnection, Q_RETURN_ARG(QString, retVal) );
187  return scheduler->dumpToString() + QLatin1Char('\n') + retVal;
188  }
189 
190  Q_SCRIPTABLE void dump()
191  {
192  scheduler->dump();
193  }
194 
195  Q_SCRIPTABLE void clear()
196  {
197  scheduler->clear();
198  }
199 
200 
201  protected Q_SLOTS:
202  // reimplementations from AgentbBasePrivate, containing sanity checks that only apply to resources
203  // such as making sure that RIDs are present as well as translations of cross-resource moves
204  // TODO: we could possibly add recovery code for no-RID notifications by re-enquing those to the change recorder
205  // as the corresponding Add notifications, although that contains a risk of endless fail/retry loops
206 
207  void itemAdded(const Akonadi::Item& item, const Akonadi::Collection& collection)
208  {
209  if ( collection.remoteId().isEmpty() ) {
210  changeProcessed();
211  return;
212  }
213  AgentBasePrivate::itemAdded( item, collection );
214  }
215 
216  void itemChanged(const Akonadi::Item& item, const QSet< QByteArray >& partIdentifiers)
217  {
218  if ( item.remoteId().isEmpty() ) {
219  changeProcessed();
220  return;
221  }
222  AgentBasePrivate::itemChanged( item, partIdentifiers );
223  }
224 
225  void itemsFlagsChanged(const Item::List& items, const QSet< QByteArray >& addedFlags,
226  const QSet< QByteArray >& removedFlags)
227  {
228  if (addedFlags.isEmpty() && removedFlags.isEmpty() ) {
229  changeProcessed();
230  return;
231  }
232 
233  Item::List validItems;
234  foreach ( const Akonadi::Item &item, items ) {
235  if ( !item.remoteId().isEmpty() ) {
236  validItems << item;
237  }
238  }
239  if ( validItems.isEmpty() ) {
240  changeProcessed();
241  return;
242  }
243 
244  AgentBasePrivate::itemsFlagsChanged( validItems, addedFlags, removedFlags );
245  }
246 
247  // TODO move the move translation code from AgentBasePrivate here, it's wrong for agents
248  void itemMoved(const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &destination)
249  {
250  if ( item.remoteId().isEmpty() || destination.remoteId().isEmpty() || destination == source ) {
251  changeProcessed();
252  return;
253  }
254  AgentBasePrivate::itemMoved( item, source, destination );
255  }
256 
257  void itemsMoved(const Item::List& items, const Collection& source, const Collection& destination)
258  {
259  if ( destination.remoteId().isEmpty() || destination == source ) {
260  changeProcessed();
261  return;
262  }
263 
264  Item::List validItems;
265  foreach ( const Akonadi::Item &item, items ) {
266  if ( !item.remoteId().isEmpty() ) {
267  validItems << item;
268  }
269  }
270  if ( validItems.isEmpty() ) {
271  changeProcessed();
272  return;
273  }
274 
275  AgentBasePrivate::itemsMoved( validItems, source, destination );
276  }
277 
278  void itemRemoved(const Akonadi::Item& item)
279  {
280  if ( item.remoteId().isEmpty() ) {
281  changeProcessed();
282  return;
283  }
284  AgentBasePrivate::itemRemoved( item );
285  }
286 
287  void itemsRemoved(const Item::List& items)
288  {
289  Item::List validItems;
290  foreach ( const Akonadi::Item &item, items ) {
291  if ( !item.remoteId().isEmpty() ) {
292  validItems << item;
293  }
294  }
295  if ( validItems.isEmpty() ) {
296  changeProcessed();
297  return;
298  }
299 
300  AgentBasePrivate::itemsRemoved( validItems );
301  }
302 
303  void collectionAdded(const Akonadi::Collection& collection, const Akonadi::Collection& parent)
304  {
305  if ( parent.remoteId().isEmpty() ) {
306  changeProcessed();
307  return;
308  }
309  AgentBasePrivate::collectionAdded( collection, parent );
310  }
311 
312  void collectionChanged(const Akonadi::Collection& collection)
313  {
314  if ( collection.remoteId().isEmpty() ) {
315  changeProcessed();
316  return;
317  }
318  AgentBasePrivate::collectionChanged( collection );
319  }
320 
321  void collectionChanged(const Akonadi::Collection& collection, const QSet< QByteArray >& partIdentifiers)
322  {
323  if ( collection.remoteId().isEmpty() ) {
324  changeProcessed();
325  return;
326  }
327  AgentBasePrivate::collectionChanged( collection, partIdentifiers );
328  }
329 
330  void collectionMoved(const Akonadi::Collection& collection, const Akonadi::Collection& source, const Akonadi::Collection& destination)
331  {
332  // unknown destination or source == destination means we can't do/don't have to do anything
333  if ( destination.remoteId().isEmpty() || source == destination ) {
334  changeProcessed();
335  return;
336  }
337 
338  // inter-resource moves, requires we know which resources the source and destination are in though
339  if ( !source.resource().isEmpty() && !destination.resource().isEmpty() && source.resource() != destination.resource() ) {
340  if ( source.resource() == q_ptr->identifier() ) { // moved away from us
341  AgentBasePrivate::collectionRemoved( collection );
342  } else if ( destination.resource() == q_ptr->identifier() ) { // moved to us
343  scheduler->taskDone(); // stop change replay for now
344  RecursiveMover *mover = new RecursiveMover( this );
345  mover->setCollection( collection, destination );
346  scheduler->scheduleMoveReplay( collection, mover );
347  }
348  return;
349  }
350 
351  // intra-resource move, requires the moved collection to have a valid id though
352  if ( collection.remoteId().isEmpty() ) {
353  changeProcessed();
354  return;
355  }
356 
357  // intra-resource move, ie. something we can handle internally
358  AgentBasePrivate::collectionMoved( collection, source, destination );
359  }
360 
361  void collectionRemoved(const Akonadi::Collection& collection)
362  {
363  if ( collection.remoteId().isEmpty() ) {
364  changeProcessed();
365  return;
366  }
367  AgentBasePrivate::collectionRemoved( collection );
368  }
369 
370  public:
371  // synchronize states
372  Collection currentCollection;
373 
374  ResourceScheduler *scheduler;
375  ItemSync *mItemSyncer;
376  ItemFetchScope *mItemSyncFetchScope;
377  ItemSync::TransactionMode mItemTransactionMode;
378  CollectionSync *mCollectionSyncer;
379  bool mHierarchicalRid;
380  QTimer mProgressEmissionCompressor;
381  int mUnemittedProgress;
382  QMap<Akonadi::Collection::Id, QVariantMap> mUnemittedAdvancedStatus;
383  bool mAutomaticProgressReporting;
384  QPointer<RecursiveMover> m_recursiveMover;
385 };
386 
387 ResourceBase::ResourceBase( const QString & id )
388  : AgentBase( new ResourceBasePrivate( this ), id )
389 {
390  Q_D( ResourceBase );
391 
392  new Akonadi__ResourceAdaptor( this );
393 
394  d->scheduler = new ResourceScheduler( this );
395 
396  d->mChangeRecorder->setChangeRecordingEnabled( true );
397  d->mChangeRecorder->setCollectionMoveTranslationEnabled( false ); // we deal with this ourselves
398  connect( d->mChangeRecorder, SIGNAL(changesAdded()),
399  d->scheduler, SLOT(scheduleChangeReplay()) );
400 
401  d->mChangeRecorder->setResourceMonitored( d->mId.toLatin1() );
402  d->mChangeRecorder->fetchCollection( true );
403 
404  connect( d->scheduler, SIGNAL(executeFullSync()),
405  SLOT(retrieveCollections()) );
406  connect( d->scheduler, SIGNAL(executeCollectionTreeSync()),
407  SLOT(retrieveCollections()) );
408  connect( d->scheduler, SIGNAL(executeCollectionSync(Akonadi::Collection)),
409  SLOT(slotSynchronizeCollection(Akonadi::Collection)) );
410  connect( d->scheduler, SIGNAL(executeCollectionAttributesSync(Akonadi::Collection)),
411  SLOT(slotSynchronizeCollectionAttributes(Akonadi::Collection)) );
412  connect( d->scheduler, SIGNAL(executeItemFetch(Akonadi::Item,QSet<QByteArray>)),
413  SLOT(slotPrepareItemRetrieval(Akonadi::Item)) );
414  connect( d->scheduler, SIGNAL(executeResourceCollectionDeletion()),
415  SLOT(slotDeleteResourceCollection()) );
416  connect ( d->scheduler, SIGNAL(executeCacheInvalidation(Akonadi::Collection)),
417  SLOT(slotInvalidateCache(Akonadi::Collection)) );
418  connect( d->scheduler, SIGNAL(status(int,QString)),
419  SIGNAL(status(int,QString)) );
420  connect( d->scheduler, SIGNAL(executeChangeReplay()),
421  d->mChangeRecorder, SLOT(replayNext()) );
422  connect( d->scheduler, SIGNAL(executeRecursiveMoveReplay(RecursiveMover*)),
423  SLOT(slotRecursiveMoveReplay(RecursiveMover*)) );
424  connect( d->scheduler, SIGNAL(fullSyncComplete()), SIGNAL(synchronized()) );
425  connect( d->scheduler, SIGNAL(collectionTreeSyncComplete()), SIGNAL(collectionTreeSynchronized()) );
426  connect( d->mChangeRecorder, SIGNAL(nothingToReplay()), d->scheduler, SLOT(taskDone()) );
427  connect( d->mChangeRecorder, SIGNAL(collectionRemoved(Akonadi::Collection)),
428  d->scheduler, SLOT(collectionRemoved(Akonadi::Collection)) );
429  connect( this, SIGNAL(abortRequested()), this, SLOT(slotAbortRequested()) );
430  connect( this, SIGNAL(synchronized()), d->scheduler, SLOT(taskDone()) );
431  connect( this, SIGNAL(collectionTreeSynchronized()), d->scheduler, SLOT(taskDone()) );
432  connect( this, SIGNAL(agentNameChanged(QString)),
433  this, SIGNAL(nameChanged(QString)) );
434 
435  connect( &d->mProgressEmissionCompressor, SIGNAL(timeout()),
436  this, SLOT(slotDelayedEmitProgress()) );
437 
438  d->scheduler->setOnline( d->mOnline );
439  if ( !d->mChangeRecorder->isEmpty() )
440  d->scheduler->scheduleChangeReplay();
441 
442  new ResourceSelectJob( identifier() );
443 
444  connect( d->mChangeRecorder->session(), SIGNAL(reconnected()), SLOT(slotSessionReconnected()) );
445 }
446 
447 ResourceBase::~ResourceBase()
448 {
449 }
450 
451 void ResourceBase::synchronize()
452 {
453  d_func()->scheduler->scheduleFullSync();
454 }
455 
456 void ResourceBase::setName( const QString &name )
457 {
458  AgentBase::setAgentName( name );
459 }
460 
461 QString ResourceBase::name() const
462 {
463  return AgentBase::agentName();
464 }
465 
466 QString ResourceBase::parseArguments( int argc, char **argv )
467 {
468  QString identifier;
469  if ( argc < 3 ) {
470  kDebug() << "Not enough arguments passed...";
471  exit( 1 );
472  }
473 
474  for ( int i = 1; i < argc - 1; ++i ) {
475  if ( QLatin1String( argv[ i ] ) == QLatin1String( "--identifier" ) )
476  identifier = QLatin1String( argv[ i + 1 ] );
477  }
478 
479  if ( identifier.isEmpty() ) {
480  kDebug() << "Identifier argument missing";
481  exit( 1 );
482  }
483 
484  const QFileInfo fi( QString::fromLocal8Bit( argv[0] ) );
485  // strip off full path and possible .exe suffix
486  const QByteArray catalog = fi.baseName().toLatin1();
487 
488  KCmdLineArgs::init( argc, argv, ServerManager::addNamespace( identifier ).toLatin1(), catalog,
489  ki18nc( "@title application name", "Akonadi Resource" ), KDEPIMLIBS_VERSION,
490  ki18nc( "@title application description", "Akonadi Resource" ) );
491 
492  KCmdLineOptions options;
493  options.add( "identifier <argument>",
494  ki18nc( "@label commandline option", "Resource identifier" ) );
495  KCmdLineArgs::addCmdLineOptions( options );
496 
497  return identifier;
498 }
499 
500 int ResourceBase::init( ResourceBase *r )
501 {
502  QApplication::setQuitOnLastWindowClosed( false );
503  KGlobal::locale()->insertCatalog( QLatin1String( "libakonadi" ) );
504  int rv = kapp->exec();
505  delete r;
506  return rv;
507 }
508 
509 void ResourceBasePrivate::slotAbortRequested()
510 {
511  Q_Q( ResourceBase );
512 
513  scheduler->cancelQueues();
514  QMetaObject::invokeMethod( q, "abortActivity" );
515 }
516 
517 void ResourceBase::itemRetrieved( const Item &item )
518 {
519  Q_D( ResourceBase );
520  Q_ASSERT( d->scheduler->currentTask().type == ResourceScheduler::FetchItem );
521  if ( !item.isValid() ) {
522  d->scheduler->currentTask().sendDBusReplies( i18nc( "@info", "Invalid item retrieved" ) );
523  d->scheduler->taskDone();
524  return;
525  }
526 
527  Item i( item );
528  QSet<QByteArray> requestedParts = d->scheduler->currentTask().itemParts;
529  foreach ( const QByteArray &part, requestedParts ) {
530  if ( !item.loadedPayloadParts().contains( part ) ) {
531  kWarning() << "Item does not provide part" << part;
532  }
533  }
534 
535  ItemModifyJob *job = new ItemModifyJob( i );
536  // FIXME: remove once the item with which we call retrieveItem() has a revision number
537  job->disableRevisionCheck();
538  connect( job, SIGNAL(result(KJob*)), SLOT(slotDeliveryDone(KJob*)) );
539 }
540 
541 void ResourceBasePrivate::slotDeliveryDone(KJob * job)
542 {
543  Q_Q( ResourceBase );
544  Q_ASSERT( scheduler->currentTask().type == ResourceScheduler::FetchItem );
545  if ( job->error() ) {
546  emit q->error( i18nc( "@info", "Error while creating item: %1", job->errorString() ) );
547  }
548  scheduler->currentTask().sendDBusReplies( job->error() ? job->errorString() : QString() );
549  scheduler->taskDone();
550 }
551 
552 void ResourceBase::collectionAttributesRetrieved( const Collection &collection )
553 {
554  Q_D( ResourceBase );
555  Q_ASSERT( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionAttributes );
556  if ( !collection.isValid() ) {
557  emit attributesSynchronized( d->scheduler->currentTask().collection.id() );
558  d->scheduler->taskDone();
559  return;
560  }
561 
562  CollectionModifyJob *job = new CollectionModifyJob( collection );
563  connect( job, SIGNAL(result(KJob*)), SLOT(slotCollectionAttributesSyncDone(KJob*)) );
564 }
565 
566 void ResourceBasePrivate::slotCollectionAttributesSyncDone(KJob * job)
567 {
568  Q_Q( ResourceBase );
569  Q_ASSERT( scheduler->currentTask().type == ResourceScheduler::SyncCollectionAttributes );
570  if ( job->error() ) {
571  emit q->error( i18nc( "@info", "Error while updating collection: %1", job->errorString() ) );
572  }
573  emit q->attributesSynchronized( scheduler->currentTask().collection.id() );
574  scheduler->taskDone();
575 }
576 
577 void ResourceBasePrivate::slotDeleteResourceCollection()
578 {
579  Q_Q( ResourceBase );
580 
581  CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::FirstLevel );
582  job->fetchScope().setResource( q->identifier() );
583  connect( job, SIGNAL(result(KJob*)), q, SLOT(slotDeleteResourceCollectionDone(KJob*)) );
584 }
585 
586 void ResourceBasePrivate::slotDeleteResourceCollectionDone( KJob *job )
587 {
588  Q_Q( ResourceBase );
589  if ( job->error() ) {
590  emit q->error( job->errorString() );
591  scheduler->taskDone();
592  } else {
593  const CollectionFetchJob *fetchJob = static_cast<const CollectionFetchJob*>( job );
594 
595  if ( !fetchJob->collections().isEmpty() ) {
596  CollectionDeleteJob *job = new CollectionDeleteJob( fetchJob->collections().first() );
597  connect( job, SIGNAL(result(KJob*)), q, SLOT(slotCollectionDeletionDone(KJob*)) );
598  } else {
599  // there is no resource collection, so just ignore the request
600  scheduler->taskDone();
601  }
602  }
603 }
604 
605 void ResourceBasePrivate::slotCollectionDeletionDone( KJob *job )
606 {
607  Q_Q( ResourceBase );
608  if ( job->error() ) {
609  emit q->error( job->errorString() );
610  }
611 
612  scheduler->taskDone();
613 }
614 
615 void ResourceBasePrivate::slotInvalidateCache( const Akonadi::Collection &collection )
616 {
617  Q_Q( ResourceBase );
618  InvalidateCacheJob *job = new InvalidateCacheJob( collection, q );
619  connect( job, SIGNAL(result(KJob*)), scheduler, SLOT(taskDone()) );
620 }
621 
622 void ResourceBase::changeCommitted( const Item& item )
623 {
624  changesCommitted( Item::List() << item );
625 }
626 
627 void ResourceBase::changesCommitted(const Item::List& items)
628 {
629  ItemModifyJob *job = new ItemModifyJob( items );
630  job->d_func()->setClean();
631  job->disableRevisionCheck(); // TODO: remove, but where/how do we handle the error?
632  job->setIgnorePayload( true ); // we only want to reset the dirty flag and update the remote id
633  connect( job, SIGNAL(finished(KJob*)), this, SLOT(changeCommittedResult(KJob*)) );
634 }
635 
636 void ResourceBase::changeCommitted( const Collection &collection )
637 {
638  CollectionModifyJob *job = new CollectionModifyJob( collection );
639  connect( job, SIGNAL(result(KJob*)), SLOT(changeCommittedResult(KJob*)) );
640 }
641 
642 void ResourceBasePrivate::changeCommittedResult( KJob *job )
643 {
644  Q_Q( ResourceBase );
645  if ( qobject_cast<CollectionModifyJob*>( job ) ) {
646  if ( job->error() ) {
647  emit q->error( i18nc( "@info", "Updating local collection failed: %1.", job->errorText() ) );
648  }
649  mChangeRecorder->d_ptr->invalidateCache( static_cast<CollectionModifyJob*>( job )->collection() );
650  } else {
651  // TODO: Error handling for item changes?
652  // Item cache is invalidated by ItemModifyJob
653  }
654 
655  changeProcessed();
656 }
657 
658 bool ResourceBase::requestItemDelivery( qint64 uid, const QString &remoteId,
659  const QString &mimeType, const QStringList &parts )
660 {
661  return requestItemDeliveryV2( uid, remoteId, mimeType, parts ).isEmpty();
662 }
663 
664 QString ResourceBase::requestItemDeliveryV2(qint64 uid, const QString &remoteId, const QString &mimeType, const QStringList &_parts)
665 {
666  Q_D( ResourceBase );
667  if ( !isOnline() ) {
668  const QString errorMsg = i18nc( "@info", "Cannot fetch item in offline mode." );
669  emit error( errorMsg );
670  return errorMsg;
671  }
672 
673  setDelayedReply( true );
674  // FIXME: we need at least the revision number too
675  Item item( uid );
676  item.setMimeType( mimeType );
677  item.setRemoteId( remoteId );
678 
679  QSet<QByteArray> parts;
680  Q_FOREACH( const QString &str, _parts )
681  parts.insert( str.toLatin1() );
682 
683  d->scheduler->scheduleItemFetch( item, parts, message() );
684 
685  return QString();
686 
687 }
688 
689 void ResourceBase::collectionsRetrieved( const Collection::List & collections )
690 {
691  Q_D( ResourceBase );
692  Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
693  d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
694  "ResourceBase::collectionsRetrieved()",
695  "Calling collectionsRetrieved() although no collection retrieval is in progress" );
696  if ( !d->mCollectionSyncer ) {
697  d->mCollectionSyncer = new CollectionSync( identifier() );
698  d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
699  connect( d->mCollectionSyncer, SIGNAL(percent(KJob*,ulong)), SLOT(slotPercent(KJob*,ulong)) );
700  connect( d->mCollectionSyncer, SIGNAL(result(KJob*)), SLOT(slotCollectionSyncDone(KJob*)) );
701  }
702  d->mCollectionSyncer->setRemoteCollections( collections );
703 }
704 
705 void ResourceBase::collectionsRetrievedIncremental( const Collection::List & changedCollections,
706  const Collection::List & removedCollections )
707 {
708  Q_D( ResourceBase );
709  Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
710  d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
711  "ResourceBase::collectionsRetrievedIncremental()",
712  "Calling collectionsRetrievedIncremental() although no collection retrieval is in progress" );
713  if ( !d->mCollectionSyncer ) {
714  d->mCollectionSyncer = new CollectionSync( identifier() );
715  d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
716  connect( d->mCollectionSyncer, SIGNAL(percent(KJob*,ulong)), SLOT(slotPercent(KJob*,ulong)) );
717  connect( d->mCollectionSyncer, SIGNAL(result(KJob*)), SLOT(slotCollectionSyncDone(KJob*)) );
718  }
719  d->mCollectionSyncer->setRemoteCollections( changedCollections, removedCollections );
720 }
721 
722 void ResourceBase::setCollectionStreamingEnabled( bool enable )
723 {
724  Q_D( ResourceBase );
725  Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
726  d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
727  "ResourceBase::setCollectionStreamingEnabled()",
728  "Calling setCollectionStreamingEnabled() although no collection retrieval is in progress" );
729  if ( !d->mCollectionSyncer ) {
730  d->mCollectionSyncer = new CollectionSync( identifier() );
731  d->mCollectionSyncer->setHierarchicalRemoteIds( d->mHierarchicalRid );
732  connect( d->mCollectionSyncer, SIGNAL(percent(KJob*,ulong)), SLOT(slotPercent(KJob*,ulong)) );
733  connect( d->mCollectionSyncer, SIGNAL(result(KJob*)), SLOT(slotCollectionSyncDone(KJob*)) );
734  }
735  d->mCollectionSyncer->setStreamingEnabled( enable );
736 }
737 
738 void ResourceBase::collectionsRetrievalDone()
739 {
740  Q_D( ResourceBase );
741  Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ||
742  d->scheduler->currentTask().type == ResourceScheduler::SyncAll,
743  "ResourceBase::collectionsRetrievalDone()",
744  "Calling collectionsRetrievalDone() although no collection retrieval is in progress" );
745  // streaming enabled, so finalize the sync
746  if ( d->mCollectionSyncer ) {
747  d->mCollectionSyncer->retrievalDone();
748  }
749  // user did the sync himself, we are done now
750  else {
751  // FIXME: we need the same special case for SyncAll as in slotCollectionSyncDone here!
752  d->scheduler->taskDone();
753  }
754 }
755 
756 void ResourceBasePrivate::slotCollectionSyncDone( KJob * job )
757 {
758  Q_Q( ResourceBase );
759  mCollectionSyncer = 0;
760  if ( job->error() ) {
761  if ( job->error() != Job::UserCanceled )
762  emit q->error( job->errorString() );
763  } else {
764  if ( scheduler->currentTask().type == ResourceScheduler::SyncAll ) {
765  CollectionFetchJob *list = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive );
766  list->setFetchScope( q->changeRecorder()->collectionFetchScope() );
767  list->fetchScope().setResource( mId );
768  q->connect( list, SIGNAL(result(KJob*)), q, SLOT(slotLocalListDone(KJob*)) );
769  return;
770  } else if ( scheduler->currentTask().type == ResourceScheduler::SyncCollectionTree ) {
771  scheduler->scheduleCollectionTreeSyncCompletion();
772  }
773  }
774  scheduler->taskDone();
775 }
776 
777 void ResourceBasePrivate::slotLocalListDone( KJob * job )
778 {
779  Q_Q( ResourceBase );
780  if ( job->error() ) {
781  emit q->error( job->errorString() );
782  } else {
783  Collection::List cols = static_cast<CollectionFetchJob*>( job )->collections();
784  foreach ( const Collection &col, cols ) {
785  scheduler->scheduleSync( col );
786  }
787  scheduler->scheduleFullSyncCompletion();
788  }
789  scheduler->taskDone();
790 }
791 
792 void ResourceBasePrivate::slotSynchronizeCollection( const Collection &col )
793 {
794  Q_Q( ResourceBase );
795  currentCollection = col;
796  // check if this collection actually can contain anything
797  QStringList contentTypes = currentCollection.contentMimeTypes();
798  contentTypes.removeAll( Collection::mimeType() );
799  contentTypes.removeAll( Collection::virtualMimeType() );
800  if ( !contentTypes.isEmpty() || col.isVirtual() ) {
801  if ( mAutomaticProgressReporting ) {
802  emit q->status( AgentBase::Running, i18nc( "@info:status", "Syncing folder '%1'", currentCollection.displayName() ) );
803  }
804  q->retrieveItems( currentCollection );
805  return;
806  }
807  scheduler->taskDone();
808 }
809 
810 void ResourceBasePrivate::slotSynchronizeCollectionAttributes( const Collection &col )
811 {
812  Q_Q( ResourceBase );
813  QMetaObject::invokeMethod( q, "retrieveCollectionAttributes", Q_ARG( Akonadi::Collection, col ) );
814 }
815 
816 void ResourceBasePrivate::slotPrepareItemRetrieval( const Akonadi::Item &item )
817 {
818  Q_Q( ResourceBase );
819  ItemFetchJob *fetch = new ItemFetchJob( item, this );
820  fetch->fetchScope().setAncestorRetrieval( q->changeRecorder()->itemFetchScope().ancestorRetrieval() );
821  fetch->fetchScope().setCacheOnly( true );
822 
823  // copy list of attributes to fetch
824  const QSet<QByteArray> attributes = q->changeRecorder()->itemFetchScope().attributes();
825  foreach ( const QByteArray &attribute, attributes )
826  fetch->fetchScope().fetchAttribute( attribute );
827 
828  q->connect( fetch, SIGNAL(result(KJob*)), SLOT(slotPrepareItemRetrievalResult(KJob*)) );
829 }
830 
831 void ResourceBasePrivate::slotPrepareItemRetrievalResult( KJob* job )
832 {
833  Q_Q( ResourceBase );
834  Q_ASSERT_X( scheduler->currentTask().type == ResourceScheduler::FetchItem,
835  "ResourceBasePrivate::slotPrepareItemRetrievalResult()",
836  "Preparing item retrieval although no item retrieval is in progress" );
837  if ( job->error() ) {
838  q->cancelTask( job->errorText() );
839  return;
840  }
841  ItemFetchJob *fetch = qobject_cast<ItemFetchJob*>( job );
842  if ( fetch->items().count() != 1 ) {
843  q->cancelTask( i18n( "The requested item no longer exists" ) );
844  return;
845  }
846  const Item item = fetch->items().first();
847  const QSet<QByteArray> parts = scheduler->currentTask().itemParts;
848  if ( !q->retrieveItem( item, parts ) )
849  q->cancelTask();
850 }
851 
852 void ResourceBasePrivate::slotRecursiveMoveReplay( RecursiveMover *mover )
853 {
854  Q_Q( ResourceBase );
855  Q_ASSERT( mover );
856  Q_ASSERT( !m_recursiveMover );
857  m_recursiveMover = mover;
858  connect( mover, SIGNAL(result(KJob*)), q, SLOT(slotRecursiveMoveReplayResult(KJob*)) );
859  mover->start();
860 }
861 
862 void ResourceBasePrivate::slotRecursiveMoveReplayResult( KJob *job )
863 {
864  Q_Q( ResourceBase );
865  m_recursiveMover = 0;
866 
867  if ( job->error() ) {
868  q->deferTask();
869  return;
870  }
871 
872  changeProcessed();
873 }
874 
875 void ResourceBase::itemsRetrievalDone()
876 {
877  Q_D( ResourceBase );
878  // streaming enabled, so finalize the sync
879  if ( d->mItemSyncer ) {
880  d->mItemSyncer->deliveryDone();
881  }
882  // user did the sync himself, we are done now
883  else {
884  d->scheduler->taskDone();
885  }
886 }
887 
888 void ResourceBase::clearCache()
889 {
890  Q_D( ResourceBase );
891  d->scheduler->scheduleResourceCollectionDeletion();
892 }
893 
894 void ResourceBase::invalidateCache(const Collection& collection)
895 {
896  Q_D( ResourceBase );
897  d->scheduler->scheduleCacheInvalidation( collection );
898 }
899 
900 Collection ResourceBase::currentCollection() const
901 {
902  Q_D( const ResourceBase );
903  Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::SyncCollection ,
904  "ResourceBase::currentCollection()",
905  "Trying to access current collection although no item retrieval is in progress" );
906  return d->currentCollection;
907 }
908 
909 Item ResourceBase::currentItem() const
910 {
911  Q_D( const ResourceBase );
912  Q_ASSERT_X( d->scheduler->currentTask().type == ResourceScheduler::FetchItem ,
913  "ResourceBase::currentItem()",
914  "Trying to access current item although no item retrieval is in progress" );
915  return d->scheduler->currentTask().item;
916 }
917 
918 void ResourceBase::synchronizeCollectionTree()
919 {
920  d_func()->scheduler->scheduleCollectionTreeSync();
921 }
922 
923 void ResourceBase::cancelTask()
924 {
925  Q_D( ResourceBase );
926  switch ( d->scheduler->currentTask().type ) {
927  case ResourceScheduler::FetchItem:
928  itemRetrieved( Item() ); // sends the error reply and
929  break;
930  case ResourceScheduler::ChangeReplay:
931  d->changeProcessed();
932  break;
933  case ResourceScheduler::SyncCollectionTree:
934  case ResourceScheduler::SyncAll:
935  if ( d->mCollectionSyncer )
936  d->mCollectionSyncer->rollback();
937  else
938  d->scheduler->taskDone();
939  break;
940  case ResourceScheduler::SyncCollection:
941  if ( d->mItemSyncer ) {
942  d->mItemSyncer->rollback();
943  } else {
944  d->scheduler->taskDone();
945  }
946  break;
947  default:
948  d->scheduler->taskDone();
949  }
950 }
951 
952 void ResourceBase::cancelTask( const QString &msg )
953 {
954  cancelTask();
955 
956  emit error( msg );
957 }
958 
959 void ResourceBase::deferTask()
960 {
961  Q_D( ResourceBase );
962  d->scheduler->deferTask();
963 }
964 
965 void ResourceBase::doSetOnline( bool state )
966 {
967  d_func()->scheduler->setOnline( state );
968 }
969 
970 void ResourceBase::synchronizeCollection( qint64 collectionId )
971 {
972  synchronizeCollection( collectionId, false );
973 }
974 
975 void ResourceBase::synchronizeCollection( qint64 collectionId, bool recursive )
976 {
977  CollectionFetchJob* job = new CollectionFetchJob( Collection( collectionId ), recursive ? CollectionFetchJob::Recursive : CollectionFetchJob::Base );
978  job->setFetchScope( changeRecorder()->collectionFetchScope() );
979  job->fetchScope().setResource( identifier() );
980  job->setProperty( "recursive", recursive );
981  connect( job, SIGNAL(result(KJob*)), SLOT(slotCollectionListDone(KJob*)) );
982 }
983 
984 void ResourceBasePrivate::slotCollectionListDone( KJob *job )
985 {
986  if ( !job->error() ) {
987  Collection::List list = static_cast<CollectionFetchJob*>( job )->collections();
988  if ( !list.isEmpty() ) {
989  if ( job->property( "recursive" ).toBool() ) {
990  Q_FOREACH ( const Collection &collection, list ) {
991  scheduler->scheduleSync( collection );
992  }
993  } else {
994  scheduler->scheduleSync( list.first() );
995  }
996  }
997  }
998  // TODO: error handling
999 }
1000 
1001 void ResourceBase::synchronizeCollectionAttributes( qint64 collectionId )
1002 {
1003  CollectionFetchJob* job = new CollectionFetchJob( Collection( collectionId ), CollectionFetchJob::Base );
1004  job->setFetchScope( changeRecorder()->collectionFetchScope() );
1005  job->fetchScope().setResource( identifier() );
1006  connect( job, SIGNAL(result(KJob*)), SLOT(slotCollectionListForAttributesDone(KJob*)) );
1007 }
1008 
1009 void ResourceBasePrivate::slotCollectionListForAttributesDone( KJob *job )
1010 {
1011  if ( !job->error() ) {
1012  Collection::List list = static_cast<CollectionFetchJob*>( job )->collections();
1013  if ( !list.isEmpty() ) {
1014  Collection col = list.first();
1015  scheduler->scheduleAttributesSync( col );
1016  }
1017  }
1018  // TODO: error handling
1019 }
1020 
1021 void ResourceBase::setTotalItems( int amount )
1022 {
1023  kDebug() << amount;
1024  Q_D( ResourceBase );
1025  setItemStreamingEnabled( true );
1026  if ( d->mItemSyncer ) {
1027  d->mItemSyncer->setTotalItems( amount );
1028  }
1029 }
1030 
1031 void ResourceBase::setItemStreamingEnabled( bool enable )
1032 {
1033  Q_D( ResourceBase );
1034  d->createItemSyncInstanceIfMissing();
1035  if ( d->mItemSyncer ) {
1036  d->mItemSyncer->setStreamingEnabled( enable );
1037  }
1038 }
1039 
1040 void ResourceBase::itemsRetrieved( const Item::List &items )
1041 {
1042  Q_D( ResourceBase );
1043  d->createItemSyncInstanceIfMissing();
1044  if ( d->mItemSyncer ) {
1045  d->mItemSyncer->setFullSyncItems( items );
1046  }
1047 }
1048 
1049 void ResourceBase::itemsRetrievedIncremental( const Item::List &changedItems,
1050  const Item::List &removedItems )
1051 {
1052  Q_D( ResourceBase );
1053  d->createItemSyncInstanceIfMissing();
1054  if ( d->mItemSyncer ) {
1055  d->mItemSyncer->setIncrementalSyncItems( changedItems, removedItems );
1056  }
1057 }
1058 
1059 void ResourceBasePrivate::slotItemSyncDone( KJob *job )
1060 {
1061  mItemSyncer = 0;
1062  Q_Q( ResourceBase );
1063  if ( job->error() && job->error() != Job::UserCanceled ) {
1064  emit q->error( job->errorString() );
1065  }
1066  scheduler->taskDone();
1067 }
1068 
1069 void ResourceBasePrivate::slotDelayedEmitProgress()
1070 {
1071  Q_Q( ResourceBase );
1072  if ( mAutomaticProgressReporting ) {
1073  emit q->percent( mUnemittedProgress );
1074 
1075  Q_FOREACH( const QVariantMap &statusMap, mUnemittedAdvancedStatus ) {
1076  emit q->advancedStatus( statusMap );
1077  }
1078  }
1079  mUnemittedProgress = 0;
1080  mUnemittedAdvancedStatus.clear();
1081 }
1082 
1083 void ResourceBasePrivate::slotPercent( KJob *job, unsigned long percent )
1084 {
1085  mUnemittedProgress = percent;
1086 
1087  const Collection collection = job->property( "collection" ).value<Collection>();
1088  if ( collection.isValid() ) {
1089  QVariantMap statusMap;
1090  statusMap.insert( QLatin1String( "key" ), QString::fromLatin1( "collectionSyncProgress" ) );
1091  statusMap.insert( QLatin1String( "collectionId" ), collection.id() );
1092  statusMap.insert( QLatin1String( "percent" ), static_cast<unsigned int>( percent ) );
1093 
1094  mUnemittedAdvancedStatus[collection.id()] = statusMap;
1095  }
1096  // deliver completion right away, intermediate progress at 1s intervals
1097  if ( percent == 100 ) {
1098  mProgressEmissionCompressor.stop();
1099  slotDelayedEmitProgress();
1100  } else if ( !mProgressEmissionCompressor.isActive() ) {
1101  mProgressEmissionCompressor.start();
1102  }
1103 }
1104 
1105 void ResourceBase::setHierarchicalRemoteIdentifiersEnabled( bool enable )
1106 {
1107  Q_D( ResourceBase );
1108  d->mHierarchicalRid = enable;
1109 }
1110 
1111 void ResourceBase::scheduleCustomTask( QObject *receiver, const char *method, const QVariant &argument, SchedulePriority priority )
1112 {
1113  Q_D( ResourceBase );
1114  d->scheduler->scheduleCustomTask( receiver, method, argument, priority );
1115 }
1116 
1117 void ResourceBase::taskDone()
1118 {
1119  Q_D( ResourceBase );
1120  d->scheduler->taskDone();
1121 }
1122 
1123 void ResourceBase::retrieveCollectionAttributes( const Collection &collection )
1124 {
1125  collectionAttributesRetrieved( collection );
1126 }
1127 
1128 void Akonadi::ResourceBase::abortActivity()
1129 {
1130 
1131 }
1132 
1133 void ResourceBase::setItemTransactionMode(ItemSync::TransactionMode mode)
1134 {
1135  Q_D( ResourceBase );
1136  d->mItemTransactionMode = mode;
1137 }
1138 
1139 void ResourceBase::setItemSynchronizationFetchScope(const ItemFetchScope& fetchScope)
1140 {
1141  Q_D( ResourceBase );
1142  if ( !d->mItemSyncFetchScope )
1143  d->mItemSyncFetchScope = new ItemFetchScope;
1144  *(d->mItemSyncFetchScope) = fetchScope;
1145 }
1146 
1147 void ResourceBase::setAutomaticProgressReporting( bool enabled )
1148 {
1149  Q_D( ResourceBase );
1150  d->mAutomaticProgressReporting = enabled;
1151 }
1152 
1153 QString ResourceBase::dumpNotificationListToString() const
1154 {
1155  Q_D( const ResourceBase );
1156  return d->dumpNotificationListToString();
1157 }
1158 
1159 QString ResourceBase::dumpSchedulerToString() const
1160 {
1161  Q_D( const ResourceBase );
1162  return d->dumpToString();
1163 }
1164 
1165 void ResourceBase::dumpMemoryInfo() const
1166 {
1167  Q_D( const ResourceBase );
1168  return d->dumpMemoryInfo();
1169 }
1170 
1171 QString ResourceBase::dumpMemoryInfoToString() const
1172 {
1173  Q_D( const ResourceBase );
1174  return d->dumpMemoryInfoToString();
1175 }
1176 
1177 #include "resourcebase.moc"
1178 #include "moc_resourcebase.cpp"
Akonadi::CollectionModifyJob
Job that modifies a collection in the Akonadi storage.
Definition: collectionmodifyjob.h:82
Akonadi::RecursiveMover
Helper class for expanding inter-resource collection moves inside ResourceBase.
Definition: recursivemover_p.h:37
Akonadi::ItemFetchScope::fetchAttribute
void fetchAttribute(const QByteArray &type, bool fetch=true)
Sets whether the attribute of the given type should be fetched.
Definition: itemfetchscope.cpp:78
Akonadi::ResourceBase::retrieveCollectionAttributes
void retrieveCollectionAttributes(const Akonadi::Collection &collection)
Retrieve the attributes of a single collection from the backend.
Definition: resourcebase.cpp:1123
Akonadi::ResourceBase::abortActivity
void abortActivity()
Abort any activity in progress in the backend.
Definition: resourcebase.cpp:1128
Akonadi::ItemModifyJob::disableRevisionCheck
void disableRevisionCheck()
Disables the check of the revision number.
Definition: itemmodifyjob.cpp:374
Akonadi::AgentBase::percent
void percent(int progress)
This signal should be emitted whenever the progress of an action in the agent (e.g.
Akonadi::ResourceBase::retrieveCollections
virtual void retrieveCollections()=0
Retrieve the collection tree from the remote server and supply it via collectionsRetrieved() or colle...
Akonadi::CollectionFetchJob::collections
Collection::List collections() const
Returns the list of fetched collection.
Definition: collectionfetchjob.cpp:175
Akonadi::AgentBase::abortRequested
void abortRequested()
Emitted when another application has remotely asked the agent to abort its current operation...
Akonadi::ResourceBase::dumpNotificationListToString
QString dumpNotificationListToString() const
Dump the contents of the current ChangeReplay.
Definition: resourcebase.cpp:1153
Akonadi::Collection::displayName
QString displayName() const
Returns the display name (EntityDisplayAttribute::displayName()) if set, and Collection::name() other...
Definition: collection.cpp:86
Akonadi::ResourceBase::attributesSynchronized
void attributesSynchronized(qlonglong collectionId)
Emitted when a collection attributes synchronization has been completed.
Akonadi::ResourceBase::collectionsRetrievalDone
void collectionsRetrievalDone()
Call this method to indicate you finished synchronizing the collection tree.
Definition: resourcebase.cpp:738
Akonadi::ResourceBase::setAutomaticProgressReporting
void setAutomaticProgressReporting(bool enabled)
Enable or disable automatic progress reporting.
Definition: resourcebase.cpp:1147
Akonadi::ResourceBase::setCollectionStreamingEnabled
void setCollectionStreamingEnabled(bool enable)
Enable collection streaming, that is collections don't have to be delivered at once as result of a re...
Definition: resourcebase.cpp:722
Akonadi::ResourceBase::synchronizeCollectionAttributes
void synchronizeCollectionAttributes(qint64 id)
This method is called whenever the collection with the given id shall have its attributes synchronize...
Definition: resourcebase.cpp:1001
Akonadi::CollectionFetchJob::FirstLevel
Only list direct sub-collections of the base collection.
Definition: collectionfetchjob.h:63
Akonadi::CollectionFetchJob::fetchScope
CollectionFetchScope & fetchScope()
Returns the collection fetch scope.
Definition: collectionfetchjob.cpp:437
Akonadi::CollectionFetchScope::setResource
void setResource(const QString &resource)
Sets a resource filter, that is only collections owned by the specified resource are retrieved...
Definition: collectionfetchscope.cpp:114
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::CollectionFetchJob
Job that fetches collections from the Akonadi storage.
Definition: collectionfetchjob.h:53
Akonadi::ResourceBase::itemsRetrieved
void itemsRetrieved(const Item::List &items)
Call this method to supply the full collection listing from the remote server.
Definition: resourcebase.cpp:1040
Akonadi::Collection::virtualMimeType
static QString virtualMimeType()
Returns the mimetype used for virtual collections.
Definition: collection.cpp:202
Akonadi::AgentBase::agentNameChanged
void agentNameChanged(const QString &name)
This signal is emitted whenever the name of the agent has changed.
Akonadi::Collection::mimeType
static QString mimeType()
Returns the mimetype used for collections.
Definition: collection.cpp:197
Akonadi::ResourceBase::setItemSynchronizationFetchScope
void setItemSynchronizationFetchScope(const ItemFetchScope &fetchScope)
Set the fetch scope applied for item synchronization.
Definition: resourcebase.cpp:1139
Akonadi::ResourceBase::synchronizeCollectionTree
void synchronizeCollectionTree()
Refetches the Collections.
Definition: resourcebase.cpp:918
Akonadi::ResourceBase::setTotalItems
void setTotalItems(int amount)
Call this method when you want to use the itemsRetrieved() method in streaming mode and indicate the ...
Definition: resourcebase.cpp:1021
Akonadi::ResourceBase::nameChanged
void nameChanged(const QString &name)
This signal is emitted whenever the name of the resource has changed.
Akonadi::AgentBasePrivate
Definition: agentbase_p.h:38
Akonadi::ResourceBase::changesCommitted
void changesCommitted(const Item::List &items)
Resets the dirty flag of all given items and updates remote ids.
Definition: resourcebase.cpp:627
Akonadi::ItemFetchJob::items
Item::List items() const
Returns the fetched items.
Definition: itemfetchjob.cpp:228
Akonadi::AgentBase
The base class for all Akonadi agents and resources.
Definition: agentbase.h:80
Akonadi::CollectionFetchJob::Base
Only fetch the base collection.
Definition: collectionfetchjob.h:62
Akonadi::ItemSync
Syncs between items known to a client (usually a resource) and the Akonadi storage.
Definition: itemsync.h:53
Akonadi::ResourceBase::itemsRetrievalDone
void itemsRetrievalDone()
Call this method to indicate you finished synchronizing the current collection.
Definition: resourcebase.cpp:875
Akonadi::ResourceBase::deferTask
void deferTask()
Stops the execution of the current task and continues with the next one.
Definition: resourcebase.cpp:959
Akonadi::ItemFetchJob::fetchScope
ItemFetchScope & fetchScope()
Returns the item fetch scope.
Definition: itemfetchjob.cpp:256
Akonadi::AgentBase::setAgentName
void setAgentName(const QString &name)
This method is used to set the name of the agent.
Definition: agentbase.cpp:975
Akonadi::ResourceBase::SchedulePriority
SchedulePriority
Describes the scheduling priority of a task that has been queued for execution.
Definition: resourcebase.h:602
Akonadi::ResourceBase::synchronize
void synchronize()
This method is called whenever the resource should start synchronize all data.
Definition: resourcebase.cpp:451
Akonadi::AgentBase::error
void error(const QString &message)
This signal shall be used to report errors.
Akonadi::AgentBase::status
virtual int status() const
This method returns the current status code of the agent.
Akonadi::ResourceBase::clearCache
void clearCache()
Call this method to remove all items and collections of the resource from the server cache...
Definition: resourcebase.cpp:888
Akonadi::ResourceBase::collectionAttributesRetrieved
void collectionAttributesRetrieved(const Collection &collection)
Call this method from retrieveCollectionAttributes() once the result is available.
Definition: resourcebase.cpp:552
Akonadi::Entity::remoteId
QString remoteId() const
Returns the remote id of the entity.
Definition: entity.cpp:82
Akonadi::ResourceBase::collectionsRetrieved
void collectionsRetrieved(const Collection::List &collections)
Call this to supply the full folder tree retrieved from the remote server.
Definition: resourcebase.cpp:689
Akonadi::Collection::root
static Collection root()
Returns the root collection.
Definition: collection.cpp:192
Akonadi::ResourceBase::currentItem
Item currentItem() const
Returns the item that is currently retrieved.
Definition: resourcebase.cpp:909
Akonadi::CollectionDeleteJob
Job that deletes a collection in the Akonadi storage.
Definition: collectiondeletejob.h:63
Akonadi::ResourceBase::itemsRetrievedIncremental
void itemsRetrievedIncremental(const Item::List &changedItems, const Item::List &removedItems)
Call this method to supply incrementally retrieved items from the remote server.
Definition: resourcebase.cpp:1049
Akonadi::ServerManager::agentServiceName
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...
Definition: servermanager.cpp:310
Akonadi::ResourceBase::doSetOnline
void doSetOnline(bool online)
Inherited from AgentBase.
Definition: resourcebase.cpp:965
Akonadi::Entity::id
Id id() const
Returns the unique identifier of the entity.
Definition: entity.cpp:72
Akonadi::ResourceBase::collectionTreeSynchronized
void collectionTreeSynchronized()
Emitted when a collection tree synchronization has been completed.
Akonadi::CollectionFetchJob::setFetchScope
void setFetchScope(const CollectionFetchScope &fetchScope)
Sets the collection fetch scope.
Definition: collectionfetchjob.cpp:431
Akonadi::ResourceBase::synchronizeCollection
void synchronizeCollection(qint64 id)
This method is called whenever the collection with the given id shall be synchronized.
Definition: resourcebase.cpp:970
Akonadi::ItemFetchScope
Specifies which parts of an item should be fetched from the Akonadi storage.
Definition: itemfetchscope.h:68
Akonadi::ItemFetchScope::setAncestorRetrieval
void setAncestorRetrieval(AncestorRetrieval ancestorDepth)
Sets how many levels of ancestor collections should be included in the retrieval. ...
Definition: itemfetchscope.cpp:128
Akonadi::ResourceBase::setItemTransactionMode
void setItemTransactionMode(ItemSync::TransactionMode mode)
Set transaction mode for item sync'ing.
Definition: resourcebase.cpp:1133
Akonadi::InvalidateCacheJob
Helper job to invalidate item cache for an entire collection.
Definition: invalidatecachejob_p.h:34
Akonadi::AgentBase::identifier
QString identifier() const
Returns the instance identifier of this agent.
Definition: agentbase.cpp:970
Akonadi::ItemModifyJob::setIgnorePayload
void setIgnorePayload(bool ignore)
Sets whether the payload of the modified item shall be omitted from transmission to the Akonadi stora...
Definition: itemmodifyjob.cpp:335
Akonadi::ItemSync::TransactionMode
TransactionMode
Transaction mode used by ItemSync.
Definition: itemsync.h:158
Akonadi::ResourceBase::changeCommitted
void changeCommitted(const Item &item)
Resets the dirty flag of the given item and updates the remote id.
Definition: resourcebase.cpp:622
Akonadi::AgentBase::changeRecorder
ChangeRecorder * changeRecorder() const
Returns the Akonadi::ChangeRecorder object used for monitoring.
Definition: agentbase.cpp:1014
Akonadi::ResourceBase::dumpMemoryInfo
void dumpMemoryInfo() const
Dumps memory usage information to stdout.
Definition: resourcebase.cpp:1165
Akonadi::ResourceBase::setHierarchicalRemoteIdentifiersEnabled
void setHierarchicalRemoteIdentifiersEnabled(bool enable)
Indicate the use of hierarchical remote identifiers.
Definition: resourcebase.cpp:1105
Akonadi::CollectionSync
Definition: collectionsync_p.h:53
Akonadi::AgentBase::isOnline
bool isOnline() const
Returns whether the agent is currently online.
Akonadi::ResourceBase::itemRetrieved
void itemRetrieved(const Item &item)
Call this method from retrieveItem() once the result is available.
Definition: resourcebase.cpp:517
Akonadi::AgentBase::changeProcessed
void changeProcessed()
Marks the current change as processes and replays the next change if change recording is enabled (noo...
Definition: agentbase.cpp:1008
Akonadi::RecursiveMover::setCollection
void setCollection(const Akonadi::Collection &collection, const Akonadi::Collection &parentCollection)
Set the collection that is actually moved.
Definition: recursivemover.cpp:43
Akonadi::ItemModifyJob
Job that modifies an existing item in the Akonadi storage.
Definition: itemmodifyjob.h:97
Akonadi::ItemFetchJob
Job that fetches items from the Akonadi storage.
Definition: itemfetchjob.h:82
Akonadi::ResourceSelectJob
Job that selects a resource context for remote identifier based operations.
Definition: resourceselectjob_p.h:82
Akonadi::ResourceBase::~ResourceBase
~ResourceBase()
Destroys the base resource.
Definition: resourcebase.cpp:447
Akonadi::ChangeRecorder::changeProcessed
void changeProcessed()
Removes the previously emitted change from the records.
Definition: changerecorder.cpp:91
Akonadi::Collection::contentMimeTypes
QStringList contentMimeTypes() const
Returns a list of possible content mimetypes, e.g.
Definition: collection.cpp:115
Akonadi::ResourceBase::init
static int init(int argc, char **argv)
Use this method in the main function of your resource application to initialize your resource subclas...
Definition: resourcebase.h:180
Akonadi::ResourceBase::setItemStreamingEnabled
void setItemStreamingEnabled(bool enable)
Enable item streaming.
Definition: resourcebase.cpp:1031
Akonadi::ResourceBase::name
QString name() const
Returns the name of the resource.
Definition: resourcebase.cpp:461
Akonadi::ResourceBase::taskDone
void taskDone()
Indicate that the current task is finished.
Definition: resourcebase.cpp:1117
Akonadi::ResourceBase::cancelTask
void cancelTask()
Stops the execution of the current task and continues with the next one.
Definition: resourcebase.cpp:923
Akonadi::ChangeRecorder::isEmpty
bool isEmpty() const
Returns whether there are recorded changes.
Definition: changerecorder.cpp:85
Akonadi::ResourceBase::currentCollection
Collection currentCollection() const
Returns the collection that is currently synchronized.
Definition: resourcebase.cpp:900
Akonadi::Collection::resource
QString resource() const
Returns the identifier of the resource owning the collection.
Definition: collection.cpp:207
Akonadi::Job::UserCanceled
The user canceld this job.
Definition: job.h:108
Akonadi::ResourceBase::ResourceBase
ResourceBase(const QString &id)
Creates a base resource.
Definition: resourcebase.cpp:387
Akonadi::AgentBase::Running
The agent is working on something.
Definition: agentbase.h:365
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi::ItemSync::setTransactionMode
void setTransactionMode(TransactionMode mode)
Set the transaction mode to use for this sync.
Definition: itemsync.cpp:470
Akonadi::ResourceBase::collectionsRetrievedIncremental
void collectionsRetrievedIncremental(const Collection::List &changedCollections, const Collection::List &removedCollections)
Call this to supply incrementally retrieved collections from the remote server.
Definition: resourcebase.cpp:705
Akonadi::ServerManager::addNamespace
static QString addNamespace(const QString &string)
Adds the multi-instance namespace to string if required (with '_' as separator).
Definition: servermanager.cpp:324
Akonadi::ResourceBase::setName
void setName(const QString &name)
This method is used to set the name of the resource.
Definition: resourcebase.cpp:456
Akonadi::CollectionFetchJob::Recursive
List all sub-collections.
Definition: collectionfetchjob.h:64
Akonadi::ResourceBase::dumpMemoryInfoToString
QString dumpMemoryInfoToString() const
Returns a string with memory usage information.
Definition: resourcebase.cpp:1171
Akonadi::Collection::List
QList< Collection > List
Describes a list of collections.
Definition: collection.h:81
Akonadi::AgentBase::agentName
QString agentName() const
Returns the name of the agent.
Definition: agentbase.cpp:998
Akonadi::ResourceBase
The base class for all Akonadi resources.
Definition: resourcebase.h:147
Akonadi::Collection::isVirtual
bool isVirtual() const
Returns whether the collection is virtual, for example a search collection.
Definition: collection.cpp:261
Akonadi::ResourceBase::dumpSchedulerToString
QString dumpSchedulerToString() const
Dump the state of the scheduler.
Definition: resourcebase.cpp:1159
Akonadi::ResourceBase::scheduleCustomTask
void scheduleCustomTask(QObject *receiver, const char *method, const QVariant &argument, SchedulePriority priority=Append)
Schedules a custom task in the internal scheduler.
Definition: resourcebase.cpp:1111
Akonadi::ItemFetchScope::setCacheOnly
void setCacheOnly(bool cacheOnly)
Sets whether payload data should be requested from remote sources or just from the local cache...
Definition: itemfetchscope.cpp:106
Akonadi::ResourceBase::invalidateCache
void invalidateCache(const Collection &collection)
Call this method to invalidate all cached content in collection.
Definition: resourcebase.cpp:894
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

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

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal