diff --git a/akonadi/CMakeLists.txt b/akonadi/CMakeLists.txt
index ca2bb3990..15781684b 100644
--- a/akonadi/CMakeLists.txt
+++ b/akonadi/CMakeLists.txt
@@ -1,235 +1,240 @@
project(akonadi-kde)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" )
if(CMAKE_COMPILE_GCOV)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
endif(CMAKE_COMPILE_GCOV)
if (KDE4_BUILD_TESTS)
# only with this macro the AKONADI_TESTS_EXPORT macro will do something
add_definitions(-DCOMPILING_TESTS)
add_subdirectory( tests )
endif (KDE4_BUILD_TESTS)
add_definitions( -DQT_NO_CAST_FROM_ASCII )
add_definitions( -DQT_NO_CAST_TO_ASCII )
add_subdirectory( kabc )
add_subdirectory( kmime )
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${QT_QTDBUS_INCLUDE_DIR}
${Boost_INCLUDE_DIR}
${KDE4_INCLUDE_DIR}
${AKONADI_INCLUDE_DIR}
${AKONADI_INCLUDE_DIR}/akonadi/private
)
# libakonadi-kde
set( akonadikde_LIB_SRC
entity.cpp # keep it at top to not break enable-final
agentbase.cpp
agentfilterproxymodel.cpp
agentinstance.cpp
agentinstancecreatejob.cpp
agentinstancemodel.cpp
agentinstancewidget.cpp
agentmanager.cpp
agenttype.cpp
agenttypemodel.cpp
agenttypewidget.cpp
agenttypedialog.cpp
attribute.cpp
attributefactory.cpp
cachepolicy.cpp
cachepolicypage.cpp
changerecorder.cpp
collection.cpp
collectioncopyjob.cpp
collectioncreatejob.cpp
collectiondeletejob.cpp
collectiondialog.cpp
collectionfilterproxymodel.cpp
collectiongeneralpropertiespage.cpp
collectionfetchjob.cpp
collectionmodel.cpp
collectionmodel_p.cpp
collectionmodifyjob.cpp
collectionpathresolver.cpp
collectionpropertiesdialog.cpp
collectionpropertiespage.cpp
collectionrequester.cpp
collectionrightsattribute.cpp
collectionselectjob.cpp
collectionstatistics.cpp
collectionstatisticsdelegate.cpp
collectionstatisticsjob.cpp
collectionstatisticsmodel.cpp
collectionsync.cpp
collectionview.cpp
control.cpp
entitydisplayattribute.cpp
#entitysortfilterproxymodel.cpp
erroroverlay.cpp
exception.cpp
expungejob.cpp
firstrun.cpp
flatcollectionproxymodel.cpp
item.cpp
itemcreatejob.cpp
itemcopyjob.cpp
itemdeletejob.cpp
itemfetchjob.cpp
itemfetchscope.cpp
itemmodel.cpp
itemmonitor.cpp
itemmovejob.cpp
itemserializer.cpp
itemserializerplugin.cpp
itemmodifyjob.cpp
itemsync.cpp
itemview.cpp
job.cpp
linkjob.cpp
mimetypechecker.cpp
monitor.cpp
monitor_p.cpp
pastehelper.cpp
protocolhelper.cpp
resourcebase.cpp
resourcescheduler.cpp
resourceselectjob.cpp
searchcreatejob.cpp
selftestdialog.cpp
session.cpp
servermanager.cpp
standardactionmanager.cpp
subscriptionjob.cpp
subscriptionchangeproxymodel.cpp
subscriptiondialog.cpp
subscriptionmodel.cpp
transactionjobs.cpp
transactionsequence.cpp
+ transportresource.cpp
unlinkjob.cpp
# Temporary until ported to Qt-plugin framework
pluginloader.cpp
)
# DBus interfaces and adaptors
set(akonadi_xml ${AKONADI_DBUS_INTERFACES_DIR}/org.freedesktop.Akonadi.NotificationManager.xml)
set_source_files_properties(${akonadi_xml} PROPERTIES INCLUDE "notificationmessage_p.h")
qt4_add_dbus_interface( akonadikde_LIB_SRC ${akonadi_xml} notificationmanagerinterface )
qt4_add_dbus_interfaces( akonadikde_LIB_SRC ${AKONADI_DBUS_INTERFACES_DIR}/org.freedesktop.Akonadi.AgentManager.xml )
qt4_add_dbus_interfaces( akonadikde_LIB_SRC ${AKONADI_DBUS_INTERFACES_DIR}/org.freedesktop.Akonadi.Tracer.xml )
qt4_add_dbus_adaptor( akonadikde_LIB_SRC ${AKONADI_DBUS_INTERFACES_DIR}/org.freedesktop.Akonadi.Resource.xml resourcebase.h Akonadi::ResourceBase )
qt4_add_dbus_adaptor( akonadikde_LIB_SRC ${AKONADI_DBUS_INTERFACES_DIR}/org.freedesktop.Akonadi.Agent.Status.xml agentbase.h Akonadi::AgentBase )
qt4_add_dbus_adaptor( akonadikde_LIB_SRC ${AKONADI_DBUS_INTERFACES_DIR}/org.freedesktop.Akonadi.Agent.Control.xml agentbase.h Akonadi::AgentBase )
+# TODO move this to kdesupport/akonadi/interfaces
+qt4_add_dbus_adaptor( akonadikde_LIB_SRC interfaces/org.freedesktop.Akonadi.Resource.Transport.xml transportresource.h Akonadi::TransportResource )
+#qt4_add_dbus_interface( akonadikde_LIB_SRC interfaces/org.freedesktop.Akonadi.Resource.Transport.xml resourcetransportinterface )
kde4_add_ui_files( akonadikde_LIB_SRC
cachepolicypage.ui
collectiongeneralpropertiespage.ui
subscriptiondialog.ui
controlprogressindicator.ui
selftestdialog.ui
)
kde4_add_library( akonadi-kde SHARED ${akonadikde_LIB_SRC} )
macro_ensure_version( "4.2.0" ${KDE_VERSION} KDE_IS_AT_LEAST_42 )
target_link_libraries( akonadi-kde ${KDE4_SOLID_LIBS} ${QT_QTNETWORK_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTSQL_LIBRARY} ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${AKONADI_COMMON_LIBRARIES} )
set( AKONADI_KDE_DEPS ${KDE4_KDEUI_LIBS} ${QT_QTDBUS_LIBRARY} ${QT_QTCORE_LIBRARY} )
if(${KDE_IS_AT_LEAST_42})
target_link_libraries( akonadi-kde LINK_INTERFACE_LIBRARIES ${AKONADI_KDE_DEPS})
else(${KDE_IS_AT_LEAST_42})
target_link_libraries( akonadi-kde ${AKONADI_KDE_DEPS})
endif(${KDE_IS_AT_LEAST_42})
set_target_properties( akonadi-kde PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} )
install( TARGETS akonadi-kde EXPORT kdepimlibsLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS} )
########### install files ###############
install( FILES
akonadi_export.h
agentbase.h
agentfilterproxymodel.h
agentinstance.h
agentinstancecreatejob.h
agentinstancemodel.h
agentinstancewidget.h
agentmanager.h
agenttype.h
agenttypemodel.h
agenttypewidget.h
agenttypedialog.h
attribute.h
attributefactory.h
cachepolicy.h
changerecorder.h
collection.h
collectioncopyjob.h
collectioncreatejob.h
collectiondeletejob.h
collectiondialog.h
collectionfilterproxymodel.h
collectionfetchjob.h
collectionmodel.h
collectionmodifyjob.h
collectionpropertiesdialog.h
collectionpropertiespage.h
collectionrequester.h
collectionstatisticsdelegate.h
collectionstatisticsmodel.h
collectionstatistics.h
collectionstatisticsjob.h
collectionview.h
control.h
entity.h
entitydisplayattribute.h
# entitysortfilterproxymodel.h
exception.h
item.h
itemcreatejob.h
itemcopyjob.h
itemdeletejob.h
itemfetchjob.h
itemfetchscope.h
itemmodel.h
itemmodifyjob.h
itemmonitor.h
itemmovejob.h
itempayloadinternals_p.h
itemserializerplugin.h
itemsync.h
itemview.h
job.h
linkjob.h
mimetypechecker.h
monitor.h
qtest_akonadi.h
resourcebase.h
searchcreatejob.h
session.h
servermanager.h
standardactionmanager.h
transactionjobs.h
transactionsequence.h
+ transportresource.h
unlinkjob.h
DESTINATION ${INCLUDE_INSTALL_DIR}/akonadi COMPONENT Devel
)
install( FILES
collectionpathresolver_p.h
DESTINATION ${INCLUDE_INSTALL_DIR}/akonadi/private COMPONENT Devel
)
install( FILES
kcfg2dbus.xsl
DESTINATION ${DATA_INSTALL_DIR}/akonadi-kde
)
diff --git a/akonadi/interfaces/org.freedesktop.Akonadi.Resource.Transport.xml b/akonadi/interfaces/org.freedesktop.Akonadi.Resource.Transport.xml
new file mode 100644
index 000000000..cdf40ffc9
--- /dev/null
+++ b/akonadi/interfaces/org.freedesktop.Akonadi.Resource.Transport.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/akonadi/resourcebase.h b/akonadi/resourcebase.h
index 1dcee1eb5..06e0a3f34 100644
--- a/akonadi/resourcebase.h
+++ b/akonadi/resourcebase.h
@@ -1,448 +1,448 @@
/*
This file is part of akonadiresources.
Copyright (c) 2006 Till Adam
Copyright (c) 2007 Volker Krause
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
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef AKONADI_RESOURCEBASE_H
#define AKONADI_RESOURCEBASE_H
#include "akonadi_export.h"
#include
#include
#include
class KJob;
class ResourceAdaptor;
namespace Akonadi {
class ResourceBasePrivate;
/**
* @short The base class for all Akonadi resources.
*
* This class should be used as a base class by all resource agents,
* because it encapsulates large parts of the protocol between
* resource agent, agent manager and the Akonadi storage.
*
* It provides many convenience methods to make implementing a
* new Akonadi resource agent as simple as possible.
*
* How to write a resource
*
* The following provides an overview of what you need to do to implement
* your own Akonadi resource. In the following, the term 'backend' refers
* to the entity the resource connects with Akonadi, be it a single file
* or a remote server.
*
* @todo Complete this (online/offline state management)
*
* Basic %Resource Framework
*
* The following is needed to create a new resource:
* - A new class deriving from Akonadi::ResourceBase, implementing at least all
* pure-virtual methods, see below for further details.
* - call init() in your main() function.
* - a .desktop file similar to the following example
* \code
* [Desktop Entry]
* Encoding=UTF-8
* Name=My Akonadi Resource
* Type=AkonadiResource
* Exec=akonadi_my_resource
* Icon=my-icon
*
* X-Akonadi-MimeTypes=
* X-Akonadi-Capabilities=Resource
* X-Akonadi-Identifier=akonadi_my_resource
* \endcode
*
* Handling PIM Items
*
* To follow item changes in the backend, the following steps are necessary:
* - Implement retrieveItems() to synchronize all items in the given
* collection. If the backend supports incremental retrieval,
* implementing support for that is recommended to improve performance.
* - Convert the items provided by the backend to Akonadi items.
* This typically happens either in retrieveItems() if you retrieved
* the collection synchronously (not recommended for network backends) or
* in the result slot of the asynchronous retrieval job.
* Converting means to create Akonadi::Item objects for every retrieved
* item. It's very important that every object has its remote identifier set.
* - Call itemsRetrieved() or itemsRetrievedIncremental() respectively
* with the item objects created above. The Akonadi storage will then be
* updated automatically. Note that it is usually not necessary to manipulate
* any item in the Akonadi storage manually.
*
* To fetch item data on demand, the method retrieveItem() needs to be
* reimplemented. Fetch the requested data there and call itemRetrieved()
* with the result item.
*
* To write local changes back to the backend, you need to re-implement
* the following three methods:
* - itemAdded()
* - itemChanged()
* - itemRemoved()
* Note that these three functions don't get the full payload of the items by default,
* you need to change the item fetch scope of the change recorder to fetch the full
* payload. This can be expensive with big payloads, though.
* Once you have handled changes in these methods call changeCommitted().
* These methods are called whenever a local item related to this resource is
* added, modified or deleted. They are only called if the resource is online, otherwise
* all changes are recorded and replayed as soon the resource is online again.
*
* Handling Collections
*
* To follow collection changes in the backend, the following steps are necessary:
* - Implement retrieveCollections() to retrieve collections from the backend.
* If the backend supports incremental collections updates, implementing
* support for that is recommended to improve performance.
* - Convert the collections of the backend to Akonadi collections.
* This typically happens either in retrieveCollections() if you retrieved
* the collection synchronously (not recommended for network backends) or
* in the result slot of the asynchronous retrieval job.
* Converting means to create Akonadi::Collection objects for every retrieved
* collection. It's very important that every object has its remote identifier
* and its parent remote identifier set.
* - Call collectionsRetrieved() or collectionsRetrievedIncremental() respectively
* with the collection objects created above. The Akonadi storage will then be
* updated automatically. Note that it is usually not necessary to manipulate
* any collection in the Akonadi storage manually.
*
*
* To write local collection changes back to the backend, you need to re-implement
* the following three methods:
* - collectionAdded()
* - collectionChanged()
* - collectionRemoved()
* Once you have handled changes in these methods call changeCommitted().
* These methods are called whenever a local collection related to this resource is
* added, modified or deleted. They are only called if the resource is online, otherwise
* all changes are recorded and replayed as soon the resource is online again.
*
* @todo Convenience base class for collection-less resources
*/
// FIXME_API: API dox need to be updated for Observer approach (kevin)
class AKONADI_EXPORT ResourceBase : public AgentBase
{
Q_OBJECT
public:
/**
* Use this method in the main function of your resource
* application to initialize your resource subclass.
* This method also takes care of creating a KApplication
* object and parsing command line arguments.
*
* @note In case the given class is also derived from AgentBase::Observer
* it gets registered as its own observer (see AgentBase::Observer), e.g.
* resourceInstance->registerObserver( resourceInstance );
*
* @code
*
* class MyResource : public ResourceBase
* {
* ...
* };
*
* int main( int argc, char **argv )
* {
* return ResourceBase::init( argc, argv );
* }
*
* @endcode
*/
template
static int init( int argc, char **argv )
{
const QString id = parseArguments( argc, argv );
KApplication app;
T* r = new T( id );
// check if T also inherits AgentBase::Observer and
// if it does, automatically register it on itself
Observer *observer = dynamic_cast( r );
if ( observer != 0 )
r->registerObserver( observer );
return init( r );
}
/**
* This method is used to set the name of the resource.
*/
//FIXME_API: make sure location is renamed to this by resourcebase
void setName( const QString &name );
/**
* Returns the name of the resource.
*/
QString name() const;
Q_SIGNALS:
/**
* This signal is emitted whenever the name of the resource has changed.
*
* @param name The new name of the resource.
*/
void nameChanged( const QString &name );
/**
* Emitted when a full synchronization has been completed.
*/
void synchronized();
protected Q_SLOTS:
/**
* Retrieve the collection tree from the remote server and supply it via
* collectionsRetrieved() or collectionsRetrievedIncremental().
* @see collectionsRetrieved(), collectionsRetrievedIncremental()
*/
virtual void retrieveCollections() = 0;
/**
* Retrieve all (new/changed) items in collection @p collection.
* It is recommended to use incremental retrieval if the backend supports that
* and provide the result by calling itemsRetrievedIncremental().
* If incremental retrieval is not possible, provide the full listing by calling
* itemsRetrieved( const Item::List& ).
* In any case, ensure that all items have a correctly set remote identifier
- * to allow synchronizing with already locally existing items.
- * In case you don't want to use the built-in item syncing code, store the retrived
+ * to allow synchronizing with items already existing locally.
+ * In case you don't want to use the built-in item syncing code, store the retrieved
* items manually and call itemsRetrieved() once you are done.
- * @param collection The collection to sync.
- * @see itemsRetrieved( const Item::List &), itemsRetrievedIncremental(), itemsRetrieved(), currentCollection()
+ * @param collection The collection whose items to retrieve.
+ * @see itemsRetrieved( const Item::List& ), itemsRetrievedIncremental(), itemsRetrieved(), currentCollection()
*/
virtual void retrieveItems( const Akonadi::Collection &collection ) = 0;
/**
* Retrieve a single item from the backend. The item to retrieve is provided as @p item.
* Add the requested payload parts and call itemRetrieved() when done.
- * @param item The empty item which payload should be retrieved. Use this object when delivering
- * the result instead of creating a new item to ensure conflict detection to work.
+ * @param item The empty item whose payload should be retrieved. Use this object when delivering
+ * the result instead of creating a new item to ensure conflict detection will work.
* @param parts The item parts that should be retrieved.
* @return false if there is an immediate error when retrieving the item.
* @see itemRetrieved()
*/
virtual bool retrieveItem( const Akonadi::Item &item, const QSet &parts ) = 0;
protected:
/**
* Creates a base resource.
*
* @param id The instance id of the resource.
*/
ResourceBase( const QString & id );
/**
* Destroys the base resource.
*/
~ResourceBase();
/**
* Call this method from retrieveItem() once the result is available.
*
* @param item The retrieved item.
*/
void itemRetrieved( const Item &item );
/**
* Resets the dirty flag of the given item and updates the remote id.
*
* Call whenever you have successfully written changes back to the server.
* This implicitly calls changeProcessed().
* @param item The changed item.
*/
void changeCommitted( const Item &item );
/**
* Call whenever you have successfully handled or ignored a collection
* change notification.
*
* This will update the remote identifier of @p collection if necessary,
* as well as any other collection attributes.
* This implicitly calls changeProcessed().
* @param collection The collection which changes have been handled.
*/
void changeCommitted( const Collection &collection );
/**
* Call this to supply the full folder tree retrieved from the remote server.
*
* @param collections A list of collections.
* @see collectionsRetrievedIncremental()
*/
void collectionsRetrieved( const Collection::List &collections );
/**
* Call this to supply incrementally retrieved collections from the remote server.
*
* @param changedCollections Collections that have been added or changed.
* @param removedCollections Collections that have been deleted.
* @see collectionsRetrieved()
*/
void collectionsRetrievedIncremental( const Collection::List &changedCollections,
const Collection::List &removedCollections );
/**
* Call this method to supply the full collection listing from the remote server.
*
* If the remote server supports incremental listing, it's strongly
* recommended to use itemsRetrievedIncremental() instead.
* @param items A list of items.
* @see itemsRetrievedIncremental().
*/
void itemsRetrieved( const Item::List &items );
/**
* Call this method when you want to use the itemsRetrieved() method
* in streaming mode and indicate the amount of items that will arrive
* that way.
* @deprecated Use setItemStreamingEnabled( true ) + itemsRetrieved[Incremental]()
* + itemsRetrieved() instead.
*/
void setTotalItems( int amount );
/**
* Enable item streaming.
* Item streaming is disabled by default.
* @param enable @c true if items are delivered in chunks rather in one big block.
*/
void setItemStreamingEnabled( bool enable );
/**
* Call this method to supply incrementally retrieved items from the remote server.
*
* @param changedItems Items changed in the backend.
* @param removedItems Items removed from the backend.
*/
void itemsRetrievedIncremental( const Item::List &changedItems,
const Item::List &removedItems );
/**
* Call this method to indicate you finished synchronizing the current collection.
*
* This is not needed if you use the built in syncing without item streaming
* and call itemsRetrieved() or itemsRetrievedIncremental() instead.
* If item streaming is enabled, call this method once all items have been delivered
* using itemsRetrieved() or itemsRetrievedIncremental().
* @see retrieveItems()
*/
void itemsRetrievalDone();
/**
* Call this method to remove all items and collections of the resource from the
* server cache.
*
* The method should be used whenever the configuration of the resource has changed
* and therefor the cached items might not be valid any longer.
*
* @since 4.3
*/
void clearCache();
/**
* Returns the collection that is currently synchronized.
*/
Collection currentCollection() const;
/**
* Returns the item that is currently retrieved.
*/
Item currentItem() const;
/**
* This method is called whenever the resource should start synchronize all data.
*/
void synchronize();
/**
* This method is called whenever the collection with the given @p id
* shall be synchronized.
*/
void synchronizeCollection( qint64 id );
/**
* Refetches the Collections.
*/
void synchronizeCollectionTree();
/**
* Stops the execution of the current task and continues with the next one.
*/
void cancelTask();
/**
* Stops the execution of the current task and continues with the next one.
* Additionally an error message is emitted.
*/
void cancelTask( const QString &error );
/**
* Stops the execution of the current task and continues with the next one.
* The current task will be tried again later.
*
* @since 4.3
*/
void deferTask();
/**
* Inherited from AgentBase.
*/
void doSetOnline( bool online );
private:
static QString parseArguments( int, char** );
static int init( ResourceBase *r );
// dbus resource interface
friend class ::ResourceAdaptor;
bool requestItemDelivery( qint64 uid, const QString &remoteId, const QString &mimeType, const QStringList &parts );
private:
Q_DECLARE_PRIVATE( ResourceBase )
Q_PRIVATE_SLOT( d_func(), void slotDeliveryDone( KJob* ) )
Q_PRIVATE_SLOT( d_func(), void slotCollectionSyncDone( KJob* ) )
Q_PRIVATE_SLOT( d_func(), void slotDeleteResourceCollection() )
Q_PRIVATE_SLOT( d_func(), void slotDeleteResourceCollectionDone( KJob* ) )
Q_PRIVATE_SLOT( d_func(), void slotCollectionDeletionDone( KJob* ) )
Q_PRIVATE_SLOT( d_func(), void slotLocalListDone( KJob* ) )
Q_PRIVATE_SLOT( d_func(), void slotSynchronizeCollection( const Akonadi::Collection& ) )
Q_PRIVATE_SLOT( d_func(), void slotCollectionListDone( KJob* ) )
Q_PRIVATE_SLOT( d_func(), void slotItemSyncDone( KJob* ) )
Q_PRIVATE_SLOT( d_func(), void slotPercent( KJob*, unsigned long ) )
};
}
#ifndef AKONADI_RESOURCE_MAIN
/**
* Convenience Macro for the most common main() function for Akonadi resources.
*/
#define AKONADI_RESOURCE_MAIN( resourceClass ) \
int main( int argc, char **argv ) \
{ \
return Akonadi::ResourceBase::init( argc, argv ); \
}
#endif
#endif
diff --git a/akonadi/transportresource.cpp b/akonadi/transportresource.cpp
new file mode 100644
index 000000000..5deaaf440
--- /dev/null
+++ b/akonadi/transportresource.cpp
@@ -0,0 +1,46 @@
+/*
+ Copyright (c) 2009 Constantin Berzan
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "transportresource.h"
+
+#include "transportadaptor.h"
+
+#include
+#include
+
+using namespace Akonadi;
+
+TransportResource::TransportResource( const QString &id )
+ : ResourceBase( id )
+{
+ new TransportAdaptor( this );
+}
+
+void TransportResource::emitResult( KJob *job )
+{
+ if( job->error() ) {
+ emit transportResult( false, job->errorString() );
+ } else {
+ emit transportResult( true, i18n( "Sending succeeded." ) );
+ }
+
+ // TODO unsure if I need something like QDBusMessage reply = ... here
+}
+
+#include "transportresource.moc"
diff --git a/akonadi/transportresource.h b/akonadi/transportresource.h
new file mode 100644
index 000000000..45f21c0d7
--- /dev/null
+++ b/akonadi/transportresource.h
@@ -0,0 +1,118 @@
+/*
+ Copyright (c) 2009 Constantin Berzan
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef AKONADI_TRANSPORTRESOURCE_H
+#define AKONADI_TRANSPORTRESOURCE_H
+
+#include "akonadi_export.h"
+
+#include
+
+#include
+#include
+
+class KJob;
+
+namespace Akonadi {
+
+/**
+ * @short Resource implementing mail transport capability.
+ *
+ * TODO docu
+ */
+// TODO name: TransportResourceBase?
+class AKONADI_EXPORT TransportResource : public ResourceBase
+{
+ Q_OBJECT
+
+ public:
+#if 0
+ /**
+ * Use this method in the main function of your resource
+ * application to initialize your resource subclass.
+ * This method also takes care of creating a KApplication
+ * object and parsing command line arguments.
+ *
+ * @note In case the given class is also derived from AgentBase::Observer
+ * it gets registered as its own observer (see AgentBase::Observer), e.g.
+ * resourceInstance->registerObserver( resourceInstance );
+ *
+ * @code
+ *
+ * class MyResource : public ResourceBase
+ * {
+ * ...
+ * };
+ *
+ * int main( int argc, char **argv )
+ * {
+ * return ResourceBase::init( argc, argv );
+ * }
+ *
+ * @endcode
+ */
+ template
+ static int init( int argc, char **argv )
+ {
+ const QString id = parseArguments( argc, argv );
+ KApplication app;
+ T* r = new T( id );
+
+ // check if T also inherits AgentBase::Observer and
+ // if it does, automatically register it on itself
+ Observer *observer = dynamic_cast( r );
+ if ( observer != 0 )
+ r->registerObserver( observer );
+ return init( r );
+ }
+#endif
+
+ Q_SIGNALS:
+ void transportResult( bool result, const QString &message );
+
+ public Q_SLOTS:
+ virtual void send( Akonadi::Item::Id message ) = 0;
+
+ protected:
+ TransportResource( const QString &id );
+
+ protected Q_SLOTS:
+ void emitResult( KJob* );
+
+ private:
+ // TODO probably need a private class.
+
+};
+
+}
+
+#if 0
+#ifndef AKONADI_RESOURCE_MAIN
+/**
+ * Convenience Macro for the most common main() function for Akonadi resources.
+ */
+#define AKONADI_RESOURCE_MAIN( resourceClass ) \
+ int main( int argc, char **argv ) \
+ { \
+ return Akonadi::ResourceBase::init( argc, argv ); \
+ }
+#endif
+#endif
+
+#endif