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

akonadi

  • 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 <klocale.h>
42 #include <kstandarddirs.h>
43 
44 #include <Solid/PowerManagement>
45 
46 #include <QtCore/QDir>
47 #include <QtCore/QSettings>
48 #include <QtCore/QTimer>
49 #include <QtDBus/QtDBus>
50 #include <QApplication>
51 
52 #include <signal.h>
53 #include <stdlib.h>
54 
55 
56 //#define EXPERIMENTAL_INPROCESS_AGENTS 1
57 
58 using namespace Akonadi;
59 
60 static AgentBase *sAgentBase = 0;
61 
62 AgentBase::Observer::Observer()
63 {
64 }
65 
66 AgentBase::Observer::~Observer()
67 {
68 }
69 
70 void AgentBase::Observer::itemAdded( const Item &item, const Collection &collection )
71 {
72  Q_UNUSED( item );
73  Q_UNUSED( collection );
74  if ( sAgentBase != 0 ) {
75  sAgentBase->d_ptr->changeProcessed();
76  }
77 }
78 
79 void AgentBase::Observer::itemChanged( const Item &item, const QSet<QByteArray> &partIdentifiers )
80 {
81  Q_UNUSED( item );
82  Q_UNUSED( partIdentifiers );
83  if ( sAgentBase != 0 ) {
84  sAgentBase->d_ptr->changeProcessed();
85  }
86 }
87 
88 void AgentBase::Observer::itemRemoved( const Item &item )
89 {
90  Q_UNUSED( item );
91  if ( sAgentBase != 0 ) {
92  sAgentBase->d_ptr->changeProcessed();
93  }
94 }
95 
96 void AgentBase::Observer::collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent )
97 {
98  Q_UNUSED( collection );
99  Q_UNUSED( parent );
100  if ( sAgentBase != 0 ) {
101  sAgentBase->d_ptr->changeProcessed();
102  }
103 }
104 
105 void AgentBase::Observer::collectionChanged( const Collection &collection )
106 {
107  Q_UNUSED( collection );
108  if ( sAgentBase != 0 ) {
109  sAgentBase->d_ptr->changeProcessed();
110  }
111 }
112 
113 void AgentBase::Observer::collectionRemoved( const Collection &collection )
114 {
115  Q_UNUSED( collection );
116  if ( sAgentBase != 0 ) {
117  sAgentBase->d_ptr->changeProcessed();
118  }
119 }
120 
121 void AgentBase::ObserverV2::itemMoved( const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest )
122 {
123  Q_UNUSED( item );
124  Q_UNUSED( source );
125  Q_UNUSED( dest );
126  if ( sAgentBase != 0 ) {
127  sAgentBase->d_ptr->changeProcessed();
128  }
129 }
130 
131 void AgentBase::ObserverV2::itemLinked( const Akonadi::Item& item, const Akonadi::Collection& collection )
132 {
133  Q_UNUSED( item );
134  Q_UNUSED( collection );
135  if ( sAgentBase != 0 ) {
136  // not implementation, let's disconnect the signal to enable optimizations in Monitor
137  QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL(itemLinked(Akonadi::Item,Akonadi::Collection)),
138  sAgentBase->d_ptr, SLOT(itemLinked(Akonadi::Item,Akonadi::Collection)) );
139  sAgentBase->d_ptr->changeProcessed();
140  }
141 }
142 
143 void AgentBase::ObserverV2::itemUnlinked( const Akonadi::Item& item, const Akonadi::Collection& collection )
144 {
145  Q_UNUSED( item );
146  Q_UNUSED( collection );
147  if ( sAgentBase != 0 ) {
148  // not implementation, let's disconnect the signal to enable optimizations in Monitor
149  QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL(itemUnlinked(Akonadi::Item,Akonadi::Collection)),
150  sAgentBase->d_ptr, SLOT(itemUnlinked(Akonadi::Item,Akonadi::Collection)) );
151  sAgentBase->d_ptr->changeProcessed();
152  }
153 }
154 
155 void AgentBase::ObserverV2::collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest )
156 {
157  Q_UNUSED( collection );
158  Q_UNUSED( source );
159  Q_UNUSED( dest );
160  if ( sAgentBase != 0 ) {
161  sAgentBase->d_ptr->changeProcessed();
162  }
163 }
164 
165 void AgentBase::ObserverV2::collectionChanged( const Akonadi::Collection &collection, const QSet<QByteArray> &changedAttributes )
166 {
167  Q_UNUSED( changedAttributes );
168  collectionChanged( collection );
169 }
170 
171 //@cond PRIVATE
172 
173 AgentBasePrivate::AgentBasePrivate( AgentBase *parent )
174  : q_ptr( parent ),
175  mDBusConnection( QString() ),
176  mStatusCode( AgentBase::Idle ),
177  mProgress( 0 ),
178  mNeedsNetwork( false ),
179  mOnline( false ),
180  mDesiredOnlineState( false ),
181  mSettings( 0 ),
182  mChangeRecorder( 0 ),
183  mTracer( 0 ),
184  mObserver( 0 )
185 {
186 #ifdef Q_OS_WINCE
187  QThread::currentThread()->setPriority( QThread::LowPriority );
188 #endif
189  Internal::setClientType( Internal::Agent );
190 }
191 
192 AgentBasePrivate::~AgentBasePrivate()
193 {
194  mChangeRecorder->setConfig( 0 );
195  delete mSettings;
196 }
197 
198 void AgentBasePrivate::init()
199 {
200  Q_Q( AgentBase );
201 
205  SessionPrivate::createDefaultSession( mId.toLatin1() );
206 
207  if ( QThread::currentThread() != QCoreApplication::instance()->thread() ) {
208  mDBusConnection = QDBusConnection::connectToBus( QDBusConnection::SessionBus, q->identifier() );
209  Q_ASSERT( mDBusConnection.isConnected() );
210  }
211 
212  mTracer = new org::freedesktop::Akonadi::Tracer( ServerManager::serviceName( ServerManager::Server ),
213  QLatin1String( "/tracing" ),
214  DBusConnectionPool::threadConnection(), q );
215 
216  new Akonadi__ControlAdaptor( q );
217  new Akonadi__StatusAdaptor( q );
218  if ( !DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/" ), q, QDBusConnection::ExportAdaptors ) )
219  q->error( i18n( "Unable to register object at dbus: %1", DBusConnectionPool::threadConnection().lastError().message() ) );
220 
221  mSettings = new QSettings( QString::fromLatin1( "%1/agent_config_%2" ).arg( Internal::xdgSaveDir( "config" ), mId ), QSettings::IniFormat );
222 
223  mChangeRecorder = new ChangeRecorder( q );
224  mChangeRecorder->ignoreSession( Session::defaultSession() );
225  mChangeRecorder->itemFetchScope().setCacheOnly( true );
226  mChangeRecorder->setConfig( mSettings );
227 
228  mDesiredOnlineState = mSettings->value( QLatin1String( "Agent/DesiredOnlineState" ), true ).toBool();
229  mOnline = mDesiredOnlineState;
230 
231  // reinitialize the status message now that online state is available
232  mStatusMessage = defaultReadyMessage();
233 
234  mName = mSettings->value( QLatin1String( "Agent/Name" ) ).toString();
235  if ( mName.isEmpty() ) {
236  mName = mSettings->value( QLatin1String( "Resource/Name" ) ).toString();
237  if ( !mName.isEmpty() ) {
238  mSettings->remove( QLatin1String( "Resource/Name" ) );
239  mSettings->setValue( QLatin1String( "Agent/Name" ), mName );
240  }
241  }
242 
243  connect( mChangeRecorder, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)),
244  SLOT(itemAdded(Akonadi::Item,Akonadi::Collection)) );
245  connect( mChangeRecorder, SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)),
246  SLOT(itemChanged(Akonadi::Item,QSet<QByteArray>)) );
247  connect( mChangeRecorder, SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)),
248  SLOT(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)) );
249  connect( mChangeRecorder, SIGNAL(itemRemoved(Akonadi::Item)),
250  SLOT(itemRemoved(Akonadi::Item)) );
251  connect( mChangeRecorder, SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)),
252  SLOT(collectionAdded(Akonadi::Collection,Akonadi::Collection)) );
253  connect( mChangeRecorder, SIGNAL(itemLinked(Akonadi::Item,Akonadi::Collection)),
254  SLOT(itemLinked(Akonadi::Item,Akonadi::Collection)) );
255  connect( mChangeRecorder, SIGNAL(itemUnlinked(Akonadi::Item,Akonadi::Collection)),
256  SLOT(itemUnlinked(Akonadi::Item,Akonadi::Collection)) );
257  connect( mChangeRecorder, SIGNAL(collectionChanged(Akonadi::Collection)),
258  SLOT(collectionChanged(Akonadi::Collection)) );
259  connect( mChangeRecorder, SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)),
260  SLOT(collectionChanged(Akonadi::Collection,QSet<QByteArray>)) );
261  connect( mChangeRecorder, SIGNAL(collectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)),
262  SLOT(collectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)) );
263  connect( mChangeRecorder, SIGNAL(collectionRemoved(Akonadi::Collection)),
264  SLOT(collectionRemoved(Akonadi::Collection)) );
265  connect( mChangeRecorder, SIGNAL(collectionSubscribed(Akonadi::Collection,Akonadi::Collection)),
266  SLOT(collectionSubscribed(Akonadi::Collection,Akonadi::Collection)) );
267  connect( mChangeRecorder, SIGNAL(collectionUnsubscribed(Akonadi::Collection)),
268  SLOT(collectionUnsubscribed(Akonadi::Collection)) );
269 
270  connect( q, SIGNAL(status(int,QString)), q, SLOT(slotStatus(int,QString)) );
271  connect( q, SIGNAL(percent(int)), q, SLOT(slotPercent(int)) );
272  connect( q, SIGNAL(warning(QString)), q, SLOT(slotWarning(QString)) );
273  connect( q, SIGNAL(error(QString)), q, SLOT(slotError(QString)) );
274 
275  connect( Solid::PowerManagement::notifier(), SIGNAL(resumingFromSuspend()), q, SLOT(slotResumedFromSuspend()) );
276 
277  // Use reference counting to allow agents to finish internal jobs when the
278  // agent is stopped.
279  KGlobal::ref();
280  if ( QThread::currentThread() == QCoreApplication::instance()->thread() ) {
281  KGlobal::setAllowQuit( true );
282  }
283 
284 #ifndef Q_OS_WINCE
285  // disable session management
286  if ( KApplication::kApplication() ) {
287  KApplication::kApplication()->disableSessionManagement();
288  }
289 #endif
290 
291  mResourceTypeName = AgentManager::self()->instance( mId ).type().name();
292  setProgramName();
293 
294  QTimer::singleShot( 0, q, SLOT(delayedInit()) );
295 }
296 
297 void AgentBasePrivate::delayedInit()
298 {
299  Q_Q( AgentBase );
300  const QString serviceId = ServerManager::agentServiceName( ServerManager::Agent, mId );
301  if ( !DBusConnectionPool::threadConnection().registerService( serviceId ) ) {
302  kFatal() << "Unable to register service" << serviceId << "at dbus:" << DBusConnectionPool::threadConnection().lastError().message();
303  }
304  q->setOnlineInternal( mDesiredOnlineState );
305 }
306 
307 void AgentBasePrivate::setProgramName()
308 {
309  // ugly, really ugly, if you find another solution, change it and blame me for this code (Andras)
310  QString programName = mResourceTypeName;
311  if ( !mName.isEmpty() ) {
312  programName = i18nc( "Name and type of Akonadi resource", "%1 of type %2", mName, mResourceTypeName ) ;
313  }
314  const_cast<KAboutData*>( KGlobal::mainComponent().aboutData() )->setProgramName( ki18n( programName.toUtf8() ) );
315 }
316 
317 void AgentBasePrivate::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection )
318 {
319  if ( mObserver != 0 ) {
320  mObserver->itemAdded( item, collection );
321  }
322 }
323 
324 void AgentBasePrivate::itemChanged( const Akonadi::Item &item, const QSet<QByteArray> &partIdentifiers )
325 {
326  if ( mObserver != 0 ) {
327  mObserver->itemChanged( item, partIdentifiers );
328  }
329 }
330 
331 void AgentBasePrivate::itemMoved( const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest )
332 {
333  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
334  if ( mObserver ) {
335  // inter-resource moves, requires we know which resources the source and destination are in though
336  if ( !source.resource().isEmpty() && !dest.resource().isEmpty() ) {
337  if ( source.resource() != dest.resource() ) {
338  if ( source.resource() == q_ptr->identifier() ) { // moved away from us
339  Akonadi::Item i( item );
340  i.setParentCollection( source );
341  mObserver->itemRemoved( i );
342  } else if ( dest.resource() == q_ptr->identifier() ) { // moved to us
343  mObserver->itemAdded( item, dest );
344  } else if ( observer2 ) {
345  observer2->itemMoved( item, source, dest );
346  } else {
347  // not for us, not sure if we should get here at all
348  changeProcessed();
349  }
350  return;
351  }
352  }
353  // intra-resource move
354  if ( observer2 ) {
355  observer2->itemMoved( item, source, dest );
356  } else {
357  // ### we cannot just call itemRemoved here as this will already trigger changeProcessed()
358  // so, just itemAdded() is good enough as no resource can have implemented intra-resource moves anyway
359  // without using ObserverV2
360  mObserver->itemAdded( item, dest );
361  // mObserver->itemRemoved( item );
362  }
363  }
364 }
365 
366 void AgentBasePrivate::itemRemoved( const Akonadi::Item &item )
367 {
368  if ( mObserver != 0 ) {
369  mObserver->itemRemoved( item );
370  }
371 }
372 
373 void AgentBasePrivate::itemLinked( const Akonadi::Item &item, const Akonadi::Collection &collection )
374 {
375  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
376  if ( observer2 ) {
377  observer2->itemLinked( item, collection );
378  } else {
379  changeProcessed();
380  }
381 }
382 
383 void AgentBasePrivate::itemUnlinked( const Akonadi::Item &item, const Akonadi::Collection &collection )
384 {
385  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
386  if ( observer2 ) {
387  observer2->itemUnlinked( item, collection );
388  } else {
389  changeProcessed();
390  }
391 }
392 
393 void AgentBasePrivate::collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent )
394 {
395  if ( mObserver != 0 ) {
396  mObserver->collectionAdded( collection, parent );
397  }
398 }
399 
400 void AgentBasePrivate::collectionChanged( const Akonadi::Collection &collection )
401 {
402  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
403  if ( mObserver != 0 && observer2 == 0 ) { // For ObserverV2 we use the variant with the part identifiers
404  mObserver->collectionChanged( collection );
405  }
406 }
407 
408 void AgentBasePrivate::collectionChanged( const Akonadi::Collection &collection, const QSet<QByteArray> &changedAttributes )
409 {
410  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
411  if ( observer2 != 0 ) {
412  observer2->collectionChanged( collection, changedAttributes );
413  }
414 }
415 
416 void AgentBasePrivate::collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest )
417 {
418  AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
419  if ( observer2 ) {
420  observer2->collectionMoved( collection, source, dest );
421  } else if ( mObserver ) {
422  // ### we cannot just call collectionRemoved here as this will already trigger changeProcessed()
423  // so, just collectionAdded() is good enough as no resource can have implemented intra-resource moves anyway
424  // without using ObserverV2
425  mObserver->collectionAdded( collection, dest );
426  } else {
427  changeProcessed();
428  }
429 }
430 
431 void AgentBasePrivate::collectionRemoved( const Akonadi::Collection &collection )
432 {
433  if ( mObserver != 0 ) {
434  mObserver->collectionRemoved( collection );
435  }
436 }
437 
438 void AgentBasePrivate::collectionSubscribed( const Akonadi::Collection &collection, const Akonadi::Collection &parent )
439 {
440  Q_UNUSED( collection );
441  Q_UNUSED( parent );
442  changeProcessed();
443 }
444 
445 void AgentBasePrivate::collectionUnsubscribed( const Akonadi::Collection &collection )
446 {
447  Q_UNUSED( collection );
448  changeProcessed();
449 }
450 
451 void AgentBasePrivate::changeProcessed()
452 {
453  mChangeRecorder->changeProcessed();
454  QTimer::singleShot( 0, mChangeRecorder, SLOT(replayNext()) );
455 }
456 
457 void AgentBasePrivate::slotStatus( int status, const QString &message )
458 {
459  mStatusMessage = message;
460  mStatusCode = 0;
461 
462  switch ( status ) {
463  case AgentBase::Idle:
464  if ( mStatusMessage.isEmpty() ) {
465  mStatusMessage = defaultReadyMessage();
466  }
467 
468  mStatusCode = 0;
469  break;
470  case AgentBase::Running:
471  if ( mStatusMessage.isEmpty() ) {
472  mStatusMessage = defaultSyncingMessage();
473  }
474 
475  mStatusCode = 1;
476  break;
477  case AgentBase::Broken:
478  if ( mStatusMessage.isEmpty() ) {
479  mStatusMessage = defaultErrorMessage();
480  }
481 
482  mStatusCode = 2;
483  break;
484 
485  case AgentBase::NotConfigured:
486 
487  mStatusCode = 3;
488  break;
489 
490  default:
491  Q_ASSERT( !"Unknown status passed" );
492  break;
493  }
494 }
495 
496 void AgentBasePrivate::slotPercent( int progress )
497 {
498  mProgress = progress;
499 }
500 
501 void AgentBasePrivate::slotWarning( const QString& message )
502 {
503  mTracer->warning( QString::fromLatin1( "AgentBase(%1)" ).arg( mId ), message );
504 }
505 
506 void AgentBasePrivate::slotError( const QString& message )
507 {
508  mTracer->error( QString::fromLatin1( "AgentBase(%1)" ).arg( mId ), message );
509 }
510 
511 void AgentBasePrivate::slotNetworkStatusChange( Solid::Networking::Status stat )
512 {
513  Q_Q( AgentBase );
514  q->setOnlineInternal( mDesiredOnlineState && ( stat == Solid::Networking::Unknown || stat == Solid::Networking::Connected ) );
515 }
516 
517 void AgentBasePrivate::slotResumedFromSuspend()
518 {
519  if ( mNeedsNetwork ) {
520  slotNetworkStatusChange( Solid::Networking::status() );
521  }
522 }
523 
524 AgentBase::AgentBase( const QString & id )
525  : d_ptr( new AgentBasePrivate( this ) )
526 {
527  sAgentBase = this;
528  d_ptr->mId = id;
529  d_ptr->init();
530 }
531 
532 AgentBase::AgentBase( AgentBasePrivate* d, const QString &id ) :
533  d_ptr( d )
534 {
535  sAgentBase = this;
536  d_ptr->mId = id;
537  d_ptr->init();
538 }
539 
540 AgentBase::~AgentBase()
541 {
542  delete d_ptr;
543 }
544 
545 QString AgentBase::parseArguments( int argc, char **argv )
546 {
547  QString identifier;
548  if ( argc < 3 ) {
549  kDebug() << "Not enough arguments passed...";
550  exit( 1 );
551  }
552 
553  for ( int i = 1; i < argc - 1; ++i ) {
554  if ( QLatin1String( argv[ i ] ) == QLatin1String( "--identifier" ) ) {
555  identifier = QLatin1String( argv[ i + 1 ] );
556  }
557  }
558 
559  if ( identifier.isEmpty() ) {
560  kDebug() << "Identifier argument missing";
561  exit( 1 );
562  }
563 
564  const QFileInfo fi( QString::fromLocal8Bit( argv[0] ) );
565  // strip off full path and possible .exe suffix
566  const QByteArray catalog = fi.baseName().toLatin1();
567 
568  KCmdLineArgs::init( argc, argv, ServerManager::addNamespace( identifier ).toLatin1(), catalog, ki18n( "Akonadi Agent" ), KDEPIMLIBS_VERSION,
569  ki18n( "Akonadi Agent" ) );
570 
571  KCmdLineOptions options;
572  options.add( "identifier <argument>", ki18n( "Agent identifier" ) );
573  KCmdLineArgs::addCmdLineOptions( options );
574 
575  return identifier;
576 }
577 
578 // @endcond
579 
580 int AgentBase::init( AgentBase *r )
581 {
582  QApplication::setQuitOnLastWindowClosed( false );
583  KGlobal::locale()->insertCatalog( QLatin1String( "libakonadi" ) );
584  int rv = kapp->exec();
585  delete r;
586  return rv;
587 }
588 
589 int AgentBase::status() const
590 {
591  Q_D( const AgentBase );
592 
593  return d->mStatusCode;
594 }
595 
596 QString AgentBase::statusMessage() const
597 {
598  Q_D( const AgentBase );
599 
600  return d->mStatusMessage;
601 }
602 
603 int AgentBase::progress() const
604 {
605  Q_D( const AgentBase );
606 
607  return d->mProgress;
608 }
609 
610 QString AgentBase::progressMessage() const
611 {
612  Q_D( const AgentBase );
613 
614  return d->mProgressMessage;
615 }
616 
617 bool AgentBase::isOnline() const
618 {
619  Q_D( const AgentBase );
620 
621  return d->mOnline;
622 }
623 
624 void AgentBase::setNeedsNetwork( bool needsNetwork )
625 {
626  Q_D( AgentBase );
627  d->mNeedsNetwork = needsNetwork;
628 
629  if ( d->mNeedsNetwork ) {
630  connect( Solid::Networking::notifier()
631  , SIGNAL(statusChanged(Solid::Networking::Status))
632  , this, SLOT(slotNetworkStatusChange(Solid::Networking::Status))
633  , Qt::UniqueConnection );
634 
635  } else {
636  disconnect( Solid::Networking::notifier(), 0, 0, 0 );
637  setOnlineInternal( d->mDesiredOnlineState );
638  }
639 }
640 
641 void AgentBase::setOnline( bool state )
642 {
643  Q_D( AgentBase );
644  d->mDesiredOnlineState = state;
645  d->mSettings->setValue( QLatin1String( "Agent/DesiredOnlineState" ), state );
646  setOnlineInternal( state );
647 }
648 
649 void AgentBase::setOnlineInternal( bool state )
650 {
651  Q_D( AgentBase );
652  d->mOnline = state;
653 
654  const QString newMessage = d->defaultReadyMessage();
655  if ( d->mStatusMessage != newMessage && d->mStatusCode != AgentBase::Broken ) {
656  emit status( d->mStatusCode, newMessage );
657  }
658 
659  doSetOnline( state );
660  emit onlineChanged( state );
661 }
662 
663 void AgentBase::doSetOnline( bool online )
664 {
665  Q_UNUSED( online );
666 }
667 
668 void AgentBase::configure( WId windowId )
669 {
670  Q_UNUSED( windowId );
671  emit configurationDialogAccepted();
672 }
673 
674 #ifdef Q_OS_WIN //krazy:exclude=cpp
675 void AgentBase::configure( qlonglong windowId )
676 {
677  configure( reinterpret_cast<WId>( windowId ) );
678 }
679 #endif
680 
681 WId AgentBase::winIdForDialogs() const
682 {
683  const bool registered = DBusConnectionPool::threadConnection().interface()->isServiceRegistered( QLatin1String( "org.freedesktop.akonaditray" ) );
684  if ( !registered ) {
685  return 0;
686  }
687 
688  QDBusInterface dbus( QLatin1String( "org.freedesktop.akonaditray" ), QLatin1String( "/Actions" ),
689  QLatin1String( "org.freedesktop.Akonadi.Tray" ) );
690  const QDBusMessage reply = dbus.call( QLatin1String( "getWinId" ) );
691 
692  if ( reply.type() == QDBusMessage::ErrorMessage ) {
693  return 0;
694  }
695 
696  const WId winid = (WId)reply.arguments().at( 0 ).toLongLong();
697 
698  return winid;
699 }
700 
701 void AgentBase::quit()
702 {
703  Q_D( AgentBase );
704  aboutToQuit();
705 
706  if ( d->mSettings ) {
707  d->mChangeRecorder->setConfig( 0 );
708  d->mSettings->sync();
709  }
710 
711  KGlobal::deref();
712 }
713 
714 void AgentBase::aboutToQuit()
715 {
716 }
717 
718 void AgentBase::cleanup()
719 {
720  Q_D( AgentBase );
721  // prevent the monitor from picking up deletion signals for our own data if we are a resource
722  // and thus avoid that we kill our own data as last act before our own death
723  d->mChangeRecorder->blockSignals( true );
724 
725  aboutToQuit();
726 
727  const QString fileName = d->mSettings->fileName();
728 
729  /*
730  * First destroy the settings object...
731  */
732  d->mChangeRecorder->setConfig( 0 );
733  delete d->mSettings;
734  d->mSettings = 0;
735 
736  /*
737  * ... then remove the file from hd.
738  */
739  QFile::remove( fileName );
740 
741  /*
742  * ... and remove the changes file from hd.
743  */
744  QFile::remove( fileName + QLatin1String( "_changes.dat" ) );
745 
746  /*
747  * ... and also remove the agent configuration file if there is one.
748  */
749  QString configFile = KStandardDirs::locateLocal( "config", config()->name() );
750  QFile::remove( configFile );
751 
752  KGlobal::deref();
753 }
754 
755 void AgentBase::registerObserver( Observer *observer )
756 {
757  // TODO in theory we should re-connect change recorder signals here that we disconnected previously
758  d_ptr->mObserver = observer;
759 }
760 
761 QString AgentBase::identifier() const
762 {
763  return d_ptr->mId;
764 }
765 
766 void AgentBase::setAgentName( const QString &name )
767 {
768  Q_D( AgentBase );
769  if ( name == d->mName ) {
770  return;
771  }
772 
773  // TODO: rename collection
774  d->mName = name;
775 
776  if ( d->mName.isEmpty() || d->mName == d->mId ) {
777  d->mSettings->remove( QLatin1String( "Resource/Name" ) );
778  d->mSettings->remove( QLatin1String( "Agent/Name" ) );
779  } else
780  d->mSettings->setValue( QLatin1String( "Agent/Name" ), d->mName );
781 
782  d->mSettings->sync();
783 
784  d->setProgramName();
785 
786  emit agentNameChanged( d->mName );
787 }
788 
789 QString AgentBase::agentName() const
790 {
791  Q_D( const AgentBase );
792  if ( d->mName.isEmpty() ) {
793  return d->mId;
794  } else {
795  return d->mName;
796  }
797 }
798 
799 void AgentBase::changeProcessed()
800 {
801  Q_D( AgentBase );
802  d->changeProcessed();
803 }
804 
805 ChangeRecorder * AgentBase::changeRecorder() const
806 {
807  return d_ptr->mChangeRecorder;
808 }
809 
810 KSharedConfigPtr AgentBase::config()
811 {
812  if ( QCoreApplication::instance()->thread() == QThread::currentThread() ) {
813  return KGlobal::config();
814  } else {
815  return componentData().config();
816  }
817 }
818 
819 void AgentBase::abort()
820 {
821  emit abortRequested();
822 }
823 
824 void AgentBase::reconfigure()
825 {
826  emit reloadConfiguration();
827 }
828 
829 extern QThreadStorage<KComponentData*> s_agentComponentDatas;
830 
831 KComponentData AgentBase::componentData()
832 {
833  if ( QThread::currentThread() == QCoreApplication::instance()->thread() ) {
834  if ( s_agentComponentDatas.hasLocalData() ) {
835  return *( s_agentComponentDatas.localData() );
836  } else {
837  return KGlobal::mainComponent();
838  }
839  }
840 
841  Q_ASSERT( s_agentComponentDatas.hasLocalData() );
842  return *( s_agentComponentDatas.localData() );
843 }
844 
845 #include "moc_agentbase.cpp"
846 #include "moc_agentbase_p.cpp"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jul 13 2013 01:27:31 by doxygen 1.8.3.1 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-4.10.5 API Reference

Skip menu "kdepimlibs-4.10.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
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