24 #include "dbusconnectionpool.h"
26 #include "imapparser_p.h"
28 #include "session_p.h"
31 #include <klocalizedstring.h>
33 #include <QtCore/QEventLoop>
34 #include <QtCore/QTimer>
35 #include <QtCore/QTextStream>
36 #include <QtNetwork/QHostAddress>
37 #include <QtNetwork/QTcpSocket>
38 #include <QtDBus/QDBusInterface>
39 #include <QtDBus/QDBusConnectionInterface>
41 using namespace Akonadi;
43 static QDBusAbstractInterface *s_jobtracker = 0;
46 void JobPrivate::handleResponse(
const QByteArray & tag,
const QByteArray & data )
50 if ( mCurrentSubJob ) {
51 mCurrentSubJob->d_ptr->handleResponse( tag, data );
56 if ( data.startsWith(
"NO " ) || data.startsWith(
"BAD " ) ) {
57 QString msg = QString::fromUtf8( data );
59 msg.remove( 0, msg.startsWith( QLatin1String(
"NO " ) ) ? 3 : 4 );
61 if ( msg.endsWith( QLatin1String(
"\r\n" ) ) )
65 q->setErrorText( msg );
68 }
else if ( data.startsWith(
"OK" ) ) {
75 QTimer::singleShot( 0, q, SLOT(delayedEmitResult()) );
80 q->doHandleResponse( tag, data );
83 void JobPrivate::init( QObject *parent )
87 mParentJob =
dynamic_cast<Job*
>( parent );
88 mSession =
dynamic_cast<Session*
>( parent );
94 mSession = mParentJob->d_ptr->mSession;
98 mSession->d->addJob( q );
103 if ( !s_jobtracker ) {
106 static QTime s_lastTime;
107 if ( s_lastTime.isNull() || s_lastTime.elapsed() > 3000 ) {
108 if ( s_lastTime.isNull() )
110 if ( DBusConnectionPool::threadConnection().interface()->isServiceRegistered(QLatin1String(
"org.kde.akonadiconsole" ) ) ) {
111 s_jobtracker =
new QDBusInterface( QLatin1String(
"org.kde.akonadiconsole" ),
112 QLatin1String(
"/jobtracker" ),
113 QLatin1String(
"org.freedesktop.Akonadi.JobTracker" ),
114 DBusConnectionPool::threadConnection(), 0 );
116 s_lastTime.restart();
122 QMetaObject::invokeMethod( q,
"signalCreationToJobTracker", Qt::QueuedConnection );
125 void JobPrivate::signalCreationToJobTracker()
128 if ( s_jobtracker ) {
132 QList<QVariant> argumentList;
133 argumentList << QLatin1String( mSession->
sessionId() )
134 << QString::number(reinterpret_cast<quintptr>( q ), 16)
135 << ( mParentJob ? QString::number( reinterpret_cast<quintptr>( mParentJob ), 16) : QString() )
136 << QString::fromLatin1( q->metaObject()->className() )
137 << jobDebuggingString();
138 s_jobtracker->callWithArgumentList(QDBus::NoBlock, QLatin1String(
"jobCreated" ), argumentList);
142 void JobPrivate::signalStartedToJobTracker()
145 if ( s_jobtracker ) {
147 QList<QVariant> argumentList;
148 argumentList << QString::number(reinterpret_cast<quintptr>( q ), 16);
149 s_jobtracker->callWithArgumentList(QDBus::NoBlock, QLatin1String(
"jobStarted" ), argumentList);
153 void JobPrivate::delayedEmitResult()
159 void JobPrivate::startQueued()
164 emit q->aboutToStart( q );
166 QTimer::singleShot( 0, q, SLOT(startNext()) );
167 QMetaObject::invokeMethod( q,
"signalStartedToJobTracker", Qt::QueuedConnection );
170 void JobPrivate::lostConnection()
174 if ( mCurrentSubJob ) {
175 mCurrentSubJob->d_ptr->lostConnection();
182 void JobPrivate::slotSubJobAboutToStart(
Job * job )
184 Q_ASSERT( mCurrentSubJob == 0 );
185 mCurrentSubJob = job;
188 void JobPrivate::startNext()
192 if ( mStarted && !mCurrentSubJob && q->hasSubjobs() ) {
195 job->d_ptr->startQueued();
202 mTag = mParentJob->d_ptr->newTag();
204 mTag = QByteArray::number( mSession->d->nextTag() );
215 Q_ASSERT_X( !mWriteFinished,
"Job::writeData()",
"Calling writeData() after emitting writeFinished()" );
216 mSession->d->writeData( data );
221 mSession->d->itemRevisionChanged( itemId, oldRevision, newRevision );
227 foreach ( KJob *j, q->subjobs() ) {
230 job->d_ptr->updateItemRevision( itemId, oldRevision, newRevision );
238 Q_UNUSED( oldRevision );
239 Q_UNUSED( newRevision );
242 int JobPrivate::protocolVersion()
const
244 return mSession->d->protocolVersion;
250 : KCompositeJob( parent ),
253 d_ptr->init( parent );
257 : KCompositeJob( parent ),
260 d_ptr->init( parent );
268 if ( s_jobtracker ) {
269 QList<QVariant> argumentList;
270 argumentList << QString::number(reinterpret_cast<quintptr>( this ), 16)
272 s_jobtracker->callWithArgumentList(QDBus::NoBlock, QLatin1String(
"jobEnded" ), argumentList);
285 d->mSession->d->forceReconnect();
298 str = i18n(
"Cannot connect to the Akonadi service." );
301 str = i18n(
"The protocol version of the Akonadi server is incompatible. Make sure you have a compatible version installed." );
304 str = i18n(
"User canceled operation." );
309 str = i18n(
"Unknown error." );
312 if ( !errorText().isEmpty() ) {
313 str += QString::fromLatin1(
" (%1)" ).arg( errorText() );
320 bool rv = KCompositeJob::addSubjob( job );
323 QTimer::singleShot( 0,
this, SLOT(startNext()) );
330 bool rv = KCompositeJob::removeSubjob( job );
331 if ( job == d_ptr->mCurrentSubJob ) {
332 d_ptr->mCurrentSubJob = 0;
333 QTimer::singleShot( 0,
this, SLOT(startNext()) );
340 kDebug() <<
"Unhandled response: " << tag << data;
343 void Job::slotResult(KJob * job)
345 if ( d_ptr->mCurrentSubJob == job ) {
347 d_ptr->mCurrentSubJob = 0;
348 KCompositeJob::slotResult( job );
350 QTimer::singleShot( 0,
this, SLOT(startNext()) );
355 KCompositeJob::removeSubjob( job );
361 d_ptr->mWriteFinished =
true;
365 #include "moc_job.cpp"