diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | framework/CMakeLists.txt | 1 | ||||
-rw-r--r-- | framework/actions/CMakeLists.txt | 1 | ||||
-rw-r--r-- | framework/actions/action.cpp | 4 | ||||
-rw-r--r-- | framework/actions/action.h | 3 | ||||
-rw-r--r-- | framework/actions/actionbroker.cpp | 9 | ||||
-rw-r--r-- | framework/actions/actionbroker.h | 3 | ||||
-rw-r--r-- | framework/actions/actionhandler.cpp | 37 | ||||
-rw-r--r-- | framework/actions/actionhandler.h | 14 | ||||
-rw-r--r-- | framework/actions/actionresult.cpp | 20 | ||||
-rw-r--r-- | framework/actions/actionresult.h | 66 | ||||
-rw-r--r-- | framework/domain/CMakeLists.txt | 4 | ||||
-rw-r--r-- | framework/domain/actions/sinkactions.cpp | 101 | ||||
-rw-r--r-- | framework/domain/actions/tests/CMakeLists.txt | 6 | ||||
-rw-r--r-- | framework/domain/actions/tests/sinkactiontest.cpp | 60 | ||||
-rw-r--r-- | framework/domain/composercontroller.cpp | 5 | ||||
-rw-r--r-- | framework/domain/maillistmodel.cpp | 2 |
17 files changed, 271 insertions, 66 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index bb3d0941..a3784ad6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -1,6 +1,7 @@ | |||
1 | project(kube) | 1 | project(kube) |
2 | 2 | ||
3 | cmake_minimum_required(VERSION 2.8.12) | 3 | cmake_minimum_required(VERSION 2.8.12) |
4 | enable_testing() | ||
4 | 5 | ||
5 | add_subdirectory(framework) | 6 | add_subdirectory(framework) |
6 | add_subdirectory(components) | 7 | add_subdirectory(components) |
diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index c216d3c0..4fecaf14 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt | |||
@@ -27,6 +27,7 @@ find_package(KF5Codecs CONFIG REQUIRED) | |||
27 | set(CMAKE_AUTOMOC ON) | 27 | set(CMAKE_AUTOMOC ON) |
28 | add_definitions("-Wall -std=c++0x -g") | 28 | add_definitions("-Wall -std=c++0x -g") |
29 | include_directories(.) | 29 | include_directories(.) |
30 | include_directories(SYSTEM ${KDE_INSTALL_FULL_INCLUDEDIR}/KF5/) | ||
30 | include_directories(SYSTEM ${KDE_INSTALL_FULL_INCLUDEDIR}/KF5/KMime) | 31 | include_directories(SYSTEM ${KDE_INSTALL_FULL_INCLUDEDIR}/KF5/KMime) |
31 | include_directories(SYSTEM ${KDE_INSTALL_FULL_INCLUDEDIR}/KF5/KIconThemes) | 32 | include_directories(SYSTEM ${KDE_INSTALL_FULL_INCLUDEDIR}/KF5/KIconThemes) |
32 | 33 | ||
diff --git a/framework/actions/CMakeLists.txt b/framework/actions/CMakeLists.txt index a09445b0..d757f654 100644 --- a/framework/actions/CMakeLists.txt +++ b/framework/actions/CMakeLists.txt | |||
@@ -3,6 +3,7 @@ set(SRCS | |||
3 | action.cpp | 3 | action.cpp |
4 | actionhandler.cpp | 4 | actionhandler.cpp |
5 | actionbroker.cpp | 5 | actionbroker.cpp |
6 | actionresult.cpp | ||
6 | context.cpp | 7 | context.cpp |
7 | ) | 8 | ) |
8 | 9 | ||
diff --git a/framework/actions/action.cpp b/framework/actions/action.cpp index e6ba2daf..28dd5e2a 100644 --- a/framework/actions/action.cpp +++ b/framework/actions/action.cpp | |||
@@ -85,8 +85,8 @@ bool Action::ready() const | |||
85 | return ActionBroker::instance().isActionReady(mActionId, mContext); | 85 | return ActionBroker::instance().isActionReady(mActionId, mContext); |
86 | } | 86 | } |
87 | 87 | ||
88 | void Action::execute() | 88 | ActionResult Action::execute() |
89 | { | 89 | { |
90 | ActionBroker::instance().executeAction(mActionId, mContext); | 90 | return ActionBroker::instance().executeAction(mActionId, mContext); |
91 | } | 91 | } |
92 | 92 | ||
diff --git a/framework/actions/action.h b/framework/actions/action.h index b820955e..1ad4a47e 100644 --- a/framework/actions/action.h +++ b/framework/actions/action.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <QObject> | 21 | #include <QObject> |
22 | #include "context.h" | 22 | #include "context.h" |
23 | #include "actionresult.h" | ||
23 | 24 | ||
24 | namespace Kube { | 25 | namespace Kube { |
25 | 26 | ||
@@ -43,7 +44,7 @@ public: | |||
43 | 44 | ||
44 | bool ready() const; | 45 | bool ready() const; |
45 | 46 | ||
46 | Q_INVOKABLE void execute(); | 47 | Q_INVOKABLE ActionResult execute(); |
47 | 48 | ||
48 | Q_SIGNALS: | 49 | Q_SIGNALS: |
49 | void readyChanged(); | 50 | void readyChanged(); |
diff --git a/framework/actions/actionbroker.cpp b/framework/actions/actionbroker.cpp index 43a535a1..890a5566 100644 --- a/framework/actions/actionbroker.cpp +++ b/framework/actions/actionbroker.cpp | |||
@@ -54,17 +54,22 @@ bool ActionBroker::isActionReady(const QByteArray &actionId, Context *context) | |||
54 | return false; | 54 | return false; |
55 | } | 55 | } |
56 | 56 | ||
57 | void ActionBroker::executeAction(const QByteArray &actionId, Context *context) | 57 | ActionResult ActionBroker::executeAction(const QByteArray &actionId, Context *context) |
58 | { | 58 | { |
59 | if (context) { | 59 | if (context) { |
60 | for (const auto handler : mHandler.values(actionId)) { | 60 | for (const auto handler : mHandler.values(actionId)) { |
61 | if (handler) { | 61 | if (handler) { |
62 | handler->execute(context); | 62 | //FIXME All handler together return one result |
63 | return handler->execute(context); | ||
63 | } | 64 | } |
64 | } | 65 | } |
65 | } else { | 66 | } else { |
66 | qWarning() << "Can't execute without context"; | 67 | qWarning() << "Can't execute without context"; |
67 | } | 68 | } |
69 | ActionResult result; | ||
70 | result.setDone(); | ||
71 | result.setError(1); | ||
72 | return result; | ||
68 | } | 73 | } |
69 | 74 | ||
70 | void ActionBroker::registerHandler(const QByteArray &actionId, ActionHandler *handler) | 75 | void ActionBroker::registerHandler(const QByteArray &actionId, ActionHandler *handler) |
diff --git a/framework/actions/actionbroker.h b/framework/actions/actionbroker.h index 08eac742..8f3eaeb2 100644 --- a/framework/actions/actionbroker.h +++ b/framework/actions/actionbroker.h | |||
@@ -24,6 +24,7 @@ | |||
24 | namespace Kube { | 24 | namespace Kube { |
25 | class Context; | 25 | class Context; |
26 | class ActionHandler; | 26 | class ActionHandler; |
27 | class ActionResult; | ||
27 | 28 | ||
28 | class ActionBroker : public QObject | 29 | class ActionBroker : public QObject |
29 | { | 30 | { |
@@ -32,7 +33,7 @@ public: | |||
32 | static ActionBroker &instance(); | 33 | static ActionBroker &instance(); |
33 | 34 | ||
34 | bool isActionReady(const QByteArray &actionId, Context *context); | 35 | bool isActionReady(const QByteArray &actionId, Context *context); |
35 | void executeAction(const QByteArray &actionId, Context *context); | 36 | ActionResult executeAction(const QByteArray &actionId, Context *context); |
36 | 37 | ||
37 | void registerHandler(const QByteArray &actionId, ActionHandler *handler); | 38 | void registerHandler(const QByteArray &actionId, ActionHandler *handler); |
38 | 39 | ||
diff --git a/framework/actions/actionhandler.cpp b/framework/actions/actionhandler.cpp index d4b01734..4ae8d0a9 100644 --- a/framework/actions/actionhandler.cpp +++ b/framework/actions/actionhandler.cpp | |||
@@ -45,17 +45,24 @@ bool ActionHandler::isActionReady(Context *context) | |||
45 | return false; | 45 | return false; |
46 | } | 46 | } |
47 | 47 | ||
48 | void ActionHandler::execute(Context *context) | 48 | ActionResult ActionHandler::execute(Context *context) |
49 | { | 49 | { |
50 | ActionResult result; | ||
50 | QVariant returnedValue; | 51 | QVariant returnedValue; |
51 | qWarning() << "Executing the handler"; | 52 | qWarning() << "Executing the handler"; |
52 | if (context) { | 53 | if (context) { |
54 | //The base implementation to call the handler in QML | ||
53 | QMetaObject::invokeMethod(this, "handler", | 55 | QMetaObject::invokeMethod(this, "handler", |
54 | Q_RETURN_ARG(QVariant, returnedValue), | 56 | Q_RETURN_ARG(QVariant, returnedValue), |
55 | Q_ARG(QVariant, QVariant::fromValue(context))); | 57 | Q_ARG(QVariant, QVariant::fromValue(context))); |
58 | //TODO: support async handlers in QML | ||
59 | result.setDone(); | ||
56 | } else { | 60 | } else { |
57 | qWarning() << "The handler didn't get a context"; | 61 | qWarning() << "The handler didn't get a context"; |
62 | result.setDone(); | ||
63 | result.setError(1); | ||
58 | } | 64 | } |
65 | return result; | ||
59 | } | 66 | } |
60 | 67 | ||
61 | void ActionHandler::setActionId(const QByteArray &actionId) | 68 | void ActionHandler::setActionId(const QByteArray &actionId) |
@@ -79,12 +86,36 @@ ActionHandlerHelper::ActionHandlerHelper(const QByteArray &actionId, const IsRea | |||
79 | setActionId(actionId); | 86 | setActionId(actionId); |
80 | } | 87 | } |
81 | 88 | ||
89 | ActionHandlerHelper::ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &isReady, const JobHandler &handler) | ||
90 | : ActionHandler(nullptr), | ||
91 | isReadyFunction(isReady), | ||
92 | jobHandlerFunction(handler) | ||
93 | { | ||
94 | setActionId(actionId); | ||
95 | } | ||
96 | |||
82 | bool ActionHandlerHelper::isActionReady(Context *context) | 97 | bool ActionHandlerHelper::isActionReady(Context *context) |
83 | { | 98 | { |
84 | return isReadyFunction(context); | 99 | return isReadyFunction(context); |
85 | } | 100 | } |
86 | 101 | ||
87 | void ActionHandlerHelper::execute(Context *context) | 102 | ActionResult ActionHandlerHelper::execute(Context *context) |
88 | { | 103 | { |
89 | handlerFunction(context); | 104 | ActionResult result; |
105 | if (handlerFunction) { | ||
106 | handlerFunction(context); | ||
107 | result.setDone(); | ||
108 | } else { | ||
109 | jobHandlerFunction(context).then<void>([=]() { | ||
110 | auto modifyableResult = result; | ||
111 | modifyableResult.setDone(); | ||
112 | }, | ||
113 | [=](int errorCode, const QString &string) { | ||
114 | qWarning() << "Job failed: " << errorCode << string; | ||
115 | auto modifyableResult = result; | ||
116 | modifyableResult.setError(1); | ||
117 | modifyableResult.setDone(); | ||
118 | }).exec(); | ||
119 | } | ||
120 | return result; | ||
90 | } | 121 | } |
diff --git a/framework/actions/actionhandler.h b/framework/actions/actionhandler.h index 1820bfd4..c8c10dc7 100644 --- a/framework/actions/actionhandler.h +++ b/framework/actions/actionhandler.h | |||
@@ -21,6 +21,9 @@ | |||
21 | #include <QObject> | 21 | #include <QObject> |
22 | #include <QMultiMap> | 22 | #include <QMultiMap> |
23 | #include <functional> | 23 | #include <functional> |
24 | #include <Async/Async> | ||
25 | |||
26 | #include "actionresult.h" | ||
24 | 27 | ||
25 | namespace Kube { | 28 | namespace Kube { |
26 | class Context; | 29 | class Context; |
@@ -36,7 +39,7 @@ public: | |||
36 | virtual bool isActionReady(Context *context); | 39 | virtual bool isActionReady(Context *context); |
37 | 40 | ||
38 | // void pre(Context *context); | 41 | // void pre(Context *context); |
39 | virtual void execute(Context *context); | 42 | virtual ActionResult execute(Context *context); |
40 | // void post(Context *context); | 43 | // void post(Context *context); |
41 | 44 | ||
42 | void setActionId(const QByteArray &); | 45 | void setActionId(const QByteArray &); |
@@ -52,14 +55,17 @@ class ActionHandlerHelper : public ActionHandler | |||
52 | public: | 55 | public: |
53 | typedef std::function<bool(Context*)> IsReadyFunction; | 56 | typedef std::function<bool(Context*)> IsReadyFunction; |
54 | typedef std::function<void(Context*)> Handler; | 57 | typedef std::function<void(Context*)> Handler; |
58 | typedef std::function<KAsync::Job<void>(Context*)> JobHandler; | ||
55 | 59 | ||
56 | ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &, const Handler &); | 60 | ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &, const Handler &); |
61 | ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &, const JobHandler &); | ||
57 | 62 | ||
58 | bool isActionReady(Context *context) Q_DECL_OVERRIDE; | 63 | bool isActionReady(Context *context) Q_DECL_OVERRIDE; |
59 | void execute(Context *context) Q_DECL_OVERRIDE; | 64 | ActionResult execute(Context *context) Q_DECL_OVERRIDE; |
60 | private: | 65 | private: |
61 | const std::function<bool(Context*)> isReadyFunction; | 66 | const IsReadyFunction isReadyFunction; |
62 | const std::function<void(Context*)> handlerFunction; | 67 | const Handler handlerFunction; |
68 | const JobHandler jobHandlerFunction; | ||
63 | }; | 69 | }; |
64 | 70 | ||
65 | } | 71 | } |
diff --git a/framework/actions/actionresult.cpp b/framework/actions/actionresult.cpp new file mode 100644 index 00000000..631c61c4 --- /dev/null +++ b/framework/actions/actionresult.cpp | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | |||
4 | This library is free software; you can redistribute it and/or modify it | ||
5 | under the terms of the GNU Library General Public License as published by | ||
6 | the Free Software Foundation; either version 2 of the License, or (at your | ||
7 | option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
12 | License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Library General Public License | ||
15 | along with this library; see the file COPYING.LIB. If not, write to the | ||
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
17 | 02110-1301, USA. | ||
18 | */ | ||
19 | #include "actionresult.h" | ||
20 | |||
diff --git a/framework/actions/actionresult.h b/framework/actions/actionresult.h new file mode 100644 index 00000000..cdc6a160 --- /dev/null +++ b/framework/actions/actionresult.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | |||
4 | This library is free software; you can redistribute it and/or modify it | ||
5 | under the terms of the GNU Library General Public License as published by | ||
6 | the Free Software Foundation; either version 2 of the License, or (at your | ||
7 | option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
12 | License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Library General Public License | ||
15 | along with this library; see the file COPYING.LIB. If not, write to the | ||
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
17 | 02110-1301, USA. | ||
18 | */ | ||
19 | #pragma once | ||
20 | |||
21 | #include <QObject> | ||
22 | #include <QSharedPointer> | ||
23 | |||
24 | namespace Kube { | ||
25 | |||
26 | struct ActionResultData | ||
27 | { | ||
28 | ActionResultData() : mError(0), mDone(false) {} | ||
29 | int mError; | ||
30 | bool mDone; | ||
31 | }; | ||
32 | |||
33 | class ActionResult : public QObject | ||
34 | { | ||
35 | Q_OBJECT | ||
36 | public: | ||
37 | ActionResult() : QObject(), mData(new ActionResultData()) {} | ||
38 | ActionResult(const ActionResult &rhs) : QObject(), mData(rhs.mData) {} | ||
39 | ActionResult &operator=(const ActionResult &rhs) | ||
40 | { | ||
41 | mData = rhs.mData; | ||
42 | return *this; | ||
43 | } | ||
44 | virtual ~ActionResult() {} | ||
45 | |||
46 | void setDone() { | ||
47 | mData->mDone = true; | ||
48 | } | ||
49 | |||
50 | bool isDone() const { | ||
51 | return mData->mDone; | ||
52 | } | ||
53 | |||
54 | void setError(int error) { | ||
55 | mData->mError = error; | ||
56 | } | ||
57 | |||
58 | int error() const { | ||
59 | return mData->mError; | ||
60 | } | ||
61 | |||
62 | private: | ||
63 | QSharedPointer<ActionResultData> mData; | ||
64 | }; | ||
65 | |||
66 | } | ||
diff --git a/framework/domain/CMakeLists.txt b/framework/domain/CMakeLists.txt index b3d47750..29385b39 100644 --- a/framework/domain/CMakeLists.txt +++ b/framework/domain/CMakeLists.txt | |||
@@ -27,7 +27,9 @@ include_directories(${CURL_INCLUDE_DIRS}) | |||
27 | add_library(mailplugin SHARED ${mailplugin_SRCS}) | 27 | add_library(mailplugin SHARED ${mailplugin_SRCS}) |
28 | 28 | ||
29 | qt5_use_modules(mailplugin Core Quick Qml WebKitWidgets) | 29 | qt5_use_modules(mailplugin Core Quick Qml WebKitWidgets) |
30 | target_link_libraries(mailplugin actionplugin settingsplugin sink KF5::MimeTreeParser KF5::Codecs KF5::Package ${CURL_LIBRARIES}) | 30 | target_link_libraries(mailplugin actionplugin settingsplugin sink KF5::MimeTreeParser KF5::Codecs KF5::Package KF5::Async ${CURL_LIBRARIES}) |
31 | |||
32 | add_subdirectory(actions/tests) | ||
31 | 33 | ||
32 | install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) | 34 | install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) |
33 | install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) | 35 | install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) |
diff --git a/framework/domain/actions/sinkactions.cpp b/framework/domain/actions/sinkactions.cpp index dea6fc72..5dbe623c 100644 --- a/framework/domain/actions/sinkactions.cpp +++ b/framework/domain/actions/sinkactions.cpp | |||
@@ -81,16 +81,7 @@ static ActionHandlerHelper sendMailHandler("org.kde.kube.actions.sendmail", | |||
81 | }, | 81 | }, |
82 | [](Context *context) { | 82 | [](Context *context) { |
83 | auto accountId = context->property("accountId").value<QByteArray>(); | 83 | auto accountId = context->property("accountId").value<QByteArray>(); |
84 | //For ssl use "smtps://mainserver.example.net | ||
85 | // QByteArray cacert; // = "/path/to/certificate.pem"; | ||
86 | auto message = context->property("message").value<KMime::Message::Ptr>(); | 84 | auto message = context->property("message").value<KMime::Message::Ptr>(); |
87 | auto mimeMessage = Sink::Store::getTemporaryFilePath(); | ||
88 | QFile file(mimeMessage); | ||
89 | if (!file.open(QIODevice::ReadWrite)) { | ||
90 | qWarning() << "Failed to open the file: " << file.errorString() << mimeMessage; | ||
91 | return; | ||
92 | } | ||
93 | file.write(message->encodedContent()); | ||
94 | qWarning() << "Sending a mail: "; | 85 | qWarning() << "Sending a mail: "; |
95 | 86 | ||
96 | Sink::Query query; | 87 | Sink::Query query; |
@@ -98,53 +89,63 @@ static ActionHandlerHelper sendMailHandler("org.kde.kube.actions.sendmail", | |||
98 | query += Sink::Query::PropertyFilter("account", QVariant::fromValue(accountId)); | 89 | query += Sink::Query::PropertyFilter("account", QVariant::fromValue(accountId)); |
99 | Sink::Store::fetchAll<Sink::ApplicationDomain::SinkResource>(query) | 90 | Sink::Store::fetchAll<Sink::ApplicationDomain::SinkResource>(query) |
100 | .then<void, QList<Sink::ApplicationDomain::SinkResource::Ptr>>([=](const QList<Sink::ApplicationDomain::SinkResource::Ptr> &resources) { | 91 | .then<void, QList<Sink::ApplicationDomain::SinkResource::Ptr>>([=](const QList<Sink::ApplicationDomain::SinkResource::Ptr> &resources) { |
101 | if (resources.isEmpty()) { | 92 | if (!resources.isEmpty()) { |
102 | qWarning() << "Failed to find a mailtransport resource"; | ||
103 | } else { | ||
104 | auto resourceId = resources[0]->identifier(); | 93 | auto resourceId = resources[0]->identifier(); |
105 | qDebug() << "Sending message via resource: " << resourceId; | 94 | qDebug() << "Sending message via resource: " << resourceId; |
106 | Sink::ApplicationDomain::Mail mail(resourceId); | 95 | Sink::ApplicationDomain::Mail mail(resourceId); |
107 | mail.setProperty("mimeMessage", mimeMessage); | 96 | mail.setBlobProperty("mimeMessage", message->encodedContent()); |
108 | Sink::Store::create(mail).exec(); | 97 | return Sink::Store::create(mail); |
109 | // return Sink::Store::create(mail); | ||
110 | } | 98 | } |
99 | qWarning() << "Failed to find a mailtransport resource"; | ||
111 | return KAsync::error<void>(0, "Failed to find a MailTransport resource."); | 100 | return KAsync::error<void>(0, "Failed to find a MailTransport resource."); |
112 | }).exec(); | 101 | }).exec(); |
113 | } | 102 | } |
114 | ); | 103 | ); |
115 | 104 | ||
116 | // static ActionHandlerHelper saveAsDraft("org.kde.kube.actions.save-as-draft", | 105 | static ActionHandlerHelper saveAsDraft("org.kde.kube.actions.save-as-draft", |
117 | // [](Context *context) -> bool { | 106 | [](Context *context) -> bool { |
118 | // return context->property("mail").isValid(); | 107 | auto accountId = context->property("accountId").value<QByteArray>(); |
119 | // }, | 108 | auto message = context->property("message").value<KMime::Message::Ptr>(); |
120 | // [](Context *context) { | 109 | return !accountId.isEmpty() && message; |
121 | // Sink::Query query; | 110 | }, |
122 | // query += Sink::Query::RequestedProperties(QByteArrayList() << "name") | 111 | ActionHandlerHelper::JobHandler([](Context *context) -> KAsync::Job<void> { |
123 | // //FIXME do something like specialuse? | 112 | qWarning() << "executing save as draft"; |
124 | // query += Sink::Query::PropertyFilter("name", "Drafts"); | 113 | const auto accountId = context->property("accountId").value<QByteArray>(); |
125 | // // query += Sink::Query::PropertyContainsFilter("specialuser", "drafts"); | 114 | const auto message = context->property("message").value<KMime::Message::Ptr>(); |
126 | // query += Sink::Query::PropertyFilter("drafts", true); | 115 | auto existingMail = context->property("existingMail").value<Sink::ApplicationDomain::Mail>(); |
127 | // //TODO Use drafts folder of that specific account | 116 | if (!message) { |
128 | // Sink::Store::fetchAll<Sink::ApplicationDomain::Folder>(query) | 117 | qWarning() << "Failed to get the mail: " << context->property("mail"); |
129 | // .then<void, QList<Sink::ApplicationDomain::Folder>>([](const QList<Sink::ApplicationDomain::Folder> folders) { | 118 | return KAsync::error<void>(1, "Failed to get the mail: " + context->property("mail").toString()); |
130 | // if (folders.isEmpty()) { | 119 | } |
131 | // return KAsync::start([]() { | 120 | |
132 | // //If message is already existing, modify, otherwise create | 121 | if (existingMail.identifier().isEmpty()) { |
133 | // }); | 122 | Sink::Query query; |
134 | // } | 123 | query += Sink::Query::RequestedProperties(QByteArrayList() << "name"); |
135 | // }); | 124 | query += Sink::Query::PropertyContainsFilter("specialpurpose", "drafts"); |
136 | // //TODO | 125 | query += Sink::Query::AccountFilter(accountId); |
137 | // // * Find drafts folder | 126 | qWarning() << "fetching the drafts folder"; |
138 | // // * Store KMime::Message on disk for use in blob property | 127 | return Sink::Store::fetchAll<Sink::ApplicationDomain::Folder>(query) |
139 | // // * Check if message is already existing and either create or update | 128 | .then<void, QList<Sink::ApplicationDomain::Folder::Ptr>>([=](const QList<Sink::ApplicationDomain::Folder::Ptr> folders) { |
140 | // // * | 129 | qWarning() << "fetched a drafts folder" << folders.size(); |
141 | // // auto mail = context->property("mail").value<Sink::ApplicationDomain::Mail::Ptr>(); | 130 | if (folders.isEmpty()) { |
142 | // // if (!mail) { | 131 | return KAsync::error<void>(1, "Failed to find a drafts folder."); |
143 | // // qWarning() << "Failed to get the mail mail: " << context->property("mail"); | 132 | } |
144 | // // return; | 133 | if (folders.size() > 1) { |
145 | // // } | 134 | qWarning() << "Found too many draft folders (taking the first): " << folders; |
146 | // // mail->setProperty("unread", false); | 135 | } |
147 | // // qDebug() << "Mark as read " << mail->identifier(); | 136 | const auto folder = folders.first(); |
148 | // // Sink::Store::modify(*mail).exec(); | 137 | Sink::ApplicationDomain::Mail mail(folder->resourceInstanceIdentifier()); |
149 | // } | 138 | mail.setProperty("folder", folder->identifier()); |
150 | // ); | 139 | mail.setBlobProperty("mimeMessage", message->encodedContent()); |
140 | return Sink::Store::create(mail); | ||
141 | }) | ||
142 | .then<void>([](){ | ||
143 | qWarning() << "done"; | ||
144 | }); | ||
145 | } else { | ||
146 | qWarning() << "Modifying an existing mail"; | ||
147 | existingMail.setBlobProperty("mimeMessage", message->encodedContent()); | ||
148 | return Sink::Store::modify(existingMail); | ||
149 | } | ||
150 | }) | ||
151 | ); | ||
diff --git a/framework/domain/actions/tests/CMakeLists.txt b/framework/domain/actions/tests/CMakeLists.txt new file mode 100644 index 00000000..dc9d01b1 --- /dev/null +++ b/framework/domain/actions/tests/CMakeLists.txt | |||
@@ -0,0 +1,6 @@ | |||
1 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) | ||
2 | cmake_policy(SET CMP0063 NEW) | ||
3 | add_executable(sinkactiontest sinkactiontest.cpp) | ||
4 | add_test(sinkactiontest sinkactiontest) | ||
5 | qt5_use_modules(sinkactiontest Core Test Concurrent) | ||
6 | target_link_libraries(sinkactiontest sink actionplugin KF5::Mime mailplugin) | ||
diff --git a/framework/domain/actions/tests/sinkactiontest.cpp b/framework/domain/actions/tests/sinkactiontest.cpp new file mode 100644 index 00000000..3e4567fd --- /dev/null +++ b/framework/domain/actions/tests/sinkactiontest.cpp | |||
@@ -0,0 +1,60 @@ | |||
1 | #include <QTest> | ||
2 | #include <QDebug> | ||
3 | #include <QSignalSpy> | ||
4 | #include <sink/test.h> | ||
5 | #include <sink/store.h> | ||
6 | #include <sink/log.h> | ||
7 | #include <KMime/Message> | ||
8 | |||
9 | #include <actions/action.h> | ||
10 | #include <actions/context.h> | ||
11 | |||
12 | using namespace Sink; | ||
13 | |||
14 | class SinkActionTest : public QObject | ||
15 | { | ||
16 | Q_OBJECT | ||
17 | private slots: | ||
18 | |||
19 | void initTestCase() | ||
20 | { | ||
21 | Sink::Test::initTest(); | ||
22 | Sink::Log::setDebugOutputLevel(Sink::Log::Trace); | ||
23 | } | ||
24 | |||
25 | void testSaveAsDraftFail() | ||
26 | { | ||
27 | Kube::Context context; | ||
28 | auto future = Kube::Action("org.kde.kube.actions.save-as-draft", context).execute(); | ||
29 | |||
30 | QTRY_VERIFY(future.isDone()); | ||
31 | //because of empty context | ||
32 | QVERIFY(future.error()); | ||
33 | } | ||
34 | |||
35 | void testSaveAsDraftNew() | ||
36 | { | ||
37 | auto message = KMime::Message::Ptr::create(); | ||
38 | message->subject(true)->fromUnicodeString(QString::fromLatin1("Foobar"), "utf8"); | ||
39 | message->assemble(); | ||
40 | |||
41 | auto &&account = Test::TestAccount::registerAccount(); | ||
42 | auto folder = account.createEntity<ApplicationDomain::Folder>(); | ||
43 | folder->setProperty("specialpurpose", QVariant::fromValue(QByteArrayList() << "drafts")); | ||
44 | |||
45 | Kube::Context context; | ||
46 | context.setProperty("message", QVariant::fromValue(message)); | ||
47 | context.setProperty("accountId", QVariant::fromValue(account.identifier)); | ||
48 | auto future = Kube::Action("org.kde.kube.actions.save-as-draft", context).execute(); | ||
49 | |||
50 | QTRY_VERIFY(future.isDone()); | ||
51 | QVERIFY(!future.error()); | ||
52 | auto mails = account.entities<Sink::ApplicationDomain::Mail>(); | ||
53 | QCOMPARE(mails.size(), 1); | ||
54 | auto mail = mails.first(); | ||
55 | QCOMPARE(mail->getProperty("folder").toByteArray(), folder->identifier()); | ||
56 | } | ||
57 | }; | ||
58 | |||
59 | QTEST_GUILESS_MAIN(SinkActionTest) | ||
60 | #include "sinkactiontest.moc" | ||
diff --git a/framework/domain/composercontroller.cpp b/framework/domain/composercontroller.cpp index bca90d33..0cf61442 100644 --- a/framework/domain/composercontroller.cpp +++ b/framework/domain/composercontroller.cpp | |||
@@ -185,9 +185,12 @@ void ComposerController::send() | |||
185 | void ComposerController::saveAsDraft() | 185 | void ComposerController::saveAsDraft() |
186 | { | 186 | { |
187 | auto mail = assembleMessage(); | 187 | auto mail = assembleMessage(); |
188 | auto currentAccountId = identityModel()->index(m_currentAccountIndex, 0).data(IdentitiesModel::AccountId).toByteArray(); | ||
189 | |||
188 | Kube::Context context; | 190 | Kube::Context context; |
189 | context.setProperty("message", QVariant::fromValue(mail)); | 191 | context.setProperty("message", QVariant::fromValue(mail)); |
190 | Kube::Action("org.kde.kube.actions.saveasdraft", context).execute(); | 192 | context.setProperty("accountId", QVariant::fromValue(currentAccountId)); |
193 | Kube::Action("org.kde.kube.actions.save-as-draft", context).execute(); | ||
191 | clear(); | 194 | clear(); |
192 | } | 195 | } |
193 | 196 | ||
diff --git a/framework/domain/maillistmodel.cpp b/framework/domain/maillistmodel.cpp index 7cbc5587..2df3ecbc 100644 --- a/framework/domain/maillistmodel.cpp +++ b/framework/domain/maillistmodel.cpp | |||
@@ -111,10 +111,10 @@ void MailListModel::setParentFolder(const QVariant &parentFolder) | |||
111 | Sink::Query query; | 111 | Sink::Query query; |
112 | query.liveQuery = true; | 112 | query.liveQuery = true; |
113 | query.requestedProperties << "subject" << "sender" << "senderName" << "date" << "unread" << "important" << "folder"; | 113 | query.requestedProperties << "subject" << "sender" << "senderName" << "date" << "unread" << "important" << "folder"; |
114 | query.propertyFilter.insert("folder", folder->identifier()); | ||
115 | query.resources << folder->resourceInstanceIdentifier(); | 114 | query.resources << folder->resourceInstanceIdentifier(); |
116 | query.sortProperty = "date"; | 115 | query.sortProperty = "date"; |
117 | query.limit = 100; | 116 | query.limit = 100; |
117 | query += Sink::Query::PropertyFilter("folder", *folder); | ||
118 | qWarning() << "Running folder query: " << folder->resourceInstanceIdentifier() << folder->identifier(); | 118 | qWarning() << "Running folder query: " << folder->resourceInstanceIdentifier() << folder->identifier(); |
119 | runQuery(query); | 119 | runQuery(query); |
120 | } | 120 | } |