diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/client/main.cpp | 87 | ||||
-rw-r--r-- | examples/dummyresource/CMakeLists.txt | 2 | ||||
-rw-r--r-- | examples/dummyresource/domainadaptor.cpp | 6 | ||||
-rw-r--r-- | examples/dummyresource/domainadaptor.h | 12 | ||||
-rw-r--r-- | examples/dummyresource/dummystore.cpp | 22 | ||||
-rw-r--r-- | examples/dummyresource/dummystore.h | 2 | ||||
-rw-r--r-- | examples/dummyresource/facade.cpp | 22 | ||||
-rw-r--r-- | examples/dummyresource/facade.h | 6 | ||||
-rw-r--r-- | examples/dummyresource/resourcefacade.cpp | 84 | ||||
-rw-r--r-- | examples/dummyresource/resourcefacade.h | 49 | ||||
-rw-r--r-- | examples/dummyresource/resourcefactory.cpp | 77 | ||||
-rw-r--r-- | examples/dummyresource/resourcefactory.h | 1 |
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 | ||
39 | template <typename T> | 42 | template <typename T> |
40 | class View : public QWidget | 43 | class 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 | |||
90 | class MyApplication : public QApplication | ||
91 | { | ||
92 | QElapsedTimer t; | ||
93 | public: | ||
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 | |||
85 | int main(int argc, char *argv[]) | 109 | int 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) | |||
4 | include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) | 4 | include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) |
5 | 5 | ||
6 | 6 | ||
7 | add_library(${PROJECT_NAME} SHARED facade.cpp resourcefactory.cpp domainadaptor.cpp resourcefacade.cpp dummystore.cpp) | 7 | add_library(${PROJECT_NAME} SHARED facade.cpp resourcefactory.cpp domainadaptor.cpp dummystore.cpp) |
8 | generate_flatbuffers(${PROJECT_NAME} dummycalendar) | 8 | generate_flatbuffers(${PROJECT_NAME} dummycalendar) |
9 | qt5_use_modules(${PROJECT_NAME} Core Network) | 9 | qt5_use_modules(${PROJECT_NAME} Core Network) |
10 | target_link_libraries(${PROJECT_NAME} akonadi2common) | 10 | target_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 | ||
54 | DummyFolderAdaptorFactory::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. | 36 | class DummyMailAdaptorFactory : public DomainTypeAdaptorFactory<Akonadi2::ApplicationDomain::Mail, Akonadi2::ApplicationDomain::Buffer::Dummy, Akonadi2::ApplicationDomain::Buffer::DummyBuilder> |
35 | class DummyMailAdaptorFactory : public DomainTypeAdaptorFactory<Akonadi2::ApplicationDomain::Mail, DummyCalendar::DummyEvent, DummyCalendar::DummyEventBuilder> | ||
36 | { | 37 | { |
37 | public: | 38 | public: |
38 | DummyMailAdaptorFactory(); | 39 | DummyMailAdaptorFactory(); |
39 | virtual ~DummyMailAdaptorFactory() {}; | 40 | virtual ~DummyMailAdaptorFactory() {}; |
40 | }; | 41 | }; |
42 | |||
43 | class DummyFolderAdaptorFactory : public DomainTypeAdaptorFactory<Akonadi2::ApplicationDomain::Folder, Akonadi2::ApplicationDomain::Buffer::Dummy, Akonadi2::ApplicationDomain::Buffer::DummyBuilder> | ||
44 | { | ||
45 | public: | ||
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 | ||
39 | static 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 | |||
39 | QMap<QString, QMap<QString, QVariant> > populateEvents() | 46 | QMap<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 | ||
64 | QMap<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 | |||
57 | static QMap<QString, QMap<QString, QVariant> > s_eventSource = populateEvents(); | 73 | static QMap<QString, QMap<QString, QVariant> > s_eventSource = populateEvents(); |
58 | static QMap<QString, QMap<QString, QVariant> > s_mailSource = populateMails(); | 74 | static QMap<QString, QMap<QString, QVariant> > s_mailSource = populateMails(); |
75 | static QMap<QString, QMap<QString, QVariant> > s_folderSource = populateFolders(); | ||
59 | 76 | ||
60 | QMap<QString, QMap<QString, QVariant> > DummyStore::events() const | 77 | QMap<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 | |||
87 | QMap<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 @@ | |||
23 | class DummyStore | 23 | class DummyStore |
24 | { | 24 | { |
25 | public: | 25 | public: |
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 | |||
33 | DummyResourceMailFacade::DummyResourceMailFacade(const QByteArray &instanceIdentifier) | 34 | DummyResourceMailFacade::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 | ||
42 | static void addFolder(const QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Folder::Ptr> > &resultProvider, QByteArray uid, QString name, QString icon) | 43 | |
44 | DummyResourceFolderFacade::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 | ||
50 | KAsync::Job<void> load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<Akonadi2::ApplicationDomain::Folder::Ptr> > &resultProvider) | 49 | DummyResourceFolderFacade::~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 | ||
39 | class DummyResourceFolderFacade : public Akonadi2::StoreFacade<Akonadi2::ApplicationDomain::Folder> | 39 | class DummyResourceFolderFacade : public Akonadi2::GenericFacade<Akonadi2::ApplicationDomain::Folder> |
40 | { | 40 | { |
41 | public: | 41 | public: |
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 | |||
25 | DummyResourceConfigFacade::DummyResourceConfigFacade() | ||
26 | : Akonadi2::StoreFacade<Akonadi2::ApplicationDomain::AkonadiResource>() | ||
27 | { | ||
28 | |||
29 | } | ||
30 | |||
31 | DummyResourceConfigFacade::~DummyResourceConfigFacade() | ||
32 | { | ||
33 | |||
34 | } | ||
35 | |||
36 | QSharedPointer<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 | |||
44 | KAsync::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 | |||
51 | KAsync::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 | |||
61 | KAsync::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 | |||
68 | KAsync::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 | |||
27 | namespace Akonadi2 { | ||
28 | class Query; | ||
29 | } | ||
30 | |||
31 | class QSettings; | ||
32 | |||
33 | class DummyResourceConfigFacade : public Akonadi2::StoreFacade<Akonadi2::ApplicationDomain::AkonadiResource> | ||
34 | { | ||
35 | public: | ||
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 | |||
47 | private: | ||
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 | */ |
54 | template<typename DomainType> | ||
55 | class IndexUpdater : public Akonadi2::Preprocessor { | 55 | class IndexUpdater : public Akonadi2::Preprocessor { |
56 | public: | 56 | public: |
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 | ||
98 | template<typename DomainType> | ||
99 | class DefaultIndexUpdater : public Akonadi2::Preprocessor { | ||
100 | public: | ||
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 | |||
101 | DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QSharedPointer<Akonadi2::Pipeline> &pipeline) | 118 | DummyResource::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 | ||
185 | void 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 | |||
159 | void 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) | 206 | void 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: | |||
38 | private: | 38 | private: |
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 | ||