akonadi
agentinstancecreatejob.cpp
00001 /* 00002 Copyright (c) 2008 Volker Krause <vkrause@kde.org> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 00018 */ 00019 00020 #include "agentinstancecreatejob.h" 00021 00022 #include "agentinstance.h" 00023 #include "agentmanager.h" 00024 #include "agentmanager_p.h" 00025 #include "controlinterface.h" 00026 #include "dbusconnectionpool.h" 00027 #include "kjobprivatebase_p.h" 00028 00029 #include <kdebug.h> 00030 #include <klocale.h> 00031 00032 #include <QtCore/QTimer> 00033 00034 #ifdef Q_OS_UNIX 00035 #include <sys/types.h> 00036 #include <signal.h> 00037 #endif 00038 00039 using namespace Akonadi; 00040 00041 #if defined(Q_WS_MAEMO_5) || defined(Q_OS_WINCE) 00042 static const int safetyTimeout = 60000; // ms 00043 #else 00044 static const int safetyTimeout = 10000; // ms 00045 #endif 00046 00047 00048 namespace Akonadi { 00052 class AgentInstanceCreateJobPrivate : public KJobPrivateBase 00053 { 00054 public: 00055 AgentInstanceCreateJobPrivate( AgentInstanceCreateJob* parent ) : q( parent ), 00056 parentWidget( 0 ), 00057 safetyTimer( new QTimer( parent ) ), 00058 doConfig( false ), 00059 tooLate( false ) 00060 { 00061 QObject::connect( AgentManager::self(), SIGNAL( instanceAdded( const Akonadi::AgentInstance& ) ), 00062 q, SLOT( agentInstanceAdded( const Akonadi::AgentInstance& ) ) ); 00063 QObject::connect( safetyTimer, SIGNAL( timeout() ), q, SLOT( timeout() ) ); 00064 } 00065 00066 void agentInstanceAdded( const AgentInstance &instance ) 00067 { 00068 if ( agentInstance == instance && !tooLate ) { 00069 safetyTimer->stop(); 00070 if ( doConfig ) { 00071 // return from dbus call first before doing the next one 00072 QTimer::singleShot( 0, q, SLOT( doConfigure() ) ); 00073 } else { 00074 q->emitResult(); 00075 } 00076 } 00077 } 00078 00079 void doConfigure() 00080 { 00081 org::freedesktop::Akonadi::Agent::Control *agentControlIface = 00082 new org::freedesktop::Akonadi::Agent::Control( QLatin1String( "org.freedesktop.Akonadi.Agent." ) + agentInstance.identifier(), 00083 QLatin1String( "/" ), DBusConnectionPool::threadConnection(), q ); 00084 if ( !agentControlIface || !agentControlIface->isValid() ) { 00085 if ( agentControlIface ) 00086 delete agentControlIface; 00087 00088 q->setError( KJob::UserDefinedError ); 00089 q->setErrorText( i18n( "Unable to access D-Bus interface of created agent." ) ); 00090 q->emitResult(); 00091 return; 00092 } 00093 00094 q->connect( agentControlIface, SIGNAL( configurationDialogAccepted() ), 00095 q, SLOT( configurationDialogAccepted() ) ); 00096 q->connect( agentControlIface, SIGNAL( configurationDialogRejected() ), 00097 q, SLOT( configurationDialogRejected() ) ); 00098 00099 agentInstance.configure( parentWidget ); 00100 } 00101 00102 void configurationDialogAccepted() 00103 { 00104 // The user clicked 'Ok' in the initial configuration dialog, so we assume 00105 // he wants to keep the resource and the job is done. 00106 q->emitResult(); 00107 } 00108 00109 void configurationDialogRejected() 00110 { 00111 // The user clicked 'Cancel' in the initial configuration dialog, so we assume 00112 // he wants to abort the 'create new resource' job and the new resource will be 00113 // removed again. 00114 AgentManager::self()->removeInstance( agentInstance ); 00115 00116 q->emitResult(); 00117 } 00118 00119 void timeout() 00120 { 00121 tooLate = true; 00122 q->setError( KJob::UserDefinedError ); 00123 q->setErrorText( i18n( "Agent instance creation timed out." ) ); 00124 q->emitResult(); 00125 } 00126 00127 void emitResult() 00128 { 00129 q->emitResult(); 00130 } 00131 00132 void doStart(); 00133 00134 AgentInstanceCreateJob* q; 00135 AgentType agentType; 00136 QString agentTypeId; 00137 AgentInstance agentInstance; 00138 QWidget* parentWidget; 00139 QTimer *safetyTimer; 00140 bool doConfig; 00141 bool tooLate; 00142 }; 00143 00144 } 00145 00146 AgentInstanceCreateJob::AgentInstanceCreateJob( const AgentType &agentType, QObject *parent ) 00147 : KJob( parent ), 00148 d( new AgentInstanceCreateJobPrivate( this ) ) 00149 { 00150 d->agentType = agentType; 00151 } 00152 00153 AgentInstanceCreateJob::AgentInstanceCreateJob( const QString &typeId, QObject *parent ) 00154 : KJob( parent ), 00155 d( new AgentInstanceCreateJobPrivate( this ) ) 00156 { 00157 d->agentTypeId = typeId; 00158 } 00159 00160 AgentInstanceCreateJob::~ AgentInstanceCreateJob() 00161 { 00162 delete d; 00163 } 00164 00165 void AgentInstanceCreateJob::configure( QWidget *parent ) 00166 { 00167 d->parentWidget = parent; 00168 d->doConfig = true; 00169 } 00170 00171 AgentInstance AgentInstanceCreateJob::instance() const 00172 { 00173 return d->agentInstance; 00174 } 00175 00176 void AgentInstanceCreateJob::start() 00177 { 00178 d->start(); 00179 } 00180 00181 void AgentInstanceCreateJobPrivate::doStart() 00182 { 00183 if ( !agentType.isValid() && !agentTypeId.isEmpty() ) 00184 agentType = AgentManager::self()->type( agentTypeId ); 00185 00186 if ( !agentType.isValid() ) { 00187 q->setError( KJob::UserDefinedError ); 00188 q->setErrorText( i18n( "Unable to obtain agent type '%1'.", agentTypeId) ); 00189 QTimer::singleShot( 0, q, SLOT( emitResult() ) ); 00190 return; 00191 } 00192 00193 agentInstance = AgentManager::self()->d->createInstance( agentType ); 00194 if ( !agentInstance.isValid() ) { 00195 q->setError( KJob::UserDefinedError ); 00196 q->setErrorText( i18n( "Unable to create agent instance." ) ); 00197 QTimer::singleShot( 0, q, SLOT( emitResult() ) ); 00198 } else { 00199 int timeout = safetyTimeout; 00200 #ifdef Q_OS_UNIX 00201 // Increate the timeout when valgrinding the agent, because that slows down things a log. 00202 QString agentValgrind = QString::fromLocal8Bit( qgetenv( "AKONADI_VALGRIND" ) ); 00203 if ( !agentValgrind.isEmpty() && agentType.identifier().contains( agentValgrind ) ) 00204 timeout *= 15; 00205 #endif 00206 safetyTimer->start( timeout ); 00207 } 00208 } 00209 00210 #include "agentinstancecreatejob.moc"