diff options
31 files changed, 795 insertions, 144 deletions
diff --git a/applications/kmail-mobile/Avatar.qml b/applications/kube-mail-mobile/Avatar.qml index 3d3ffb2e..3d3ffb2e 100644 --- a/applications/kmail-mobile/Avatar.qml +++ b/applications/kube-mail-mobile/Avatar.qml | |||
diff --git a/applications/kmail-mobile/ColorPalette.qml b/applications/kube-mail-mobile/ColorPalette.qml index c3993954..c3993954 100644 --- a/applications/kmail-mobile/ColorPalette.qml +++ b/applications/kube-mail-mobile/ColorPalette.qml | |||
diff --git a/applications/kmail-mobile/ComposerView.qml b/applications/kube-mail-mobile/ComposerView.qml index d2f478b0..d2f478b0 100644 --- a/applications/kmail-mobile/ComposerView.qml +++ b/applications/kube-mail-mobile/ComposerView.qml | |||
diff --git a/applications/kmail-mobile/FolderListModel.qml b/applications/kube-mail-mobile/FolderListModel.qml index 19093d51..19093d51 100644 --- a/applications/kmail-mobile/FolderListModel.qml +++ b/applications/kube-mail-mobile/FolderListModel.qml | |||
diff --git a/applications/kmail-mobile/FolderListView.qml b/applications/kube-mail-mobile/FolderListView.qml index 1baa03b6..1baa03b6 100644 --- a/applications/kmail-mobile/FolderListView.qml +++ b/applications/kube-mail-mobile/FolderListView.qml | |||
diff --git a/applications/kmail-mobile/MailListModel.qml b/applications/kube-mail-mobile/MailListModel.qml index 4b425b90..4b425b90 100644 --- a/applications/kmail-mobile/MailListModel.qml +++ b/applications/kube-mail-mobile/MailListModel.qml | |||
diff --git a/applications/kmail-mobile/MailListView.qml b/applications/kube-mail-mobile/MailListView.qml index 869ce5e5..869ce5e5 100644 --- a/applications/kmail-mobile/MailListView.qml +++ b/applications/kube-mail-mobile/MailListView.qml | |||
diff --git a/applications/kmail-mobile/SingleMailView.qml b/applications/kube-mail-mobile/SingleMailView.qml index ae184c4a..ae184c4a 100644 --- a/applications/kmail-mobile/SingleMailView.qml +++ b/applications/kube-mail-mobile/SingleMailView.qml | |||
diff --git a/applications/kmail-mobile/main.qml b/applications/kube-mail-mobile/main.qml index 751c080c..751c080c 100644 --- a/applications/kmail-mobile/main.qml +++ b/applications/kube-mail-mobile/main.qml | |||
diff --git a/applications/kube-mail/package/contents/ui/Composer.qml b/applications/kube-mail/package/contents/ui/Composer.qml new file mode 100644 index 00000000..d32ee7c6 --- /dev/null +++ b/applications/kube-mail/package/contents/ui/Composer.qml | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
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 3 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 | //import org.kde.kube.mail 1.0 as Mail | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | import QtQuick 2.4 | ||
20 | import QtQuick.Controls 1.3 | ||
21 | import QtQuick.Layouts 1.1 | ||
22 | |||
23 | Item { | ||
24 | id: root | ||
25 | |||
26 | ColumnLayout { | ||
27 | |||
28 | anchors.fill: parent | ||
29 | |||
30 | GridLayout { | ||
31 | |||
32 | columns: 2 | ||
33 | |||
34 | Label { | ||
35 | text: "To" | ||
36 | } | ||
37 | |||
38 | TextField { | ||
39 | id: to | ||
40 | |||
41 | Layout.fillWidth: true | ||
42 | } | ||
43 | |||
44 | Label { | ||
45 | text: "Cc" | ||
46 | } | ||
47 | |||
48 | TextField { | ||
49 | id: cc | ||
50 | |||
51 | Layout.fillWidth: true | ||
52 | } | ||
53 | |||
54 | Label { | ||
55 | text: "Bcc" | ||
56 | } | ||
57 | |||
58 | TextField { | ||
59 | id: bcc | ||
60 | |||
61 | Layout.fillWidth: true | ||
62 | } | ||
63 | } | ||
64 | |||
65 | TextField { | ||
66 | id: subject | ||
67 | |||
68 | Layout.fillWidth: true | ||
69 | |||
70 | placeholderText: "Subject" | ||
71 | } | ||
72 | |||
73 | TextArea { | ||
74 | id: content | ||
75 | |||
76 | Layout.fillWidth: true | ||
77 | Layout.fillHeight: true | ||
78 | |||
79 | } | ||
80 | |||
81 | RowLayout { | ||
82 | Button { | ||
83 | text: "Send" | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | } | ||
diff --git a/applications/kube-mail/package/contents/ui/main.qml b/applications/kube-mail/package/contents/ui/main.qml index 33744157..ef37ae19 100644 --- a/applications/kube-mail/package/contents/ui/main.qml +++ b/applications/kube-mail/package/contents/ui/main.qml | |||
@@ -32,16 +32,16 @@ ApplicationWindow { | |||
32 | 32 | ||
33 | visible: true | 33 | visible: true |
34 | 34 | ||
35 | Action.ActionHandler { | 35 | // Action.ActionHandler { |
36 | actionId: "org.kde.kube.actions.mark-as-read" | 36 | // actionId: "org.kde.kube.actions.mark-as-read" |
37 | function isReady(context) { | 37 | // function isReady(context) { |
38 | return context.mail ? true : false; | 38 | // return context.mail ? true : false; |
39 | } | 39 | // } |
40 | 40 | // | |
41 | function handler(context) { | 41 | // function handler(context) { |
42 | console.warn("Got message:", context.mail) | 42 | // console.warn("Got message:", context.mail) |
43 | } | 43 | // } |
44 | } | 44 | // } |
45 | 45 | ||
46 | Action.Context { | 46 | Action.Context { |
47 | id: "maillistcontext" | 47 | id: "maillistcontext" |
@@ -55,6 +55,12 @@ ApplicationWindow { | |||
55 | context: maillistcontext | 55 | context: maillistcontext |
56 | } | 56 | } |
57 | 57 | ||
58 | Action.Action { | ||
59 | id: "deleteAction" | ||
60 | actionId: "org.kde.kube.actions.delete" | ||
61 | context: maillistcontext | ||
62 | } | ||
63 | |||
58 | //UI | 64 | //UI |
59 | toolBar: ToolBar { | 65 | toolBar: ToolBar { |
60 | 66 | ||
@@ -62,48 +68,38 @@ ApplicationWindow { | |||
62 | anchors.fill: parent | 68 | anchors.fill: parent |
63 | 69 | ||
64 | PlasmaComponents.ToolButton { | 70 | PlasmaComponents.ToolButton { |
65 | |||
66 | height: parent.height | 71 | height: parent.height |
67 | |||
68 | iconName: "mail-message-new" | 72 | iconName: "mail-message-new" |
69 | |||
70 | text: "Compose" | 73 | text: "Compose" |
74 | enabled: false | ||
71 | } | 75 | } |
72 | 76 | ||
73 | PlasmaComponents.ToolButton { | 77 | PlasmaComponents.ToolButton { |
74 | |||
75 | height: parent.height | 78 | height: parent.height |
76 | |||
77 | iconName: "mail-mark-unread" | 79 | iconName: "mail-mark-unread" |
78 | text: "Mark Unread" | 80 | text: "Mark As Read" |
79 | enabled: markAsReadAction.ready | 81 | enabled: markAsReadAction.ready |
80 | |||
81 | onClicked: { | 82 | onClicked: { |
82 | markAsReadAction.execute() | 83 | markAsReadAction.execute() |
83 | } | 84 | } |
84 | } | 85 | } |
85 | 86 | ||
86 | PlasmaComponents.ToolButton { | 87 | PlasmaComponents.ToolButton { |
87 | |||
88 | height: parent.height | 88 | height: parent.height |
89 | |||
90 | iconName: "mail-mark-important" | 89 | iconName: "mail-mark-important" |
91 | text: "Mark Important" | 90 | text: "Mark Important" |
92 | 91 | enabled: false | |
93 | onClicked: { | 92 | onClicked: { |
94 | mailList.markMailImportant(true) | ||
95 | } | 93 | } |
96 | } | 94 | } |
97 | 95 | ||
98 | PlasmaComponents.ToolButton { | 96 | PlasmaComponents.ToolButton { |
99 | |||
100 | height: parent.height | 97 | height: parent.height |
101 | |||
102 | iconName: "edit-delete" | 98 | iconName: "edit-delete" |
103 | text: "Delete Mail" | 99 | text: "Delete Mail" |
104 | 100 | enabled: deleteAction.ready | |
105 | onClicked: { | 101 | onClicked: { |
106 | mailList.deleteMail() | 102 | deleteAction.execute() |
107 | } | 103 | } |
108 | } | 104 | } |
109 | } | 105 | } |
@@ -114,7 +110,6 @@ ApplicationWindow { | |||
114 | 110 | ||
115 | FolderListView { | 111 | FolderListView { |
116 | id: folderListView | 112 | id: folderListView |
117 | |||
118 | width: unit.size * 55 | 113 | width: unit.size * 55 |
119 | Layout.maximumWidth: unit.size * 150 | 114 | Layout.maximumWidth: unit.size * 150 |
120 | Layout.minimumWidth: unit.size * 30 | 115 | Layout.minimumWidth: unit.size * 30 |
@@ -123,7 +118,6 @@ ApplicationWindow { | |||
123 | MailListView { | 118 | MailListView { |
124 | id: mailListView | 119 | id: mailListView |
125 | parentFolder: folderListView.currentFolder | 120 | parentFolder: folderListView.currentFolder |
126 | |||
127 | width: unit.size * 80 | 121 | width: unit.size * 80 |
128 | Layout.maximumWidth: unit.size * 250 | 122 | Layout.maximumWidth: unit.size * 250 |
129 | Layout.minimumWidth: unit.size * 50 | 123 | Layout.minimumWidth: unit.size * 50 |
@@ -132,7 +126,6 @@ ApplicationWindow { | |||
132 | SingleMailView { | 126 | SingleMailView { |
133 | id: mailView | 127 | id: mailView |
134 | mail: mailListView.currentMail | 128 | mail: mailListView.currentMail |
135 | |||
136 | Layout.fillWidth: true | 129 | Layout.fillWidth: true |
137 | } | 130 | } |
138 | 131 | ||
@@ -141,7 +134,6 @@ ApplicationWindow { | |||
141 | //TODO find a better way to scale UI | 134 | //TODO find a better way to scale UI |
142 | Item { | 135 | Item { |
143 | id: unit | 136 | id: unit |
144 | |||
145 | property int size: 5 | 137 | property int size: 5 |
146 | } | 138 | } |
147 | 139 | ||
diff --git a/docs/design.md b/docs/design.md index e8a39915..38edde01 100644 --- a/docs/design.md +++ b/docs/design.md | |||
@@ -3,16 +3,17 @@ | |||
3 | ## Overview | 3 | ## Overview |
4 | Kube is supposed to be a small and concise codebase that is easy to modify and evolve. | 4 | Kube is supposed to be a small and concise codebase that is easy to modify and evolve. |
5 | 5 | ||
6 | It's following a reactive model, where in one direction we have controllers generating modifications, and in the other direction models updating themselves on changes. | 6 | It's following a reactive model, where in one direction we have actions generating modifications, and in the other direction models updating themselves on changes. |
7 | 7 | ||
8 | The overall architecture is split into three layers; Ui, Domain Logic and Infrastructure. | 8 | The overall architecture is split into three layers; Ui, Domain Logic and Infrastructure. |
9 | 9 | ||
10 | ``` | 10 | ``` |
11 | +----------------------------+ | 11 | +----------------------------+ |
12 | | UI / Application | | 12 | | UI Components | |
13 | +----------------------------+ | 13 | +----------------------------+ |
14 | | | | 14 | | | |
15 | | Domain Logic | | 15 | | Domain Logic | |
16 | | Actions/Models | | ||
16 | | | | 17 | | | |
17 | +--------------+------+------+ | 18 | +--------------+------+------+ |
18 | | | | | | 19 | | | | | |
@@ -21,9 +22,9 @@ The overall architecture is split into three layers; Ui, Domain Logic and Infras | |||
21 | +--------------+------+------+ | 22 | +--------------+------+------+ |
22 | ``` | 23 | ``` |
23 | 24 | ||
24 | The UI Layer consists of views (mostly written in QML), view-models (models that are view specific and potentially implement user interaction details), and the glue code to use various controllers from the interface. Different UI layers may exist for different form factors. | 25 | The UI Layer consists of views (mostly written in QML), view-models (models that are view specific and potentially implement user interaction details), and the glue code to use various models and actions from the interface. Different UI layers may exist for different form factors. |
25 | 26 | ||
26 | The domain logic layer holds the application state. It povides models to access data and controllers to act upon it. The domain logic is by definition Kube specific and not sharable with other applications, as it needs to be taylored exactly according to the requirements of Kube. | 27 | The domain logic layer holds the application state. It povides models to access data and actions to act upon it. The domain logic is by definition Kube specific and not sharable with other applications, as it needs to be taylored exactly according to the requirements of Kube. |
27 | 28 | ||
28 | The infrastructure layer provides: | 29 | The infrastructure layer provides: |
29 | 30 | ||
@@ -32,20 +33,38 @@ The infrastructure layer provides: | |||
32 | * Various functionality provided by libraries (email sending, ldap, iTip handling, iCal implementation (kcalcore), vCard implementation, ...) | 33 | * Various functionality provided by libraries (email sending, ldap, iTip handling, iCal implementation (kcalcore), vCard implementation, ...) |
33 | Various bits of the infrastructure layer may be exchanged on different platforms, to i.e. integrate into native infrastructure providers on a platform. | 34 | Various bits of the infrastructure layer may be exchanged on different platforms, to i.e. integrate into native infrastructure providers on a platform. |
34 | 35 | ||
35 | Note: By using the onion architecture we ensure the infrastructure is exchangable just as well as the UI. | ||
36 | Note: The domain objects might also be specified in Akonadi Next. | ||
37 | |||
38 | ## UI / Application | 36 | ## UI / Application |
39 | The UI / Application layer contains all the views, and their composition, that make up the application. | 37 | The UI / Application layer contains all the view components, and their composition, that make up the application. |
40 | All the interactions between the different components are defined here. | 38 | All the interactions between the different components are defined here. |
41 | 39 | ||
42 | ### UI Component Interaction | 40 | ## Components |
43 | UI components will have to be able to: | 41 | The application consists of various application components. A component could be a maillist, an event-editor or the complete kube-mail application. Each component is instantiable on it's own, and has an API to interact with it. The API i.e. allows to set a folder for the maillist, or an event for the event-editor. Components can be nested (a component can instantiate another component) |
42 | |||
43 | A component primarily is a QML UI. | ||
44 | |||
45 | The QML UI is built on top of: | ||
46 | |||
47 | * One or more models that are instantiated to provide the data. | ||
48 | * Actions that are instantiated in QML. | ||
49 | |||
50 | ## Component interaction | ||
51 | The application is made up of various nested components that often need to interact with each other. | ||
52 | |||
53 | If we look at the example of the org.kube.mail component: | ||
54 | 1. The folderlist-component current-folder property is connected to maillist parentFolder property to display the mails of the currently selected folder. | ||
55 | 2. The "add-note" action might either switch to the org.kube.note application as currently displayed component, or it might just display a quick-note widget directly inline. | ||
56 | |||
57 | The first usecase can be achieved by the parent component doing a property binding to connect the different components together as desired. | ||
58 | |||
59 | The second usecase requires actions to interact with 'a' parent component, but without knowing with which one. Actions can thus be handled by ActionHandlers anywhere in the application. | ||
44 | 60 | ||
45 | * Load certain views directly inline (e.g. load a calendar into a mail with an invitation, or a maileditor into the maillist) | 61 | This makes it possible for i.e. a maillist to display a note-widget directly inline, or letting the parent component handle the action to show a full note editor. |
46 | * Change the overall application state by i.e. triggering the calendar to show a certain date-range. | 62 | If nothing handles the action, the root component (the shell)can switch to the note application component. |
47 | 63 | ||
48 | This is ideally decoupled in a way that the provider of such a service can be replaced without changing the users of the service. Additionally it should be possible for external applications (such as a plasmoid), to load the same views, possibly through the same mechanism. | 64 | ## Third party users of components |
65 | Since components are self contained and made available throuh the KPackage sytem, external applications can load fully functional Kube components. | ||
66 | |||
67 | For example, the KDE calendar plasmoid could load the Kube Event Viewer component when available, and thus provide Kube's full functionality of that component, including all actions etc, without having to reimplement the Domain Logic (as is the case if only data access is provided through akonadi). | ||
49 | 68 | ||
50 | ## Domain Logic | 69 | ## Domain Logic |
51 | 70 | ||
@@ -57,55 +76,58 @@ Models should always be reactive and configured with a query, so they are asynch | |||
57 | 76 | ||
58 | By implementing everything according to that model we can later on achieve lazy-loading of properties and zero-copy (or at least close to zero-copy) directly from storage without modifying anything besides data access. | 77 | By implementing everything according to that model we can later on achieve lazy-loading of properties and zero-copy (or at least close to zero-copy) directly from storage without modifying anything besides data access. |
59 | 78 | ||
60 | ### Controllers | 79 | Models are self contained and have an API to set i.e. a query for what to load. Models can load data from anywhere. Typically models are implemented in C++ to interface with the rest of the system, but some models may also be implemented directly in QML. |
61 | Use-case specific controllers are used to operate on the data. Controllers allow to completely separate the modifications from the view. | ||
62 | Rather than splitting controllers by domain type (e.g. an email controller, or a calendar controller), we specifically write controllers for specific usecases (e.g. an email editor), that exposes all required actions. That way we ensure that the API's a UI is working with is always clear an consice, and that we have all domain logic captured in the domain logic layer, rather than the UI layer. | ||
63 | Of course controllers will need to share functionality internally as soon as an action is available from more than one place. | ||
64 | 80 | ||
65 | ### Email Domain Logic | 81 | ### Actions |
66 | * Folder list | 82 | An action represents something that can be done, such as "mark as read", "delete", "move somewhere", but also "show this mail" or "give me a composer to write a mail". |
67 | * Folder List Controller | ||
68 | * Move mail to folder | ||
69 | * Move/Copy/Delete folder | ||
70 | * Synchronize folder | ||
71 | * Folder List Model | ||
72 | * Mixes akonadi next queries and subqueries (folder list with smart folders) | ||
73 | * name | ||
74 | * statistics | ||
75 | 83 | ||
76 | * Mail list | 84 | An action has: |
77 | * MailListController | 85 | * an id (i.e. org.kube.actions.make-as-read) |
78 | * Mark as read | 86 | * an active state (a property for the UI to know when the action can be triggered, that changes depending on the context) |
79 | * Flag as important | 87 | * an action context, which contains everything the action needs to execute. |
80 | * Move to trash | 88 | * an icon |
81 | * MailListModel | 89 | * a name |
82 | * subject | ||
83 | * date | ||
84 | * sender | ||
85 | * folder | ||
86 | * ThreadModel | ||
87 | * thread leader (otherwise like maillist model) | ||
88 | * number of mails in thread | ||
89 | 90 | ||
90 | * Mail Viewer | 91 | The action context contains the dataset the action works upon plus any additional information that is required. A mark-as-read action for instance only requires the mail-set to work on, while a tag-with action requires any entity (mail, event, ...) and a tag (unless there is one action per tag...). |
91 | * MailViewController | 92 | The action can, through property-binding, reevaluate its active state based on the currently set context that the UI continuously updates through property binding. Context objects can be shared by various actions. |
92 | * reply | ||
93 | * forward | ||
94 | * move to trash | ||
95 | * MailModel | ||
96 | * subject, date, sender, folder, content, attachments | ||
97 | 93 | ||
98 | ## Infrastructure | 94 | #### Automatic action discovery |
95 | While in many places explicit instantiation of actions is desirable, sometimes we may want to offer all available actions for a certain type. For this it should be possible to i.e. query for all actions that apply to a mail. That way it is possible to centrally add a new action that automatically becomes available everywhere. Note that this only works for actions that don't require an additional UI, since the components would have to embedd that somewhere. | ||
96 | |||
97 | #### Implementation | ||
98 | Actions are objects that provide the API, and that QML can instantiate directly with it's id. The C++ implementation looks up the action handler via a broker. | ||
99 | |||
100 | * Action: The interface to execute/launch the action. Forwards request and context to broker. | ||
101 | * ActionHandler: A handler for a specific action. Registers itself with the broker. | ||
102 | * ActionBroker: Forwards action requests to handlers. | ||
103 | * Context: The context containing everything the handler needs to execute the action. | ||
104 | |||
105 | ### Controller | ||
106 | For every domain object a controller is implemented to be able to edit the domain object. The domain object is a QObject with a QObject-property for every property of th edomain object and a QValidator, so editors can easily be build using property binding while providing property-level validation and feedback. | ||
107 | |||
108 | The domain object is exposed as an opaque QVariant that can i.e. be used in an action-context. This way details from the infrastructure layer don't leak to the UI layer | ||
99 | 109 | ||
110 | ### Notifications | ||
111 | The system will provide notifications from various sources. | ||
112 | |||
113 | Notifications could be: | ||
114 | |||
115 | * New mails arrived | ||
116 | * An error occurred | ||
117 | * A synchronization is in progress | ||
118 | * ... | ||
119 | |||
120 | Notifications can be displayed in various places of the application. | ||
121 | |||
122 | ## Infrastructure | ||
100 | The infrastructure layer interfaces with the rest of the system. It is the place where we can integrate with various native infrastructure parts. | 123 | The infrastructure layer interfaces with the rest of the system. It is the place where we can integrate with various native infrastructure parts. |
101 | The interface of the infrastructure layer, that is used by the domain logic, may not expose any implementation details of any infrastructure part, to ensure that all infrastructure parts are exchangable. | 124 | The interface of the infrastructure layer, that is used by the domain logic, may not expose any implementation details of any infrastructure part, to ensure that all infrastructure parts are exchangable. |
102 | 125 | ||
103 | Note: The infrastructure blocks will use only types provided by the domain logic. This means i.e. that no KCalCore containers may be used in such an interface. To avoid hard dependencies on any specific implementation, the infrastructure parts will have to have interfaces, and a factory must be used to supply concrete implementations. That way it is also possible to inject dummy implementations. | ||
104 | |||
105 | ### Akonadi Next | 126 | ### Akonadi Next |
106 | Akonadi Next is used for primary data access and handles all synchronization. | 127 | Akonadi Next is used for primary data access and handles all synchronization. |
107 | 128 | ||
108 | Interactions with Akonadi Next involve: | 129 | Interactions with Akonadi Next involve: |
130 | |||
109 | * Adding/removing/configuring resources | 131 | * Adding/removing/configuring resources |
110 | * Triggering synchronization | 132 | * Triggering synchronization |
111 | * Querying of data | 133 | * Querying of data |
@@ -141,71 +163,89 @@ Probably requires access to identities in some way. | |||
141 | * ObjectTreeParser | 163 | * ObjectTreeParser |
142 | * KMime | 164 | * KMime |
143 | 165 | ||
144 | ## Interaction with external applications | ||
145 | External applications, like the KDE calendar plasmoid, should be able to load parts of Kube when available. It should for instance be possible to load the Event editor as embeddable QML component, that is fully functional. That way it becomes very easy for third parties to provide extra functionality if Kube is installed, without having to reimplement the Domain Logic (as is the case if only data access is provided through akonadi). | ||
146 | |||
147 | The same mechanism should probably be used by Kube itself to ensure loose coupling and allow mashups with various content types. | ||
148 | |||
149 | Note: We'll probably want a component-viewer application to easily load and test individual components (similar to plasmoidviewer). | ||
150 | |||
151 | ## Testing | 166 | ## Testing |
152 | 167 | ||
153 | * Controllers can be tested by providing mock implementations of the relevant infrastructure parts. | 168 | TBD |
154 | * Models can be tested by providing fake implementations of the relevant infrastructure parts. | ||
155 | * Infrastructure parts can be tested individually. | ||
156 | |||
157 | # The new design | ||
158 | |||
159 | The application consists of various application components. A component could be a maillist, an event-editor or the complete kube-mail application. Each component is instantiable on it's own, and has an API to interact with it. The API i.e. allows to set a folder for the maillist, or an event for the event-editor. Components can be nested (a component can instantiate another component) | ||
160 | |||
161 | Components are requested from a factory, allowing to return different versions depending on modifiers passed in, or the global application context (i.e. mobile variants of the UI). | ||
162 | |||
163 | A component primarily is a QML UI. | ||
164 | The QML UI is built on top of: | ||
165 | * One or more models that are instantiated to provide the data. | ||
166 | * Actions that are instatiated in QML. | ||
167 | |||
168 | ## Models | ||
169 | 169 | ||
170 | Models are self contained and have an API to set i.e. a query for what to load. Models can load data from anywhere. | 170 | ## Problems/Notes: |
171 | * Dynamic switching between various component UI's can be solved using KPackage | ||
172 | * change-requests sometimes also need to be handled by sub-components | ||
173 | ** If you hit the reply button in the main view, but replies always work inline in the messagelist, the messagelist should still be able to capture the request and handle it. But if the request only goes to parent objects, that is not possible. Perhaps we need a pub-sub mechanism. | ||
171 | 174 | ||
175 | ## Example usage in QML | ||
172 | 176 | ||
173 | ## Actions | 177 | ``` |
174 | 178 | KubeActions.Action { | |
175 | An action represents something that can be done, such as "mark as read", "delete", "move somewhere". | 179 | requestId: "org.kde.kube.mail.reply" |
176 | 180 | onRequest { | |
177 | An action has: | 181 | mail: context.mail |
178 | * an id (org.kube.mail.make-as-read) | 182 | } |
179 | * an active state (a property for the UI to know when the action can be triggered, that changes depending on the context) | 183 | } |
180 | * an action context, which contains everything the action needs to execute. | 184 | |
181 | * an action icon | 185 | KubeActions.ActionContext { |
182 | * an action name | 186 | id: actionContext |
183 | 187 | mail: kubeMailListView.currentMail | |
184 | The action context contains the dataset the action works upon plus any additional information that is required. A mark-as-read action for instance only requires the mail-set to work on, while a tag-with action requires any entity (mail, event, ...) and a tag (unless there is one action per tag...). | 188 | } |
185 | The action can through property-binding reevaluate its active state based on the currently set context that the UI continuously updates through property binding. Context objects can be shared by various actions. | 189 | |
186 | 190 | KubeActions.ActionHandle { | |
187 | ### Automatic action discovery | 191 | property int progress |
188 | While in may places explicit instantiation of actions is desirable, sometimes we may want to offer all available actions for a certain type. For this it should be possible to i.e. query for all actions that apply to a mail. That way it is possible to centrally add a new action that automatically becomes available everywhere. Note that this only works for actions that don't require an additional UI, since the components would have to embedd that somewhere. | 192 | property bool complete |
189 | 193 | property bool error | |
190 | ### Implementation | 194 | property string errormessage |
191 | 195 | } | |
192 | Actions could be simply objects that provide the API, and that QML can instantiate directly with it's id. The C++ implementation of the action can then lookup the action implementation using the id and call it with it's context when executed. | 196 | |
193 | 197 | KubeActions.Action { | |
194 | ## Component interaction | 198 | id: markAsReadAction |
195 | 199 | action: "org.kde.kube.action.mark-as-read" | |
196 | The application is made up of various nested components that sometimes need to interact with each other. | 200 | context: actionContext |
197 | 201 | //execute() returns an ActionHandle | |
198 | If we look at the example of the org.kube.mail component: | 202 | } |
199 | 1. The folderlist-component current-folder property is connected to maillist parentFolder property to display the mails of the currently selected folder. | 203 | |
200 | 2. The "add-note" action might either switch the application state to the org.kube.note application, or it might just display a quick-note widget directly inline. | 204 | KubeComponents.FolderList { |
201 | 205 | id: kubeFolderListView | |
202 | The first usecase can be achieved by the parent component doing a property binding to connect the different components together as desired. | 206 | } |
207 | |||
208 | KubeComponents.MailList { | ||
209 | id: kubeMailListView | ||
210 | parentFolder: kubeFolderListView.currentFolder | ||
211 | } | ||
212 | |||
213 | KubeComponents.MailView { | ||
214 | id: kubeMailView | ||
215 | mail: kubeMailListView.currentMail | ||
216 | } | ||
217 | ``` | ||
203 | 218 | ||
204 | The second usecase requires actions to interact with 'a' parent component, but without knowing with which one. Actions can thus post requests for application state changes, that bubble up through the components and can be catched by any of the parent components. | 219 | ## Email Domain Logic |
220 | * Folder list | ||
221 | * Folder List Controller | ||
222 | * Move mail to folder | ||
223 | * Move/Copy/Delete folder | ||
224 | * Synchronize folder | ||
225 | * Folder List Model | ||
226 | * Mixes akonadi next queries and subqueries (folder list with smart folders) | ||
227 | * name | ||
228 | * statistics | ||
205 | 229 | ||
206 | This makes it possible for i.e. a maillist to display a note-widget directly inline, or handing the request up to the parent component which could show a full note editor. | 230 | * Mail list |
207 | And if nothing handles the request it bubbles up to the root component (the shell), which can then switch to the note application component. | 231 | * MailListController |
232 | * Mark as read | ||
233 | * Flag as important | ||
234 | * Move to trash | ||
235 | * MailListModel | ||
236 | * subject | ||
237 | * date | ||
238 | * sender | ||
239 | * folder | ||
240 | * ThreadModel | ||
241 | * thread leader (otherwise like maillist model) | ||
242 | * number of mails in thread | ||
208 | 243 | ||
209 | ### Application state changes requests | 244 | * Mail Viewer |
245 | * MailViewController | ||
246 | * reply | ||
247 | * forward | ||
248 | * move to trash | ||
249 | * MailModel | ||
250 | * subject, date, sender, folder, content, attachments | ||
210 | 251 | ||
211 | A request always requires a context that tells the handler what to do. This could be the note to edit, or the date-range to display in the calendar, or the recepient for the mail composer. | ||
diff --git a/docs/project.md b/docs/project.md index a710eb1b..9e0db20b 100644 --- a/docs/project.md +++ b/docs/project.md | |||
@@ -1,14 +1,14 @@ | |||
1 | # Why? | 1 | # Why? |
2 | This project started with the aim to produce a product that doesn't cater to all usecases, but does what it does well. | 2 | This project started with the aim to produce a product that doesn't cater to all usecases, but does what it does well. |
3 | We want a codebase that is well maintainable by a small team, and that can move fast. | 3 | We want a codebase that is well maintainable by a small team, and that can move fast. |
4 | We want a codebase where it is fast and easy to prototype new features and turn them eventually into full implementations, without compromising the quality of the rest of the system. Additionaly the product should be portable accross a variety of platforms, including mobile, not only due to a portable codebase, but also due to different interfaces for the various formfactors. | 4 | We want a codebase where it is fast and easy to prototype new features and turn them eventually into full implementations, without compromising the quality of the rest of the system. Additionaly the product should be portable accross a variety of platforms, including mobile, not only due to a portable codebase, but also due to different UI's for the various formfactors. |
5 | 5 | ||
6 | Because no existing codebase fullfills those premises or easily allows to reach them, this project started. | 6 | Because no existing codebase fullfills those premises or easily allows to reach them, this project started. |
7 | 7 | ||
8 | 8 | ||
9 | ## Differentiators | 9 | ## Differentiators |
10 | In order to avoid simply replicating what's already existing it's important to know how this product differentiates to other existing solutions. | 10 | In order to avoid simply replicating what's already existing it's important to know how this product differentiates to other existing solutions. |
11 | This section is supposed to outline that | 11 | This section is supposed to outline that. |
12 | 12 | ||
13 | * To Roundcube Next | 13 | * To Roundcube Next |
14 | * Native application | 14 | * Native application |
@@ -53,7 +53,7 @@ Team Members: Michael Bohlender, Sandro Knauss, Aaron Seigo | |||
53 | 53 | ||
54 | It's the team leads responsibility to: | 54 | It's the team leads responsibility to: |
55 | 55 | ||
56 | * Organize regular online meetings (medium yet unknown) | 56 | * Organize regular online meetings (so far on google hangouts) |
57 | * Give direction to the product and ensure it's followed | 57 | * Give direction to the product and ensure it's followed |
58 | * Direct development and oversee decisions | 58 | * Direct development and oversee decisions |
59 | * Ensure documentation of decisions | 59 | * Ensure documentation of decisions |
@@ -66,10 +66,17 @@ Should the team not be able to reach consensus, the team lead makes the final de | |||
66 | NOTE: We should probably have a phabricator board for open decisions. | 66 | NOTE: We should probably have a phabricator board for open decisions. |
67 | 67 | ||
68 | ## Planning | 68 | ## Planning |
69 | All planning happens on the KDE Phabricator instance: https://phabricator.kde.org/project/view/43/ | 69 | All planning happens on the [KDE Phabricator instance](https://phabricator.kde.org/project/view/43/). |
70 | 70 | ||
71 | ## Releases / Milestones | 71 | ## Releases / Milestones |
72 | Releases will follow achieved milestones. Milestones are assembled from tasks on the roadmap. | 72 | Releases will follow achieved milestones. Milestones are assembled from tasks on the roadmap. |
73 | 73 | ||
74 | ## Versioning | 74 | ## Versioning |
75 | The product will follow the semantic versioning scheme (semver.org), with each feature release corresponding to a milestone on phabricator. | 75 | The product will follow the semantic versioning scheme (semver.org), with each feature release corresponding to a milestone on phabricator. |
76 | |||
77 | ## Git repository | ||
78 | The git repository can be found here: [git://anongit.kde.org/kontact-quick](git://anongit.kde.org/kontact-quick) | ||
79 | |||
80 | The "development" branch is used for the latest development version, master is always stable and always releasable. Branches for specific versions that receive patch releases may be created as required. | ||
81 | |||
82 | For new developments use feature branches prefixed with "feature/" or simply use the "git flow" tool. | ||
diff --git a/docs/usecases.md b/docs/usecases.md new file mode 100644 index 00000000..4d08d9f7 --- /dev/null +++ b/docs/usecases.md | |||
@@ -0,0 +1,162 @@ | |||
1 | |||
2 | U1 Finding mail | ||
3 | U 1.1 As a user I want to see my unread mail. # | ||
4 | U 1.2 As a user I want to see my important mail | ||
5 | U 1.3 As a user I want to see the latest mail from a specific folder # | ||
6 | U 1.4 As a user I want to see the latest mail from a specific account | ||
7 | U 1.5 As a user I want to see the latest mail from all accounts | ||
8 | U 1.6 As a user I want to search for a specific email # | ||
9 | U1.6.1 by search string matching the full mail # | ||
10 | U 1.7 As a user I want to get an overview over how many unread mails I have (in my inbox) # | ||
11 | U 1.8 As a user I want to be notified about incoming mail | ||
12 | U 1.8.1 As a user I want to be able to set filterrules for incoming mail notifications | ||
13 | |||
14 | U 1.9 As a user I want to go though my mail by thread | ||
15 | U 1.10 As a user I want to find my emails by date range | ||
16 | U 1.11 As a user I want to find emails by sender | ||
17 | |||
18 | |||
19 | U 1.? As a user I want to regularly see mails that match a custom search query | ||
20 | |||
21 | |||
22 | |||
23 | U2 Managing mail (B is for bulk) | ||
24 | U 2.1 As a user I want to delete an email (B) # | ||
25 | U 2.2 As a user I want to mark an email as read/unread (B) # | ||
26 | U 2.3 As a user I want to mark an enail as imporatnt/not important (B) # | ||
27 | U 2.4 As a user I want to organize my emails into folders # | ||
28 | U 2.4.1 As a user I want to create a folder # | ||
29 | U 2.4.2 As a user I want to remove a folder # | ||
30 | U 2.4.3 As a user I want to move a folder # | ||
31 | U 2.4.4 As a user I want to move an email to a folder (B) # | ||
32 | U 2.4.5 As a user I want to copy an email to a folder (B) ??? # | ||
33 | U 2.4.6 As a user I want to set remote filter rules to automatically sort my incoming emails into folders | ||
34 | U 2.4.7 As a user I want to set local filter rules to automatically sort my incoming emails into folders | ||
35 | U 2.4.8 As a user I want to hide folders | ||
36 | U 2.4.9 As a user I want to bookmark my favourite folder | ||
37 | |||
38 | |||
39 | U 2-? As a user I want to archive an email (B) ??? | ||
40 | U 2-? As a user I want to print an email ??? | ||
41 | U 2-? As a user I want to mark email as spam (B) ??? | ||
42 | |||
43 | U3 Reading mail | ||
44 | U 3.I As a user I want to read an email # | ||
45 | U 3.2 As a user I want to add the sender to my addressbook | ||
46 | U 3.3 As a user I want to reply to an email # | ||
47 | U 3.3.1 As a user I want to reply to all # | ||
48 | U 3.3.2 As a user I want to reply to sender # | ||
49 | U 3.4 As a user I want to forward an email # | ||
50 | U 3.5 As a user I want to open an attachemnt # | ||
51 | U 3.6 As a user I want to save an attachment # | ||
52 | U 3.7 As a user I want view attachments inline | ||
53 | U 3.7.1 vcard | ||
54 | U 3.8 As a user I want to read html mails | ||
55 | |||
56 | |||
57 | |||
58 | U4 Writing email | ||
59 | U 4.1 As a user I want to write an email from scratch # | ||
60 | U 4.2 As a user I want to write an email from draft # | ||
61 | U 4.3 As a user I want to write an email from template | ||
62 | U 4.5 As a user I want to specify the subject # | ||
63 | U 4.6 As a user I want to add recievers (to / cc / bcc) # | ||
64 | U 4.6.1 from addressbook | ||
65 | U 4.6.2 from previous receivers / senders | ||
66 | U 4.6.3 by hand # | ||
67 | U 4.6.4 from ldap # | ||
68 | U 4.7 As a user I want to handle attachments # | ||
69 | U 4.7.1 As a user I want to add an attachment # | ||
70 | U 4.7.1.2 … from the cloud # | ||
71 | U 4.7.2 As a user I want to remove an attachment # | ||
72 | U 4.7.3 As a user I want to rename an attachment | ||
73 | U 4.7.4 As a user I want to shrink an attachment ??? | ||
74 | U 4.7.5 As a user I want to be warned about not having an attachment | ||
75 | U 4.8 As a user I want to write html mails | ||
76 | U 4.9 As a user I want to encrypt my mails | ||
77 | U 4.9.1 by hand | ||
78 | U 4.9.2 by policy | ||
79 | U 4.10 As a user I want to sign my messages | ||
80 | U 4.10.1 by hand | ||
81 | U 4.10.2 by policy | ||
82 | U 4.11 As a user I want to attach a signature to my mails | ||
83 | U 4.12 As a user I want to have my emails spellchecked | ||
84 | |||
85 | U 4.13 Send email from specific account | ||
86 | U 4.15 As a user I want to be able to send my email at a later time specified by me. | ||
87 | |||
88 | |||
89 | U 5 Account settup / configuration | ||
90 | U5.1 As a user I want to set up a Kolab Now account | ||
91 | U 5.2 As a user I want to set up a custom Kolab account #? | ||
92 | U 5.3 As a user I want to set up a maildir account # | ||
93 | U 5.4 As a user I want to set up a imap account (including smtp) #? | ||
94 | U 5.4.1 As a user I want to specify my Draft / Trash / Sent folder | ||
95 | U 5.5 As a user I want to delete an account | ||
96 | U 5.6 As a user I want to modify an account | ||
97 | U 5.6.1 As a user I want to add/modify/delete and additional identity | ||
98 | U 5.7 As a user I want to temporarily disable an account | ||
99 | U 5.8 As a user I want to see the online/offline state of my accounts | ||
100 | |||
101 | U 6 Crypto | ||
102 | U 6.1 As a user I want to be able to | ||
103 | |||
104 | U 7 Syncronize with server | ||
105 | U 7.1 As a user I want to specify which folder get synced | ||
106 | U 7.2 As a user I want to specfy how many email per folder get synced | ||
107 | U 7.3 As a user I want to specify the sync intervals | ||
108 | U 7.4 As a user I want to manually controll the sync | ||
109 | U 7.5 As a user I want to be able to folder sync priorities | ||
110 | |||
111 | |||
112 | U 10 Special features | ||
113 | U 10.1 As a user I want to set my out of office status | ||
114 | U 10.2 As a user I want to be only load a partial mail (mobile) | ||
115 | |||
116 | |||
117 | |||
118 | |||
119 | |||
120 | |||
121 | |||
122 | |||
123 | |||
124 | |||
125 | |||
126 | |||
127 | |||
128 | Calendar | ||
129 | |||
130 | U 1 viewing schedule | ||
131 | |||
132 | U 1.1 As a user I want to know what is on the agenda for today | ||
133 | U 1.2 As a user I want to get an overview over what is coming next week / month | ||
134 | U 1.3 As a user I want to see when I have free timeslots | ||
135 | U 1.4 As a user I want to be reminded about upcoming events | ||
136 | U 1.5 As a user I want to see the schedule of my colleagues | ||
137 | U 1.6 As a user I want to search for an event | ||
138 | U 1.7 As a user I want to see the deadlines for my tasks in the calendar | ||
139 | U 1.8 As a user I want to see the start date for my tasks | ||
140 | |||
141 | U 2 Creating and Importing and Exporting | ||
142 | U 2.1 As a user I want to create a new event from scratch | ||
143 | U 2.2 As a user I want to import a calandar (e.g. university schedule) | ||
144 | U 2.3 As a user I want to import an event | ||
145 | U 2.4 As a user I want to export an event | ||
146 | U 2.5 As a user I want to export a calendar | ||
147 | U 2.6 As a user I want to publish an event | ||
148 | U 2.6.1 by sending it by email | ||
149 | |||
150 | U 3 Invitations | ||
151 | U 3.1 As a user I want to invite people to an event | ||
152 | U 3.2 As a user I want to schedule an event | ||
153 | U 3.2.1 with my colleagues | ||
154 | U 3.2.2 with external people (and my colleagues) | ||
155 | U 3.3 As a user I want to react to invitations | ||
156 | U 3.3.1 As a user I want to see if I have time for an event I was invited to | ||
157 | U 3.3.2 As a user I want to decline an invitation | ||
158 | U 3.3.3 As a user I want to accept an invitation and add it to my calendar | ||
159 | U 3.3.4 As a user I want to propose a different timeslot for an event | ||
160 | U 3.3.5 As a user I want to restart the scheduling process to find a different time slot | ||
161 | U 3.4 As a user I want to get an overview over pending invitations I sent | ||
162 | U 3.5 As a user I want to get an overview over new / incoming invitations \ No newline at end of file | ||
diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 8301392a..0b2b505d 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt | |||
@@ -24,6 +24,7 @@ find_package(KF5Libkleo) | |||
24 | 24 | ||
25 | set(CMAKE_AUTOMOC ON) | 25 | set(CMAKE_AUTOMOC ON) |
26 | add_definitions("-Wall -std=c++0x -g") | 26 | add_definitions("-Wall -std=c++0x -g") |
27 | include_directories(.) | ||
27 | include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/common) | 28 | include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/common) |
28 | include_directories(SYSTEM /work/install/include/) | 29 | include_directories(SYSTEM /work/install/include/) |
29 | include_directories(SYSTEM /work/install/include/KF5/) | 30 | include_directories(SYSTEM /work/install/include/KF5/) |
diff --git a/framework/mail/CMakeLists.txt b/framework/mail/CMakeLists.txt index 0abc6880..9a32cc83 100644 --- a/framework/mail/CMakeLists.txt +++ b/framework/mail/CMakeLists.txt | |||
@@ -5,6 +5,7 @@ set(mailplugin_SRCS | |||
5 | singlemailcontroller.cpp | 5 | singlemailcontroller.cpp |
6 | folderlistmodel.cpp | 6 | folderlistmodel.cpp |
7 | folderlistcontroller.cpp | 7 | folderlistcontroller.cpp |
8 | actions/akonadiactions.cpp | ||
8 | objecttreesource.cpp | 9 | objecttreesource.cpp |
9 | stringhtmlwriter.cpp | 10 | stringhtmlwriter.cpp |
10 | ) | 11 | ) |
@@ -13,7 +14,7 @@ add_library(mailplugin SHARED ${mailplugin_SRCS}) | |||
13 | 14 | ||
14 | qt5_use_modules(mailplugin Core Quick Qml) | 15 | qt5_use_modules(mailplugin Core Quick Qml) |
15 | 16 | ||
16 | target_link_libraries(mailplugin KF5::akonadi2common KF5::Otp) | 17 | target_link_libraries(mailplugin actionplugin KF5::akonadi2common KF5::Otp actionplugin) |
17 | 18 | ||
18 | install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/kube/mail) | 19 | install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/kube/mail) |
19 | install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/kube/mail) | 20 | install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/kube/mail) |
diff --git a/framework/mail/actions/akonadiactions.cpp b/framework/mail/actions/akonadiactions.cpp new file mode 100644 index 00000000..d0a51deb --- /dev/null +++ b/framework/mail/actions/akonadiactions.cpp | |||
@@ -0,0 +1,75 @@ | |||
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 "akonadiactions.h" | ||
20 | |||
21 | #include <actions/context.h> | ||
22 | |||
23 | #include <akonadi2common/clientapi.h> | ||
24 | |||
25 | using namespace Kube; | ||
26 | |||
27 | ActionHandlerHelper::ActionHandlerHelper(const QByteArray &actionId, const std::function<bool(Context*)> &isReady, const std::function<void(Context*)> &handler) | ||
28 | : ActionHandler(nullptr), | ||
29 | isReadyFunction(isReady), | ||
30 | handlerFunction(handler) | ||
31 | { | ||
32 | setActionId(actionId); | ||
33 | } | ||
34 | |||
35 | bool ActionHandlerHelper::isActionReady(Context *context) | ||
36 | { | ||
37 | return isReadyFunction(context); | ||
38 | } | ||
39 | |||
40 | void ActionHandlerHelper::execute(Context *context) | ||
41 | { | ||
42 | handlerFunction(context); | ||
43 | } | ||
44 | |||
45 | static ActionHandlerHelper markAsReadHandler("org.kde.kube.actions.mark-as-read", | ||
46 | [](Context *context) -> bool { | ||
47 | return context->property("mail").isValid(); | ||
48 | }, | ||
49 | [](Context *context) { | ||
50 | auto mail = context->property("mail").value<Akonadi2::ApplicationDomain::Mail::Ptr>(); | ||
51 | if (!mail) { | ||
52 | qWarning() << "Failed to get the mail mail: " << context->property("mail"); | ||
53 | return; | ||
54 | } | ||
55 | mail->setProperty("unread", false); | ||
56 | qDebug() << "Mark as read " << mail->identifier(); | ||
57 | Akonadi2::Store::modify(*mail).exec(); | ||
58 | } | ||
59 | ); | ||
60 | |||
61 | static ActionHandlerHelper deleteHandler("org.kde.kube.actions.delete", | ||
62 | [](Context *context) -> bool { | ||
63 | return context->property("mail").isValid(); | ||
64 | }, | ||
65 | [](Context *context) { | ||
66 | auto mail = context->property("mail").value<Akonadi2::ApplicationDomain::Mail::Ptr>(); | ||
67 | if (!mail) { | ||
68 | qWarning() << "Failed to get the mail mail: " << context->property("mail"); | ||
69 | return; | ||
70 | } | ||
71 | mail->setProperty("unread", false); | ||
72 | qDebug() << "Remove " << mail->identifier(); | ||
73 | Akonadi2::Store::remove(*mail).exec(); | ||
74 | } | ||
75 | ); | ||
diff --git a/framework/mail/actions/akonadiactions.h b/framework/mail/actions/akonadiactions.h new file mode 100644 index 00000000..a583ebf8 --- /dev/null +++ b/framework/mail/actions/akonadiactions.h | |||
@@ -0,0 +1,40 @@ | |||
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 <actions/actionhandler.h> | ||
22 | #include <functional> | ||
23 | |||
24 | namespace Kube { | ||
25 | class Context; | ||
26 | |||
27 | class ActionHandlerHelper : public ActionHandler | ||
28 | { | ||
29 | Q_OBJECT | ||
30 | public: | ||
31 | ActionHandlerHelper(const QByteArray &actionId, const std::function<bool(Context*)> &, const std::function<void(Context*)> &); | ||
32 | |||
33 | bool isActionReady(Context *context) Q_DECL_OVERRIDE; | ||
34 | void execute(Context *context) Q_DECL_OVERRIDE; | ||
35 | private: | ||
36 | const std::function<bool(Context*)> isReadyFunction; | ||
37 | const std::function<void(Context*)> handlerFunction; | ||
38 | }; | ||
39 | |||
40 | } | ||
diff --git a/framework/mail/folderlistcontroller.cpp b/framework/mail/folderlistcontroller.cpp index 9edc547c..3b1cf9f8 100644 --- a/framework/mail/folderlistcontroller.cpp +++ b/framework/mail/folderlistcontroller.cpp | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #include "folderlistcontroller.h" | 21 | #include "folderlistcontroller.h" |
2 | 22 | ||
3 | #include "folderlistmodel.h" | 23 | #include "folderlistmodel.h" |
diff --git a/framework/mail/folderlistcontroller.h b/framework/mail/folderlistcontroller.h index 84ce24be..11057f21 100644 --- a/framework/mail/folderlistcontroller.h +++ b/framework/mail/folderlistcontroller.h | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #pragma once | 21 | #pragma once |
2 | 22 | ||
3 | #include "folderlistmodel.h" | 23 | #include "folderlistmodel.h" |
diff --git a/framework/mail/folderlistmodel.cpp b/framework/mail/folderlistmodel.cpp index 0f66c46f..204dfdbf 100644 --- a/framework/mail/folderlistmodel.cpp +++ b/framework/mail/folderlistmodel.cpp | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #include "folderlistmodel.h" | 21 | #include "folderlistmodel.h" |
2 | #include <akonadi2common/clientapi.h> | 22 | #include <akonadi2common/clientapi.h> |
3 | #include <akonadi2common/applicationdomaintype.h> | 23 | #include <akonadi2common/applicationdomaintype.h> |
diff --git a/framework/mail/folderlistmodel.h b/framework/mail/folderlistmodel.h index 9ce3ee79..d412c29c 100644 --- a/framework/mail/folderlistmodel.h +++ b/framework/mail/folderlistmodel.h | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #pragma once | 21 | #pragma once |
2 | 22 | ||
3 | #include <QObject> | 23 | #include <QObject> |
diff --git a/framework/mail/maillistcontroller.cpp b/framework/mail/maillistcontroller.cpp index 07baeb01..ed353b70 100644 --- a/framework/mail/maillistcontroller.cpp +++ b/framework/mail/maillistcontroller.cpp | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #include "maillistcontroller.h" | 21 | #include "maillistcontroller.h" |
2 | 22 | ||
3 | #include <QStringList> | 23 | #include <QStringList> |
diff --git a/framework/mail/maillistcontroller.h b/framework/mail/maillistcontroller.h index 3c969403..959c63a3 100644 --- a/framework/mail/maillistcontroller.h +++ b/framework/mail/maillistcontroller.h | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #pragma once | 21 | #pragma once |
2 | 22 | ||
3 | #include "maillistmodel.h" | 23 | #include "maillistmodel.h" |
diff --git a/framework/mail/maillistmodel.cpp b/framework/mail/maillistmodel.cpp index f7a92097..2314e155 100644 --- a/framework/mail/maillistmodel.cpp +++ b/framework/mail/maillistmodel.cpp | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #include "maillistmodel.h" | 21 | #include "maillistmodel.h" |
2 | 22 | ||
3 | #include "stringhtmlwriter.h" | 23 | #include "stringhtmlwriter.h" |
diff --git a/framework/mail/maillistmodel.h b/framework/mail/maillistmodel.h index 7eb55ffd..1d56e6b8 100644 --- a/framework/mail/maillistmodel.h +++ b/framework/mail/maillistmodel.h | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #pragma once | 21 | #pragma once |
2 | 22 | ||
3 | #include <akonadi2common/clientapi.h> | 23 | #include <akonadi2common/clientapi.h> |
diff --git a/framework/mail/mailplugin.cpp b/framework/mail/mailplugin.cpp index bf92f4e7..8b35dfb7 100644 --- a/framework/mail/mailplugin.cpp +++ b/framework/mail/mailplugin.cpp | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #include "mailplugin.h" | 21 | #include "mailplugin.h" |
2 | 22 | ||
3 | #include "maillistmodel.h" | 23 | #include "maillistmodel.h" |
diff --git a/framework/mail/mailplugin.h b/framework/mail/mailplugin.h index e835c384..ebd091ee 100644 --- a/framework/mail/mailplugin.h +++ b/framework/mail/mailplugin.h | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #pragma once | 21 | #pragma once |
2 | 22 | ||
3 | #include <QQmlEngine> | 23 | #include <QQmlEngine> |
diff --git a/framework/mail/singlemailcontroller.cpp b/framework/mail/singlemailcontroller.cpp index fecf2fbc..5f7a6d93 100644 --- a/framework/mail/singlemailcontroller.cpp +++ b/framework/mail/singlemailcontroller.cpp | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #include "singlemailcontroller.h" | 21 | #include "singlemailcontroller.h" |
2 | 22 | ||
3 | SingleMailController::SingleMailController(QObject *parent) : QObject(parent), m_model(new MailListModel) | 23 | SingleMailController::SingleMailController(QObject *parent) : QObject(parent), m_model(new MailListModel) |
diff --git a/framework/mail/singlemailcontroller.h b/framework/mail/singlemailcontroller.h index bdac971c..283b03c4 100644 --- a/framework/mail/singlemailcontroller.h +++ b/framework/mail/singlemailcontroller.h | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net> | ||
3 | Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Library General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
13 | License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | 02110-1301, USA. | ||
19 | */ | ||
20 | |||
1 | #pragma once | 21 | #pragma once |
2 | 22 | ||
3 | #include "maillistmodel.h" | 23 | #include "maillistmodel.h" |
@@ -1 +1,7 @@ | |||
1 | site_name: Kontact Quick | 1 | site_name: Kube |
2 | pages: | ||
3 | - Index: index.md | ||
4 | - Project: project.md | ||
5 | - Design: design.md | ||
6 | - Requirements: requirements.md | ||
7 | theme: readthedocs | ||