diff options
-rw-r--r-- | components/kube/contents/ui/Kube.qml | 56 | ||||
-rw-r--r-- | framework/qml/ConversationView.qml | 24 | ||||
-rw-r--r-- | framework/qml/FolderListView.qml | 17 | ||||
-rw-r--r-- | framework/qml/MailListView.qml | 66 | ||||
-rw-r--r-- | framework/qml/Messages.qml | 10 | ||||
-rw-r--r-- | framework/src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | framework/src/sinkfabric.cpp | 141 | ||||
-rw-r--r-- | framework/src/sinkfabric.h | 0 |
8 files changed, 189 insertions, 126 deletions
diff --git a/components/kube/contents/ui/Kube.qml b/components/kube/contents/ui/Kube.qml index 81c678bd..8092a073 100644 --- a/components/kube/contents/ui/Kube.qml +++ b/components/kube/contents/ui/Kube.qml | |||
@@ -36,59 +36,35 @@ Controls2.ApplicationWindow { | |||
36 | 36 | ||
37 | visible: true | 37 | visible: true |
38 | 38 | ||
39 | Kube.NotificationHandler { | 39 | Kube.Listener { |
40 | id: notificationHandler | 40 | filter: Kube.Messages.notification |
41 | function handler(n) { | 41 | onMessageReceived: { |
42 | console.warn("We got a notification: ", n.message) | 42 | console.warn("We got a notification: ", message.message) |
43 | if (n.type == Kube.Notification.Warning) { | 43 | if (message.type == Kube.Notification.Warning) { |
44 | console.warn("And it's a warning!", n.type) | 44 | console.warn("And it's a warning!", message.type) |
45 | } | 45 | } |
46 | notificationPopup.notify(n.message); | 46 | notificationPopup.notify(message.message); |
47 | } | 47 | } |
48 | } | 48 | } |
49 | 49 | ||
50 | //BEGIN Actions | 50 | Kube.Listener { |
51 | Kube.Context { | 51 | filter: Kube.Messages.reply |
52 | id: maillistcontext | 52 | onMessageReceived: { |
53 | property variant mail | 53 | composer.loadMessage(message.mail, false) |
54 | property bool isDraft | ||
55 | mail: mailListView.currentMail | ||
56 | isDraft: mailListView.isDraft | ||
57 | } | ||
58 | |||
59 | Kube.Action { | ||
60 | id: replyAction | ||
61 | actionId: "org.kde.kube.actions.reply" | ||
62 | context: maillistcontext | ||
63 | } | ||
64 | //END Actions | ||
65 | |||
66 | //BEGIN ActionHandler | ||
67 | Kube.ActionHandler { | ||
68 | actionId: "org.kde.kube.actions.reply" | ||
69 | function isReady(context) { | ||
70 | return context.mail ? true : false; | ||
71 | } | ||
72 | |||
73 | function handler(context) { | ||
74 | composer.loadMessage(context.mail, false) | ||
75 | composer.open() | 54 | composer.open() |
76 | } | 55 | } |
77 | } | 56 | } |
78 | 57 | ||
79 | Kube.ActionHandler { | 58 | Kube.Listener { |
80 | actionId: "org.kde.kube.actions.edit" | 59 | filter: Kube.Messages.edit |
81 | function isReady(context) { | 60 | onMessageReceived: { |
82 | return context.mail && context.isDraft; | 61 | composer.loadMessage(message.mail, true) |
83 | } | ||
84 | function handler(context) { | ||
85 | composer.loadMessage(context.mail, true) | ||
86 | composer.open() | 62 | composer.open() |
87 | } | 63 | } |
88 | } | 64 | } |
89 | //END ActionHandler | ||
90 | 65 | ||
91 | //Controller | 66 | //Controller |
67 | //TODO replace | ||
92 | Kube.FolderController { | 68 | Kube.FolderController { |
93 | id: folderController | 69 | id: folderController |
94 | } | 70 | } |
diff --git a/framework/qml/ConversationView.qml b/framework/qml/ConversationView.qml index 85712a5a..d7d33c78 100644 --- a/framework/qml/ConversationView.qml +++ b/framework/qml/ConversationView.qml | |||
@@ -548,32 +548,12 @@ Rectangle { | |||
548 | rightMargin: Kube.Units.largeSpacing | 548 | rightMargin: Kube.Units.largeSpacing |
549 | } | 549 | } |
550 | 550 | ||
551 | Kube.Context { | ||
552 | id: mailcontext | ||
553 | property variant mail | ||
554 | property bool isDraft | ||
555 | mail: model.mail | ||
556 | isDraft: model.draft | ||
557 | } | ||
558 | |||
559 | Kube.Action { | ||
560 | id: replyAction | ||
561 | actionId: "org.kde.kube.actions.reply" | ||
562 | context: maillistcontext | ||
563 | } | ||
564 | |||
565 | Kube.Action { | ||
566 | id: editAction | ||
567 | actionId: "org.kde.kube.actions.edit" | ||
568 | context: maillistcontext | ||
569 | } | ||
570 | |||
571 | iconName: model.draft ? Kube.Icons.edit : Kube.Icons.replyToSender | 551 | iconName: model.draft ? Kube.Icons.edit : Kube.Icons.replyToSender |
572 | onClicked: { | 552 | onClicked: { |
573 | if (model.draft) { | 553 | if (model.draft) { |
574 | editAction.execute() | 554 | Kube.Fabric.postMessage(Kube.Messages.edit, {"mail": model.mail, "isDraft": model.draft}) |
575 | } else { | 555 | } else { |
576 | replyAction.execute() | 556 | Kube.Fabric.postMessage(Kube.Messages.reply, {"mail": model.mail, "isDraft": model.draft}) |
577 | } | 557 | } |
578 | } | 558 | } |
579 | } | 559 | } |
diff --git a/framework/qml/FolderListView.qml b/framework/qml/FolderListView.qml index 78d3c5d0..42841221 100644 --- a/framework/qml/FolderListView.qml +++ b/framework/qml/FolderListView.qml | |||
@@ -30,17 +30,6 @@ Rectangle { | |||
30 | 30 | ||
31 | color: Kube.Colors.textColor | 31 | color: Kube.Colors.textColor |
32 | 32 | ||
33 | Kube.FolderController { | ||
34 | id: folderController | ||
35 | } | ||
36 | Kube.Listener { | ||
37 | id: controllerListener | ||
38 | filter: Kube.Messages.folderSelection | ||
39 | onMessageReceived: { | ||
40 | folderController.folder = message.folder | ||
41 | } | ||
42 | } | ||
43 | |||
44 | TreeView { | 33 | TreeView { |
45 | id: treeView | 34 | id: treeView |
46 | 35 | ||
@@ -66,7 +55,7 @@ Rectangle { | |||
66 | model.fetchMore(currentIndex) | 55 | model.fetchMore(currentIndex) |
67 | Kube.Fabric.postMessage(Kube.Messages.folderSelection, {"folder":model.data(currentIndex, Kube.FolderListModel.DomainObject), | 56 | Kube.Fabric.postMessage(Kube.Messages.folderSelection, {"folder":model.data(currentIndex, Kube.FolderListModel.DomainObject), |
68 | "trash":model.data(currentIndex, Kube.FolderListModel.Trash)}) | 57 | "trash":model.data(currentIndex, Kube.FolderListModel.Trash)}) |
69 | folderController.synchronizeAction.execute() | 58 | Kube.Fabric.postMessage(Kube.Messages.synchronize, {"folder":model.data(currentIndex, Kube.FolderListModel.DomainObject)}) |
70 | console.error(model.data) | 59 | console.error(model.data) |
71 | } | 60 | } |
72 | 61 | ||
@@ -117,9 +106,7 @@ Rectangle { | |||
117 | visible: parent.containsDrag | 106 | visible: parent.containsDrag |
118 | } | 107 | } |
119 | onDropped: { | 108 | onDropped: { |
120 | folderController.folder = model.domainObject | 109 | Kube.Fabric.postMessage(Kube.Messages.moveToFolder, {"mail": drop.source.mail, "folder":model.domainObject}) |
121 | folderController.mail = drop.source.mail | ||
122 | folderController.moveToFolderAction.execute() | ||
123 | drop.accept(Qt.MoveAction) | 110 | drop.accept(Qt.MoveAction) |
124 | drop.source.visible = false | 111 | drop.source.visible = false |
125 | } | 112 | } |
diff --git a/framework/qml/MailListView.qml b/framework/qml/MailListView.qml index 570b92f8..97a222a7 100644 --- a/framework/qml/MailListView.qml +++ b/framework/qml/MailListView.qml | |||
@@ -31,12 +31,15 @@ Item { | |||
31 | property bool isImportant : false | 31 | property bool isImportant : false |
32 | property bool isTrash : false | 32 | property bool isTrash : false |
33 | property bool isUnread : false | 33 | property bool isUnread : false |
34 | property variant currentMail: null | ||
35 | |||
36 | onCurrentMailChanged: Kube.Fabric.postMessage(Kube.Messages.mailSelection, {"mail":currentMail}) | ||
34 | 37 | ||
35 | Kube.Listener { | 38 | Kube.Listener { |
36 | filter: Kube.Messages.folderSelection | 39 | filter: Kube.Messages.folderSelection |
37 | onMessageReceived: { | 40 | onMessageReceived: { |
38 | parentFolder = message.folder | 41 | parentFolder = message.folder |
39 | Kube.Fabric.postMessage(Kube.Messages.mailSelection, {"mail":null}) | 42 | currentMail = null |
40 | } | 43 | } |
41 | } | 44 | } |
42 | 45 | ||
@@ -47,35 +50,10 @@ Item { | |||
47 | } | 50 | } |
48 | } | 51 | } |
49 | 52 | ||
50 | Kube.MailController { | ||
51 | id: mailController | ||
52 | unread: root.isUnread | ||
53 | trash: root.isTrash | ||
54 | important: root.isImportant | ||
55 | draft: root.isDraft | ||
56 | operateOnThreads: mailListModel.isThreaded | ||
57 | } | ||
58 | |||
59 | Kube.Listener { | ||
60 | id: controllerListener | ||
61 | filter: Kube.Messages.mailSelection | ||
62 | onMessageReceived: { | ||
63 | mailController.mail = message.mail | ||
64 | } | ||
65 | } | ||
66 | |||
67 | Shortcut { | 53 | Shortcut { |
68 | sequence: StandardKey.Delete | 54 | sequence: StandardKey.Delete |
69 | onActivated: mailController.moveToTrashAction.execute() | 55 | enabled: isTrash |
70 | enabled: mailController.moveToTrashAction.enabled | 56 | onActivated: Kube.Fabric.postMessage(Kube.Messages.moveToTrash, {"mail":currentMail}) |
71 | } | ||
72 | Shortcut { | ||
73 | sequence: StandardKey.MoveToNextLine | ||
74 | onActivated: root.currentIndex++ | ||
75 | } | ||
76 | Shortcut { | ||
77 | sequence: StandardKey.MoveToPreviousLine | ||
78 | onActivated: root.currentIndex-- | ||
79 | } | 57 | } |
80 | 58 | ||
81 | Kube.Label { | 59 | Kube.Label { |
@@ -106,7 +84,7 @@ Item { | |||
106 | //END keyboard nav | 84 | //END keyboard nav |
107 | 85 | ||
108 | onCurrentItemChanged: { | 86 | onCurrentItemChanged: { |
109 | Kube.Fabric.postMessage(Kube.Messages.mailSelection, {"mail":currentItem.currentData.mail}) | 87 | root.currentMail = currentItem.currentData.mail; |
110 | root.isDraft = currentItem.currentData.draft; | 88 | root.isDraft = currentItem.currentData.draft; |
111 | root.isTrash = currentItem.currentData.trash; | 89 | root.isTrash = currentItem.currentData.trash; |
112 | root.isImportant = currentItem.currentData.important; | 90 | root.isImportant = currentItem.currentData.important; |
@@ -286,50 +264,40 @@ Item { | |||
286 | Kube.Button { | 264 | Kube.Button { |
287 | id: readButton | 265 | id: readButton |
288 | text: "r" | 266 | text: "r" |
289 | enabled: mailController.markAsReadAction.enabled | ||
290 | visible: enabled | 267 | visible: enabled |
291 | onClicked: { | 268 | enabled: model.unread |
292 | mailController.markAsReadAction.execute() | 269 | onClicked: Kube.Fabric.postMessage(Kube.Messages.markAsRead, {"mail": model.mail}) |
293 | } | ||
294 | } | 270 | } |
295 | Kube.Button { | 271 | Kube.Button { |
296 | id: unreadButton | 272 | id: unreadButton |
297 | text: "u" | 273 | text: "u" |
298 | enabled: mailController.markAsUnreadAction.enabled | ||
299 | visible: enabled | 274 | visible: enabled |
300 | onClicked: { | 275 | enabled: !model.unread |
301 | mailController.markAsUnreadAction.execute() | 276 | onClicked: Kube.Fabric.postMessage(Kube.Messages.markAsUnread, {"mail": model.mail}) |
302 | } | ||
303 | } | 277 | } |
304 | 278 | ||
305 | Kube.Button { | 279 | Kube.Button { |
306 | id: importantButton | 280 | id: importantButton |
307 | text: "i" | 281 | text: "i" |
308 | enabled: mailController.toggleImportantAction.enabled | ||
309 | visible: enabled | 282 | visible: enabled |
310 | onClicked: { | 283 | enabled: !!model.mail |
311 | mailController.toggleImportantAction.execute() | 284 | onClicked: Kube.Fabric.postMessage(Kube.Messages.toggleImportant, {"mail": model.mail, "important": model.important}) |
312 | } | ||
313 | } | 285 | } |
314 | 286 | ||
315 | Kube.Button { | 287 | Kube.Button { |
316 | id: deleteButton | 288 | id: deleteButton |
317 | text: "d" | 289 | text: "d" |
318 | enabled: mailController.moveToTrashAction.enabled | ||
319 | visible: enabled | 290 | visible: enabled |
320 | onClicked: { | 291 | enabled: !!model.mail |
321 | mailController.moveToTrashAction.execute() | 292 | onClicked: Kube.Fabric.postMessage(Kube.Messages.moveToTrash, {"mail": model.mail}) |
322 | } | ||
323 | } | 293 | } |
324 | 294 | ||
325 | Kube.Button { | 295 | Kube.Button { |
326 | id: restoreButton | 296 | id: restoreButton |
327 | text: "re" | 297 | text: "re" |
328 | enabled: mailController.restoreFromTrashAction.enabled | ||
329 | visible: enabled | 298 | visible: enabled |
330 | onClicked: { | 299 | enabled: !!model.trash |
331 | mailController.restoreFromTrashAction.execute() | 300 | onClicked: Kube.Fabric.postMessage(Kube.Messages.restoreFromTrash, {"mail": model.mail}) |
332 | } | ||
333 | } | 301 | } |
334 | } | 302 | } |
335 | } | 303 | } |
diff --git a/framework/qml/Messages.qml b/framework/qml/Messages.qml index b4b170ec..1b384bfa 100644 --- a/framework/qml/Messages.qml +++ b/framework/qml/Messages.qml | |||
@@ -27,6 +27,16 @@ Item { | |||
27 | 27 | ||
28 | //Actions | 28 | //Actions |
29 | property string moveToTrash: "moveToTrash" | 29 | property string moveToTrash: "moveToTrash" |
30 | property string restoreFromTrash: "restoreFromTrash" | ||
31 | property string markAsRead: "markAsRead" | ||
32 | property string markAsUnread: "markAsUnread" | ||
33 | property string toggleImportant: "toggleImportant" | ||
34 | property string moveToFolder: "moveToFolder" | ||
35 | |||
36 | property string notification: "notification" | ||
30 | property string search: "search" | 37 | property string search: "search" |
38 | property string synchronize: "synchronize" | ||
39 | property string reply: "reply" | ||
40 | property string edit: "edit" | ||
31 | } | 41 | } |
32 | 42 | ||
diff --git a/framework/src/CMakeLists.txt b/framework/src/CMakeLists.txt index 39f17c32..cf971497 100644 --- a/framework/src/CMakeLists.txt +++ b/framework/src/CMakeLists.txt | |||
@@ -50,6 +50,7 @@ set(SRCS | |||
50 | accounts/accountsmodel.cpp | 50 | accounts/accountsmodel.cpp |
51 | notifications/notificationhandler.cpp | 51 | notifications/notificationhandler.cpp |
52 | fabric.cpp | 52 | fabric.cpp |
53 | sinkfabric.cpp | ||
53 | ) | 54 | ) |
54 | 55 | ||
55 | add_library(frameworkplugin SHARED ${SRCS}) | 56 | add_library(frameworkplugin SHARED ${SRCS}) |
diff --git a/framework/src/sinkfabric.cpp b/framework/src/sinkfabric.cpp new file mode 100644 index 00000000..68a75a86 --- /dev/null +++ b/framework/src/sinkfabric.cpp | |||
@@ -0,0 +1,141 @@ | |||
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 | |||
20 | #include <actions/actionhandler.h> | ||
21 | |||
22 | #include <QFile> | ||
23 | |||
24 | #include <sink/store.h> | ||
25 | #include <sink/log.h> | ||
26 | #include <sink/notification.h> | ||
27 | #include <sink/notifier.h> | ||
28 | |||
29 | #include "fabric.h" | ||
30 | |||
31 | SINK_DEBUG_AREA("sinkactions") | ||
32 | |||
33 | using namespace Kube; | ||
34 | using namespace Sink; | ||
35 | using namespace Sink::ApplicationDomain; | ||
36 | |||
37 | class SinkListener : public Kube::Fabric::Listener | ||
38 | { | ||
39 | public: | ||
40 | SinkListener() = default; | ||
41 | |||
42 | void notify(const QString &id, const QVariantMap &message) | ||
43 | { | ||
44 | SinkLog() << "Received message: " << id << message; | ||
45 | if (id == "synchronize"/*Kube::Messages::synchronize*/) { | ||
46 | if (auto folder = message["folder"].value<ApplicationDomain::Folder::Ptr>()) { | ||
47 | SinkLog() << "Synchronizing folder " << folder->resourceInstanceIdentifier() << folder->identifier(); | ||
48 | auto scope = SyncScope().resourceFilter(folder->resourceInstanceIdentifier()).filter<Mail::Folder>(QVariant::fromValue(folder->identifier())); | ||
49 | scope.setType<ApplicationDomain::Mail>(); | ||
50 | Store::synchronize(scope).exec(); | ||
51 | } else { | ||
52 | SinkLog() << "Synchronizing all"; | ||
53 | Store::synchronize(SyncScope()).exec(); | ||
54 | } | ||
55 | } | ||
56 | if (id == "markAsRead"/*Kube::Messages::synchronize*/) { | ||
57 | if (auto mail = message["mail"].value<ApplicationDomain::Mail::Ptr>()) { | ||
58 | mail->setUnread(false); | ||
59 | Store::modify(*mail).exec(); | ||
60 | } | ||
61 | } | ||
62 | if (id == "markAsUnread"/*Kube::Messages::synchronize*/) { | ||
63 | if (auto mail = message["mail"].value<ApplicationDomain::Mail::Ptr>()) { | ||
64 | mail->setUnread(true); | ||
65 | Store::modify(*mail).exec(); | ||
66 | } | ||
67 | } | ||
68 | if (id == "toggleImportant"/*Kube::Messages::synchronize*/) { | ||
69 | if (auto mail = message["mail"].value<ApplicationDomain::Mail::Ptr>()) { | ||
70 | mail->setImportant(message["important"].toBool()); | ||
71 | Store::modify(*mail).exec(); | ||
72 | } | ||
73 | } | ||
74 | if (id == "moveToTrash"/*Kube::Messages::synchronize*/) { | ||
75 | if (auto mail = message["mail"].value<ApplicationDomain::Mail::Ptr>()) { | ||
76 | mail->setTrash(true); | ||
77 | Store::modify(*mail).exec(); | ||
78 | } | ||
79 | } | ||
80 | if (id == "moveToFolder"/*Kube::Messages::synchronize*/) { | ||
81 | if (auto mail = message["mail"].value<ApplicationDomain::Mail::Ptr>()) { | ||
82 | auto folder = message["folder"].value<ApplicationDomain::Folder::Ptr>(); | ||
83 | mail->setFolder(*folder); | ||
84 | Store::modify(*mail).exec(); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | } | ||
89 | |||
90 | }; | ||
91 | |||
92 | static SinkListener sinkListener; | ||
93 | |||
94 | class NotificationListener { | ||
95 | NotificationListener() | ||
96 | : mNotifier{Sink::Query{Sink::Query::LiveQuery}} | ||
97 | { | ||
98 | mNotifier.registerHandler([this] (const Sink::Notification ¬ification) { | ||
99 | Notification n; | ||
100 | qWarning() << "Received notification: " << notification; | ||
101 | QVariantMap message; | ||
102 | if (notification.type == Sink::Notification::Warning) { | ||
103 | message["type"] = Notification::Warning; | ||
104 | if (notification.code == Sink::ApplicationDomain::TransmissionError) { | ||
105 | message["message"] = "Failed to send message."; | ||
106 | } else { | ||
107 | return; | ||
108 | } | ||
109 | } else if (notification.type == Sink::Notification::Status) { | ||
110 | if (notification.code == Sink::ApplicationDomain::ErrorStatus) { | ||
111 | //A resource entered error status | ||
112 | message["type"] = Notification::Warning; | ||
113 | message["message"] = "A resource experienced an error."; | ||
114 | } else { | ||
115 | return; | ||
116 | } | ||
117 | } else if (notification.type == Sink::Notification::Error) { | ||
118 | if (notification.code == Sink::ApplicationDomain::ConnectionError) { | ||
119 | message["type"] = Notification::Warning; | ||
120 | message["message"] = "Failed to connect to server."; | ||
121 | } else { | ||
122 | return; | ||
123 | } | ||
124 | } else if (notification.type == Sink::Notification::Info) { | ||
125 | if (notification.code == Sink::ApplicationDomain::TransmissionSuccess) { | ||
126 | message["type"] = Notification::Info; | ||
127 | message["message"] = "A message has been sent."; | ||
128 | } else { | ||
129 | return; | ||
130 | } | ||
131 | } else { | ||
132 | return; | ||
133 | } | ||
134 | }); | ||
135 | |||
136 | } | ||
137 | |||
138 | Sink::Notifier mNotifier; | ||
139 | |||
140 | }; | ||
141 | |||
diff --git a/framework/src/sinkfabric.h b/framework/src/sinkfabric.h new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/framework/src/sinkfabric.h | |||