Commit 8b3b4c2b authored by Volker Krause's avatar Volker Krause
Browse files

- move network connection handling out of Job into Session

- move job scheduling out of JobQueue into Session
- jobs use the thread-global default session if no session is specified
- auto-reconnect if connection to server has been lost
- support arbitrary session identifiers (needed to solve indirect notification loops)
- make Job a KCompositeJob, allowing to easily execute sequential sub-jobs
- since Job derives from KJob now, jobs are auto-deleted after execution

svn path=/trunk/KDE/kdepim/akonadi/; revision=632537
parent 935de3e5
......@@ -31,10 +31,10 @@ DeleteCommand::DeleteCommand(const QString & uid) :
void DeleteCommand::exec()
{
DataReference ref( mUid.toUInt(), QString() );
ItemDeleteJob delJob( ref );
if ( !delJob.exec() ) {
ItemDeleteJob* delJob = new ItemDeleteJob( ref );
if ( !delJob->exec() ) {
err() << "Error deleting item '" << mUid << "': "
<< delJob.errorText()
<< delJob->errorString()
<< endl;
}
}
......@@ -32,13 +32,13 @@ FetchCommand::FetchCommand(const QString & uid) :
void FetchCommand::exec()
{
DataReference ref( mUid.toUInt(), QString() );
ItemFetchJob fetchJob( ref );
if ( !fetchJob.exec() ) {
ItemFetchJob* fetchJob = new ItemFetchJob( ref );
if ( !fetchJob->exec() ) {
err() << "Error fetching item '" << mUid << "': "
<< fetchJob.errorText()
<< fetchJob->errorString()
<< endl;
} else {
foreach( Item *item, fetchJob.items() ) {
foreach( Item *item, fetchJob->items() ) {
out() << item->data() << endl;
}
}
......
......@@ -28,6 +28,8 @@
#include <libakonadi/itemfetchjob.h>
#include <kmime/kmime_message.h>
using namespace Akonadi;
ListCommand::ListCommand( const QString &path )
: mPath( path )
{
......@@ -36,55 +38,53 @@ ListCommand::ListCommand( const QString &path )
void ListCommand::exec()
{
Akonadi::CollectionListJob collectionJob( mPath.toUtf8() );
if ( !collectionJob.exec() ) {
CollectionListJob* collectionJob = new CollectionListJob( mPath.toUtf8() );
if ( !collectionJob->exec() ) {
err() << "Error listing collection '" << mPath << "': "
<< collectionJob.errorText()
<< collectionJob->errorString()
<< endl;
return;
} else {
foreach( Akonadi::Collection *collection, collectionJob.collections() ) {
foreach( Akonadi::Collection *collection, collectionJob->collections() ) {
out() << collection->name() << endl;
}
}
if ( mPath.indexOf( "/", 1 ) > 0 ) {
Akonadi::ItemFetchJob itemFetchJob( mPath.toUtf8() );
if ( !itemFetchJob.exec() ) {
err() << "Error listing items at '" << mPath << "': "
<< itemFetchJob.errorText()
<< endl;
} else {
foreach( Akonadi::Item *item, itemFetchJob.items() ) {
QString str;
str = QLatin1String("Item: ") + QString::number( item->reference().persistanceID() );
if ( !item->reference().externalUrl().isEmpty() ) {
str += QLatin1String(" [") + item->reference().externalUrl().toString() + QLatin1Char(']');
}
if ( !item->flags().isEmpty() ) {
str += QLatin1String(" ( ");
foreach( QByteArray flag, item->flags() ) {
str += flag + QLatin1Char(' ');
}
str += QLatin1Char(')');
ItemFetchJob* itemFetchJob = new ItemFetchJob( mPath.toUtf8() );
if ( !itemFetchJob->exec() ) {
err() << "Error listing items at '" << mPath << "': "
<< itemFetchJob->errorString()
<< endl;
} else {
foreach( Akonadi::Item *item, itemFetchJob->items() ) {
QString str;
str = QLatin1String("Item: ") + QString::number( item->reference().persistanceID() );
if ( !item->reference().externalUrl().isEmpty() ) {
str += QLatin1String(" [") + item->reference().externalUrl().toString() + QLatin1Char(']');
}
if ( !item->flags().isEmpty() ) {
str += QLatin1String(" ( ");
foreach( QByteArray flag, item->flags() ) {
str += flag + QLatin1Char(' ');
}
str += QLatin1String(" [") + item->mimeType() + QLatin1Char(']');
out() << str << endl;
str += QLatin1Char(')');
}
str += QLatin1String(" [") + item->mimeType() + QLatin1Char(']');
out() << str << endl;
}
}
#if 0
Akonadi::MessageFetchJob messageJob( mPath.toUtf8() );
if ( !messageJob.exec() ) {
err() << "Error listing messages at '" << mPath << "': "
<< messageJob.errorText()
<< endl;
} else {
foreach( Akonadi::Message *m, messageJob.messages() ) {
KMime::Message *message = m->mime();
out() << "Subject: " << message->subject()->asUnicodeString() << endl;
}
Akonadi::MessageFetchJob messageJob( mPath.toUtf8() );
if ( !messageJob.exec() ) {
err() << "Error listing messages at '" << mPath << "': "
<< messageJob.errorString()
<< endl;
} else {
foreach( Akonadi::Message *m, messageJob.messages() ) {
KMime::Message *message = m->mime();
out() << "Subject: " << message->subject()->asUnicodeString() << endl;
}
#endif
}
#endif
}
......@@ -80,22 +80,21 @@ void BrowserWidget::itemActivated(const QModelIndex & index)
if ( ref.isNull() )
return;
ItemFetchJob *job = new ItemFetchJob( ref, this );
connect( job, SIGNAL(done(Akonadi::Job*)), SLOT(itemFetchDone(Akonadi::Job*)) );
connect( job, SIGNAL(result(KJob*)), SLOT(itemFetchDone(KJob*)) );
job->start();
}
void BrowserWidget::itemFetchDone(Akonadi::Job * job)
void BrowserWidget::itemFetchDone(KJob * job)
{
ItemFetchJob *fetch = static_cast<ItemFetchJob*>( job );
if ( job->error() ) {
qWarning() << "Item fetch failed: " << job->errorText();
qWarning() << "Item fetch failed: " << job->errorString();
} else if ( fetch->items().isEmpty() ) {
qWarning() << "No item found!";
} else {
Item *item = fetch->items().first();
mDataView->setPlainText( item->data() );
}
job->deleteLater();
}
#include "browserwidget.moc"
......@@ -26,6 +26,8 @@ class QModelIndex;
class QTextEdit;
class QTreeView;
class KJob;
namespace Akonadi {
class CollectionView;
class CollectionModel;
......@@ -44,7 +46,7 @@ class BrowserWidget: public QWidget
private slots:
void collectionActivated( const QModelIndex &index );
void itemActivated( const QModelIndex &index );
void itemFetchDone( Akonadi::Job* job );
void itemFetchDone( KJob *job );
private:
Akonadi::CollectionModel *mCollectionModel;
......
......@@ -25,7 +25,7 @@
#include "contactmodel.h"
#include "dummymodel.h"
#include <libakonadi/jobqueue.h>
#include <libakonadi/session.h>
#include <libakonadi/itemappendjob.h>
#include <libakonadi/messagefetchjob.h>
......@@ -184,7 +184,7 @@ void DataProvider::loadAkonadi()
void DataProvider::saveAkonadi()
{
if ( mAgendaModel ) {
// Akonadi::JobQueue jobQueue( this );
// Akonadi::Session jobQueue( this );
KCal::ICalFormat format;
foreach( Event e, mAgendaModel->events() ) {
KCal::Event *event = new KCal::Event();
......
......@@ -67,8 +67,7 @@ void AkonadiSlave::get(const KUrl & url)
kDebug() << k_funcinfo << url << endl;
ItemFetchJob *job = new ItemFetchJob( DataReference( url.fileName().toInt(), QString() ) );
if ( !job->exec() ) {
error( KIO::ERR_INTERNAL, job->errorMessage() );
job->deleteLater();
error( KIO::ERR_INTERNAL, job->errorString() );
return;
}
if ( job->items().count() != 1 ) {
......@@ -79,7 +78,6 @@ void AkonadiSlave::get(const KUrl & url)
data( QByteArray() );
finished();
}
job->deleteLater();
finished();
}
......@@ -89,8 +87,7 @@ void AkonadiSlave::stat(const KUrl & url)
kDebug() << k_funcinfo << url << endl;
ItemFetchJob *job = new ItemFetchJob( DataReference( url.fileName().toInt(), QString() ) );
if ( !job->exec() ) {
error( KIO::ERR_INTERNAL, job->errorMessage() );
job->deleteLater();
error( KIO::ERR_INTERNAL, job->errorString() );
return;
}
if ( job->items().count() != 1 ) {
......@@ -103,6 +100,5 @@ void AkonadiSlave::stat(const KUrl & url)
statEntry( entry );
finished();
}
job->deleteLater();
}
......@@ -38,7 +38,6 @@ set( akonadi_LIB_SRC
itemstorejob.cpp
itemmodel.cpp
job.cpp
jobqueue.cpp
messagecollectionattribute.cpp
messagecollectionmodel.cpp
message.cpp
......@@ -47,6 +46,7 @@ set( akonadi_LIB_SRC
monitor.cpp
profilemanager.cpp
profilemodel.cpp
session.cpp
transactionjobs.cpp
)
......@@ -86,7 +86,6 @@ install( FILES
itemfetchjob.h
itemstorejob.h
job.h
jobqueue.h
messagecollectionattribute.h
messagecollectionmodel.h
message.h
......@@ -94,6 +93,7 @@ install( FILES
messagemodel.h
monitor.h
profilemanager.h
session.h
transactionjobs.h
DESTINATION ${INCLUDE_INSTALL_DIR}/libakonadi
)
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......@@ -24,8 +24,8 @@
#include "collectionmodel.h"
#include "collectionrenamejob.h"
#include "itemappendjob.h"
#include "jobqueue.h"
#include "monitor.h"
#include "session.h"
#include <kdebug.h>
#include <kiconloader.h>
......@@ -50,7 +50,7 @@ class CollectionModel::Private
Collection *editedCollection;
QString editOldName;
Monitor* monitor;
JobQueue *queue;
Session *session;
QStringList mimeTypes;
void updateSupportedMimeTypes( Collection *col )
......@@ -72,16 +72,16 @@ CollectionModel::CollectionModel( QObject * parent ) :
d->currentEdit = Private::None;
d->editedCollection = 0;
d->queue = new JobQueue( this );
d->session = new Session( QByteArray("CollectionModel-") + QByteArray::number( qrand() ), this );
// start a list job
CollectionListJob *job = new CollectionListJob( Collection::prefix(), true, d->queue );
connect( job, SIGNAL(done(Akonadi::Job*)), SLOT(listDone(Akonadi::Job*)) );
CollectionListJob *job = new CollectionListJob( Collection::prefix(), true, d->session );
connect( job, SIGNAL(result(KJob*)), SLOT(listDone(KJob*)) );
// monitor collection changes
d->monitor = new Monitor();
d->monitor->monitorCollection( Collection::root(), true );
d->monitor->ignoreSession( d->queue );
d->monitor->ignoreSession( d->session );
connect( d->monitor, SIGNAL(collectionChanged(QString)), SLOT(collectionChanged(QString)) );
connect( d->monitor, SIGNAL(collectionAdded(QString)), SLOT(collectionChanged(QString)) );
connect( d->monitor, SIGNAL(collectionRemoved(QString)), SLOT(collectionRemoved(QString)) );
......@@ -230,8 +230,8 @@ void CollectionModel::collectionChanged( const QString &path )
{
if ( d->collections.contains( path ) ) {
// update
CollectionStatusJob *job = new CollectionStatusJob( path, d->queue );
connect( job, SIGNAL(done(Akonadi::Job*)), SLOT(updateDone(Akonadi::Job*)) );
CollectionStatusJob *job = new CollectionStatusJob( path, d->session );
connect( job, SIGNAL(result(KJob*)), SLOT(updateDone(KJob*)) );
} else {
// new collection
int index = path.lastIndexOf( Collection::delimiter() );
......@@ -242,11 +242,11 @@ void CollectionModel::collectionChanged( const QString &path )
parent = Collection::root();
// re-list parent non-recursively
CollectionListJob *job = new CollectionListJob( parent, false, d->queue );
connect( job, SIGNAL(done(Akonadi::Job*)), SLOT(listDone(Akonadi::Job*)) );
CollectionListJob *job = new CollectionListJob( parent, false, d->session );
connect( job, SIGNAL(result(KJob*)), SLOT(listDone(KJob*)) );
// list the new collection recursively
job = new CollectionListJob( path, true, d->queue );
connect( job, SIGNAL(done(Akonadi::Job*)), SLOT(listDone(Akonadi::Job*)) );
job = new CollectionListJob( path, true, d->session );
connect( job, SIGNAL(result(KJob*)), SLOT(listDone(KJob*)) );
}
}
......@@ -266,11 +266,11 @@ void CollectionModel::collectionRemoved( const QString &path )
}
}
void CollectionModel::updateDone( Job * job )
void CollectionModel::updateDone( KJob * job )
{
if ( job->error() ) {
// TODO: handle job errors
kWarning() << k_funcinfo << "Job error: " << job->errorText() << endl;
kWarning() << k_funcinfo << "Job error: " << job->errorString() << endl;
} else {
CollectionStatusJob *csjob = static_cast<CollectionStatusJob*>( job );
QString path = csjob->path();
......@@ -288,8 +288,6 @@ void CollectionModel::updateDone( Job * job )
emit dataChanged( startIndex, endIndex );
}
}
job->deleteLater();
}
QModelIndex CollectionModel::indexForPath( const QString &path, int column )
......@@ -310,10 +308,10 @@ QModelIndex CollectionModel::indexForPath( const QString &path, int column )
return QModelIndex();
}
void CollectionModel::listDone( Job * job )
void CollectionModel::listDone( KJob * job )
{
if ( job->error() ) {
qWarning() << "Job error: " << job->errorText() << endl;
qWarning() << "Job error: " << job->errorString() << endl;
} else {
Collection::List collections = static_cast<CollectionListJob*>( job )->collections();
......@@ -337,13 +335,12 @@ void CollectionModel::listDone( Job * job )
// start a status job for every collection to get message counts, etc.
if ( col->type() != Collection::VirtualParent ) {
CollectionStatusJob* csjob = new CollectionStatusJob( col->path(), d->queue );
connect( csjob, SIGNAL(done(Akonadi::Job*)), SLOT(updateDone(Akonadi::Job*)) );
CollectionStatusJob* csjob = new CollectionStatusJob( col->path(), d->session );
connect( csjob, SIGNAL(result(KJob*)), SLOT(updateDone(KJob*)) );
}
}
}
job->deleteLater();
}
bool CollectionModel::setData( const QModelIndex & index, const QVariant & value, int role )
......@@ -361,8 +358,8 @@ bool CollectionModel::setData( const QModelIndex & index, const QVariant & value
newPath = d->editedCollection->name();
else
newPath = d->editedCollection->parent() + Collection::delimiter() + d->editedCollection->name();
CollectionRenameJob *job = new CollectionRenameJob( d->editedCollection->path(), newPath, d->queue );
connect( job, SIGNAL(done(Akonadi::Job*)), SLOT(editDone(Akonadi::Job*)) );
CollectionRenameJob *job = new CollectionRenameJob( d->editedCollection->path(), newPath, d->session );
connect( job, SIGNAL(result(KJob*)), SLOT(editDone(KJob*)) );
emit dataChanged( index, index );
return true;
}
......@@ -391,10 +388,10 @@ Qt::ItemFlags CollectionModel::flags( const QModelIndex & index ) const
return flags;
}
void CollectionModel::editDone( Job * job )
void CollectionModel::editDone( KJob * job )
{
if ( job->error() ) {
qWarning() << "Edit failed: " << job->errorText() << " - reverting current transaction";
qWarning() << "Edit failed: " << job->errorString() << " - reverting current transaction";
// revert current transaction
switch ( d->currentEdit ) {
case Private::Create:
......@@ -415,7 +412,6 @@ void CollectionModel::editDone( Job * job )
// transaction done
}
d->currentEdit = Private::None;
job->deleteLater();
}
bool CollectionModel::createCollection( const QModelIndex & parent, const QString & name )
......@@ -438,8 +434,8 @@ bool CollectionModel::createCollection( const QModelIndex & parent, const QStrin
endInsertRows();
// start creation job
CollectionCreateJob *job = new CollectionCreateJob( d->editedCollection->path(), d->queue );
connect( job, SIGNAL(done(Akonadi::Job*)), SLOT(editDone(Akonadi::Job*)) );
CollectionCreateJob *job = new CollectionCreateJob( d->editedCollection->path(), d->session );
connect( job, SIGNAL(result(KJob*)), SLOT(editDone(KJob*)) );
d->currentEdit = Private::Create;
return true;
......@@ -516,21 +512,20 @@ bool CollectionModel::dropMimeData(const QMimeData * data, Qt::DropAction action
// HACK for some unknown reason the data is sometimes 0-terminated...
if ( !item.isEmpty() && item.at( item.size() - 1 ) == 0 )
item.resize( item.size() - 1 );
ItemAppendJob *job = new ItemAppendJob( path, item, type.toLatin1(), d->queue );
connect( job, SIGNAL(done(Akonadi::Job*)), SLOT(appendDone(Akonadi::Job*)) );
ItemAppendJob *job = new ItemAppendJob( path, item, type.toLatin1(), d->session );
connect( job, SIGNAL(result(KJob*)), SLOT(appendDone(KJob*)) );
return true;
}
return false;
}
void CollectionModel::appendDone(Job * job)
void CollectionModel::appendDone(KJob * job)
{
if ( job->error() ) {
kWarning() << "Append failed: " << job->errorText() << endl;
kWarning() << "Append failed: " << job->errorString() << endl;
// TODO: error handling
}
job->deleteLater();
}
#include "collectionmodel.moc"
/*
Copyright (c) 2006 Volker Krause <volker.krause@rwth-aachen.de>
Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
......@@ -171,22 +171,22 @@ class AKONADI_EXPORT CollectionModel : public QAbstractItemModel
/**
Connected to the collection status job.
*/
void updateDone( Akonadi::Job *job );
void updateDone( KJob *job );
/**
Connected to the list jobs.
*/
void listDone( Akonadi::Job *job );
void listDone( KJob *job );
/**
Connected to edit jobs.
*/
void editDone( Akonadi::Job *job );
void editDone( KJob *job );
/**
Connected to item append jobs used for DND.
*/
void appendDone( Akonadi::Job *job );
void appendDone( KJob *job );
private:
class Private;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment