From e06e1dad4a4570e5c1181d05ab6ed7a5d74c6c91 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 3 May 2016 20:24:09 +0200 Subject: A save-as-draft action & action results This patch introduces tracking of actions, so they can be tested. It also provides a save-as-draft action, that looks for the draft folder, and stores the mail accordingly. --- framework/actions/CMakeLists.txt | 1 + framework/actions/action.cpp | 4 +-- framework/actions/action.h | 3 +- framework/actions/actionbroker.cpp | 9 +++-- framework/actions/actionbroker.h | 3 +- framework/actions/actionhandler.cpp | 37 +++++++++++++++++++-- framework/actions/actionhandler.h | 14 +++++--- framework/actions/actionresult.cpp | 20 +++++++++++ framework/actions/actionresult.h | 66 +++++++++++++++++++++++++++++++++++++ 9 files changed, 144 insertions(+), 13 deletions(-) create mode 100644 framework/actions/actionresult.cpp create mode 100644 framework/actions/actionresult.h (limited to 'framework/actions') 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 action.cpp actionhandler.cpp actionbroker.cpp + actionresult.cpp context.cpp ) 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 return ActionBroker::instance().isActionReady(mActionId, mContext); } -void Action::execute() +ActionResult Action::execute() { - ActionBroker::instance().executeAction(mActionId, mContext); + return ActionBroker::instance().executeAction(mActionId, mContext); } 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 @@ #include #include "context.h" +#include "actionresult.h" namespace Kube { @@ -43,7 +44,7 @@ public: bool ready() const; - Q_INVOKABLE void execute(); + Q_INVOKABLE ActionResult execute(); Q_SIGNALS: 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) return false; } -void ActionBroker::executeAction(const QByteArray &actionId, Context *context) +ActionResult ActionBroker::executeAction(const QByteArray &actionId, Context *context) { if (context) { for (const auto handler : mHandler.values(actionId)) { if (handler) { - handler->execute(context); + //FIXME All handler together return one result + return handler->execute(context); } } } else { qWarning() << "Can't execute without context"; } + ActionResult result; + result.setDone(); + result.setError(1); + return result; } 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 @@ namespace Kube { class Context; class ActionHandler; +class ActionResult; class ActionBroker : public QObject { @@ -32,7 +33,7 @@ public: static ActionBroker &instance(); bool isActionReady(const QByteArray &actionId, Context *context); - void executeAction(const QByteArray &actionId, Context *context); + ActionResult executeAction(const QByteArray &actionId, Context *context); void registerHandler(const QByteArray &actionId, ActionHandler *handler); 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) return false; } -void ActionHandler::execute(Context *context) +ActionResult ActionHandler::execute(Context *context) { + ActionResult result; QVariant returnedValue; qWarning() << "Executing the handler"; if (context) { + //The base implementation to call the handler in QML QMetaObject::invokeMethod(this, "handler", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, QVariant::fromValue(context))); + //TODO: support async handlers in QML + result.setDone(); } else { qWarning() << "The handler didn't get a context"; + result.setDone(); + result.setError(1); } + return result; } void ActionHandler::setActionId(const QByteArray &actionId) @@ -79,12 +86,36 @@ ActionHandlerHelper::ActionHandlerHelper(const QByteArray &actionId, const IsRea setActionId(actionId); } +ActionHandlerHelper::ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &isReady, const JobHandler &handler) + : ActionHandler(nullptr), + isReadyFunction(isReady), + jobHandlerFunction(handler) +{ + setActionId(actionId); +} + bool ActionHandlerHelper::isActionReady(Context *context) { return isReadyFunction(context); } -void ActionHandlerHelper::execute(Context *context) +ActionResult ActionHandlerHelper::execute(Context *context) { - handlerFunction(context); + ActionResult result; + if (handlerFunction) { + handlerFunction(context); + result.setDone(); + } else { + jobHandlerFunction(context).then([=]() { + auto modifyableResult = result; + modifyableResult.setDone(); + }, + [=](int errorCode, const QString &string) { + qWarning() << "Job failed: " << errorCode << string; + auto modifyableResult = result; + modifyableResult.setError(1); + modifyableResult.setDone(); + }).exec(); + } + return result; } 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 @@ #include #include #include +#include + +#include "actionresult.h" namespace Kube { class Context; @@ -36,7 +39,7 @@ public: virtual bool isActionReady(Context *context); // void pre(Context *context); - virtual void execute(Context *context); + virtual ActionResult execute(Context *context); // void post(Context *context); void setActionId(const QByteArray &); @@ -52,14 +55,17 @@ class ActionHandlerHelper : public ActionHandler public: typedef std::function IsReadyFunction; typedef std::function Handler; + typedef std::function(Context*)> JobHandler; ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &, const Handler &); + ActionHandlerHelper(const QByteArray &actionId, const IsReadyFunction &, const JobHandler &); bool isActionReady(Context *context) Q_DECL_OVERRIDE; - void execute(Context *context) Q_DECL_OVERRIDE; + ActionResult execute(Context *context) Q_DECL_OVERRIDE; private: - const std::function isReadyFunction; - const std::function handlerFunction; + const IsReadyFunction isReadyFunction; + const Handler handlerFunction; + const JobHandler jobHandlerFunction; }; } 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 @@ +/* + Copyright (c) 2016 Christian Mollekopf + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ +#include "actionresult.h" + 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 @@ +/* + Copyright (c) 2016 Christian Mollekopf + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ +#pragma once + +#include +#include + +namespace Kube { + +struct ActionResultData +{ + ActionResultData() : mError(0), mDone(false) {} + int mError; + bool mDone; +}; + +class ActionResult : public QObject +{ + Q_OBJECT +public: + ActionResult() : QObject(), mData(new ActionResultData()) {} + ActionResult(const ActionResult &rhs) : QObject(), mData(rhs.mData) {} + ActionResult &operator=(const ActionResult &rhs) + { + mData = rhs.mData; + return *this; + } + virtual ~ActionResult() {} + + void setDone() { + mData->mDone = true; + } + + bool isDone() const { + return mData->mDone; + } + + void setError(int error) { + mData->mError = error; + } + + int error() const { + return mData->mError; + } + +private: + QSharedPointer mData; +}; + +} -- cgit v1.2.3