• 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
agentbase.cpp
1 /*
2  Copyright (c) 2006 Till Adam <adam@kde.org>
3  Copyright (c) 2007 Volker Krause <vkrause@kde.org>
4  Copyright (c) 2007 Bruno Virlet <bruno.virlet@gmail.com>
5  Copyright (c) 2008 Kevin Krammer <kevin.krammer@gmx.at>
6 
7  This library is free software; you can redistribute it and/or modify it
8  under the terms of the GNU Library General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version.
11 
12  This library is distributed in the hope that it will be useful, but WITHOUT
13  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15  License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to the
19  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  02110-1301, USA.
21 */
22 
23 #include "agentbase.h"
24 #include "agentbase_p.h"
25 
26 #include "agentmanager.h"
27 #include "changerecorder.h"
28 #include "controladaptor.h"
29 #include "dbusconnectionpool.h"
30 #include "itemfetchjob.h"
31 #include "kdepimlibs-version.h"
32 #include "monitor_p.h"
33 #include "servermanager_p.h"
34 #include "session.h"
35 #include "session_p.h"
36 #include "statusadaptor.h"
37 
38 #include <kaboutdata.h>
39 #include <kcmdlineargs.h>
40 #include <kdebug.h>
41 #include <kglobal.h>
42 #include <klocalizedstring.h>
43 #include <kstandarddirs.h>
44 
45 #include <Solid/PowerManagement>
46 
47 #include <QtCore/QDir>
48 #include <QtCore/QSettings>
49 #include <QtCore/QTimer>
50 #include <QtDBus/QtDBus>
51 #include <QApplication>
52 
53 #include <signal.h>
54 #include <stdlib.h>
55 #if defined __GLIBC__
56 # include <malloc.h> // for dumping memory information
57 #endif
58 
59 //#define EXPERIMENTAL_INPROCESS_AGENTS 1
60 
61 using namespace Akonadi;
62 
63 static AgentBase *sAgentBase = 0;
64 
65 AgentBase::Observer::Observer()
66 {
67 }
68 
69 AgentBase::Observer::~Observer()
70 {
71 }
72 
73 void AgentBase::Observer::itemAdded( const Item &item, const Collection &collection )
74 {
75  Q_UNUSED( item );
76  Q_UNUSED( collection );
77  if ( sAgentBase != 0 ) {
78  sAgentBase->d_ptr->changeProcessed();
79  }
80 }
81 
82 void AgentBase::Observer::itemChanged( const Item &item, const QSet<QByteArray> &partIdentifiers )
83 {
84  Q_UNUSED( item );
85  Q_UNUSED( partIdentifiers );
86  if ( sAgentBase != 0 ) {
87  sAgentBase->d_ptr->changeProcessed();
88  }
89 }
90 
91 void AgentBase::Observer::itemRemoved( const Item &item )
92 {
93  Q_UNUSED( item );
94  if ( sAgentBase != 0 ) {
95  sAgentBase->d_ptr->changeProcessed();
96  }
97 }
98 
99 void AgentBase::Observer::collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent )
100 {
101  Q_UNUSED( collection );
102  Q_UNUSED( parent );
103  if ( sAgentBase != 0 ) {
104  sAgentBase->d_ptr->changeProcessed();
105  }
106 }
107 
108 void AgentBase::Observer::collectionChanged( const Collection &collection )
109 {
110  Q_UNUSED( collection );
111  if ( sAgentBase != 0 ) {
112  sAgentBase->d_ptr->changeProcessed();
113  }
114 }
115 
116 void AgentBase::Observer::collectionRemoved( const Collection &collection )
117 {
118  Q_UNUSED( collection );
119  if ( sAgentBase != 0 ) {
120  sAgentBase->d_ptr->changeProcessed();
121  }
122 }
123 
124 void AgentBase::ObserverV2::itemMoved( const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest )
125 {
126  Q_UNUSED( item );
127  Q_UNUSED( source );
128  Q_UNUSED( dest );
129  if ( sAgentBase != 0 ) {
130  sAgentBase->d_ptr->changeProcessed();
131  }
132 }
133 
134 void AgentBase::ObserverV2::itemLinked( const Akonadi::Item& item, const Akonadi::Collection& collection )
135 {
136  Q_UNUSED( item );
137  Q_UNUSED( collection );
138  if ( sAgentBase != 0 ) {
139  // not implementation, let's disconnect the signal to enable optimizations in Monitor
140  QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL(itemLinked(Akonadi::Item,Akonadi::Collection)),
141  sAgentBase->d_ptr, SLOT(itemLinked(Akonadi::Item,Akonadi::Collection)) );
142  sAgentBase->d_ptr->changeProcessed();
143  }
144 }
145 
146 void AgentBase::ObserverV2::itemUnlinked( const Akonadi::Item& item, const Akonadi::Collection& collection )
147 {
148  Q_UNUSED( item );
149  Q_UNUSED( collection );
150  if ( sAgentBase != 0 ) {
151  // not implementation, let's disconnect the signal to enable optimizations in Monitor
152  QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL(itemUnlinked(Akonadi::Item,Akonadi::Collection)),
153  sAgentBase->d_ptr, SLOT(itemUnlinked(Akonadi::Item,Akonadi::Collection)) );
154  sAgentBase->d_ptr->changeProcessed();
155  }
156 }
157 
158 void AgentBase::ObserverV2::collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest )
159 {
160  Q_UNUSED( collection );
161  Q_UNUSED( source );
162  Q_UNUSED( dest );
163  if ( sAgentBase != 0 ) {
164  sAgentBase->d_ptr->changeProcessed();
165  }
166 }
167 
168 void AgentBase::ObserverV2::collectionChanged( const Akonadi::Collection &collection, const QSet<QByteArray> &changedAttributes )
169 {
170  Q_UNUSED( changedAttributes );
171  collectionChanged( collection );
172 }
173 
174 void AgentBase::ObserverV3::itemsFlagsChanged(const Akonadi::Item::List& items, const QSet< QByteArray >& addedFlags, const QSet< QByteArray >& removedFlags)
175 {
176  Q_UNUSED( items );
177  Q_UNUSED( addedFlags );
178  Q_UNUSED( removedFlags );
179 
180  if ( sAgentBase != 0 ) {
181  // not implementation, let's disconnect the signal to enable optimizations in Monitor
182  QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL(itemsFlagsChanged(Akonadi::Item::List,QSet<QByteArray>,QSet<QByteArray>)),
183  sAgentBase->d_ptr, SLOT(itemsFlagsChanged(Akonadi::Item::List,QSet<QByteArray>,QSet<QByteArray>)) );
184  sAgentBase->d_ptr->changeProcessed();
185  }
186 }
187 
188 void AgentBase::ObserverV3::itemsMoved(const Akonadi::Item::List& items, const Collection& sourceCollection, const Collection& destinationCollection)
189 {
190  Q_UNUSED( items );
191  Q_UNUSED( sourceCollection );
192  Q_UNUSED( destinationCollection );
193 
194  if ( sAgentBase != 0 ) {
195  // not implementation, let's disconnect the signal to enable optimizations in Monitor
196  QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL(itemsMoved(Akonadi::Item::List,Akonadi::Collection,Akonadi::Collection)),
197  sAgentBase->d_ptr, SLOT(itemsMoved(Akonadi::Item::List,Akonadi::Collection,Akonadi::Collection)) );
198  sAgentBase->d_ptr->changeProcessed();
199  }
200 }
201 
202 void AgentBase::ObserverV3::itemsRemoved(const Akonadi::Item::List& items)
203 {
204  Q_UNUSED( items );
205 
206  if ( sAgentBase != 0 ) {
207  // not implementation, let's disconnect the signal to enable optimizations in Monitor
208  QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL(itemsRemoved(Akonadi::Item::List)),
209  sAgentBase->d_ptr, SLOT(itemsRemoved(Akonadi::Item::List)) );
210  sAgentBase->d_ptr->changeProcessed();
211  }
212 }
213 
214 void AgentBase::ObserverV3::itemsLinked(const Akonadi::Item::List& items, const Collection& collection)
215 {
216  Q_UNUSED( items );
217  Q_UNUSED( collection );
218 
219  if ( sAgentBase != 0 ) {
220  // not implementation, let's disconnect the signal to enable optimizations in Monitor
221  QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL(itemsLinked(Akonadi::Item::List,Akonadi::Collection)),
222  sAgentBase->d_ptr, SLOT(itemsLinked(Akonadi::Item::List,Akonadi::Collection)) );
223  sAgentBase->d_ptr->changeProcessed();
224  }
225 }
226 
227 void AgentBase::ObserverV3::itemsUnlinked(const Akonadi::Item::List& items, const Collection& collection)
228 {
229  Q_UNUSED( items );
230  Q_UNUSED( collection )
231 
232  if ( sAgentBase != 0 ) {
233  // not implementation, let's disconnect the signal to enable optimizations in Monitor
234  QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL(itemsUnlinked(Akonadi::Item::List,Akonadi::Collection)),
235  sAgentBase->d_ptr, SLOT(itemsUnlinked(Akonadi::Item::List,Akonadi::Collection)) );
236  sAgentBase->d_ptr->changeProcessed();
237  }
238 }
239 
240 //@cond PRIVATE
241 
242 AgentBasePrivate::AgentBasePrivate( AgentBase *parent )
243  : q_ptr( parent ),
244  mDBusConnection( QString() ),
245  mStatusCode( AgentBase::Idle ),
246  mProgress( 0 ),
247  mNeedsNetwork( false ),
248  mOnline( false ),
249  mDesiredOnlineState( false ),
250  mSettings( 0 ),
251  mChangeRecorder( 0 ),
252  mTracer( 0 ),
253  mObserver( 0 )
254 {
255 #ifdef Q_OS_WINCE
256  QThread::currentThread()->setPriority( QThread::LowPriority );
257 #endif
258  Internal::setClientType( Internal::Agent );
259 }
260 
261 AgentBasePrivate::~AgentBasePrivate()
262 {
263  mChangeRecorder->setConfig( 0 );
264  delete mSettings;
265 }
266 
267 void AgentBasePrivate::init()
268 {
269  Q_Q( AgentBase );
270 
274  SessionPrivate::createDefaultSession( mId.toLatin1() );
275 
276  if ( QThread::currentThread() != QCoreApplication::instance()->thread() ) {
277  mDBusConnection = QDBusConnection::connectToBus( QDBusConnection::SessionBus, q->identifier() );
278  Q_ASSERT( mDBusConnection.isConnected() );
279  }
280 
281  mTracer = new org::freedesktop::Akonadi::Tracer( ServerManager::serviceName( ServerManager::Server ),
282  QLatin1String( "/tracing" ),
283  DBusConnectionPool::threadConnection(), q );
284 
285  new Akonadi__ControlAdaptor( q );
286  new Akonadi__StatusAdaptor( q );
287  if ( !DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/" ), q, QDBusConnection::ExportAdaptors ) )
288  q->error( i18n( "Unable to register object at dbus: %1", DBusConnectionPool::threadConnection().lastError().message() ) );
289 
290  mSettings = new QSettings( QString::fromLatin1( "%1/agent_config_%2" ).arg( Internal::xdgSaveDir( "config" ), mId ), QSettings::IniFormat );
291 
292  mChangeRecorder = new ChangeRecorder( q );
293  mChangeRecorder->ignoreSession( Session::defaultSession() );
294  mChangeRecorder->itemFetchScope().setCacheOnly( true );
295  mChangeRecorder->setConfig( mSettings );
296 
297  mDesiredOnlineState = mSettings->value( QLatin1String( "Agent/DesiredOnlineState" ), true ).toBool();
298  mOnline = mDesiredOnlineState;
299 
300  // reinitialize the status message now that online state is available
301  mStatusMessage = defaultReadyMessage();
302 
303  mName = mSettings->value( QLatin1String( "Agent/Name" ) ).toString();
304  if ( mName.isEmpty() ) {
305  mName = mSettings->value( QLatin1String( "Resource/Name" ) ).toString();
306  if ( !mName.isEmpty() ) {
307  mSettings->remove( QLatin1String( "Resource/Name" ) );
308  mSettings->setValue( QLatin1String( "Agent/Name" ), mName );
309  }
310  }
311 
312  connect( mChangeRecorder, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)),
313  SLOT(itemAdded(Akonadi::Item,Akonadi::Collection)) );
314  connect( mChangeRecorder, SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)),
315  SLOT(itemChanged(Akonadi::Item,QSet<QByteArray>)) );
316  connect( mChangeRecorder, SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)),
317  SLOT(collectionAdded(Akonadi::Collection,Akonadi::Collection)) );
318  connect( mChangeRecorder, SIGNAL(collectionChanged(Akonadi::Collection)),
319  SLOT(collectionChanged(Akonadi::Collection)) );
320  connect( mChangeRecorder, SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)),
321  SLOT(collectionChanged(Akonadi::Collection,QSet<QByteArray>)) );
322  connect( mChangeRecorder, SIGNAL(collectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)),
323  SLOT(collectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)) );
324  connect( mChangeRecorder, SIGNAL(collectionRemoved(Akonadi::Collection)),
325  SLOT(collectionRemoved(Akonadi::Collection)) );
326  connect( mChangeRecorder, SIGNAL(collectionSubscribed(Akonadi::Collection,Akonadi::Collection)),
327  SLOT(collectionSubscribed(Akonadi::Collection,Akonadi::Collection)) );
328  connect( mChangeRecorder, SIGNAL(collectionUnsubscribed(Akonadi::Collection)),
329  SLOT(collectionUnsubscribed(Akonadi::Collection)) );
330 
331  connect( q, SIGNAL(status(int,QString)), q, SLOT(slotStatus(int,QString)) );
332  connect( q, SIGNAL(percent(int)), q, SLOT(slotPercent(int)) );
333  connect( q, SIGNAL(warning(QString)), q, SLOT(slotWarning(QString)) );
334  connect( q, SIGNAL(error(QString)), q, SLOT(slotError(QString)) );
335 
336  connect( Solid::PowerManagement::notifier(), SIGNAL(resumingFromSuspend()), q, SLOT(slotResumedFromSuspend()) );
337 
338  // Use reference counting to allow agents to finish internal jobs when the
339  // agent is stopped.
340  KGlobal::ref();
341  if ( QThread::currentThread() == QCoreApplication::instance()->thread() ) {
342  KGlobal::setAllowQuit( true );
343  }
344 
345 #ifndef Q_OS_WINCE
346  // disable session management
347  if ( KApplication::kApplication() ) {
348  KApplication::kApplication()->disableSessionManagement();
349  }
350 #endif
351 
352  mResourceTypeName = AgentManager::self()->instance( mId ).type().name();
353  setProgramName();
354 
355  QTimer::singleShot( 0, q, SLOT(delayedInit()) );
356 }
357 
358 void AgentBasePrivate::delayedInit()
359 {
360  Q_Q( AgentBase );
361 
362  const QString serviceId = ServerManager::agentServiceName( ServerManager::Agent, mId );
363  if ( !DBusConnectionPool::threadConnection().registerService( serviceId ) ) {
364  kFatal() << "Unable to register service" << serviceId << "at dbus:" << DBusConnectionPool::threadConnection().lastError().message();
365  }
366  q->setOnlineInternal( mDesiredOnlineState );
367 
368  DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/Debug" ), this, QDBusConnection::ExportScriptableSlots );
369 }
370 
371 void AgentBasePrivate::setProgramName()
372 {
373  // ugly, really ugly, if you find another solution, change it and blame me for this code (Andras)
374  QString programName = mResourceTypeName;
375  if ( !mName.isEmpty() ) {
376  programName = i18nc( "Name and type of Akonadi resource", "%1 of type %2", mName, mResourceTypeName ) ;
377  }
378  const_cast<KAboutData*>( KGlobal::mainComponent().aboutData() )->setProgramName( ki18n( programName.toUtf8() ) );
379 }
380 
381 void AgentBasePrivate::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection )
382 {
383  if ( mObserver != 0 ) {
384  mObserver->itemAdded( item, collection );
385  }
386 }
387 
388 void AgentBasePrivate::itemChanged( const Akonadi::Item &item, const QSet<QByteArray> &partIdentifiers )
389 {
390  if ( mObserver != 0 ) {
391  mObserver->itemChanged( item, partIdentifiers );
392  }
393 }
394 
395 void AgentBasePrivate::itemMoved( const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest )
396 {
397  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
398  if ( mObserver ) {
399  // inter-resource moves, requires we know which resources the source and destination are in though
400  if ( !source.resource().isEmpty() && !dest.resource().isEmpty() ) {
401  if ( source.resource() != dest.resource() ) {
402  if ( source.resource() == q_ptr->identifier() ) { // moved away from us
403  Akonadi::Item i( item );
404  i.setParentCollection( source );
405  mObserver->itemRemoved( i );
406  } else if ( dest.resource() == q_ptr->identifier() ) { // moved to us
407  mObserver->itemAdded( item, dest );
408  } else if ( observer2 ) {
409  observer2->itemMoved( item, source, dest );
410  } else {
411  // not for us, not sure if we should get here at all
412  changeProcessed();
413  }
414  return;
415  }
416  }
417  // intra-resource move
418  if ( observer2 ) {
419  observer2->itemMoved( item, source, dest );
420  } else {
421  // ### we cannot just call itemRemoved here as this will already trigger changeProcessed()
422  // so, just itemAdded() is good enough as no resource can have implemented intra-resource moves anyway
423  // without using ObserverV2
424  mObserver->itemAdded( item, dest );
425  // mObserver->itemRemoved( item );
426  }
427  }
428 }
429 
430 void AgentBasePrivate::itemRemoved( const Akonadi::Item &item )
431 {
432  if ( mObserver != 0 ) {
433  mObserver->itemRemoved( item );
434  }
435 }
436 
437 void AgentBasePrivate::itemLinked( const Akonadi::Item &item, const Akonadi::Collection &collection )
438 {
439  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
440  if ( observer2 ) {
441  observer2->itemLinked( item, collection );
442  } else {
443  changeProcessed();
444  }
445 }
446 
447 void AgentBasePrivate::itemUnlinked( const Akonadi::Item &item, const Akonadi::Collection &collection )
448 {
449  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
450  if ( observer2 ) {
451  observer2->itemUnlinked( item, collection );
452  } else {
453  changeProcessed();
454  }
455 }
456 
457 void AgentBasePrivate::itemsFlagsChanged( const Akonadi::Item::List &items, const QSet<QByteArray> &addedFlags, const QSet<QByteArray> &removedFlags )
458 {
459  AgentBase::ObserverV3 *observer3 = dynamic_cast<AgentBase::ObserverV3*>( mObserver );
460  if ( observer3 ) {
461  observer3->itemsFlagsChanged( items, addedFlags, removedFlags );
462  } else {
463  Q_ASSERT_X( false, Q_FUNC_INFO, "Batch slots must never be called when ObserverV3 is not available" );
464  }
465 }
466 
467 void AgentBasePrivate::itemsMoved( const Akonadi::Item::List &items, const Akonadi::Collection &source, const Akonadi::Collection &destination )
468 {
469  AgentBase::ObserverV3 *observer3 = dynamic_cast<AgentBase::ObserverV3*>( mObserver );
470  if ( observer3 ) {
471  observer3->itemsMoved( items, source, destination );
472  } else {
473  Q_ASSERT_X( false, Q_FUNC_INFO, "Batch slots must never be called when ObserverV3 is not available" );
474  }
475 }
476 
477 void AgentBasePrivate::itemsRemoved( const Akonadi::Item::List &items )
478 {
479  AgentBase::ObserverV3 *observer3 = dynamic_cast<AgentBase::ObserverV3*>( mObserver );
480  if ( observer3 ) {
481  observer3->itemsRemoved( items );
482  } else {
483  Q_ASSERT_X( false, Q_FUNC_INFO, "Batch slots must never be called when ObserverV3 is not available" );
484  }
485 }
486 
487 void AgentBasePrivate::itemsLinked( const Akonadi::Item::List &items, const Akonadi::Collection &collection )
488 {
489  if ( !mObserver ) {
490  changeProcessed();
491  return;
492  }
493 
494  AgentBase::ObserverV3 *observer3 = dynamic_cast<AgentBase::ObserverV3*>( mObserver );
495  if ( observer3 ) {
496  observer3->itemsLinked( items, collection );
497  } else {
498  Q_ASSERT_X( false, Q_FUNC_INFO, "Batch slots must never be called when ObserverV3 is not available" );
499  }
500 }
501 
502 void AgentBasePrivate::itemsUnlinked( const Akonadi::Item::List &items, const Akonadi::Collection &collection )
503 {
504  if ( !mObserver ) {
505  return;
506  }
507 
508  AgentBase::ObserverV3 *observer3 = dynamic_cast<AgentBase::ObserverV3*>( mObserver );
509  if ( observer3 ) {
510  observer3->itemsUnlinked( items, collection );
511  } else {
512  Q_ASSERT_X( false, Q_FUNC_INFO, "Batch slots must never be called when ObserverV3 is not available" );
513  }
514 }
515 
516 void AgentBasePrivate::collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent )
517 {
518  if ( mObserver != 0 ) {
519  mObserver->collectionAdded( collection, parent );
520  }
521 }
522 
523 void AgentBasePrivate::collectionChanged( const Akonadi::Collection &collection )
524 {
525  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
526  if ( mObserver != 0 && observer2 == 0 ) { // For ObserverV2 we use the variant with the part identifiers
527  mObserver->collectionChanged( collection );
528  }
529 }
530 
531 void AgentBasePrivate::collectionChanged( const Akonadi::Collection &collection, const QSet<QByteArray> &changedAttributes )
532 {
533  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
534  if ( observer2 != 0 ) {
535  observer2->collectionChanged( collection, changedAttributes );
536  }
537 }
538 
539 void AgentBasePrivate::collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest )
540 {
541  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
542  if ( observer2 ) {
543  observer2->collectionMoved( collection, source, dest );
544  } else if ( mObserver ) {
545  // ### we cannot just call collectionRemoved here as this will already trigger changeProcessed()
546  // so, just collectionAdded() is good enough as no resource can have implemented intra-resource moves anyway
547  // without using ObserverV2
548  mObserver->collectionAdded( collection, dest );
549  } else {
550  changeProcessed();
551  }
552 }
553 
554 void AgentBasePrivate::collectionRemoved( const Akonadi::Collection &collection )
555 {
556  if ( mObserver != 0 ) {
557  mObserver->collectionRemoved( collection );
558  }
559 }
560 
561 void AgentBasePrivate::collectionSubscribed( const Akonadi::Collection &collection, const Akonadi::Collection &parent )
562 {
563  Q_UNUSED( collection );
564  Q_UNUSED( parent );
565  changeProcessed();
566 }
567 
568 void AgentBasePrivate::collectionUnsubscribed( const Akonadi::Collection &collection )
569 {
570  Q_UNUSED( collection );
571  changeProcessed();
572 }
573 
574 void AgentBasePrivate::changeProcessed()
575 {
576  mChangeRecorder->changeProcessed();
577  QTimer::singleShot( 0, mChangeRecorder, SLOT(replayNext()) );
578 }
579 
580 void AgentBasePrivate::slotStatus( int status, const QString &message )
581 {
582  mStatusMessage = message;
583  mStatusCode = 0;
584 
585  switch ( status ) {
586  case AgentBase::Idle:
587  if ( mStatusMessage.isEmpty() ) {
588  mStatusMessage = defaultReadyMessage();
589  }
590 
591  mStatusCode = 0;
592  break;
593  case AgentBase::Running:
594  if ( mStatusMessage.isEmpty() ) {
595  mStatusMessage = defaultSyncingMessage();
596  }
597 
598  mStatusCode = 1;
599  break;
600  case AgentBase::Broken:
601  if ( mStatusMessage.isEmpty() ) {
602  mStatusMessage = defaultErrorMessage();
603  }
604 
605  mStatusCode = 2;
606  break;
607 
608  case AgentBase::NotConfigured:
609  if ( mStatusMessage.isEmpty() ) {
610  mStatusMessage = defaultUnconfiguredMessage();
611  }
612 
613  mStatusCode = 3;
614  break;
615 
616  default:
617  Q_ASSERT( !"Unknown status passed" );
618  break;
619  }
620 }
621 
622 void AgentBasePrivate::slotPercent( int progress )
623 {
624  mProgress = progress;
625 }
626 
627 void AgentBasePrivate::slotWarning( const QString& message )
628 {
629  mTracer->warning( QString::fromLatin1( "AgentBase(%1)" ).arg( mId ), message );
630 }
631 
632 void AgentBasePrivate::slotError( const QString& message )
633 {
634  mTracer->error( QString::fromLatin1( "AgentBase(%1)" ).arg( mId ), message );
635 }
636 
637 void AgentBasePrivate::slotNetworkStatusChange( Solid::Networking::Status stat )
638 {
639  Q_Q( AgentBase );
640  q->setOnlineInternal( mDesiredOnlineState && ( stat == Solid::Networking::Unknown || stat == Solid::Networking::Connected ) );
641 }
642 
643 void AgentBasePrivate::slotResumedFromSuspend()
644 {
645  if ( mNeedsNetwork ) {
646  slotNetworkStatusChange( Solid::Networking::status() );
647  }
648 }
649 
650 QString AgentBasePrivate::dumpNotificationListToString() const
651 {
652  return mChangeRecorder->dumpNotificationListToString();
653 }
654 
655 void AgentBasePrivate::dumpMemoryInfo() const
656 {
657  // Send it to stdout, so we can debug user problems.
658  // since you have to explicitely call this
659  // it won't flood users with release builds.
660  QTextStream stream( stdout );
661  stream << dumpMemoryInfoToString();
662 }
663 
664 QString AgentBasePrivate::dumpMemoryInfoToString() const
665 {
666  // man mallinfo for more info
667  QString str;
668 #if defined __GLIBC__
669  struct mallinfo mi;
670  mi = mallinfo();
671  QTextStream stream( &str );
672  stream
673  << "Total non-mmapped bytes (arena): " << mi.arena << '\n'
674  << "# of free chunks (ordblks): " << mi.ordblks << '\n'
675  << "# of free fastbin blocks (smblks>: " << mi.smblks << '\n'
676  << "# of mapped regions (hblks): " << mi.hblks << '\n'
677  << "Bytes in mapped regions (hblkhd): " << mi.hblkhd << '\n'
678  << "Max. total allocated space (usmblks): " << mi.usmblks << '\n'
679  << "Free bytes held in fastbins (fsmblks):" << mi.fsmblks << '\n'
680  << "Total allocated space (uordblks): " << mi.uordblks << '\n'
681  << "Total free space (fordblks): " << mi.fordblks << '\n'
682  << "Topmost releasable block (keepcost): " << mi.keepcost << '\n';
683 #else
684  str = QLatin1String( "mallinfo() not supported" );
685 #endif
686  return str;
687 }
688 
689 
690 AgentBase::AgentBase( const QString & id )
691  : d_ptr( new AgentBasePrivate( this ) )
692 {
693  sAgentBase = this;
694  d_ptr->mId = id;
695  d_ptr->init();
696 }
697 
698 AgentBase::AgentBase( AgentBasePrivate* d, const QString &id ) :
699  d_ptr( d )
700 {
701  sAgentBase = this;
702  d_ptr->mId = id;
703  d_ptr->init();
704 }
705 
706 AgentBase::~AgentBase()
707 {
708  delete d_ptr;
709 }
710 
711 QString AgentBase::parseArguments( int argc, char **argv )
712 {
713  QString identifier;
714  if ( argc < 3 ) {
715  kDebug() << "Not enough arguments passed...";
716  exit( 1 );
717  }
718 
719  for ( int i = 1; i < argc - 1; ++i ) {
720  if ( QLatin1String( argv[ i ] ) == QLatin1String( "--identifier" ) ) {
721  identifier = QLatin1String( argv[ i + 1 ] );
722  }
723  }
724 
725  if ( identifier.isEmpty() ) {
726  kDebug() << "Identifier argument missing";
727  exit( 1 );
728  }
729 
730  const QFileInfo fi( QString::fromLocal8Bit( argv[0] ) );
731  // strip off full path and possible .exe suffix
732  const QByteArray catalog = fi.baseName().toLatin1();
733 
734  KCmdLineArgs::init( argc, argv, ServerManager::addNamespace( identifier ).toLatin1(), catalog, ki18n( "Akonadi Agent" ), KDEPIMLIBS_VERSION,
735  ki18n( "Akonadi Agent" ) );
736 
737  KCmdLineOptions options;
738  options.add( "identifier <argument>", ki18n( "Agent identifier" ) );
739  KCmdLineArgs::addCmdLineOptions( options );
740 
741  return identifier;
742 }
743 
744 // @endcond
745 
746 int AgentBase::init( AgentBase *r )
747 {
748  QApplication::setQuitOnLastWindowClosed( false );
749  KGlobal::locale()->insertCatalog( QLatin1String( "libakonadi" ) );
750  int rv = kapp->exec();
751  delete r;
752  return rv;
753 }
754 
755 int AgentBase::status() const
756 {
757  Q_D( const AgentBase );
758 
759  return d->mStatusCode;
760 }
761 
762 QString AgentBase::statusMessage() const
763 {
764  Q_D( const AgentBase );
765 
766  return d->mStatusMessage;
767 }
768 
769 int AgentBase::progress() const
770 {
771  Q_D( const AgentBase );
772 
773  return d->mProgress;
774 }
775 
776 QString AgentBase::progressMessage() const
777 {
778  Q_D( const AgentBase );
779 
780  return d->mProgressMessage;
781 }
782 
783 bool AgentBase::isOnline() const
784 {
785  Q_D( const AgentBase );
786 
787  return d->mOnline;
788 }
789 
790 void AgentBase::setNeedsNetwork( bool needsNetwork )
791 {
792  Q_D( AgentBase );
793  d->mNeedsNetwork = needsNetwork;
794 
795  if ( d->mNeedsNetwork ) {
796  connect( Solid::Networking::notifier()
797  , SIGNAL(statusChanged(Solid::Networking::Status))
798  , this, SLOT(slotNetworkStatusChange(Solid::Networking::Status))
799  , Qt::UniqueConnection );
800 
801  } else {
802  disconnect( Solid::Networking::notifier(), 0, 0, 0 );
803  setOnlineInternal( d->mDesiredOnlineState );
804  }
805 }
806 
807 void AgentBase::setOnline( bool state )
808 {
809  Q_D( AgentBase );
810  d->mDesiredOnlineState = state;
811  d->mSettings->setValue( QLatin1String( "Agent/DesiredOnlineState" ), state );
812  setOnlineInternal( state );
813 }
814 
815 void AgentBase::setOnlineInternal( bool state )
816 {
817  Q_D( AgentBase );
818  d->mOnline = state;
819 
820  const QString newMessage = d->defaultReadyMessage();
821  if ( d->mStatusMessage != newMessage && d->mStatusCode != AgentBase::Broken ) {
822  emit status( d->mStatusCode, newMessage );
823  }
824 
825  doSetOnline( state );
826  emit onlineChanged( state );
827 }
828 
829 void AgentBase::doSetOnline( bool online )
830 {
831  Q_UNUSED( online );
832 }
833 
834 void AgentBase::configure( WId windowId )
835 {
836  Q_UNUSED( windowId );
837  emit configurationDialogAccepted();
838 }
839 
840 #ifdef Q_OS_WIN //krazy:exclude=cpp
841 void AgentBase::configure( qlonglong windowId )
842 {
843  configure( reinterpret_cast<WId>( windowId ) );
844 }
845 #endif
846 
847 WId AgentBase::winIdForDialogs() const
848 {
849  const bool registered = DBusConnectionPool::threadConnection().interface()->isServiceRegistered( QLatin1String( "org.freedesktop.akonaditray" ) );
850  if ( !registered ) {
851  return 0;
852  }
853 
854  QDBusInterface dbus( QLatin1String( "org.freedesktop.akonaditray" ), QLatin1String( "/Actions" ),
855  QLatin1String( "org.freedesktop.Akonadi.Tray" ) );
856  const QDBusMessage reply = dbus.call( QLatin1String( "getWinId" ) );
857 
858  if ( reply.type() == QDBusMessage::ErrorMessage ) {
859  return 0;
860  }
861 
862  const WId winid = (WId)reply.arguments().at( 0 ).toLongLong();
863 
864  return winid;
865 }
866 
867 void AgentBase::quit()
868 {
869  Q_D( AgentBase );
870  aboutToQuit();
871 
872  if ( d->mSettings ) {
873  d->mChangeRecorder->setConfig( 0 );
874  d->mSettings->sync();
875  }
876 
877  KGlobal::deref();
878 }
879 
880 void AgentBase::aboutToQuit()
881 {
882 }
883 
884 void AgentBase::cleanup()
885 {
886  Q_D( AgentBase );
887  // prevent the monitor from picking up deletion signals for our own data if we are a resource
888  // and thus avoid that we kill our own data as last act before our own death
889  d->mChangeRecorder->blockSignals( true );
890 
891  aboutToQuit();
892 
893  const QString fileName = d->mSettings->fileName();
894 
895  /*
896  * First destroy the settings object...
897  */
898  d->mChangeRecorder->setConfig( 0 );
899  delete d->mSettings;
900  d->mSettings = 0;
901 
902  /*
903  * ... then remove the file from hd.
904  */
905  QFile::remove( fileName );
906 
907  /*
908  * ... and remove the changes file from hd.
909  */
910  QFile::remove( fileName + QLatin1String( "_changes.dat" ) );
911 
912  /*
913  * ... and also remove the agent configuration file if there is one.
914  */
915  QString configFile = KStandardDirs::locateLocal( "config", config()->name() );
916  QFile::remove( configFile );
917 
918  KGlobal::deref();
919 }
920 
921 void AgentBase::registerObserver( Observer *observer )
922 {
923  // TODO in theory we should re-connect change recorder signals here that we disconnected previously
924  d_ptr->mObserver = observer;
925 
926  const bool haveObserverV3 = (dynamic_cast<AgentBase::ObserverV3*>(d_ptr->mObserver) != 0);
927 
928  disconnect( d_ptr->mChangeRecorder, SIGNAL(itemsFlagsChanged(Akonadi::Item::List,QSet<QByteArray>,QSet<QByteArray>)),
929  d_ptr, SLOT(itemsFlagsChanged(Akonadi::Item::List,QSet<QByteArray>,QSet<QByteArray>)) );
930  disconnect( d_ptr->mChangeRecorder, SIGNAL(itemsMoved(Akonadi::Item::List,Akonadi::Collection,Akonadi::Collection)),
931  d_ptr, SLOT(itemsMoved(Akonadi::Item::List,Akonadi::Collection,Akonadi::Collection)) );
932  disconnect( d_ptr->mChangeRecorder, SIGNAL(itemsRemoved(Akonadi::Item::List)),
933  d_ptr, SLOT(itemsRemoved(Akonadi::Item::List)) );
934  disconnect( d_ptr->mChangeRecorder, SIGNAL(itemsLinked(Akonadi::Item::List,Akonadi::Collection)),
935  d_ptr, SLOT(itemsLinked(Akonadi::Item::List,Akonadi::Collection)) );
936  disconnect( d_ptr->mChangeRecorder, SIGNAL(itemsUnlinked(Akonadi::Item::List,Akonadi::Collection)),
937  d_ptr, SLOT(itemsUnlinked(Akonadi::Item::List,Akonadi::Collection)) );
938  disconnect( d_ptr->mChangeRecorder, SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)),
939  d_ptr, SLOT(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)) );
940  disconnect( d_ptr->mChangeRecorder, SIGNAL(itemRemoved(Akonadi::Item)),
941  d_ptr, SLOT(itemRemoved(Akonadi::Item)) );
942  disconnect( d_ptr->mChangeRecorder, SIGNAL(itemLinked(Akonadi::Item,Akonadi::Collection)),
943  d_ptr, SLOT(itemLinked(Akonadi::Item,Akonadi::Collection)) );
944  disconnect( d_ptr->mChangeRecorder, SIGNAL(itemUnlinked(Akonadi::Item,Akonadi::Collection)),
945  d_ptr, SLOT(itemUnlinked(Akonadi::Item,Akonadi::Collection)) );
946 
947  if ( haveObserverV3 ) {
948  connect( d_ptr->mChangeRecorder, SIGNAL(itemsFlagsChanged(Akonadi::Item::List,QSet<QByteArray>,QSet<QByteArray>)),
949  d_ptr, SLOT(itemsFlagsChanged(Akonadi::Item::List,QSet<QByteArray>,QSet<QByteArray>)) );
950  connect( d_ptr->mChangeRecorder, SIGNAL(itemsMoved(Akonadi::Item::List,Akonadi::Collection,Akonadi::Collection)),
951  d_ptr, SLOT(itemsMoved(Akonadi::Item::List,Akonadi::Collection,Akonadi::Collection)) );
952  connect( d_ptr->mChangeRecorder, SIGNAL(itemsRemoved(Akonadi::Item::List)),
953  d_ptr, SLOT(itemsRemoved(Akonadi::Item::List)) );
954  connect( d_ptr->mChangeRecorder, SIGNAL(itemsLinked(Akonadi::Item::List,Akonadi::Collection)),
955  d_ptr, SLOT(itemsLinked(Akonadi::Item::List,Akonadi::Collection)) );
956  connect( d_ptr->mChangeRecorder, SIGNAL(itemsUnlinked(Akonadi::Item::List,Akonadi::Collection)),
957  d_ptr, SLOT(itemsUnlinked(Akonadi::Item::List,Akonadi::Collection)) );
958  } else {
959  connect( d_ptr->mChangeRecorder, SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)),
960  d_ptr, SLOT(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)) );
961  connect( d_ptr->mChangeRecorder, SIGNAL(itemRemoved(Akonadi::Item)),
962  d_ptr, SLOT(itemRemoved(Akonadi::Item)) );
963  connect( d_ptr->mChangeRecorder, SIGNAL(itemLinked(Akonadi::Item,Akonadi::Collection)),
964  d_ptr, SLOT(itemLinked(Akonadi::Item,Akonadi::Collection)) );
965  connect( d_ptr->mChangeRecorder, SIGNAL(itemUnlinked(Akonadi::Item,Akonadi::Collection)),
966  d_ptr, SLOT(itemUnlinked(Akonadi::Item,Akonadi::Collection)) );
967  }
968 }
969 
970 QString AgentBase::identifier() const
971 {
972  return d_ptr->mId;
973 }
974 
975 void AgentBase::setAgentName( const QString &name )
976 {
977  Q_D( AgentBase );
978  if ( name == d->mName ) {
979  return;
980  }
981 
982  // TODO: rename collection
983  d->mName = name;
984 
985  if ( d->mName.isEmpty() || d->mName == d->mId ) {
986  d->mSettings->remove( QLatin1String( "Resource/Name" ) );
987  d->mSettings->remove( QLatin1String( "Agent/Name" ) );
988  } else
989  d->mSettings->setValue( QLatin1String( "Agent/Name" ), d->mName );
990 
991  d->mSettings->sync();
992 
993  d->setProgramName();
994 
995  emit agentNameChanged( d->mName );
996 }
997 
998 QString AgentBase::agentName() const
999 {
1000  Q_D( const AgentBase );
1001  if ( d->mName.isEmpty() ) {
1002  return d->mId;
1003  } else {
1004  return d->mName;
1005  }
1006 }
1007 
1008 void AgentBase::changeProcessed()
1009 {
1010  Q_D( AgentBase );
1011  d->changeProcessed();
1012 }
1013 
1014 ChangeRecorder * AgentBase::changeRecorder() const
1015 {
1016  return d_ptr->mChangeRecorder;
1017 }
1018 
1019 KSharedConfigPtr AgentBase::config()
1020 {
1021  if ( QCoreApplication::instance()->thread() == QThread::currentThread() ) {
1022  return KGlobal::config();
1023  } else {
1024  return componentData().config();
1025  }
1026 }
1027 
1028 void AgentBase::abort()
1029 {
1030  emit abortRequested();
1031 }
1032 
1033 void AgentBase::reconfigure()
1034 {
1035  emit reloadConfiguration();
1036 }
1037 
1038 extern QThreadStorage<KComponentData*> s_agentComponentDatas;
1039 
1040 KComponentData AgentBase::componentData()
1041 {
1042  if ( QThread::currentThread() == QCoreApplication::instance()->thread() ) {
1043  if ( s_agentComponentDatas.hasLocalData() ) {
1044  return *( s_agentComponentDatas.localData() );
1045  } else {
1046  return KGlobal::mainComponent();
1047  }
1048  }
1049 
1050  Q_ASSERT( s_agentComponentDatas.hasLocalData() );
1051  return *( s_agentComponentDatas.localData() );
1052 }
1053 
1054 #include "moc_agentbase.cpp"
1055 #include "moc_agentbase_p.cpp"
Akonadi::AgentBase::winIdForDialogs
WId winIdForDialogs() const
This method returns the windows id, which should be used for dialogs.
Akonadi::AgentBase::ObserverV3::itemsUnlinked
virtual void itemsUnlinked(const Akonadi::Item::List &items, const Akonadi::Collection &collection)
Reimplement to handle batch notifications about items unlinking.
Definition: agentbase.cpp:227
Akonadi::AgentBase::ObserverV3::itemsMoved
virtual void itemsMoved(const Akonadi::Item::List &items, const Akonadi::Collection &sourceCollection, const Akonadi::Collection &destinationCollection)
Reimplement to handle batch notification about items move.
Definition: agentbase.cpp:188
Akonadi::AgentBase::percent
void percent(int progress)
This signal should be emitted whenever the progress of an action in the agent (e.g.
Akonadi::AgentBase::abortRequested
void abortRequested()
Emitted when another application has remotely asked the agent to abort its current operation...
Akonadi::AgentBase::NotConfigured
The agent is lacking required configuration.
Definition: agentbase.h:367
Akonadi::AgentBase::AgentBase
AgentBase(const QString &id)
Creates an agent base.
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::AgentInstance::type
AgentType type() const
Returns the agent type of this instance.
Definition: agentinstance.cpp:50
Akonadi::AgentBase::ObserverV2::itemMoved
virtual void itemMoved(const Akonadi::Item &item, const Akonadi::Collection &collectionSource, const Akonadi::Collection &collectionDestination)
Reimplement to handle item moves.
Definition: agentbase.cpp:124
Akonadi::AgentBase::setNeedsNetwork
void setNeedsNetwork(bool needsNetwork)
Sets whether the agent needs network or not.
Akonadi::AgentType::name
QString name() const
Returns the i18n'ed name of the agent type.
Definition: agenttype.cpp:51
Akonadi::AgentBase::ObserverV2::collectionMoved
virtual void collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, const Akonadi::Collection &collectionDestination)
Reimplement to handle collection moves.
Definition: agentbase.cpp:158
Akonadi::AgentBase::Observer
The interface for reacting on monitored or replayed changes.
Definition: agentbase.h:185
Akonadi::AgentBase::componentData
static KComponentData componentData()
Returns the component data object for this agent instance.
Definition: agentbase.cpp:1040
Akonadi::AgentBase::agentNameChanged
void agentNameChanged(const QString &name)
This signal is emitted whenever the name of the agent has changed.
Akonadi::AgentBase::reloadConfiguration
void reloadConfiguration()
Emitted if another application has changed the agent's configuration remotely and called AgentInstanc...
Akonadi::SessionPrivate::createDefaultSession
static void createDefaultSession(const QByteArray &sessionId)
Creates a new default session for this thread with the given sessionId.
Definition: session.cpp:429
Akonadi::ServerManager::serviceName
static QString serviceName(ServiceType serviceType)
Returns the namespaced D-Bus service name for serviceType.
Definition: servermanager.cpp:298
Akonadi::AgentBase::configurationDialogAccepted
void configurationDialogAccepted()
This signal is emitted whenever the user has accepted the configuration dialog.
Akonadi::AgentBase::ObserverV2::collectionChanged
virtual void collectionChanged(const Akonadi::Collection &collection, const QSet< QByteArray > &changedAttributes)
Reimplement to handle changes to existing collections.
Definition: agentbase.cpp:168
Akonadi::Session::defaultSession
static Session * defaultSession()
Returns the default session for this thread.
Definition: session.cpp:444
Akonadi::AgentBase::~AgentBase
~AgentBase()
Destroys the agent base.
Akonadi::AgentBasePrivate
Definition: agentbase_p.h:38
Akonadi::AgentBase
The base class for all Akonadi agents and resources.
Definition: agentbase.h:80
Akonadi::AgentBase::Observer::itemChanged
virtual void itemChanged(const Akonadi::Item &item, const QSet< QByteArray > &partIdentifiers)
Reimplement to handle changes to existing items.
Definition: agentbase.cpp:82
Akonadi::AgentBase::setAgentName
void setAgentName(const QString &name)
This method is used to set the name of the agent.
Definition: agentbase.cpp:975
Akonadi::AgentBase::error
void error(const QString &message)
This signal shall be used to report errors.
Akonadi::AgentBase::aboutToQuit
virtual void aboutToQuit()
This method is called whenever the agent application is about to quit.
Akonadi::AgentBase::Observer::~Observer
virtual ~Observer()
Destroys the observer instance.
Definition: agentbase.cpp:69
Akonadi::AgentBase::status
virtual int status() const
This method returns the current status code of the agent.
Akonadi::AgentBase::setOnline
void setOnline(bool state)
Sets whether the agent shall be online or not.
Akonadi::AgentBase::Observer::itemAdded
virtual void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection)
Reimplement to handle adding of new items.
Definition: agentbase.cpp:73
Akonadi::AgentBase::ObserverV2::itemUnlinked
virtual void itemUnlinked(const Akonadi::Item &item, const Akonadi::Collection &collection)
Reimplement to handle item unlinking.
Definition: agentbase.cpp:146
Akonadi::AgentManager::instance
AgentInstance instance(const QString &identifier) const
Returns the agent instance with the given identifier or an invalid agent instance if the identifier d...
Definition: agentmanager.cpp:404
Akonadi::AgentBase::ObserverV3::itemsFlagsChanged
virtual void itemsFlagsChanged(const Akonadi::Item::List &items, const QSet< QByteArray > &addedFlags, const QSet< QByteArray > &removedFlags)
Reimplement to handle changes in flags of existing items.
Definition: agentbase.cpp:174
Akonadi::AgentBase::config
KSharedConfigPtr config()
Returns the config object for this Agent.
Definition: agentbase.cpp:1019
Akonadi::AgentBase::doSetOnline
virtual void doSetOnline(bool online)
This method is called whenever the online status has changed.
Akonadi::AgentBase::configure
virtual void configure(WId windowId)
This method is called whenever the agent shall show its configuration dialog to the user...
Akonadi::AgentBase::ObserverV2
BC extension of Observer with support for monitoring item and collection moves.
Definition: agentbase.h:244
Akonadi::AgentBase::Observer::itemRemoved
virtual void itemRemoved(const Akonadi::Item &item)
Reimplement to handle deletion of items.
Definition: agentbase.cpp:91
Akonadi::AgentBase::cleanup
virtual void cleanup()
This method is called when the agent is removed from the system, so it can do some cleanup stuff...
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::AgentBase::ObserverV3
BC extension of ObserverV2 with support for batch operations.
Definition: agentbase.h:309
Akonadi::AgentBase::statusMessage
virtual QString statusMessage() const
This method returns an i18n'ed description of the current status code.
Akonadi::AgentBase::Observer::collectionRemoved
virtual void collectionRemoved(const Akonadi::Collection &collection)
Reimplement to handle deletion of collections.
Definition: agentbase.cpp:116
Akonadi::ChangeRecorder::setConfig
void setConfig(QSettings *settings)
Sets the QSettings object used for persistent recorded changes.
Definition: changerecorder.cpp:42
Akonadi::AgentBase::ObserverV3::itemsRemoved
virtual void itemsRemoved(const Akonadi::Item::List &items)
Reimplement to handle batch notification about items deletion.
Definition: agentbase.cpp:202
Akonadi::AgentBase::Broken
The agent encountered an error state.
Definition: agentbase.h:366
Akonadi::AgentBase::progress
virtual int progress() const
This method returns the current progress of the agent in percentage.
Akonadi::AgentBase::Observer::Observer
Observer()
Creates an observer instance.
Definition: agentbase.cpp:65
Akonadi::AgentBase::identifier
QString identifier() const
Returns the instance identifier of this agent.
Definition: agentbase.cpp:970
Akonadi::AgentBase::Observer::collectionChanged
virtual void collectionChanged(const Akonadi::Collection &collection)
Reimplement to handle changes to existing collections.
Definition: agentbase.cpp:108
Akonadi::AgentBase::changeRecorder
ChangeRecorder * changeRecorder() const
Returns the Akonadi::ChangeRecorder object used for monitoring.
Definition: agentbase.cpp:1014
Akonadi::AgentBase::registerObserver
void registerObserver(Observer *observer)
Registers the given observer for reacting on monitored or recorded changes.
Definition: agentbase.cpp:921
Akonadi::AgentBase::isOnline
bool isOnline() const
Returns whether the agent is currently online.
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::AgentBase::ObserverV3::itemsLinked
virtual void itemsLinked(const Akonadi::Item::List &items, const Akonadi::Collection &collection)
Reimplement to handle batch notifications about items linking.
Definition: agentbase.cpp:214
Akonadi::AgentBase::ObserverV2::itemLinked
virtual void itemLinked(const Akonadi::Item &item, const Akonadi::Collection &collection)
Reimplement to handle item linking.
Definition: agentbase.cpp:134
Akonadi::AgentManager::self
static AgentManager * self()
Returns the global instance of the agent manager.
Definition: agentmanager.cpp:380
Akonadi::AgentBase::init
static int init(int argc, char **argv)
Use this method in the main function of your agent application to initialize your agent subclass...
Definition: agentbase.h:395
Akonadi::Collection::resource
QString resource() const
Returns the identifier of the resource owning the collection.
Definition: collection.cpp:207
Akonadi::AgentBase::onlineChanged
void onlineChanged(bool online)
Emitted when the online state changed.
Akonadi::AgentBase::Running
The agent is working on something.
Definition: agentbase.h:365
Akonadi::AgentBase::warning
void warning(const QString &message)
This signal shall be used to report warnings.
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::AgentBase::Observer::collectionAdded
virtual void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent)
Reimplement to handle adding of new collections.
Definition: agentbase.cpp:99
Akonadi::AgentBase::progressMessage
virtual QString progressMessage() const
This method returns an i18n'ed description of the current progress.
Akonadi::AgentBase::Idle
The agent does currently nothing.
Definition: agentbase.h:364
Akonadi::AgentBase::agentName
QString agentName() const
Returns the name of the agent.
Definition: agentbase.cpp:998
Akonadi::ChangeRecorder
Records and replays change notification.
Definition: changerecorder.h:47
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:26 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