summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-12-29 20:23:58 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-12-29 20:37:22 +0100
commit48da7de1b6bcd87c57b4c7f60133f3f13fc4bff2 (patch)
treeafad136d1179480301646355fab0d95c1302d7e7
parent08dbe5251cb818b4f548029a6e96b4500fe7a35f (diff)
downloadkube-48da7de1b6bcd87c57b4c7f60133f3f13fc4bff2.tar.gz
kube-48da7de1b6bcd87c57b4c7f60133f3f13fc4bff2.zip
A typesafe action context
-rw-r--r--components/package/contents/ui/FocusComposer.qml14
-rw-r--r--framework/actions/context.cpp14
-rw-r--r--framework/actions/context.h13
-rw-r--r--framework/domain/actions/sinkactions.cpp2
-rw-r--r--framework/domain/composercontroller.cpp47
-rw-r--r--framework/domain/composercontroller.h17
6 files changed, 62 insertions, 45 deletions
diff --git a/components/package/contents/ui/FocusComposer.qml b/components/package/contents/ui/FocusComposer.qml
index d3f0d050..51d1cc0d 100644
--- a/components/package/contents/ui/FocusComposer.qml
+++ b/components/package/contents/ui/FocusComposer.qml
@@ -31,22 +31,14 @@ Controls2.Popup {
31 //Controller 31 //Controller
32 KubeFramework.ComposerController { 32 KubeFramework.ComposerController {
33 id: composer 33 id: composer
34
35 mailContext: KubeAction.Context {
36 id: mailcontext
37 property variant to
38 property variant cc
39 property variant bcc
40 property variant from
41 property variant subject
42 property variant body
43 }
44
45 onDone: { 34 onDone: {
46 root.close() 35 root.close()
47 } 36 }
48 } 37 }
49 38
39 //context
40 property variant mailcontext: composer.mailContext
41
50 //actions 42 //actions
51 property variant sendAction: composer.sendAction 43 property variant sendAction: composer.sendAction
52 property variant saveAsDraftAction: composer.saveAsDraftAction 44 property variant saveAsDraftAction: composer.saveAsDraftAction
diff --git a/framework/actions/context.cpp b/framework/actions/context.cpp
index 205b1606..8f370a0b 100644
--- a/framework/actions/context.cpp
+++ b/framework/actions/context.cpp
@@ -29,10 +29,22 @@ Context::Context(QObject *parent)
29 29
30} 30}
31 31
32void Context::clear()
33{
34 auto meta = metaObject();
35 for (auto i = meta->propertyOffset(); i < meta->propertyCount(); i++) {
36 auto property = meta->property(i);
37 setProperty(property.name(), QVariant());
38 }
39 for (const auto &p : dynamicPropertyNames()) {
40 setProperty(p, QVariant());
41 }
42}
43
32QDebug operator<<(QDebug dbg, const Kube::Context &context) 44QDebug operator<<(QDebug dbg, const Kube::Context &context)
33{ 45{
34 dbg << "Kube::Context {\n"; 46 dbg << "Kube::Context {\n";
35 auto metaObject = context.QObject::metaObject(); 47 auto metaObject = context.metaObject();
36 for (auto i = metaObject->propertyOffset(); i < metaObject->propertyCount(); i++) { 48 for (auto i = metaObject->propertyOffset(); i < metaObject->propertyCount(); i++) {
37 auto property = metaObject->property(i); 49 auto property = metaObject->property(i);
38 dbg << property.name() << context.property(property.name()) << "\n"; 50 dbg << property.name() << context.property(property.name()) << "\n";
diff --git a/framework/actions/context.h b/framework/actions/context.h
index 562e110e..42ae3a93 100644
--- a/framework/actions/context.h
+++ b/framework/actions/context.h
@@ -20,6 +20,18 @@
20 20
21#include <QObject> 21#include <QObject>
22 22
23#define KUBE_CONTEXT_PROPERTY(TYPE, NAME, LOWERCASENAME) \
24 public: Q_PROPERTY(TYPE LOWERCASENAME MEMBER m##NAME NOTIFY LOWERCASENAME##Changed) \
25 struct NAME { \
26 static constexpr const char *name = #LOWERCASENAME; \
27 typedef TYPE Type; \
28 }; \
29 void set##NAME(const TYPE &value) { setProperty(NAME::name, QVariant::fromValue(value)); } \
30 TYPE get##NAME() const { return m##NAME; } \
31 Q_SIGNALS: void LOWERCASENAME##Changed(); \
32 private: TYPE m##NAME;
33
34
23namespace Kube { 35namespace Kube {
24 36
25class Context : public QObject { 37class Context : public QObject {
@@ -27,6 +39,7 @@ class Context : public QObject {
27public: 39public:
28 Context(QObject *parent = 0); 40 Context(QObject *parent = 0);
29 virtual ~Context(){}; 41 virtual ~Context(){};
42 virtual void clear();
30}; 43};
31 44
32} 45}
diff --git a/framework/domain/actions/sinkactions.cpp b/framework/domain/actions/sinkactions.cpp
index e8127ee6..fd791a91 100644
--- a/framework/domain/actions/sinkactions.cpp
+++ b/framework/domain/actions/sinkactions.cpp
@@ -118,7 +118,7 @@ static ActionHandlerHelper sendMailHandler("org.kde.kube.actions.sendmail",
118 ActionHandlerHelper::JobHandler{[](Context *context) -> KAsync::Job<void> { 118 ActionHandlerHelper::JobHandler{[](Context *context) -> KAsync::Job<void> {
119 auto accountId = context->property("accountId").value<QByteArray>(); 119 auto accountId = context->property("accountId").value<QByteArray>();
120 auto message = context->property("message").value<KMime::Message::Ptr>(); 120 auto message = context->property("message").value<KMime::Message::Ptr>();
121 SinkLog() << "Sending a mail: "; 121 SinkLog() << "Sending a mail: " << *context;
122 122
123 Query query; 123 Query query;
124 query.containsFilter<ApplicationDomain::SinkResource::Capabilities>(ApplicationDomain::ResourceCapabilities::Mail::transport); 124 query.containsFilter<ApplicationDomain::SinkResource::Capabilities>(ApplicationDomain::ResourceCapabilities::Mail::transport);
diff --git a/framework/domain/composercontroller.cpp b/framework/domain/composercontroller.cpp
index a47f4755..7129e342 100644
--- a/framework/domain/composercontroller.cpp
+++ b/framework/domain/composercontroller.cpp
@@ -44,6 +44,7 @@ Q_DECLARE_METATYPE(KMime::Types::Mailbox)
44 44
45ComposerController::ComposerController(QObject *parent) : QObject(parent) 45ComposerController::ComposerController(QObject *parent) : QObject(parent)
46{ 46{
47 QQmlEngine::setObjectOwnership(&mContext, QQmlEngine::CppOwnership);
47} 48}
48 49
49QString ComposerController::recepientSearchString() const 50QString ComposerController::recepientSearchString() const
@@ -51,14 +52,9 @@ QString ComposerController::recepientSearchString() const
51 return QString(); 52 return QString();
52} 53}
53 54
54Kube::Context* ComposerController::mailContext() const 55Kube::Context* ComposerController::mailContext()
55{ 56{
56 return mContext; 57 return &mContext;
57}
58
59void ComposerController::setMailContext(Kube::Context *context)
60{
61 mContext = context;
62} 58}
63 59
64void ComposerController::setRecepientSearchString(const QString &s) 60void ComposerController::setRecepientSearchString(const QString &s)
@@ -84,11 +80,11 @@ QAbstractItemModel *ComposerController::recepientAutocompletionModel() const
84 80
85void ComposerController::setMessage(const KMime::Message::Ptr &msg) 81void ComposerController::setMessage(const KMime::Message::Ptr &msg)
86{ 82{
87 mContext->setProperty("to", msg->to(true)->asUnicodeString()); 83 mContext.setTo(msg->to(true)->asUnicodeString());
88 mContext->setProperty("cc", msg->cc(true)->asUnicodeString()); 84 mContext.setCc(msg->cc(true)->asUnicodeString());
89 mContext->setProperty("subject", msg->subject(true)->asUnicodeString()); 85 mContext.setSubject(msg->subject(true)->asUnicodeString());
90 mContext->setProperty("body", msg->body()); 86 mContext.setBody(msg->body());
91 mContext->setProperty("existingMessage", QVariant::fromValue(msg)); 87 mContext.setProperty("existingMessage", QVariant::fromValue(msg));
92} 88}
93 89
94void ComposerController::loadMessage(const QVariant &message, bool loadAsDraft) 90void ComposerController::loadMessage(const QVariant &message, bool loadAsDraft)
@@ -96,7 +92,7 @@ void ComposerController::loadMessage(const QVariant &message, bool loadAsDraft)
96 Sink::Query query(*message.value<Sink::ApplicationDomain::Mail::Ptr>()); 92 Sink::Query query(*message.value<Sink::ApplicationDomain::Mail::Ptr>());
97 query.request<Sink::ApplicationDomain::Mail::MimeMessage>(); 93 query.request<Sink::ApplicationDomain::Mail::MimeMessage>();
98 Sink::Store::fetchOne<Sink::ApplicationDomain::Mail>(query).syncThen<void, Sink::ApplicationDomain::Mail>([this, loadAsDraft](const Sink::ApplicationDomain::Mail &mail) { 94 Sink::Store::fetchOne<Sink::ApplicationDomain::Mail>(query).syncThen<void, Sink::ApplicationDomain::Mail>([this, loadAsDraft](const Sink::ApplicationDomain::Mail &mail) {
99 mContext->setProperty("existingMail", QVariant::fromValue(mail)); 95 mContext.setProperty("existingMail", QVariant::fromValue(mail));
100 const auto mailData = KMime::CRLFtoLF(mail.getMimeMessage()); 96 const auto mailData = KMime::CRLFtoLF(mail.getMimeMessage());
101 if (!mailData.isEmpty()) { 97 if (!mailData.isEmpty()) {
102 KMime::Message::Ptr mail(new KMime::Message); 98 KMime::Message::Ptr mail(new KMime::Message);
@@ -135,11 +131,7 @@ void applyAddresses(const QString &list, std::function<void(const QByteArray &,
135 131
136void ComposerController::clear() 132void ComposerController::clear()
137{ 133{
138 mContext->setProperty("subject", QVariant()); 134 mContext.clear();
139 mContext->setProperty("body", QVariant());
140 mContext->setProperty("to", QVariant());
141 mContext->setProperty("cc", QVariant());
142 mContext->setProperty("bcc", QVariant());
143} 135}
144 136
145 137
@@ -155,23 +147,23 @@ Kube::ActionHandler *ComposerController::messageHandler()
155 if (!mail) { 147 if (!mail) {
156 mail = KMime::Message::Ptr::create(); 148 mail = KMime::Message::Ptr::create();
157 } 149 }
158 applyAddresses(context->property("to").toString(), [&](const QByteArray &addrSpec, const QByteArray &displayName) { 150 applyAddresses(context->property(ComposerContext::To::name).toString(), [&](const QByteArray &addrSpec, const QByteArray &displayName) {
159 mail->to(true)->addAddress(addrSpec, displayName); 151 mail->to(true)->addAddress(addrSpec, displayName);
160 recordForAutocompletion(addrSpec, displayName); 152 recordForAutocompletion(addrSpec, displayName);
161 }); 153 });
162 applyAddresses(context->property("cc").toString(), [&](const QByteArray &addrSpec, const QByteArray &displayName) { 154 applyAddresses(context->property(ComposerContext::Cc::name).toString(), [&](const QByteArray &addrSpec, const QByteArray &displayName) {
163 mail->cc(true)->addAddress(addrSpec, displayName); 155 mail->cc(true)->addAddress(addrSpec, displayName);
164 recordForAutocompletion(addrSpec, displayName); 156 recordForAutocompletion(addrSpec, displayName);
165 }); 157 });
166 applyAddresses(context->property("bcc").toString(), [&](const QByteArray &addrSpec, const QByteArray &displayName) { 158 applyAddresses(context->property(ComposerContext::Bcc::name).toString(), [&](const QByteArray &addrSpec, const QByteArray &displayName) {
167 mail->bcc(true)->addAddress(addrSpec, displayName); 159 mail->bcc(true)->addAddress(addrSpec, displayName);
168 recordForAutocompletion(addrSpec, displayName); 160 recordForAutocompletion(addrSpec, displayName);
169 }); 161 });
170 162
171 mail->from(true)->addAddress(context->property("identity").value<KMime::Types::Mailbox>()); 163 mail->from(true)->addAddress(context->property("identity").value<KMime::Types::Mailbox>());
172 164
173 mail->subject(true)->fromUnicodeString(context->property("subject").toString(), "utf-8"); 165 mail->subject(true)->fromUnicodeString(context->property(ComposerContext::Subject::name).toString(), "utf-8");
174 mail->setBody(context->property("body").toString().toUtf8()); 166 mail->setBody(context->property(ComposerContext::Body::name).toString().toUtf8());
175 mail->assemble(); 167 mail->assemble();
176 168
177 context->setProperty("message", QVariant::fromValue(mail)); 169 context->setProperty("message", QVariant::fromValue(mail));
@@ -181,7 +173,7 @@ Kube::ActionHandler *ComposerController::messageHandler()
181 173
182Kube::Action* ComposerController::saveAsDraftAction() 174Kube::Action* ComposerController::saveAsDraftAction()
183{ 175{
184 auto action = new Kube::Action("org.kde.kube.actions.save-as-draft", *mContext); 176 auto action = new Kube::Action("org.kde.kube.actions.save-as-draft", mContext);
185 action->addPreHandler(messageHandler()); 177 action->addPreHandler(messageHandler());
186 action->addPostHandler(new Kube::ActionHandlerHelper( 178 action->addPostHandler(new Kube::ActionHandlerHelper(
187 [this](Kube::Context *context) { 179 [this](Kube::Context *context) {
@@ -192,8 +184,7 @@ Kube::Action* ComposerController::saveAsDraftAction()
192 184
193Kube::Action* ComposerController::sendAction() 185Kube::Action* ComposerController::sendAction()
194{ 186{
195 qWarning() << "send action"; 187 auto action = new Kube::Action("org.kde.kube.actions.sendmail", mContext);
196 auto action = new Kube::Action("org.kde.kube.actions.sendmail", *mContext);
197 // action->addPreHandler(identityHandler()); 188 // action->addPreHandler(identityHandler());
198 action->addPreHandler(messageHandler()); 189 action->addPreHandler(messageHandler());
199 // action->addPreHandler(encryptionHandler()); 190 // action->addPreHandler(encryptionHandler());
@@ -214,8 +205,8 @@ void ComposerController::setCurrentIdentityIndex(int index)
214 mb.setName(currentIndex.data(IdentitiesModel::Username).toString()); 205 mb.setName(currentIndex.data(IdentitiesModel::Username).toString());
215 mb.setAddress(currentIndex.data(IdentitiesModel::Address).toString().toUtf8()); 206 mb.setAddress(currentIndex.data(IdentitiesModel::Address).toString().toUtf8());
216 SinkLog() << "Setting current identity: " << mb.prettyAddress() << "Account: " << currentAccountId; 207 SinkLog() << "Setting current identity: " << mb.prettyAddress() << "Account: " << currentAccountId;
217 mContext->setProperty("identity", QVariant::fromValue(mb)); 208 mContext.setProperty("identity", QVariant::fromValue(mb));
218 mContext->setProperty("accountId", QVariant::fromValue(currentAccountId)); 209 mContext.setProperty("accountId", QVariant::fromValue(currentAccountId));
219 } else { 210 } else {
220 SinkWarning() << "No valid identity for index: " << index << " out of available in model: " << identityModel()->rowCount(); 211 SinkWarning() << "No valid identity for index: " << index << " out of available in model: " << identityModel()->rowCount();
221 } 212 }
diff --git a/framework/domain/composercontroller.h b/framework/domain/composercontroller.h
index b7ff0757..11da517e 100644
--- a/framework/domain/composercontroller.h
+++ b/framework/domain/composercontroller.h
@@ -33,10 +33,20 @@ namespace KMime {
33class Message; 33class Message;
34} 34}
35 35
36class ComposerContext : public Kube::Context {
37 Q_OBJECT
38 KUBE_CONTEXT_PROPERTY(QString, To, to)
39 KUBE_CONTEXT_PROPERTY(QString, Cc, cc)
40 KUBE_CONTEXT_PROPERTY(QString, Bcc, bcc)
41 KUBE_CONTEXT_PROPERTY(QString, From, from)
42 KUBE_CONTEXT_PROPERTY(QString, Subject, subject)
43 KUBE_CONTEXT_PROPERTY(QString, Body, body)
44};
45
36class ComposerController : public QObject 46class ComposerController : public QObject
37{ 47{
38 Q_OBJECT 48 Q_OBJECT
39 Q_PROPERTY (Kube::Context* mailContext READ mailContext WRITE setMailContext) 49 Q_PROPERTY (Kube::Context* mailContext READ mailContext CONSTANT)
40 Q_PROPERTY (int currentIdentityIndex READ currentIdentityIndex WRITE setCurrentIdentityIndex) 50 Q_PROPERTY (int currentIdentityIndex READ currentIdentityIndex WRITE setCurrentIdentityIndex)
41 51
42 Q_PROPERTY (QString recepientSearchString READ recepientSearchString WRITE setRecepientSearchString) 52 Q_PROPERTY (QString recepientSearchString READ recepientSearchString WRITE setRecepientSearchString)
@@ -49,8 +59,7 @@ class ComposerController : public QObject
49public: 59public:
50 explicit ComposerController(QObject *parent = Q_NULLPTR); 60 explicit ComposerController(QObject *parent = Q_NULLPTR);
51 61
52 Kube::Context* mailContext() const; 62 Kube::Context* mailContext();
53 void setMailContext(Kube::Context *context);
54 63
55 QString recepientSearchString() const; 64 QString recepientSearchString() const;
56 void setRecepientSearchString(const QString &body); 65 void setRecepientSearchString(const QString &body);
@@ -78,5 +87,5 @@ private:
78 void setMessage(const QSharedPointer<KMime::Message> &msg); 87 void setMessage(const QSharedPointer<KMime::Message> &msg);
79 88
80 int m_currentAccountIndex = -1; 89 int m_currentAccountIndex = -1;
81 Kube::Context *mContext; 90 ComposerContext mContext;
82}; 91};