summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/client/main.cpp87
-rw-r--r--examples/dummyresource/CMakeLists.txt2
-rw-r--r--examples/dummyresource/domainadaptor.cpp6
-rw-r--r--examples/dummyresource/domainadaptor.h12
-rw-r--r--examples/dummyresource/dummystore.cpp22
-rw-r--r--examples/dummyresource/dummystore.h2
-rw-r--r--examples/dummyresource/facade.cpp22
-rw-r--r--examples/dummyresource/facade.h6
-rw-r--r--examples/dummyresource/resourcefacade.cpp84
-rw-r--r--examples/dummyresource/resourcefacade.h49
-rw-r--r--examples/dummyresource/resourcefactory.cpp77
-rw-r--r--examples/dummyresource/resourcefactory.h1
12 files changed, 184 insertions, 186 deletions
diff --git a/examples/client/main.cpp b/examples/client/main.cpp
index 0a1a725..2aeb328 100644
--- a/examples/client/main.cpp
+++ b/examples/client/main.cpp
@@ -20,21 +20,24 @@
20#include <QApplication> 20#include <QApplication>
21#include <QCommandLineParser> 21#include <QCommandLineParser>
22#include <QCommandLineOption> 22#include <QCommandLineOption>
23#include <QElapsedTimer>
23 24
24#include "common/clientapi.h" 25#include "common/clientapi.h"
25#include "common/resource.h" 26#include "common/resource.h"
26#include "common/listmodelresult.h"
27#include "common/storage.h" 27#include "common/storage.h"
28#include "common/domain/event.h" 28#include "common/domain/event.h"
29#include "common/domain/folder.h"
29#include "common/resourceconfig.h" 30#include "common/resourceconfig.h"
31#include "common/log.h"
30#include "console.h" 32#include "console.h"
31 33
32#include <QWidget> 34#include <QWidget>
33#include <QListView> 35#include <QTreeView>
34#include <QVBoxLayout> 36#include <QVBoxLayout>
35#include <QLabel> 37#include <QLabel>
36#include <QPushButton> 38#include <QPushButton>
37#include <QItemSelectionModel> 39#include <QItemSelectionModel>
40#include <iostream>
38 41
39template <typename T> 42template <typename T>
40class View : public QWidget 43class View : public QWidget
@@ -43,8 +46,8 @@ public:
43 View(QAbstractItemModel *model) 46 View(QAbstractItemModel *model)
44 : QWidget() 47 : QWidget()
45 { 48 {
46 auto listView = new QListView(this); 49 auto modelView = new QTreeView(this);
47 listView->setModel(model); 50 modelView->setModel(model);
48 resize(1000, 1500); 51 resize(1000, 1500);
49 52
50 auto topLayout = new QVBoxLayout(this); 53 auto topLayout = new QVBoxLayout(this);
@@ -61,36 +64,59 @@ public:
61 QObject::connect(syncButton, &QPushButton::pressed, []() { 64 QObject::connect(syncButton, &QPushButton::pressed, []() {
62 Akonadi2::Query query; 65 Akonadi2::Query query;
63 query.resources << "org.kde.dummy.instance1"; 66 query.resources << "org.kde.dummy.instance1";
64 Akonadi2::Store::synchronize(query); 67 query.syncOnDemand = true;
68 Akonadi2::Store::synchronize(query).exec();
65 }); 69 });
66 70
67 auto removeButton = new QPushButton(this); 71 auto removeButton = new QPushButton(this);
68 removeButton->setText("Remove"); 72 removeButton->setText("Remove");
69 QObject::connect(removeButton, &QPushButton::pressed, [listView]() { 73 QObject::connect(removeButton, &QPushButton::pressed, [modelView]() {
70 for (auto index :listView->selectionModel()->selectedIndexes()) { 74 for (auto index : modelView->selectionModel()->selectedIndexes()) {
71 auto object = index.data(DomainObjectRole).value<typename T::Ptr>(); 75 auto object = index.data(Akonadi2::Store::DomainObjectRole).value<typename T::Ptr>();
72 Akonadi2::Store::remove(*object).exec(); 76 Akonadi2::Store::remove(*object).exec();
73 } 77 }
74 }); 78 });
75 79
76 topLayout->addWidget(titleLabel); 80 topLayout->addWidget(titleLabel);
77 topLayout->addWidget(syncButton); 81 topLayout->addWidget(syncButton);
78 topLayout->addWidget(listView, 10); 82 topLayout->addWidget(modelView, 10);
79 83
80 show(); 84 show();
81 } 85 }
82 86
83}; 87};
84 88
89
90class MyApplication : public QApplication
91{
92 QElapsedTimer t;
93public:
94 MyApplication(int& argc, char ** argv) : QApplication(argc, argv) { }
95 virtual ~MyApplication() { }
96
97 virtual bool notify(QObject* receiver, QEvent* event)
98 {
99 t.start();
100 bool ret = QApplication::notify(receiver, event);
101 if(t.elapsed() > 3)
102 qDebug("processing event type %d for object %s took %dms",
103 (int)event->type(), receiver->objectName().toLocal8Bit().data(),
104 (int)t.elapsed());
105 return ret;
106 }
107};
108
85int main(int argc, char *argv[]) 109int main(int argc, char *argv[])
86{ 110{
87 QApplication app(argc, argv); 111 MyApplication app(argc, argv);
88 112
89 QCommandLineParser cliOptions; 113 QCommandLineParser cliOptions;
90 cliOptions.addPositionalArgument(QObject::tr("[resource]"), 114 cliOptions.addPositionalArgument(QObject::tr("[resource]"),
91 QObject::tr("A resource to connect to")); 115 QObject::tr("A resource to connect to"));
92 cliOptions.addOption(QCommandLineOption("clear")); 116 cliOptions.addOption(QCommandLineOption("clear"));
93 cliOptions.addOption(QCommandLineOption("debuglevel")); 117 cliOptions.addOption(QCommandLineOption("debuglevel"));
118 cliOptions.addOption(QCommandLineOption("list"));
119 cliOptions.addOption(QCommandLineOption("count"));
94 cliOptions.addHelpOption(); 120 cliOptions.addHelpOption();
95 cliOptions.process(app); 121 cliOptions.process(app);
96 QStringList resources = cliOptions.positionalArguments(); 122 QStringList resources = cliOptions.positionalArguments();
@@ -122,10 +148,43 @@ int main(int argc, char *argv[])
122 } 148 }
123 query.syncOnDemand = false; 149 query.syncOnDemand = false;
124 query.processAll = false; 150 query.processAll = false;
151 query.requestedProperties << "name";
125 query.liveQuery = true; 152 query.liveQuery = true;
126 153
127 auto model = QSharedPointer<ListModelResult<Akonadi2::ApplicationDomain::Event::Ptr> >::create(Akonadi2::Store::load<Akonadi2::ApplicationDomain::Event>(query), QList<QByteArray>() << "summary" << "uid"); 154 QTime time;
128 auto view = QSharedPointer<View<Akonadi2::ApplicationDomain::Event> >::create(model.data()); 155 time.start();
129 156 auto model = Akonadi2::Store::loadModel<Akonadi2::ApplicationDomain::Folder>(query);
130 return app.exec(); 157 qDebug() << "Loaded model in " << time.elapsed() << " ms";
158
159 if (cliOptions.isSet("list")) {
160 query.liveQuery = false;
161 qDebug() << "Listing";
162 QObject::connect(model.data(), &QAbstractItemModel::rowsInserted, [model](const QModelIndex &index, int start, int end) {
163 for (int i = start; i <= end; i++) {
164 std::cout << "\tRow " << model->rowCount() << ": " << model->data(model->index(i, 0, index)).toString().toStdString() << std::endl;
165 }
166 });
167 QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [model, &app](const QModelIndex &, const QModelIndex &, const QVector<int> &roles) {
168 if (roles.contains(Akonadi2::Store::ChildrenFetchedRole)) {
169 app.quit();
170 }
171 });
172 if (!model->data(QModelIndex(), Akonadi2::Store::ChildrenFetchedRole).toBool()) {
173 return app.exec();
174 }
175 } else if (cliOptions.isSet("count")) {
176 query.liveQuery = false;
177 QObject::connect(model.data(), &QAbstractItemModel::dataChanged, [model, &app](const QModelIndex &, const QModelIndex &, const QVector<int> &roles) {
178 if (roles.contains(Akonadi2::Store::ChildrenFetchedRole)) {
179 std::cout << "\tCounted results " << model->rowCount(QModelIndex());
180 app.quit();
181 }
182 });
183 return app.exec();
184 } else {
185 query.liveQuery = true;
186 auto view = QSharedPointer<View<Akonadi2::ApplicationDomain::Folder> >::create(model.data());
187 return app.exec();
188 }
189 return 0;
131} 190}
diff --git a/examples/dummyresource/CMakeLists.txt b/examples/dummyresource/CMakeLists.txt
index e4b51dd..1e80f81 100644
--- a/examples/dummyresource/CMakeLists.txt
+++ b/examples/dummyresource/CMakeLists.txt
@@ -4,7 +4,7 @@ add_definitions(-DQT_PLUGIN)
4include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) 4include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
5 5
6 6
7add_library(${PROJECT_NAME} SHARED facade.cpp resourcefactory.cpp domainadaptor.cpp resourcefacade.cpp dummystore.cpp) 7add_library(${PROJECT_NAME} SHARED facade.cpp resourcefactory.cpp domainadaptor.cpp dummystore.cpp)
8generate_flatbuffers(${PROJECT_NAME} dummycalendar) 8generate_flatbuffers(${PROJECT_NAME} dummycalendar)
9qt5_use_modules(${PROJECT_NAME} Core Network) 9qt5_use_modules(${PROJECT_NAME} Core Network)
10target_link_libraries(${PROJECT_NAME} akonadi2common) 10target_link_libraries(${PROJECT_NAME} akonadi2common)
diff --git a/examples/dummyresource/domainadaptor.cpp b/examples/dummyresource/domainadaptor.cpp
index d08a783..74b170d 100644
--- a/examples/dummyresource/domainadaptor.cpp
+++ b/examples/dummyresource/domainadaptor.cpp
@@ -51,3 +51,9 @@ DummyMailAdaptorFactory::DummyMailAdaptorFactory()
51 51
52} 52}
53 53
54DummyFolderAdaptorFactory::DummyFolderAdaptorFactory()
55 : DomainTypeAdaptorFactory()
56{
57
58}
59
diff --git a/examples/dummyresource/domainadaptor.h b/examples/dummyresource/domainadaptor.h
index add3e8e..e5856f8 100644
--- a/examples/dummyresource/domainadaptor.h
+++ b/examples/dummyresource/domainadaptor.h
@@ -21,6 +21,8 @@
21#include "common/domainadaptor.h" 21#include "common/domainadaptor.h"
22#include "event_generated.h" 22#include "event_generated.h"
23#include "mail_generated.h" 23#include "mail_generated.h"
24#include "folder_generated.h"
25#include "dummy_generated.h"
24#include "dummycalendar_generated.h" 26#include "dummycalendar_generated.h"
25#include "entity_generated.h" 27#include "entity_generated.h"
26 28
@@ -31,10 +33,16 @@ public:
31 virtual ~DummyEventAdaptorFactory() {}; 33 virtual ~DummyEventAdaptorFactory() {};
32}; 34};
33 35
34//TODO replace the resource specific event class by a mail class or a dummy class if no resource type is required. 36class DummyMailAdaptorFactory : public DomainTypeAdaptorFactory<Akonadi2::ApplicationDomain::Mail, Akonadi2::ApplicationDomain::Buffer::Dummy, Akonadi2::ApplicationDomain::Buffer::DummyBuilder>
35class DummyMailAdaptorFactory : public DomainTypeAdaptorFactory<Akonadi2::ApplicationDomain::Mail, DummyCalendar::DummyEvent, DummyCalendar::DummyEventBuilder>
36{ 37{
37public: 38public:
38 DummyMailAdaptorFactory(); 39 DummyMailAdaptorFactory();
39 virtual ~DummyMailAdaptorFactory() {}; 40 virtual ~DummyMailAdaptorFactory() {};
40}; 41};
42
43class DummyFolderAdaptorFactory : public DomainTypeAdaptorFactory<Akonadi2::ApplicationDomain::Folder, Akonadi2::ApplicationDomain::Buffer::Dummy, Akonadi2::ApplicationDomain::Buffer::DummyBuilder>
44{
45public:
46 DummyFolderAdaptorFactory();
47 virtual ~DummyFolderAdaptorFactory() {};
48};
diff --git a/examples/dummyresource/dummystore.cpp b/examples/dummyresource/dummystore.cpp
index 0356ec0..458695f 100644
--- a/examples/dummyresource/dummystore.cpp
+++ b/examples/dummyresource/dummystore.cpp
@@ -36,6 +36,13 @@ static QMap<QString, QVariant> createMail(int i)
36 return mail; 36 return mail;
37} 37}
38 38
39static QMap<QString, QVariant> createFolder(int i)
40{
41 QMap<QString, QVariant> folder;
42 folder.insert("name", QString("folder%1").arg(i));
43 return folder;
44}
45
39QMap<QString, QMap<QString, QVariant> > populateEvents() 46QMap<QString, QMap<QString, QVariant> > populateEvents()
40{ 47{
41 QMap<QString, QMap<QString, QVariant>> content; 48 QMap<QString, QMap<QString, QVariant>> content;
@@ -54,8 +61,18 @@ QMap<QString, QMap<QString, QVariant> > populateMails()
54 return content; 61 return content;
55} 62}
56 63
64QMap<QString, QMap<QString, QVariant> > populateFolders()
65{
66 QMap<QString, QMap<QString, QVariant>> content;
67 for (int i = 0; i < 5; i++) {
68 content.insert(QString("key%1").arg(i), createFolder(i));
69 }
70 return content;
71}
72
57static QMap<QString, QMap<QString, QVariant> > s_eventSource = populateEvents(); 73static QMap<QString, QMap<QString, QVariant> > s_eventSource = populateEvents();
58static QMap<QString, QMap<QString, QVariant> > s_mailSource = populateMails(); 74static QMap<QString, QMap<QString, QVariant> > s_mailSource = populateMails();
75static QMap<QString, QMap<QString, QVariant> > s_folderSource = populateFolders();
59 76
60QMap<QString, QMap<QString, QVariant> > DummyStore::events() const 77QMap<QString, QMap<QString, QVariant> > DummyStore::events() const
61{ 78{
@@ -66,3 +83,8 @@ QMap<QString, QMap<QString, QVariant> > DummyStore::mails() const
66{ 83{
67 return s_mailSource; 84 return s_mailSource;
68} 85}
86
87QMap<QString, QMap<QString, QVariant> > DummyStore::folders() const
88{
89 return s_folderSource;
90}
diff --git a/examples/dummyresource/dummystore.h b/examples/dummyresource/dummystore.h
index 4ecd5ea..c730118 100644
--- a/examples/dummyresource/dummystore.h
+++ b/examples/dummyresource/dummystore.h
@@ -23,7 +23,6 @@
23class DummyStore 23class DummyStore
24{ 24{
25public: 25public:
26 //TODO proper singleton
27 static DummyStore &instance() 26 static DummyStore &instance()
28 { 27 {
29 static DummyStore instance; 28 static DummyStore instance;
@@ -32,4 +31,5 @@ public:
32 31
33 QMap<QString, QMap<QString, QVariant> > events() const; 32 QMap<QString, QMap<QString, QVariant> > events() const;
34 QMap<QString, QMap<QString, QVariant> > mails() const; 33 QMap<QString, QMap<QString, QVariant> > mails() const;
34 QMap<QString, QMap<QString, QVariant> > folders() const;
35}; 35};
diff --git a/examples/dummyresource/facade.cpp b/examples/dummyresource/facade.cpp
index 5a9d722..f337bdc 100644
--- a/examples/dummyresource/facade.cpp
+++ b/examples/dummyresource/facade.cpp
@@ -30,6 +30,7 @@ DummyResourceFacade::~DummyResourceFacade()
30{ 30{
31} 31}
32 32
33
33DummyResourceMailFacade::DummyResourceMailFacade(const QByteArray &instanceIdentifier) 34DummyResourceMailFacade::DummyResourceMailFacade(const QByteArray &instanceIdentifier)
34 : Akonadi2::GenericFacade<Akonadi2::ApplicationDomain::Mail>(instanceIdentifier, QSharedPointer<DummyMailAdaptorFactory>::create()) 35 : Akonadi2::GenericFacade<Akonadi2::ApplicationDomain::Mail>(instanceIdentifier, QSharedPointer<DummyMailAdaptorFactory>::create())
35{ 36{
@@ -39,25 +40,12 @@ DummyResourceMailFacade::~DummyResourceMailFacade()
39{ 40{
40} 41}
41 42
42static void addFolder(const QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Folder::Ptr> > &resultProvider, QByteArray uid, QString name, QString icon) 43
44DummyResourceFolderFacade::DummyResourceFolderFacade(const QByteArray &instanceIdentifier)
45 : Akonadi2::GenericFacade<Akonadi2::ApplicationDomain::Folder>(instanceIdentifier, QSharedPointer<DummyFolderAdaptorFactory>::create())
43{ 46{
44 auto folder = Akonadi2::ApplicationDomain::Folder::Ptr::create();
45 folder->setProperty("name", name);
46 folder->setProperty("uid", uid);
47 resultProvider->add(folder);
48} 47}
49 48
50KAsync::Job<void> load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Folder::Ptr> > &resultProvider) 49DummyResourceFolderFacade::~DummyResourceFolderFacade()
51{ 50{
52 //Dummy implementation for a fixed set of folders
53 addFolder(resultProvider, "inbox", "INBOX", "mail-folder-inbox");
54 addFolder(resultProvider, "sent", "Sent", "mail-folder-sent");
55 addFolder(resultProvider, "trash", "Trash", "user-trash");
56 addFolder(resultProvider, "drafts", "Drafts", "document-edit");
57 addFolder(resultProvider, "1", "dragons", "folder");
58 addFolder(resultProvider, "1", "super mega long tailed dragons", "folder");
59 resultProvider->initialResultSetComplete();
60 resultProvider->complete();
61 return KAsync::null<void>();
62} 51}
63
diff --git a/examples/dummyresource/facade.h b/examples/dummyresource/facade.h
index 948116b..b00e1d7 100644
--- a/examples/dummyresource/facade.h
+++ b/examples/dummyresource/facade.h
@@ -36,13 +36,9 @@ public:
36 virtual ~DummyResourceMailFacade(); 36 virtual ~DummyResourceMailFacade();
37}; 37};
38 38
39class DummyResourceFolderFacade : public Akonadi2::StoreFacade<Akonadi2::ApplicationDomain::Folder> 39class DummyResourceFolderFacade : public Akonadi2::GenericFacade<Akonadi2::ApplicationDomain::Folder>
40{ 40{
41public: 41public:
42 DummyResourceFolderFacade(const QByteArray &instanceIdentifier); 42 DummyResourceFolderFacade(const QByteArray &instanceIdentifier);
43 virtual ~DummyResourceFolderFacade(); 43 virtual ~DummyResourceFolderFacade();
44 virtual KAsync::Job<void> create(const Akonadi2::ApplicationDomain::Folder &domainObject) { return KAsync::null<void>(); };
45 virtual KAsync::Job<void> modify(const Akonadi2::ApplicationDomain::Folder &domainObject) { return KAsync::null<void>(); };
46 virtual KAsync::Job<void> remove(const Akonadi2::ApplicationDomain::Folder &domainObject) { return KAsync::null<void>(); };
47 virtual KAsync::Job<void> load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Folder::Ptr> > &resultProvider);
48}; 44};
diff --git a/examples/dummyresource/resourcefacade.cpp b/examples/dummyresource/resourcefacade.cpp
deleted file mode 100644
index df805e4..0000000
--- a/examples/dummyresource/resourcefacade.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
1/*
2 * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include "resourcefacade.h"
21
22#include <QSettings>
23#include <QStandardPaths>
24
25DummyResourceConfigFacade::DummyResourceConfigFacade()
26 : Akonadi2::StoreFacade<Akonadi2::ApplicationDomain::AkonadiResource>()
27{
28
29}
30
31DummyResourceConfigFacade::~DummyResourceConfigFacade()
32{
33
34}
35
36QSharedPointer<QSettings> DummyResourceConfigFacade::getSettings()
37{
38 //FIXME deal with resource instances
39 const QString instanceIdentifier = "dummyresource.instance1";
40 //FIXME Use config location
41 return QSharedPointer<QSettings>::create(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/akonadi2/" + "org.kde." + instanceIdentifier + "/settings.ini", QSettings::IniFormat);
42}
43
44KAsync::Job<void> DummyResourceConfigFacade::create(const Akonadi2::ApplicationDomain::AkonadiResource &domainObject)
45{
46 //TODO create resource instance
47 //This can be generalized in a base implementation
48 return KAsync::null<void>();
49}
50
51KAsync::Job<void> DummyResourceConfigFacade::modify(const Akonadi2::ApplicationDomain::AkonadiResource &domainObject)
52{
53 //modify configuration
54 //This part is likely resource specific, but could be partially generalized
55 return KAsync::start<void>([domainObject, this]() {
56 auto settings = getSettings();
57 //TODO Write properties to file
58 });
59}
60
61KAsync::Job<void> DummyResourceConfigFacade::remove(const Akonadi2::ApplicationDomain::AkonadiResource &domainObject)
62{
63 //TODO remove resource instance
64 //This can be generalized in a base implementation
65 return KAsync::null<void>();
66}
67
68KAsync::Job<void> DummyResourceConfigFacade::load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<typename Akonadi2::ApplicationDomain::AkonadiResource::Ptr> > &resultProvider)
69{
70 //Read configuration and list all available instances.
71 //This includes runtime information about runing instances etc.
72 //Part of this is generic, and part is accessing the resource specific configuration.
73 //FIXME this currently does not support live queries (because we're not inheriting from GenericFacade)
74 //FIXME only read what was requested in the query?
75 return KAsync::start<void>([resultProvider, this]() {
76 auto settings = getSettings();
77 auto memoryAdaptor = QSharedPointer<Akonadi2::ApplicationDomain::MemoryBufferAdaptor>::create();
78 //TODO copy settings to adaptor
79 //
80 //TODO use correct instance identifier
81 //TODO key == instance identifier ?
82 resultProvider->add(QSharedPointer<Akonadi2::ApplicationDomain::AkonadiResource>::create("org.kde.dummy.instance1", "org.kde.dummy.config", 0, memoryAdaptor));
83 });
84}
diff --git a/examples/dummyresource/resourcefacade.h b/examples/dummyresource/resourcefacade.h
deleted file mode 100644
index 5a5f46b..0000000
--- a/examples/dummyresource/resourcefacade.h
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#pragma once
21
22#include <Async/Async>
23#include <common/domain/applicationdomaintype.h>
24#include <common/resultprovider.h>
25#include <common/facadeinterface.h>
26
27namespace Akonadi2 {
28 class Query;
29}
30
31class QSettings;
32
33class DummyResourceConfigFacade : public Akonadi2::StoreFacade<Akonadi2::ApplicationDomain::AkonadiResource>
34{
35public:
36 DummyResourceConfigFacade();
37 ~DummyResourceConfigFacade();
38 //Create an instance
39 KAsync::Job<void> create(const Akonadi2::ApplicationDomain::AkonadiResource &domainObject) Q_DECL_OVERRIDE;
40 //Modify configuration
41 KAsync::Job<void> modify(const Akonadi2::ApplicationDomain::AkonadiResource &domainObject) Q_DECL_OVERRIDE;
42 //Remove instance
43 KAsync::Job<void> remove(const Akonadi2::ApplicationDomain::AkonadiResource &domainObject) Q_DECL_OVERRIDE;
44 //Read configuration and available instances
45 KAsync::Job<void> load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<typename Akonadi2::ApplicationDomain::AkonadiResource::Ptr> > &resultProvider) Q_DECL_OVERRIDE;
46
47private:
48 QSharedPointer<QSettings> getSettings();
49};
diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp
index 397ca5f..e524c3f 100644
--- a/examples/dummyresource/resourcefactory.cpp
+++ b/examples/dummyresource/resourcefactory.cpp
@@ -40,6 +40,7 @@
40//This is the resources entity type, and not the domain type 40//This is the resources entity type, and not the domain type
41#define ENTITY_TYPE_EVENT "event" 41#define ENTITY_TYPE_EVENT "event"
42#define ENTITY_TYPE_MAIL "mail" 42#define ENTITY_TYPE_MAIL "mail"
43#define ENTITY_TYPE_FOLDER "folder"
43 44
44/** 45/**
45 * Index types: 46 * Index types:
@@ -51,7 +52,6 @@
51 * * range indexes like what date range an event affects. 52 * * range indexes like what date range an event affects.
52 * * group indexes like tree hierarchies as nested sets 53 * * group indexes like tree hierarchies as nested sets
53 */ 54 */
54template<typename DomainType>
55class IndexUpdater : public Akonadi2::Preprocessor { 55class IndexUpdater : public Akonadi2::Preprocessor {
56public: 56public:
57 IndexUpdater(const QByteArray &index, const QByteArray &type) 57 IndexUpdater(const QByteArray &index, const QByteArray &type)
@@ -63,21 +63,17 @@ public:
63 63
64 void newEntity(const QByteArray &uid, qint64 revision, const Akonadi2::ApplicationDomain::BufferAdaptor &newEntity, Akonadi2::Storage::Transaction &transaction) Q_DECL_OVERRIDE 64 void newEntity(const QByteArray &uid, qint64 revision, const Akonadi2::ApplicationDomain::BufferAdaptor &newEntity, Akonadi2::Storage::Transaction &transaction) Q_DECL_OVERRIDE
65 { 65 {
66 Akonadi2::ApplicationDomain::TypeImplementation<DomainType>::index(uid, newEntity, transaction);
67 add(newEntity.getProperty("remoteId"), uid, transaction); 66 add(newEntity.getProperty("remoteId"), uid, transaction);
68 } 67 }
69 68
70 void modifiedEntity(const QByteArray &uid, qint64 revision, const Akonadi2::ApplicationDomain::BufferAdaptor &oldEntity, const Akonadi2::ApplicationDomain::BufferAdaptor &newEntity, Akonadi2::Storage::Transaction &transaction) Q_DECL_OVERRIDE 69 void modifiedEntity(const QByteArray &uid, qint64 revision, const Akonadi2::ApplicationDomain::BufferAdaptor &oldEntity, const Akonadi2::ApplicationDomain::BufferAdaptor &newEntity, Akonadi2::Storage::Transaction &transaction) Q_DECL_OVERRIDE
71 { 70 {
72 Akonadi2::ApplicationDomain::TypeImplementation<DomainType>::removeIndex(uid, oldEntity, transaction);
73 Akonadi2::ApplicationDomain::TypeImplementation<DomainType>::index(uid, newEntity, transaction);
74 remove(oldEntity.getProperty("remoteId"), uid, transaction); 71 remove(oldEntity.getProperty("remoteId"), uid, transaction);
75 add(newEntity.getProperty("remoteId"), uid, transaction); 72 add(newEntity.getProperty("remoteId"), uid, transaction);
76 } 73 }
77 74
78 void deletedEntity(const QByteArray &uid, qint64 revision, const Akonadi2::ApplicationDomain::BufferAdaptor &oldEntity, Akonadi2::Storage::Transaction &transaction) Q_DECL_OVERRIDE 75 void deletedEntity(const QByteArray &uid, qint64 revision, const Akonadi2::ApplicationDomain::BufferAdaptor &oldEntity, Akonadi2::Storage::Transaction &transaction) Q_DECL_OVERRIDE
79 { 76 {
80 Akonadi2::ApplicationDomain::TypeImplementation<DomainType>::removeIndex(uid, oldEntity, transaction);
81 remove(oldEntity.getProperty("remoteId"), uid, transaction); 77 remove(oldEntity.getProperty("remoteId"), uid, transaction);
82 } 78 }
83 79
@@ -91,6 +87,7 @@ private:
91 87
92 void remove(const QVariant &value, const QByteArray &uid, Akonadi2::Storage::Transaction &transaction) 88 void remove(const QVariant &value, const QByteArray &uid, Akonadi2::Storage::Transaction &transaction)
93 { 89 {
90 //TODO hide notfound error
94 Index(mIndexIdentifier, transaction).remove(value.toByteArray(), uid); 91 Index(mIndexIdentifier, transaction).remove(value.toByteArray(), uid);
95 } 92 }
96 93
@@ -98,20 +95,49 @@ private:
98 QByteArray mBufferType; 95 QByteArray mBufferType;
99}; 96};
100 97
98template<typename DomainType>
99class DefaultIndexUpdater : public Akonadi2::Preprocessor {
100public:
101 void newEntity(const QByteArray &uid, qint64 revision, const Akonadi2::ApplicationDomain::BufferAdaptor &newEntity, Akonadi2::Storage::Transaction &transaction) Q_DECL_OVERRIDE
102 {
103 Akonadi2::ApplicationDomain::TypeImplementation<DomainType>::index(uid, newEntity, transaction);
104 }
105
106 void modifiedEntity(const QByteArray &uid, qint64 revision, const Akonadi2::ApplicationDomain::BufferAdaptor &oldEntity, const Akonadi2::ApplicationDomain::BufferAdaptor &newEntity, Akonadi2::Storage::Transaction &transaction) Q_DECL_OVERRIDE
107 {
108 Akonadi2::ApplicationDomain::TypeImplementation<DomainType>::removeIndex(uid, oldEntity, transaction);
109 Akonadi2::ApplicationDomain::TypeImplementation<DomainType>::index(uid, newEntity, transaction);
110 }
111
112 void deletedEntity(const QByteArray &uid, qint64 revision, const Akonadi2::ApplicationDomain::BufferAdaptor &oldEntity, Akonadi2::Storage::Transaction &transaction) Q_DECL_OVERRIDE
113 {
114 Akonadi2::ApplicationDomain::TypeImplementation<DomainType>::removeIndex(uid, oldEntity, transaction);
115 }
116};
117
101DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QSharedPointer<Akonadi2::Pipeline> &pipeline) 118DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QSharedPointer<Akonadi2::Pipeline> &pipeline)
102 : Akonadi2::GenericResource(instanceIdentifier, pipeline) 119 : Akonadi2::GenericResource(instanceIdentifier, pipeline)
103{ 120{
104 { 121 {
105 auto eventFactory = QSharedPointer<DummyEventAdaptorFactory>::create(); 122 QVector<Akonadi2::Preprocessor*> eventPreprocessors;
106 auto eventIndexer = new IndexUpdater<Akonadi2::ApplicationDomain::Event>("event.index.rid", ENTITY_TYPE_EVENT); 123 eventPreprocessors << new DefaultIndexUpdater<Akonadi2::ApplicationDomain::Event>;
107 mPipeline->setPreprocessors(ENTITY_TYPE_EVENT, QVector<Akonadi2::Preprocessor*>() << eventIndexer); 124 eventPreprocessors << new IndexUpdater("event.index.rid", ENTITY_TYPE_EVENT);
108 mPipeline->setAdaptorFactory(ENTITY_TYPE_EVENT, eventFactory); 125 mPipeline->setPreprocessors(ENTITY_TYPE_EVENT, eventPreprocessors);
126 mPipeline->setAdaptorFactory(ENTITY_TYPE_EVENT, QSharedPointer<DummyEventAdaptorFactory>::create());
127 }
128 {
129 QVector<Akonadi2::Preprocessor*> mailPreprocessors;
130 mailPreprocessors << new DefaultIndexUpdater<Akonadi2::ApplicationDomain::Mail>;
131 mailPreprocessors << new IndexUpdater("mail.index.rid", ENTITY_TYPE_MAIL);
132 mPipeline->setPreprocessors(ENTITY_TYPE_MAIL, mailPreprocessors);
133 mPipeline->setAdaptorFactory(ENTITY_TYPE_MAIL, QSharedPointer<DummyMailAdaptorFactory>::create());
109 } 134 }
110 { 135 {
111 auto mailFactory = QSharedPointer<DummyMailAdaptorFactory>::create(); 136 QVector<Akonadi2::Preprocessor*> folderPreprocessors;
112 auto mailIndexer = new IndexUpdater<Akonadi2::ApplicationDomain::Mail>("mail.index.rid", ENTITY_TYPE_MAIL); 137 folderPreprocessors << new DefaultIndexUpdater<Akonadi2::ApplicationDomain::Folder>;
113 mPipeline->setPreprocessors(ENTITY_TYPE_MAIL, QVector<Akonadi2::Preprocessor*>() << mailIndexer); 138 folderPreprocessors << new IndexUpdater("folder.index.rid", ENTITY_TYPE_FOLDER);
114 mPipeline->setAdaptorFactory(ENTITY_TYPE_MAIL, mailFactory); 139 mPipeline->setPreprocessors(ENTITY_TYPE_FOLDER, folderPreprocessors);
140 mPipeline->setAdaptorFactory(ENTITY_TYPE_FOLDER, QSharedPointer<DummyFolderAdaptorFactory>::create());
115 } 141 }
116} 142}
117 143
@@ -156,6 +182,27 @@ void DummyResource::createMail(const QByteArray &ridBuffer, const QMap<QString,
156 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); 182 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize());
157} 183}
158 184
185void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb)
186{
187 //Map the source format to the buffer format (which happens to be an exact copy here)
188 auto name = m_fbb.CreateString(data.value("name").toString().toStdString());
189 flatbuffers::Offset<flatbuffers::String> parent;
190 bool hasParent = false;
191 if (!data.value("parent").toString().isEmpty()) {
192 hasParent = true;
193 parent = m_fbb.CreateString(data.value("parent").toString().toStdString());
194 }
195
196 auto builder = Akonadi2::ApplicationDomain::Buffer::FolderBuilder(m_fbb);
197 builder.add_name(name);
198 if (hasParent) {
199 builder.add_parent(parent);
200 }
201 auto buffer = builder.Finish();
202 Akonadi2::ApplicationDomain::Buffer::FinishFolderBuffer(m_fbb, buffer);
203 Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize());
204}
205
159void DummyResource::synchronize(const QString &bufferType, const QMap<QString, QMap<QString, QVariant> > &data, Akonadi2::Storage::Transaction &transaction, std::function<void(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb)> createEntity) 206void DummyResource::synchronize(const QString &bufferType, const QMap<QString, QMap<QString, QVariant> > &data, Akonadi2::Storage::Transaction &transaction, std::function<void(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb)> createEntity)
160{ 207{
161 Index uidIndex("index.uid", transaction); 208 Index uidIndex("index.uid", transaction);
@@ -202,6 +249,9 @@ KAsync::Job<void> DummyResource::synchronizeWithSource()
202 synchronize(ENTITY_TYPE_MAIL, DummyStore::instance().mails(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) { 249 synchronize(ENTITY_TYPE_MAIL, DummyStore::instance().mails(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) {
203 createMail(ridBuffer, data, entityFbb); 250 createMail(ridBuffer, data, entityFbb);
204 }); 251 });
252 synchronize(ENTITY_TYPE_FOLDER, DummyStore::instance().folders(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) {
253 createFolder(ridBuffer, data, entityFbb);
254 });
205 255
206 f.setFinished(); 256 f.setFinished();
207 }); 257 });
@@ -228,5 +278,6 @@ void DummyResourceFactory::registerFacades(Akonadi2::FacadeFactory &factory)
228{ 278{
229 factory.registerFacade<Akonadi2::ApplicationDomain::Event, DummyResourceFacade>(PLUGIN_NAME); 279 factory.registerFacade<Akonadi2::ApplicationDomain::Event, DummyResourceFacade>(PLUGIN_NAME);
230 factory.registerFacade<Akonadi2::ApplicationDomain::Mail, DummyResourceMailFacade>(PLUGIN_NAME); 280 factory.registerFacade<Akonadi2::ApplicationDomain::Mail, DummyResourceMailFacade>(PLUGIN_NAME);
281 factory.registerFacade<Akonadi2::ApplicationDomain::Folder, DummyResourceFolderFacade>(PLUGIN_NAME);
231} 282}
232 283
diff --git a/examples/dummyresource/resourcefactory.h b/examples/dummyresource/resourcefactory.h
index 196d29a..67681ae 100644
--- a/examples/dummyresource/resourcefactory.h
+++ b/examples/dummyresource/resourcefactory.h
@@ -38,6 +38,7 @@ public:
38private: 38private:
39 void createEvent(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb); 39 void createEvent(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb);
40 void createMail(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb); 40 void createMail(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb);
41 void createFolder(const QByteArray &rid, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb);
41 void synchronize(const QString &bufferType, const QMap<QString, QMap<QString, QVariant> > &data, Akonadi2::Storage::Transaction &transaction, std::function<void(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb)> createEntity); 42 void synchronize(const QString &bufferType, const QMap<QString, QMap<QString, QVariant> > &data, Akonadi2::Storage::Transaction &transaction, std::function<void(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb)> createEntity);
42}; 43};
43 44