• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • Contact Us
 

akonadi

agentbase.cpp
00001 /*
00002     Copyright (c) 2006 Till Adam <adam@kde.org>
00003     Copyright (c) 2007 Volker Krause <vkrause@kde.org>
00004     Copyright (c) 2007 Bruno Virlet <bruno.virlet@gmail.com>
00005     Copyright (c) 2008 Kevin Krammer <kevin.krammer@gmx.at>
00006 
00007     This library is free software; you can redistribute it and/or modify it
00008     under the terms of the GNU Library General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or (at your
00010     option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful, but WITHOUT
00013     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00015     License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to the
00019     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00020     02110-1301, USA.
00021 */
00022 
00023 #include "agentbase.h"
00024 #include "agentbase_p.h"
00025 
00026 #include "changerecorder.h"
00027 #include "controladaptor.h"
00028 #include "dbusconnectionpool.h"
00029 #include "itemfetchjob.h"
00030 #include "monitor_p.h"
00031 #include "servermanager_p.h"
00032 #include "session.h"
00033 #include "session_p.h"
00034 #include "statusadaptor.h"
00035 #include "xdgbasedirs_p.h"
00036 
00037 #include <kaboutdata.h>
00038 #include <kcmdlineargs.h>
00039 #include <kdebug.h>
00040 #include <klocale.h>
00041 #include <kstandarddirs.h>
00042 
00043 #include <QtCore/QDir>
00044 #include <QtCore/QSettings>
00045 #include <QtCore/QTimer>
00046 #include <QtDBus/QtDBus>
00047 #include <QtGui/QApplication>
00048 
00049 #include <signal.h>
00050 #include <stdlib.h>
00051 
00052 //#define EXPERIMENTAL_INPROCESS_AGENTS 1
00053 
00054 using namespace Akonadi;
00055 
00056 static AgentBase *sAgentBase = 0;
00057 
00058 AgentBase::Observer::Observer()
00059 {
00060 }
00061 
00062 AgentBase::Observer::~Observer()
00063 {
00064 }
00065 
00066 void AgentBase::Observer::itemAdded( const Item &item, const Collection &collection )
00067 {
00068   Q_UNUSED( item );
00069   Q_UNUSED( collection );
00070   if ( sAgentBase != 0 )
00071     sAgentBase->d_ptr->changeProcessed();
00072 }
00073 
00074 void AgentBase::Observer::itemChanged( const Item &item, const QSet<QByteArray> &partIdentifiers )
00075 {
00076   Q_UNUSED( item );
00077   Q_UNUSED( partIdentifiers );
00078   if ( sAgentBase != 0 )
00079     sAgentBase->d_ptr->changeProcessed();
00080 }
00081 
00082 void AgentBase::Observer::itemRemoved( const Item &item )
00083 {
00084   Q_UNUSED( item );
00085   if ( sAgentBase != 0 )
00086     sAgentBase->d_ptr->changeProcessed();
00087 }
00088 
00089 void AgentBase::Observer::collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent )
00090 {
00091   Q_UNUSED( collection );
00092   Q_UNUSED( parent );
00093   if ( sAgentBase != 0 )
00094     sAgentBase->d_ptr->changeProcessed();
00095 }
00096 
00097 void AgentBase::Observer::collectionChanged( const Collection &collection )
00098 {
00099   Q_UNUSED( collection );
00100   if ( sAgentBase != 0 )
00101     sAgentBase->d_ptr->changeProcessed();
00102 }
00103 
00104 void AgentBase::Observer::collectionRemoved( const Collection &collection )
00105 {
00106   Q_UNUSED( collection );
00107   if ( sAgentBase != 0 )
00108     sAgentBase->d_ptr->changeProcessed();
00109 }
00110 
00111 void AgentBase::ObserverV2::itemMoved( const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest )
00112 {
00113   Q_UNUSED( item );
00114   Q_UNUSED( source );
00115   Q_UNUSED( dest );
00116   if ( sAgentBase != 0 )
00117     sAgentBase->d_ptr->changeProcessed();
00118 }
00119 
00120 void AgentBase::ObserverV2::itemLinked( const Akonadi::Item& item, const Akonadi::Collection& collection )
00121 {
00122   Q_UNUSED( item );
00123   Q_UNUSED( collection );
00124   if ( sAgentBase != 0 ) {
00125     // not implementation, let's disconnect the signal to enable optimizations in Monitor
00126     QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL( itemLinked( const Akonadi::Item&, const Akonadi::Collection& ) ),
00127                          sAgentBase->d_ptr, SLOT( itemLinked( const Akonadi::Item&, const Akonadi::Collection& ) ) );
00128     sAgentBase->d_ptr->changeProcessed();
00129   }
00130 }
00131 
00132 void AgentBase::ObserverV2::itemUnlinked( const Akonadi::Item& item, const Akonadi::Collection& collection )
00133 {
00134   Q_UNUSED( item );
00135   Q_UNUSED( collection );
00136   if ( sAgentBase != 0 ) {
00137     // not implementation, let's disconnect the signal to enable optimizations in Monitor
00138     QObject::disconnect( sAgentBase->changeRecorder(), SIGNAL( itemUnlinked( const Akonadi::Item&, const Akonadi::Collection& ) ),
00139                          sAgentBase->d_ptr, SLOT( itemUnlinked( const Akonadi::Item&, const Akonadi::Collection& ) ) );
00140     sAgentBase->d_ptr->changeProcessed();
00141   }
00142 }
00143 
00144 void AgentBase::ObserverV2::collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest )
00145 {
00146   Q_UNUSED( collection );
00147   Q_UNUSED( source );
00148   Q_UNUSED( dest );
00149   if ( sAgentBase != 0 )
00150     sAgentBase->d_ptr->changeProcessed();
00151 }
00152 
00153 void AgentBase::ObserverV2::collectionChanged( const Akonadi::Collection &collection, const QSet<QByteArray> &partIdentifiers )
00154 {
00155   Q_UNUSED( partIdentifiers );
00156   collectionChanged( collection );
00157 }
00158 
00159 //@cond PRIVATE
00160 
00161 AgentBasePrivate::AgentBasePrivate( AgentBase *parent )
00162   : q_ptr( parent ),
00163     mDBusConnection( QString() ),
00164     mStatusCode( AgentBase::Idle ),
00165     mProgress( 0 ),
00166     mNeedsNetwork( false ),
00167     mOnline( false ),
00168     mSettings( 0 ),
00169     mObserver( 0 )
00170 {
00171 #ifdef _WIN32_WCE
00172   QThread::currentThread()->setPriority(QThread::LowPriority);
00173 #endif
00174   Internal::setClientType( Internal::Agent );
00175 }
00176 
00177 AgentBasePrivate::~AgentBasePrivate()
00178 {
00179   mChangeRecorder->setConfig( 0 );
00180   delete mSettings;
00181 }
00182 
00183 void AgentBasePrivate::init()
00184 {
00185   Q_Q( AgentBase );
00186 
00190   SessionPrivate::createDefaultSession( mId.toLatin1() );
00191 
00192   if ( QThread::currentThread() != QCoreApplication::instance()->thread() ) {
00193     mDBusConnection = QDBusConnection::connectToBus( QDBusConnection::SessionBus, q->identifier() );
00194     Q_ASSERT( mDBusConnection.isConnected() );
00195   }
00196 
00197   mTracer = new org::freedesktop::Akonadi::Tracer( QLatin1String( "org.freedesktop.Akonadi" ),
00198                                                    QLatin1String( "/tracing" ),
00199                                                    DBusConnectionPool::threadConnection(), q );
00200 
00201   new Akonadi__ControlAdaptor( q );
00202   new Akonadi__StatusAdaptor( q );
00203   if ( !DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/" ), q, QDBusConnection::ExportAdaptors ) )
00204     q->error( QString::fromLatin1( "Unable to register object at dbus: %1" ).arg( DBusConnectionPool::threadConnection().lastError().message() ) );
00205 
00206   mSettings = new QSettings( QString::fromLatin1( "%1/agent_config_%2" ).arg( XdgBaseDirs::saveDir( "config", QLatin1String( "akonadi" ) ), mId ), QSettings::IniFormat );
00207 
00208   mChangeRecorder = new ChangeRecorder( q );
00209   mChangeRecorder->ignoreSession( Session::defaultSession() );
00210   mChangeRecorder->itemFetchScope().setCacheOnly( true );
00211   mChangeRecorder->setConfig( mSettings );
00212 
00213   mOnline = mSettings->value( QLatin1String( "Agent/Online" ), true ).toBool();
00214 
00215   // reinitialize the status message now that online state is available
00216   mStatusMessage = defaultReadyMessage();
00217 
00218   mName = mSettings->value( QLatin1String( "Agent/Name" ) ).toString();
00219   if ( mName.isEmpty() ) {
00220     mName = mSettings->value( QLatin1String( "Resource/Name" ) ).toString();
00221     if ( !mName.isEmpty() ) {
00222       mSettings->remove( QLatin1String( "Resource/Name" ) );
00223       mSettings->setValue( QLatin1String( "Agent/Name" ), mName );
00224     }
00225   }
00226 
00227   connect( mChangeRecorder, SIGNAL( itemAdded( const Akonadi::Item&, const Akonadi::Collection& ) ),
00228            SLOT( itemAdded( const Akonadi::Item&, const Akonadi::Collection& ) ) );
00229   connect( mChangeRecorder, SIGNAL( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ),
00230            SLOT( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ) );
00231   connect( mChangeRecorder, SIGNAL( itemMoved( const Akonadi::Item&, const Akonadi::Collection&, const Akonadi::Collection& ) ),
00232            SLOT( itemMoved( const Akonadi::Item&, const Akonadi::Collection&, const Akonadi::Collection& ) ) );
00233   connect( mChangeRecorder, SIGNAL( itemRemoved( const Akonadi::Item& ) ),
00234            SLOT( itemRemoved( const Akonadi::Item& ) ) );
00235   connect( mChangeRecorder, SIGNAL( collectionAdded( const Akonadi::Collection&, const Akonadi::Collection& ) ),
00236            SLOT( collectionAdded( const Akonadi::Collection&, const Akonadi::Collection& ) ) );
00237   connect( mChangeRecorder, SIGNAL( itemLinked( const Akonadi::Item&, const Akonadi::Collection& ) ),
00238            SLOT( itemLinked( const Akonadi::Item&, const Akonadi::Collection& ) ) );
00239   connect( mChangeRecorder, SIGNAL( itemUnlinked( const Akonadi::Item&, const Akonadi::Collection& ) ),
00240            SLOT( itemUnlinked( const Akonadi::Item&, const Akonadi::Collection& ) ) );
00241   connect( mChangeRecorder, SIGNAL( collectionChanged( const Akonadi::Collection& ) ),
00242            SLOT( collectionChanged( const Akonadi::Collection& ) ) );
00243   connect( mChangeRecorder, SIGNAL( collectionChanged( const Akonadi::Collection&, const QSet<QByteArray>& ) ),
00244            SLOT( collectionChanged( const Akonadi::Collection&, const QSet<QByteArray>& ) ) );
00245   connect( mChangeRecorder, SIGNAL( collectionMoved( const Akonadi::Collection&, const Akonadi::Collection&, const Akonadi::Collection& ) ),
00246            SLOT( collectionMoved( const Akonadi::Collection&, const Akonadi::Collection&, const Akonadi::Collection& ) ) );
00247   connect( mChangeRecorder, SIGNAL( collectionRemoved( const Akonadi::Collection& ) ),
00248            SLOT( collectionRemoved( const Akonadi::Collection& ) ) );
00249   connect( mChangeRecorder, SIGNAL( collectionSubscribed( const Akonadi::Collection&, const Akonadi::Collection& ) ),
00250            SLOT( collectionSubscribed( const Akonadi::Collection&, const Akonadi::Collection& ) ) );
00251   connect( mChangeRecorder, SIGNAL( collectionUnsubscribed( const Akonadi::Collection& ) ),
00252            SLOT( collectionUnsubscribed( const Akonadi::Collection& ) ) );
00253 
00254   connect( q, SIGNAL( status( int, const QString& ) ), q, SLOT( slotStatus( int, const QString& ) ) );
00255   connect( q, SIGNAL( percent( int ) ), q, SLOT( slotPercent( int ) ) );
00256   connect( q, SIGNAL( warning( const QString& ) ), q, SLOT( slotWarning( const QString& ) ) );
00257   connect( q, SIGNAL( error( const QString& ) ), q, SLOT( slotError( const QString& ) ) );
00258 
00259   // Use reference counting to allow agents to finish internal jobs when the
00260   // agent is stopped.
00261   KGlobal::ref();
00262   if ( QThread::currentThread() == QCoreApplication::instance()->thread() )
00263     KGlobal::setAllowQuit( true );
00264 
00265 #ifndef Q_OS_WINCE
00266   // disable session management
00267   if ( KApplication::kApplication() )
00268     KApplication::kApplication()->disableSessionManagement();
00269 #endif
00270 
00271   QTimer::singleShot( 0, q, SLOT( delayedInit() ) );
00272 }
00273 
00274 void AgentBasePrivate::delayedInit()
00275 {
00276   Q_Q( AgentBase );
00277   if ( !DBusConnectionPool::threadConnection().registerService( QLatin1String( "org.freedesktop.Akonadi.Agent." ) + mId ) )
00278     kFatal() << "Unable to register service at dbus:" << DBusConnectionPool::threadConnection().lastError().message();
00279   q->setOnline( mOnline );
00280 }
00281 
00282 void AgentBasePrivate::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection )
00283 {
00284   if ( mObserver != 0 )
00285     mObserver->itemAdded( item, collection );
00286 }
00287 
00288 void AgentBasePrivate::itemChanged( const Akonadi::Item &item, const QSet<QByteArray> &partIdentifiers )
00289 {
00290   if ( mObserver != 0 )
00291     mObserver->itemChanged( item, partIdentifiers );
00292 }
00293 
00294 void AgentBasePrivate::itemMoved( const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest )
00295 {
00296   AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
00297   if ( mObserver ) {
00298     // inter-resource moves, requires we know which resources the source and destination are in though
00299     if ( !source.resource().isEmpty() && !dest.resource().isEmpty() ) {
00300       if ( source.resource() != dest.resource() ) {
00301         if ( source.resource() == q_ptr->identifier() ) { // moved away from us
00302           Akonadi::Item i( item );
00303           i.setParentCollection( source );
00304           mObserver->itemRemoved( i );
00305         }
00306         else if ( dest.resource() == q_ptr->identifier() ) // moved to us
00307           mObserver->itemAdded( item, dest );
00308         else if ( observer2 )
00309           observer2->itemMoved( item, source, dest );
00310         else
00311           // not for us, not sure if we should get here at all
00312           changeProcessed();
00313         return;
00314       }
00315     }
00316     // intra-resource move
00317     if ( observer2 ) {
00318       observer2->itemMoved( item, source, dest );
00319     } else {
00320       // ### we cannot just call itemRemoved here as this will already trigger changeProcessed()
00321       // so, just itemAdded() is good enough as no resource can have implemented intra-resource moves anyway
00322       // without using ObserverV2
00323       mObserver->itemAdded( item, dest );
00324       // mObserver->itemRemoved( item );
00325     }
00326   }
00327 }
00328 
00329 void AgentBasePrivate::itemRemoved( const Akonadi::Item &item )
00330 {
00331   if ( mObserver != 0 )
00332     mObserver->itemRemoved( item );
00333 }
00334 
00335 void AgentBasePrivate::itemLinked( const Akonadi::Item &item, const Akonadi::Collection &collection )
00336 {
00337   AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
00338   if ( observer2 )
00339     observer2->itemLinked( item, collection );
00340   else
00341     changeProcessed();
00342 }
00343 
00344 void AgentBasePrivate::itemUnlinked( const Akonadi::Item &item, const Akonadi::Collection &collection )
00345 {
00346   AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
00347   if ( observer2 )
00348     observer2->itemUnlinked( item, collection );
00349   else
00350     changeProcessed();
00351 }
00352 
00353 void AgentBasePrivate::collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent )
00354 {
00355   if ( mObserver != 0 )
00356     mObserver->collectionAdded( collection, parent );
00357 }
00358 
00359 void AgentBasePrivate::collectionChanged( const Akonadi::Collection &collection )
00360 {
00361   AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
00362   if ( mObserver != 0 && observer2 == 0 ) // For ObserverV2 we use the variant with the part identifiers
00363     mObserver->collectionChanged( collection );
00364 }
00365 
00366 void AgentBasePrivate::collectionChanged( const Akonadi::Collection &collection, const QSet<QByteArray> &partIdentifiers )
00367 {
00368   AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
00369   if ( observer2 != 0 )
00370     observer2->collectionChanged( collection, partIdentifiers );
00371 }
00372 
00373 void AgentBasePrivate::collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest )
00374 {
00375   AgentBase::ObserverV2 *observer2 = dynamic_cast<AgentBase::ObserverV2*>( mObserver );
00376   if ( mObserver ) {
00377     // inter-resource moves, requires we know which resources the source and destination are in though
00378     if ( !source.resource().isEmpty() && !dest.resource().isEmpty() ) {
00379       if ( source.resource() != dest.resource() ) {
00380         if ( source.resource() == q_ptr->identifier() ) // moved away from us
00381           mObserver->collectionRemoved( collection );
00382         else if ( dest.resource() == q_ptr->identifier() ) // moved to us
00383           mObserver->collectionAdded( collection, dest );
00384         else if ( observer2 )
00385           observer2->collectionMoved( collection, source, dest );
00386         else // not for us, not sure if we should get here at all
00387           changeProcessed();
00388         return;
00389       }
00390     }
00391     // intra-resource move
00392     if ( observer2 ) {
00393       observer2->collectionMoved( collection, source, dest );
00394     } else {
00395       // ### we cannot just call collectionRemoved here as this will already trigger changeProcessed()
00396       // so, just collectionAdded() is good enough as no resource can have implemented intra-resource moves anyway
00397       // without using ObserverV2
00398       mObserver->collectionAdded( collection, dest );
00399     }
00400   }
00401 }
00402 
00403 void AgentBasePrivate::collectionRemoved( const Akonadi::Collection &collection )
00404 {
00405   if ( mObserver != 0 )
00406     mObserver->collectionRemoved( collection );
00407 }
00408 
00409 void AgentBasePrivate::collectionSubscribed( const Akonadi::Collection &collection, const Akonadi::Collection &parent )
00410 {
00411   Q_UNUSED( collection );
00412   Q_UNUSED( parent );
00413   changeProcessed();
00414 }
00415 
00416 void AgentBasePrivate::collectionUnsubscribed( const Akonadi::Collection &collection )
00417 {
00418   Q_UNUSED( collection );
00419   changeProcessed();
00420 }
00421 
00422 void AgentBasePrivate::changeProcessed()
00423 {
00424   mChangeRecorder->changeProcessed();
00425   QTimer::singleShot( 0, mChangeRecorder, SLOT( replayNext() ) );
00426 }
00427 
00428 void AgentBasePrivate::slotStatus( int status, const QString &message )
00429 {
00430   mStatusMessage = message;
00431   mStatusCode = 0;
00432 
00433   switch ( status ) {
00434     case AgentBase::Idle:
00435       if ( mStatusMessage.isEmpty() )
00436         mStatusMessage = defaultReadyMessage();
00437 
00438       mStatusCode = 0;
00439       break;
00440     case AgentBase::Running:
00441       if ( mStatusMessage.isEmpty() )
00442         mStatusMessage = defaultSyncingMessage();
00443 
00444       mStatusCode = 1;
00445       break;
00446     case AgentBase::Broken:
00447       if ( mStatusMessage.isEmpty() )
00448         mStatusMessage = defaultErrorMessage();
00449 
00450       mStatusCode = 2;
00451       break;
00452     default:
00453       Q_ASSERT( !"Unknown status passed" );
00454       break;
00455   }
00456 }
00457 
00458 void AgentBasePrivate::slotPercent( int progress )
00459 {
00460   mProgress = progress;
00461 }
00462 
00463 void AgentBasePrivate::slotWarning( const QString& message )
00464 {
00465   mTracer->warning( QString::fromLatin1( "AgentBase(%1)" ).arg( mId ), message );
00466 }
00467 
00468 void AgentBasePrivate::slotError( const QString& message )
00469 {
00470   mTracer->error( QString::fromLatin1( "AgentBase(%1)" ).arg( mId ), message );
00471 }
00472 
00473 void AgentBasePrivate::slotNetworkStatusChange( Solid::Networking::Status stat )
00474 {
00475   Q_Q( AgentBase );
00476   q->setOnline( stat == Solid::Networking::Unknown || stat == Solid::Networking::Connected );
00477 }
00478 
00479 AgentBase::AgentBase( const QString & id )
00480   : d_ptr( new AgentBasePrivate( this ) )
00481 {
00482   sAgentBase = this;
00483   d_ptr->mId = id;
00484   d_ptr->init();
00485 }
00486 
00487 AgentBase::AgentBase( AgentBasePrivate* d, const QString &id ) :
00488     d_ptr( d )
00489 {
00490   sAgentBase = this;
00491   d_ptr->mId = id;
00492   d_ptr->init();
00493 }
00494 
00495 AgentBase::~AgentBase()
00496 {
00497   delete d_ptr;
00498 }
00499 
00500 QString AgentBase::parseArguments( int argc, char **argv )
00501 {
00502   QString identifier;
00503   if ( argc < 3 ) {
00504     kDebug() << "Not enough arguments passed...";
00505     exit( 1 );
00506   }
00507 
00508   for ( int i = 1; i < argc - 1; ++i ) {
00509     if ( QLatin1String( argv[ i ] ) == QLatin1String( "--identifier" ) )
00510       identifier = QLatin1String( argv[ i + 1 ] );
00511   }
00512 
00513   if ( identifier.isEmpty() ) {
00514     kDebug() << "Identifier argument missing";
00515     exit( 1 );
00516   }
00517 
00518   QByteArray catalog;
00519   char *p = strrchr( argv[0], '/' );
00520   if ( p )
00521     catalog = QByteArray( p + 1 );
00522   else
00523     catalog = QByteArray( argv[0] );
00524 
00525   KCmdLineArgs::init( argc, argv, identifier.toLatin1(), catalog, ki18n( "Akonadi Agent" ), "0.1",
00526                       ki18n( "Akonadi Agent" ) );
00527 
00528   KCmdLineOptions options;
00529   options.add( "identifier <argument>", ki18n( "Agent identifier" ) );
00530   KCmdLineArgs::addCmdLineOptions( options );
00531 
00532   return identifier;
00533 }
00534 
00535 // @endcond
00536 
00537 int AgentBase::init( AgentBase *r )
00538 {
00539   QApplication::setQuitOnLastWindowClosed( false );
00540   KGlobal::locale()->insertCatalog( QLatin1String( "libakonadi" ) );
00541   int rv = kapp->exec();
00542   delete r;
00543   return rv;
00544 }
00545 
00546 int AgentBase::status() const
00547 {
00548   Q_D( const AgentBase );
00549 
00550   return d->mStatusCode;
00551 }
00552 
00553 QString AgentBase::statusMessage() const
00554 {
00555   Q_D( const AgentBase );
00556 
00557   return d->mStatusMessage;
00558 }
00559 
00560 int AgentBase::progress() const
00561 {
00562   Q_D( const AgentBase );
00563 
00564   return d->mProgress;
00565 }
00566 
00567 QString AgentBase::progressMessage() const
00568 {
00569   Q_D( const AgentBase );
00570 
00571   return d->mProgressMessage;
00572 }
00573 
00574 bool AgentBase::isOnline() const
00575 {
00576   Q_D( const AgentBase );
00577 
00578   return d->mOnline;
00579 }
00580 
00581 void AgentBase::setNeedsNetwork( bool needsNetwork )
00582 {
00583   Q_D( AgentBase );
00584   d->mNeedsNetwork = needsNetwork;
00585 
00586   if ( d->mNeedsNetwork ) {
00587     connect( Solid::Networking::notifier()
00588            , SIGNAL( statusChanged( Solid::Networking::Status ) )
00589            , this, SLOT( slotNetworkStatusChange( Solid::Networking::Status ) ) );
00590   } else {
00591     disconnect( Solid::Networking::notifier(), 0, 0, 0 );
00592     setOnline( true );
00593   }
00594 }
00595 
00596 void AgentBase::setOnline( bool state )
00597 {
00598   Q_D( AgentBase );
00599   d->mOnline = state;
00600   d->mSettings->setValue( QLatin1String( "Agent/Online" ), state );
00601   doSetOnline( state );
00602   emit onlineChanged( state );
00603 }
00604 
00605 void AgentBase::doSetOnline( bool online )
00606 {
00607   Q_UNUSED( online );
00608 }
00609 
00610 void AgentBase::configure( WId windowId )
00611 {
00612   Q_UNUSED( windowId );
00613   emit configurationDialogAccepted();
00614 }
00615 
00616 #ifdef Q_OS_WIN //krazy:exclude=cpp
00617 void AgentBase::configure( qlonglong windowId )
00618 {
00619   configure( reinterpret_cast<WId>( windowId ) );
00620 }
00621 #endif
00622 
00623 WId AgentBase::winIdForDialogs() const
00624 {
00625   const bool registered = DBusConnectionPool::threadConnection().interface()->isServiceRegistered( QLatin1String( "org.freedesktop.akonaditray" ) );
00626   if ( !registered )
00627     return 0;
00628 
00629   QDBusInterface dbus( QLatin1String( "org.freedesktop.akonaditray" ), QLatin1String( "/Actions" ),
00630                        QLatin1String( "org.freedesktop.Akonadi.Tray" ) );
00631   const QDBusMessage reply = dbus.call( QLatin1String( "getWinId" ) );
00632 
00633   if ( reply.type() == QDBusMessage::ErrorMessage )
00634     return 0;
00635 
00636   const WId winid = (WId)reply.arguments().at( 0 ).toLongLong();
00637 
00638   return winid;
00639 }
00640 
00641 void AgentBase::quit()
00642 {
00643   Q_D( AgentBase );
00644   aboutToQuit();
00645 
00646   if ( d->mSettings ) {
00647     d->mChangeRecorder->setConfig( 0 );
00648     d->mSettings->sync();
00649   }
00650 
00651   KGlobal::deref();
00652 }
00653 
00654 void AgentBase::aboutToQuit()
00655 {
00656 }
00657 
00658 void AgentBase::cleanup()
00659 {
00660   Q_D( AgentBase );
00661   // prevent the monitor from picking up deletion signals for our own data if we are a resource
00662   // and thus avoid that we kill our own data as last act before our own death
00663   d->mChangeRecorder->blockSignals( true );
00664 
00665   aboutToQuit();
00666 
00667   const QString fileName = d->mSettings->fileName();
00668 
00669   /*
00670    * First destroy the settings object...
00671    */
00672   d->mChangeRecorder->setConfig( 0 );
00673   delete d->mSettings;
00674   d->mSettings = 0;
00675 
00676   /*
00677    * ... then remove the file from hd.
00678    */
00679   QFile::remove( fileName );
00680 
00681   /*
00682    * ... and remove the changes file from hd.
00683    */
00684   QFile::remove( fileName + QLatin1String( "_changes.dat" ) );
00685 
00686   /*
00687    * ... and also remove the agent configuration file if there is one.
00688    */
00689   QString configFile = KStandardDirs::locateLocal( "config", config()->name() );
00690   QFile::remove( configFile );
00691 
00692   KGlobal::deref();
00693 }
00694 
00695 void AgentBase::registerObserver( Observer *observer )
00696 {
00697   // TODO in theory we should re-connect change recorder signals here that we disconnected previously
00698   d_ptr->mObserver = observer;
00699 }
00700 
00701 QString AgentBase::identifier() const
00702 {
00703   return d_ptr->mId;
00704 }
00705 
00706 void AgentBase::setAgentName( const QString &name )
00707 {
00708   Q_D( AgentBase );
00709   if ( name == d->mName )
00710     return;
00711 
00712   // TODO: rename collection
00713   d->mName = name;
00714 
00715   if ( d->mName.isEmpty() || d->mName == d->mId ) {
00716     d->mSettings->remove( QLatin1String( "Resource/Name" ) );
00717     d->mSettings->remove( QLatin1String( "Agent/Name" ) );
00718   } else
00719     d->mSettings->setValue( QLatin1String( "Agent/Name" ), d->mName );
00720 
00721   d->mSettings->sync();
00722 
00723   emit agentNameChanged( d->mName );
00724 }
00725 
00726 QString AgentBase::agentName() const
00727 {
00728   Q_D( const AgentBase );
00729   if ( d->mName.isEmpty() )
00730     return d->mId;
00731   else
00732     return d->mName;
00733 }
00734 
00735 void AgentBase::changeProcessed()
00736 {
00737   Q_D( AgentBase );
00738   d->changeProcessed();
00739 }
00740 
00741 ChangeRecorder * AgentBase::changeRecorder() const
00742 {
00743   return d_ptr->mChangeRecorder;
00744 }
00745 
00746 KSharedConfigPtr AgentBase::config()
00747 {
00748   if ( QCoreApplication::instance()->thread() == QThread::currentThread() )
00749     return KGlobal::config();
00750   else
00751     return componentData().config();
00752 }
00753 
00754 void AgentBase::abort()
00755 {
00756   emit abortRequested();
00757 }
00758 
00759 void AgentBase::reconfigure()
00760 {
00761   emit reloadConfiguration();
00762 }
00763 
00764 extern QThreadStorage<KComponentData*> s_agentComponentDatas;
00765 
00766 KComponentData AgentBase::componentData()
00767 {
00768   if ( QThread::currentThread() == QCoreApplication::instance()->thread() ) {
00769     if ( s_agentComponentDatas.hasLocalData() )
00770       return *(s_agentComponentDatas.localData());
00771     else
00772       return KGlobal::mainComponent();
00773   }
00774 
00775   Q_ASSERT( s_agentComponentDatas.hasLocalData() );
00776   return *(s_agentComponentDatas.localData());
00777 }
00778 
00779 #include "agentbase.moc"
00780 #include "agentbase_p.moc"

akonadi

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal