diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2018-01-09 09:35:59 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2018-01-10 12:42:13 +0100 |
commit | 6d726bb10386b3d7f5481d41b735ec06cb2163ad (patch) | |
tree | 4d591b67b54c5a83f9f1d718a4576c8ccf05859b /components | |
parent | 2d9944bd0b5cd1dd202d9dc6318d612e1aca4241 (diff) | |
download | kube-6d726bb10386b3d7f5481d41b735ec06cb2163ad.tar.gz kube-6d726bb10386b3d7f5481d41b735ec06cb2163ad.zip |
Install composer/converations/people as separate views and load them
dynamically.
Diffstat (limited to 'components')
-rw-r--r-- | components/kube/qml/AccountsView.qml | 143 | ||||
-rw-r--r-- | components/kube/qml/AddresseeListEditor.qml | 138 | ||||
-rw-r--r-- | components/kube/qml/ComposerView.qml | 533 | ||||
-rw-r--r-- | components/kube/qml/Kube.qml | 228 | ||||
-rw-r--r-- | components/kube/qml/LogView.qml | 329 | ||||
-rw-r--r-- | components/kube/qml/LoginView.qml | 52 | ||||
-rw-r--r-- | components/kube/qml/MailView.qml | 120 | ||||
-rw-r--r-- | components/kube/qml/PeopleView.qml | 38 | ||||
-rw-r--r-- | components/kube/qml/ViewManager.qml | 84 | ||||
-rw-r--r-- | components/kube/tests/tst_accountsview.qml | 37 | ||||
-rw-r--r-- | components/kube/tests/tst_composerview.qml | 97 | ||||
-rw-r--r-- | components/kube/tests/tst_logview.qml | 65 | ||||
-rw-r--r-- | components/kube/tests/tst_mailview.qml | 37 | ||||
-rw-r--r-- | components/kube/tests/tst_peopleview.qml | 37 |
14 files changed, 147 insertions, 1791 deletions
diff --git a/components/kube/qml/AccountsView.qml b/components/kube/qml/AccountsView.qml deleted file mode 100644 index 9b774907..00000000 --- a/components/kube/qml/AccountsView.qml +++ /dev/null | |||
@@ -1,143 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 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 2 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 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
17 | */ | ||
18 | |||
19 | import QtQuick 2.4 | ||
20 | import QtQuick.Layouts 1.1 | ||
21 | import QtQuick.Controls 1.3 as Controls | ||
22 | import QtQuick.Controls 2.0 | ||
23 | import org.kube.framework 1.0 as Kube | ||
24 | import org.kube.components.accounts 1.0 as KubeAccounts | ||
25 | |||
26 | FocusScope { | ||
27 | id: root | ||
28 | //Defines whether more than one account is supported. | ||
29 | property bool singleAccountMode: false | ||
30 | //Defines available account types. | ||
31 | property var availableAccountPlugins: ["kolabnow", "imap", "maildir", "gmail"] | ||
32 | |||
33 | Controls.SplitView { | ||
34 | height: parent.height | ||
35 | width: parent.width | ||
36 | |||
37 | Item { | ||
38 | id: accountList | ||
39 | width: Kube.Units.gridUnit * 12 | ||
40 | Layout.fillHeight: true | ||
41 | visible: !root.singleAccountMode | ||
42 | |||
43 | Kube.PositiveButton { | ||
44 | id: newAccountButton | ||
45 | anchors { | ||
46 | top: parent.top | ||
47 | left: parent.left | ||
48 | right: parent.right | ||
49 | margins: Kube.Units.largeSpacing | ||
50 | } | ||
51 | text: qsTr("New Account") | ||
52 | |||
53 | onClicked: accountWizard.open() | ||
54 | } | ||
55 | |||
56 | Kube.ListView { | ||
57 | id: listView | ||
58 | |||
59 | anchors { | ||
60 | top: newAccountButton.bottom | ||
61 | left: parent.left | ||
62 | right: parent.right | ||
63 | bottom: parent.bottom | ||
64 | topMargin: Kube.Units.largeSpacing | ||
65 | } | ||
66 | |||
67 | clip: true | ||
68 | |||
69 | model: Kube.AccountsModel {} | ||
70 | |||
71 | onCurrentItemChanged: { | ||
72 | if (currentItem) { | ||
73 | edit.accountId = currentItem.currentData.accountId | ||
74 | } | ||
75 | } | ||
76 | |||
77 | delegate: Kube.ListDelegate { | ||
78 | id: delegateRoot | ||
79 | |||
80 | Kube.Label { | ||
81 | anchors { | ||
82 | verticalCenter: parent.verticalCenter | ||
83 | left: parent.left | ||
84 | leftMargin: Kube.Units.largeSpacing | ||
85 | } | ||
86 | width: parent.width - Kube.Units.largeSpacing * 2 | ||
87 | |||
88 | text: model.name | ||
89 | color: delegateRoot.textColor | ||
90 | elide: Text.ElideRight | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | Item { | ||
97 | height: parent.height | ||
98 | width: Kube.Units.gridUnit * 20 | ||
99 | Layout.fillWidth: true | ||
100 | |||
101 | Kube.EditAccount { | ||
102 | id: edit | ||
103 | anchors { | ||
104 | fill: parent | ||
105 | bottomMargin: Kube.Units.largeSpacing | ||
106 | } | ||
107 | |||
108 | canRemove: !root.singleAccountMode | ||
109 | |||
110 | Component.onCompleted: { | ||
111 | //We don't have any accounts setup if accountId is empty, so we trigger the accountWizard | ||
112 | //FIXME: this assumes we load accounts synchronously, which we do right now. | ||
113 | if (accountId == "") { | ||
114 | //Require the setup to be completed since it's the first account | ||
115 | accountWizard.requireSetup = true | ||
116 | //Launch account wizard | ||
117 | accountWizard.open() | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | onActiveFocusChanged: { | ||
125 | if (activeFocus && accountWizard.visible) { | ||
126 | accountWizard.forceActiveFocus() | ||
127 | } | ||
128 | } | ||
129 | |||
130 | //BEGIN AccountWizard | ||
131 | KubeAccounts.AccountWizard { | ||
132 | id: accountWizard | ||
133 | |||
134 | parent: ApplicationWindow.overlay | ||
135 | height: app.height | ||
136 | width: app.width - app.sidebarWidth | ||
137 | x: app.sidebarWidth | ||
138 | y: 0 | ||
139 | |||
140 | availableAccountPlugins: root.availableAccountPlugins | ||
141 | } | ||
142 | //END AccountWizard | ||
143 | } | ||
diff --git a/components/kube/qml/AddresseeListEditor.qml b/components/kube/qml/AddresseeListEditor.qml deleted file mode 100644 index 8f9862e7..00000000 --- a/components/kube/qml/AddresseeListEditor.qml +++ /dev/null | |||
@@ -1,138 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Michael Bohlender, <michael.bohlender@kdemail.net> | ||
3 | * Copyright (C) 2017 Christian Mollekopf, <mollekopf@kolabsys.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | |||
21 | import QtQuick 2.7 | ||
22 | import QtQuick.Controls 1.3 | ||
23 | import QtQuick.Layouts 1.1 | ||
24 | |||
25 | import org.kube.framework 1.0 as Kube | ||
26 | |||
27 | FocusScope { | ||
28 | id: root | ||
29 | property variant controller | ||
30 | property variant completer | ||
31 | property bool encrypt: false | ||
32 | |||
33 | implicitHeight: listView.height + lineEdit.height | ||
34 | height: implicitHeight | ||
35 | |||
36 | Column { | ||
37 | anchors.fill: parent | ||
38 | |||
39 | spacing: Kube.Units.smallSpacing | ||
40 | |||
41 | ListView { | ||
42 | id: listView | ||
43 | anchors { | ||
44 | left: parent.left | ||
45 | right: parent.right | ||
46 | } | ||
47 | height: contentHeight | ||
48 | spacing: Kube.Units.smallSpacing | ||
49 | model: controller.model | ||
50 | delegate: Rectangle { | ||
51 | height: Kube.Units.gridUnit + Kube.Units.smallSpacing * 2 //smallSpacing for padding | ||
52 | width: parent.width | ||
53 | color: Kube.Colors.buttonColor | ||
54 | Row { | ||
55 | anchors { | ||
56 | top: parent.top | ||
57 | bottom: parent.bottom | ||
58 | left: parent.left | ||
59 | right: removeButton.left | ||
60 | margins: Kube.Units.smallSpacing | ||
61 | } | ||
62 | spacing: Kube.Units.smallSpacing | ||
63 | Kube.Label { | ||
64 | id: label | ||
65 | anchors { | ||
66 | top: parent.top | ||
67 | } | ||
68 | text: model.name | ||
69 | elide: Text.ElideRight | ||
70 | } | ||
71 | Kube.Icon { | ||
72 | anchors { | ||
73 | top: parent.top | ||
74 | } | ||
75 | height: Kube.Units.gridUnit | ||
76 | width: height | ||
77 | visible: root.encrypt | ||
78 | iconName: model.keyFound ? Kube.Icons.secure: Kube.Icons.insecure | ||
79 | } | ||
80 | } | ||
81 | Kube.IconButton { | ||
82 | id: removeButton | ||
83 | anchors { | ||
84 | right: parent.right | ||
85 | verticalCenter: parent.verticalCenter | ||
86 | margins: Kube.Units.smallSpacing | ||
87 | } | ||
88 | height: Kube.Units.gridUnit | ||
89 | width: height | ||
90 | onClicked: root.controller.remove(model.id) | ||
91 | padding: 0 | ||
92 | iconName: Kube.Icons.remove | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | |||
97 | FocusScope { | ||
98 | height: Kube.Units.gridUnit * Kube.Units.smallSpacing * 2 | ||
99 | width: parent.width | ||
100 | focus: true | ||
101 | |||
102 | Kube.TextButton { | ||
103 | id: button | ||
104 | text: "+ " + qsTr("Add recipient") | ||
105 | textColor: Kube.Colors.highlightColor | ||
106 | focus: true | ||
107 | onClicked: { | ||
108 | lineEdit.visible = true | ||
109 | lineEdit.forceActiveFocus() | ||
110 | } | ||
111 | } | ||
112 | |||
113 | Kube.AutocompleteLineEdit { | ||
114 | id: lineEdit | ||
115 | anchors { | ||
116 | left: parent.left | ||
117 | right: parent.right | ||
118 | } | ||
119 | visible: false | ||
120 | |||
121 | placeholderText: "+ " + qsTr("Add recipient") | ||
122 | model: root.completer.model | ||
123 | onSearchTermChanged: root.completer.searchString = searchTerm | ||
124 | onAccepted: { | ||
125 | root.controller.add({name: text}); | ||
126 | clear() | ||
127 | visible = false | ||
128 | button.forceActiveFocus() | ||
129 | } | ||
130 | onAborted: { | ||
131 | clear() | ||
132 | visible = false | ||
133 | button.forceActiveFocus() | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | } | ||
diff --git a/components/kube/qml/ComposerView.qml b/components/kube/qml/ComposerView.qml deleted file mode 100644 index 1eb88bb4..00000000 --- a/components/kube/qml/ComposerView.qml +++ /dev/null | |||
@@ -1,533 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Michael Bohlender, <michael.bohlender@kdemail.net> | ||
3 | * Copyright (C) 2017 Christian Mollekopf, <mollekopf@kolabsys.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | |||
21 | import QtQuick 2.7 | ||
22 | import QtQuick.Controls 1.3 | ||
23 | import QtQuick.Controls 2.0 as Controls2 | ||
24 | import QtQuick.Layouts 1.1 | ||
25 | import QtQuick.Dialogs 1.0 as Dialogs | ||
26 | |||
27 | import org.kube.framework 1.0 as Kube | ||
28 | |||
29 | Kube.View { | ||
30 | id: root | ||
31 | |||
32 | property bool newMessage: false | ||
33 | property bool loadAsDraft: false | ||
34 | property variant message: {} | ||
35 | property variant recipients: [] | ||
36 | |||
37 | resources: [ | ||
38 | Kube.ComposerController { | ||
39 | id: composerController | ||
40 | htmlBody: html.checked | ||
41 | sign: signCheckbox.checked | ||
42 | encrypt: encryptCheckbox.checked | ||
43 | onDone: Kube.Fabric.postMessage(Kube.Messages.componentDone, {}) | ||
44 | |||
45 | property bool foundAllKeys: to.foundAllKeys && cc.foundAllKeys && bcc.foundAllKeys | ||
46 | |||
47 | sendAction.enabled: composerController.accountId && composerController.subject && (!composerController.encrypt || composerController.foundAllKeys) && (!composerController.sign && !composerController.encrypt || composerController.foundPersonalKeys) | ||
48 | saveAsDraftAction.enabled: composerController.accountId | ||
49 | } | ||
50 | ] | ||
51 | |||
52 | Component.onCompleted: loadMessage(root.message, root.loadAsDraft) | ||
53 | |||
54 | Controls2.StackView.onActivated: { | ||
55 | Kube.Fabric.postMessage(Kube.Messages.synchronize, {"type": "mail", "specialPurpose": "drafts"}) | ||
56 | //For autocompletion | ||
57 | Kube.Fabric.postMessage(Kube.Messages.synchronize, {"type": "contacts"}) | ||
58 | } | ||
59 | |||
60 | function loadMessage(message, loadAsDraft) { | ||
61 | if (message) { | ||
62 | composerController.loadMessage(message, loadAsDraft) | ||
63 | //Forward focus for replies directly | ||
64 | if (!loadAsDraft) { | ||
65 | subject.forceActiveFocus() | ||
66 | } | ||
67 | } else if (newMessage) { | ||
68 | composerController.clear() | ||
69 | if (root.recipients) { | ||
70 | for (var i = 0; i < root.recipients.length; ++i) { | ||
71 | composerController.to.add({name: root.recipients[i]}) | ||
72 | } | ||
73 | } | ||
74 | subject.forceActiveFocus() | ||
75 | } | ||
76 | } | ||
77 | |||
78 | function closeFirstSplitIfNecessary() { | ||
79 | //Move the view forward | ||
80 | if (root.currentIndex == 0) { | ||
81 | root.incrementCurrentIndex() | ||
82 | } | ||
83 | } | ||
84 | |||
85 | //Drafts | ||
86 | Rectangle { | ||
87 | |||
88 | anchors { | ||
89 | top: parent.top | ||
90 | bottom: parent.bottom | ||
91 | } | ||
92 | |||
93 | width: Kube.Units.gridUnit * 10 | ||
94 | Layout.minimumWidth: Kube.Units.gridUnit * 5 | ||
95 | |||
96 | color: Kube.Colors.textColor | ||
97 | |||
98 | ColumnLayout { | ||
99 | |||
100 | anchors { | ||
101 | fill: parent | ||
102 | margins: Kube.Units.largeSpacing | ||
103 | } | ||
104 | |||
105 | spacing: Kube.Units.largeSpacing | ||
106 | |||
107 | Kube.PositiveButton { | ||
108 | objectName: "newMailButton" | ||
109 | anchors { | ||
110 | left: parent.left | ||
111 | right: parent.right | ||
112 | } | ||
113 | focus: true | ||
114 | text: qsTr("New Email") | ||
115 | onClicked: { | ||
116 | listView.currentIndex = -1 | ||
117 | composerController.clear() | ||
118 | subject.forceActiveFocus() | ||
119 | } | ||
120 | } | ||
121 | |||
122 | Kube.Label{ | ||
123 | text: qsTr("Drafts") | ||
124 | color: Kube.Colors.highlightedTextColor | ||
125 | } | ||
126 | |||
127 | Kube.ListView { | ||
128 | id: listView | ||
129 | activeFocusOnTab: true | ||
130 | |||
131 | anchors { | ||
132 | left: parent.left | ||
133 | right: parent.right | ||
134 | } | ||
135 | |||
136 | Layout.fillHeight: true | ||
137 | clip: true | ||
138 | currentIndex: -1 | ||
139 | highlightFollowsCurrentItem: false | ||
140 | |||
141 | //BEGIN keyboard nav | ||
142 | onActiveFocusChanged: { | ||
143 | if (activeFocus && currentIndex < 0) { | ||
144 | currentIndex = 0 | ||
145 | } | ||
146 | } | ||
147 | Keys.onDownPressed: { | ||
148 | listView.incrementCurrentIndex() | ||
149 | } | ||
150 | Keys.onUpPressed: { | ||
151 | listView.decrementCurrentIndex() | ||
152 | } | ||
153 | //END keyboard nav | ||
154 | |||
155 | onCurrentItemChanged: { | ||
156 | if (currentItem) { | ||
157 | root.loadMessage(currentItem.currentData.domainObject, true) | ||
158 | } | ||
159 | } | ||
160 | |||
161 | model: Kube.MailListModel { | ||
162 | id: mailListModel | ||
163 | showDrafts: true | ||
164 | } | ||
165 | |||
166 | delegate: Kube.ListDelegate { | ||
167 | id: delegateRoot | ||
168 | |||
169 | color: Kube.Colors.textColor | ||
170 | border.width: 0 | ||
171 | |||
172 | Item { | ||
173 | id: content | ||
174 | |||
175 | anchors { | ||
176 | fill: parent | ||
177 | margins: Kube.Units.smallSpacing | ||
178 | } | ||
179 | |||
180 | Kube.Label { | ||
181 | width: content.width | ||
182 | text: model.subject == "" ? "no subject" : model.subject | ||
183 | color: Kube.Colors.highlightedTextColor | ||
184 | maximumLineCount: 2 | ||
185 | wrapMode: Text.WrapAnywhere | ||
186 | elide: Text.ElideRight | ||
187 | } | ||
188 | |||
189 | Kube.Label { | ||
190 | anchors { | ||
191 | right: parent.right | ||
192 | bottom: parent.bottom | ||
193 | } | ||
194 | text: Qt.formatDateTime(model.date, "dd MMM yyyy") | ||
195 | font.italic: true | ||
196 | color: Kube.Colors.disabledTextColor | ||
197 | font.pointSize: Kube.Units.smallFontSize | ||
198 | visible: !delegateRoot.hovered | ||
199 | } | ||
200 | } | ||
201 | Row { | ||
202 | id: buttons | ||
203 | |||
204 | anchors { | ||
205 | right: parent.right | ||
206 | bottom: parent.bottom | ||
207 | margins: Kube.Units.smallSpacing | ||
208 | } | ||
209 | |||
210 | visible: delegateRoot.hovered | ||
211 | spacing: Kube.Units.smallSpacing | ||
212 | opacity: 0.7 | ||
213 | |||
214 | Kube.IconButton { | ||
215 | id: deleteButton | ||
216 | activeFocusOnTab: true | ||
217 | iconName: Kube.Icons.moveToTrash | ||
218 | visible: enabled | ||
219 | enabled: !!model.mail | ||
220 | onClicked: Kube.Fabric.postMessage(Kube.Messages.moveToTrash, {"mail": model.mail}) | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | } | ||
227 | |||
228 | //Content | ||
229 | Rectangle { | ||
230 | Layout.fillWidth: true | ||
231 | Layout.minimumWidth: Kube.Units.gridUnit * 5 | ||
232 | anchors { | ||
233 | top: parent.top | ||
234 | bottom: parent.bottom | ||
235 | } | ||
236 | color: Kube.Colors.backgroundColor | ||
237 | |||
238 | ColumnLayout { | ||
239 | anchors { | ||
240 | fill: parent | ||
241 | margins: Kube.Units.largeSpacing | ||
242 | leftMargin: Kube.Units.largeSpacing + Kube.Units.gridUnit * 2 | ||
243 | rightMargin: Kube.Units.largeSpacing + Kube.Units.gridUnit * 2 | ||
244 | } | ||
245 | |||
246 | spacing: Kube.Units.smallSpacing | ||
247 | |||
248 | Kube.TextField { | ||
249 | id: subject | ||
250 | Layout.fillWidth: true | ||
251 | activeFocusOnTab: true | ||
252 | |||
253 | placeholderText: qsTr("Enter Subject...") | ||
254 | text: composerController.subject | ||
255 | onTextChanged: composerController.subject = text; | ||
256 | onActiveFocusChanged: { | ||
257 | if (activeFocus) { | ||
258 | closeFirstSplitIfNecessary() | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | |||
263 | Flow { | ||
264 | id: attachments | ||
265 | |||
266 | Layout.fillWidth: true | ||
267 | layoutDirection: Qt.RightToLeft | ||
268 | spacing: Kube.Units.smallSpacing | ||
269 | clip: true | ||
270 | |||
271 | Repeater { | ||
272 | model: composerController.attachments.model | ||
273 | delegate: Kube.AttachmentDelegate { | ||
274 | name: model.filename | ||
275 | icon: model.iconname | ||
276 | clip: true | ||
277 | actionIcon: Kube.Icons.remove | ||
278 | onExecute: composerController.attachments.remove(model.id) | ||
279 | } | ||
280 | } | ||
281 | } | ||
282 | |||
283 | RowLayout { | ||
284 | |||
285 | spacing: Kube.Units.largeSpacing | ||
286 | |||
287 | Kube.Switch { | ||
288 | id: html | ||
289 | text: checked ? qsTr("plain") : qsTr("html") | ||
290 | focusPolicy: Qt.TabFocus | ||
291 | focus: false | ||
292 | checked: composerController.htmlBody | ||
293 | } | ||
294 | |||
295 | Row { | ||
296 | visible: html.checked | ||
297 | spacing: 1 | ||
298 | |||
299 | Kube.IconButton { | ||
300 | iconName: Kube.Icons.bold | ||
301 | checkable: true | ||
302 | checked: textEditor.bold | ||
303 | onClicked: textEditor.bold = !textEditor.bold | ||
304 | focusPolicy: Qt.TabFocus | ||
305 | focus: false | ||
306 | } | ||
307 | Kube.IconButton { | ||
308 | iconName: Kube.Icons.italic | ||
309 | checkable: true | ||
310 | checked: textEditor.italic | ||
311 | onClicked: textEditor.italic = !textEditor.italic | ||
312 | focusPolicy: Qt.TabFocus | ||
313 | focus: false | ||
314 | } | ||
315 | Kube.IconButton { | ||
316 | iconName: Kube.Icons.underline | ||
317 | checkable: true | ||
318 | checked: textEditor.underline | ||
319 | onClicked: textEditor.underline = !textEditor.underline | ||
320 | focusPolicy: Qt.TabFocus | ||
321 | focus: false | ||
322 | } | ||
323 | } | ||
324 | |||
325 | Item { | ||
326 | height: 1 | ||
327 | Layout.fillWidth: true | ||
328 | } | ||
329 | |||
330 | Kube.Button { | ||
331 | text: qsTr("Attach file") | ||
332 | |||
333 | onClicked: { | ||
334 | fileDialogComponent.createObject(parent) | ||
335 | } | ||
336 | |||
337 | Component { | ||
338 | id: fileDialogComponent | ||
339 | Dialogs.FileDialog { | ||
340 | id: fileDialog | ||
341 | visible: true | ||
342 | title: "Choose a file to attach" | ||
343 | selectFolder: false | ||
344 | onAccepted: { | ||
345 | composerController.attachments.add({url: fileDialog.fileUrl}) | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | |||
352 | Kube.TextEditor { | ||
353 | id: textEditor | ||
354 | |||
355 | Layout.fillWidth: true | ||
356 | Layout.fillHeight: true | ||
357 | htmlEnabled: html.checked | ||
358 | |||
359 | onActiveFocusChanged: closeFirstSplitIfNecessary() | ||
360 | Keys.onEscapePressed: recipients.forceActiveFocus() | ||
361 | initialText: composerController.body | ||
362 | onTextChanged: composerController.body = text; | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | |||
367 | //Recepients | ||
368 | FocusScope { | ||
369 | id: recipients | ||
370 | anchors { | ||
371 | top: parent.top | ||
372 | bottom: parent.bottom | ||
373 | } | ||
374 | width: Kube.Units.gridUnit * 15 | ||
375 | activeFocusOnTab: true | ||
376 | |||
377 | //background | ||
378 | Rectangle { | ||
379 | anchors.fill: parent | ||
380 | color: Kube.Colors.backgroundColor | ||
381 | |||
382 | Rectangle { | ||
383 | height: parent.height | ||
384 | width: 1 | ||
385 | color: Kube.Colors.buttonColor | ||
386 | } | ||
387 | } | ||
388 | |||
389 | //Content | ||
390 | ColumnLayout { | ||
391 | anchors { | ||
392 | fill: parent | ||
393 | margins: Kube.Units.largeSpacing | ||
394 | } | ||
395 | |||
396 | spacing: Kube.Units.largeSpacing | ||
397 | ColumnLayout { | ||
398 | Layout.maximumWidth: parent.width | ||
399 | Layout.fillWidth: true | ||
400 | Layout.fillHeight: true | ||
401 | |||
402 | Kube.Label { | ||
403 | text: qsTr("Sending Email to:") | ||
404 | } | ||
405 | |||
406 | AddresseeListEditor { | ||
407 | Layout.preferredHeight: implicitHeight | ||
408 | Layout.fillWidth: true | ||
409 | focus: true | ||
410 | activeFocusOnTab: true | ||
411 | encrypt: composerController.encrypt | ||
412 | controller: composerController.to | ||
413 | completer: composerController.recipientCompleter | ||
414 | } | ||
415 | |||
416 | Kube.Label { | ||
417 | text: qsTr("Sending Copy to (CC):") | ||
418 | } | ||
419 | AddresseeListEditor { | ||
420 | id: cc | ||
421 | Layout.preferredHeight: cc.implicitHeight | ||
422 | Layout.fillWidth: true | ||
423 | activeFocusOnTab: true | ||
424 | encrypt: composerController.encrypt | ||
425 | controller: composerController.cc | ||
426 | completer: composerController.recipientCompleter | ||
427 | } | ||
428 | |||
429 | Kube.Label { | ||
430 | text: qsTr("Sending Secret Copy to (Bcc):") | ||
431 | } | ||
432 | AddresseeListEditor { | ||
433 | id: bcc | ||
434 | Layout.preferredHeight: bcc.implicitHeight | ||
435 | Layout.fillWidth: true | ||
436 | activeFocusOnTab: true | ||
437 | encrypt: composerController.encrypt | ||
438 | controller: composerController.bcc | ||
439 | completer: composerController.recipientCompleter | ||
440 | } | ||
441 | Item { | ||
442 | width: parent.width | ||
443 | Layout.fillHeight: true | ||
444 | } | ||
445 | } | ||
446 | |||
447 | RowLayout { | ||
448 | enabled: composerController.foundPersonalKeys | ||
449 | Kube.CheckBox { | ||
450 | id: encryptCheckbox | ||
451 | checked: composerController.encrypt | ||
452 | } | ||
453 | Kube.Label { | ||
454 | text: qsTr("encrypt") | ||
455 | } | ||
456 | } | ||
457 | |||
458 | RowLayout { | ||
459 | enabled: composerController.foundPersonalKeys | ||
460 | Kube.CheckBox { | ||
461 | id: signCheckbox | ||
462 | checked: composerController.sign | ||
463 | } | ||
464 | Kube.Label { | ||
465 | text: qsTr("sign") | ||
466 | } | ||
467 | } | ||
468 | Kube.Label { | ||
469 | visible: !composerController.foundPersonalKeys | ||
470 | Layout.maximumWidth: parent.width | ||
471 | text: qsTr("Encryption is not available because your personal key has not been found.") | ||
472 | wrapMode: Text.Wrap | ||
473 | } | ||
474 | |||
475 | RowLayout { | ||
476 | Layout.maximumWidth: parent.width | ||
477 | width: parent.width | ||
478 | height: Kube.Units.gridUnit | ||
479 | |||
480 | Kube.Button { | ||
481 | width: saveDraftButton.width | ||
482 | text: qsTr("Discard") | ||
483 | onClicked: Kube.Fabric.postMessage(Kube.Messages.componentDone, {}) | ||
484 | } | ||
485 | |||
486 | Kube.Button { | ||
487 | id: saveDraftButton | ||
488 | |||
489 | text: qsTr("Save as Draft") | ||
490 | enabled: composerController.saveAsDraftAction.enabled | ||
491 | onClicked: { | ||
492 | composerController.saveAsDraftAction.execute() | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | |||
497 | ColumnLayout { | ||
498 | Layout.maximumWidth: parent.width | ||
499 | Layout.fillWidth: true | ||
500 | Kube.Label { | ||
501 | id: fromLabel | ||
502 | text: qsTr("You are sending this from:") | ||
503 | } | ||
504 | |||
505 | Kube.ComboBox { | ||
506 | id: identityCombo | ||
507 | |||
508 | width: parent.width - Kube.Units.largeSpacing * 2 | ||
509 | |||
510 | model: composerController.identitySelector.model | ||
511 | textRole: "address" | ||
512 | Layout.fillWidth: true | ||
513 | onCurrentIndexChanged: { | ||
514 | composerController.identitySelector.currentIndex = currentIndex | ||
515 | } | ||
516 | } | ||
517 | } | ||
518 | |||
519 | Kube.PositiveButton { | ||
520 | objectName: "sendButton" | ||
521 | id: sendButton | ||
522 | |||
523 | width: parent.width | ||
524 | |||
525 | text: qsTr("Send") | ||
526 | enabled: composerController.sendAction.enabled | ||
527 | onClicked: { | ||
528 | composerController.sendAction.execute() | ||
529 | } | ||
530 | } | ||
531 | } | ||
532 | }//FocusScope | ||
533 | } | ||
diff --git a/components/kube/qml/Kube.qml b/components/kube/qml/Kube.qml index 9a31ba58..be3f7e34 100644 --- a/components/kube/qml/Kube.qml +++ b/components/kube/qml/Kube.qml | |||
@@ -86,35 +86,6 @@ Controls2.ApplicationWindow { | |||
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | Kube.Listener { | ||
90 | filter: Kube.Messages.reply | ||
91 | onMessageReceived: { | ||
92 | kubeViews.openComposerWithMail(message.mail, false) | ||
93 | } | ||
94 | } | ||
95 | |||
96 | Kube.Listener { | ||
97 | filter: Kube.Messages.edit | ||
98 | onMessageReceived: { | ||
99 | kubeViews.openComposerWithMail(message.mail, true) | ||
100 | } | ||
101 | } | ||
102 | |||
103 | Kube.Listener { | ||
104 | filter: Kube.Messages.compose | ||
105 | onMessageReceived: kubeViews.openComposer(true, message.recipients) | ||
106 | } | ||
107 | |||
108 | Kube.Listener { | ||
109 | filter: Kube.Messages.requestLogin | ||
110 | onMessageReceived: kubeViews.setLoginView(message.accountId) | ||
111 | } | ||
112 | |||
113 | Kube.Listener { | ||
114 | filter: Kube.Messages.requestAccountsConfiguration | ||
115 | onMessageReceived: kubeViews.setAccountsView() | ||
116 | } | ||
117 | |||
118 | //BEGIN Shortcuts | 89 | //BEGIN Shortcuts |
119 | Shortcut { | 90 | Shortcut { |
120 | sequence: StandardKey.Quit | 91 | sequence: StandardKey.Quit |
@@ -174,48 +145,20 @@ Controls2.ApplicationWindow { | |||
174 | 145 | ||
175 | spacing: Kube.Units.largeSpacing - Kube.Units.smallSpacing | 146 | spacing: Kube.Units.largeSpacing - Kube.Units.smallSpacing |
176 | 147 | ||
177 | Kube.IconButton { | ||
178 | id: composerButton | ||
179 | iconName: Kube.Icons.edit_inverted | ||
180 | onClicked: kubeViews.openComposer(false, []) | ||
181 | activeFocusOnTab: true | ||
182 | checkable: true | ||
183 | Controls2.ButtonGroup.group: viewButtonGroup | ||
184 | tooltip: qsTr("composer") | ||
185 | } | ||
186 | |||
187 | Kube.IconButton { | ||
188 | id: mailButton | ||
189 | iconName: Kube.Icons.mail_inverted | ||
190 | onClicked: kubeViews.setMailView() | ||
191 | activeFocusOnTab: true | ||
192 | checkable: true | ||
193 | checked: true | ||
194 | Controls2.ButtonGroup.group: viewButtonGroup | ||
195 | tooltip: qsTr("mails") | ||
196 | } | ||
197 | |||
198 | Kube.IconButton { | ||
199 | id: peopleButton | ||
200 | iconName: Kube.Icons.user_inverted | ||
201 | onClicked: kubeViews.setPeopleView() | ||
202 | activeFocusOnTab: true | ||
203 | checkable: true | ||
204 | Controls2.ButtonGroup.group: viewButtonGroup | ||
205 | tooltip: qsTr("people") | ||
206 | } | ||
207 | Repeater { | 148 | Repeater { |
208 | model: Kube.ExtensionModel {} | 149 | model: Kube.ExtensionModel { |
150 | id: extensionModel | ||
151 | sortOrder: ["composer", "conversation", "people"] | ||
152 | } | ||
209 | Kube.IconButton { | 153 | Kube.IconButton { |
154 | id: button | ||
210 | iconName: model.icon | 155 | iconName: model.icon |
211 | onClicked: { | 156 | onClicked: kubeViews.showView(model.name) |
212 | var component = Qt.createComponent(model.source) | ||
213 | kubeViews.pushView(component, {}) | ||
214 | } | ||
215 | activeFocusOnTab: true | 157 | activeFocusOnTab: true |
216 | checkable: true | 158 | checkable: true |
217 | Controls2.ButtonGroup.group: viewButtonGroup | 159 | Controls2.ButtonGroup.group: viewButtonGroup |
218 | tooltip: model.tooltip | 160 | tooltip: model.tooltip |
161 | checked: kubeViews.currentViewName == model.name | ||
219 | } | 162 | } |
220 | } | 163 | } |
221 | } | 164 | } |
@@ -240,10 +183,11 @@ Controls2.ApplicationWindow { | |||
240 | Kube.IconButton { | 183 | Kube.IconButton { |
241 | id: logButton | 184 | id: logButton |
242 | iconName: Kube.Icons.info_inverted | 185 | iconName: Kube.Icons.info_inverted |
243 | onClicked: kubeViews.setLogView() | 186 | onClicked: kubeViews.showView("log") |
244 | activeFocusOnTab: true | 187 | activeFocusOnTab: true |
245 | checkable: true | 188 | checkable: true |
246 | alert: logView.pendingError | 189 | alert: kubeViews.getView("log").pendingError |
190 | checked: kubeViews.currentViewName == "log" | ||
247 | Controls2.ButtonGroup.group: viewButtonGroup | 191 | Controls2.ButtonGroup.group: viewButtonGroup |
248 | tooltip: qsTr("logview") | 192 | tooltip: qsTr("logview") |
249 | } | 193 | } |
@@ -251,141 +195,95 @@ Controls2.ApplicationWindow { | |||
251 | Kube.IconButton { | 195 | Kube.IconButton { |
252 | id: accountsButton | 196 | id: accountsButton |
253 | iconName: Kube.Icons.menu_inverted | 197 | iconName: Kube.Icons.menu_inverted |
254 | onClicked: kubeViews.setAccountsView() | 198 | onClicked: kubeViews.showView("accounts") |
255 | activeFocusOnTab: true | 199 | activeFocusOnTab: true |
256 | checkable: true | 200 | checkable: true |
201 | checked: kubeViews.currentViewName == "accounts" | ||
257 | Controls2.ButtonGroup.group: viewButtonGroup | 202 | Controls2.ButtonGroup.group: viewButtonGroup |
258 | tooltip: qsTr("settings") | 203 | tooltip: qsTr("settings") |
259 | } | 204 | } |
260 | } | 205 | } |
261 | } | 206 | } |
262 | Controls2.StackView { | 207 | ViewManager { |
263 | id: kubeViews | 208 | id: kubeViews |
264 | |||
265 | anchors { | 209 | anchors { |
266 | top: mainContent.top | 210 | top: mainContent.top |
267 | bottom: mainContent.bottom | 211 | bottom: mainContent.bottom |
268 | } | 212 | } |
269 | Layout.fillWidth: true | 213 | Layout.fillWidth: true |
270 | 214 | ||
271 | Kube.Listener { | 215 | extensionModel: extensionModel |
272 | filter: Kube.Messages.componentDone | ||
273 | onMessageReceived: { | ||
274 | //Return to the mailview if we try to pop everything off | ||
275 | if (kubeViews.depth == 1) { | ||
276 | kubeViews.setMailView() | ||
277 | } else { | ||
278 | kubeViews.pop(Controls2.StackView.Immediate) | ||
279 | } | ||
280 | } | ||
281 | } | ||
282 | |||
283 | onCurrentItemChanged: { | ||
284 | if (currentItem) { | ||
285 | currentItem.forceActiveFocus() | ||
286 | } | ||
287 | } | ||
288 | 216 | ||
289 | Component.onCompleted: { | 217 | Component.onCompleted: { |
290 | //Setup the initial item stack | 218 | dontFocus = true |
291 | if (!currentItem) { | 219 | showView("conversation") |
292 | setMailView() | 220 | if (startupCheck.noAccount) { |
293 | if (startupCheck.noAccount) { | 221 | showView("accounts") |
294 | setAccountsView() | ||
295 | } | ||
296 | } | 222 | } |
223 | dontFocus = false | ||
297 | } | 224 | } |
298 | 225 | ||
299 | ///Replace the current view (we can't go back to the old view, and we destroy the old view) | 226 | Kube.Listener { |
300 | function replaceView(view) { | 227 | filter: Kube.Messages.reply |
301 | if (currentItem != view) { | 228 | onMessageReceived: kubeViews.replaceView("composer", {message: message.mail, loadAsDraft: false}) |
302 | kubeViews.replace(null, view, {}, Controls2.StackView.Immediate) | ||
303 | } | ||
304 | } | ||
305 | |||
306 | ///Push a new view on the stack (the old view remains, and we can go back once done) | ||
307 | function pushView(view, properties) { | ||
308 | kubeViews.push(view, properties, Controls2.StackView.Immediate) | ||
309 | } | ||
310 | |||
311 | //TODO replacing here while a composer is open is destructive | ||
312 | function setPeopleView() { | ||
313 | replaceView(peopleView) | ||
314 | } | 229 | } |
315 | 230 | ||
316 | function setMailView() { | 231 | Kube.Listener { |
317 | replaceView(mailView) | 232 | filter: Kube.Messages.edit |
233 | onMessageReceived: kubeViews.replaceView("composer", {message: message.mail, loadAsDraft: true}) | ||
318 | } | 234 | } |
319 | 235 | ||
320 | function setAccountsView() { | 236 | Kube.Listener { |
321 | pushView(accountsView, {}) | 237 | filter: Kube.Messages.compose |
238 | onMessageReceived: kubeViews.replaceView("composer", {newMessage: true, recipients: message.recipients}) | ||
322 | } | 239 | } |
323 | 240 | ||
324 | function setLogView() { | 241 | Kube.Listener { |
325 | replaceView(logView) | 242 | filter: Kube.Messages.requestAccountsConfiguration |
243 | onMessageReceived: kubeViews.showView("accounts") | ||
326 | } | 244 | } |
327 | 245 | ||
328 | function setLoginView(account) { | 246 | Kube.Listener { |
329 | if (currentItem != loginView) { | 247 | filter: Kube.Messages.componentDone |
330 | pushView(loginView, {accountId: account}) | 248 | onMessageReceived: { |
249 | kubeViews.closeView() | ||
331 | } | 250 | } |
332 | } | 251 | } |
333 | 252 | ||
334 | function openComposer(newMessage, recipients) { | 253 | Kube.Listener { |
335 | pushView(composerView, {newMessage: newMessage, recipients: recipients}) | 254 | filter: Kube.Messages.requestLogin |
336 | } | 255 | onMessageReceived: { |
337 | 256 | loginView.createObject(kubeViews, {accountId: message.accountId}) | |
338 | function openComposerWithMail(mail, openAsDraft) { | ||
339 | pushView(composerView, {message: mail, loadAsDraft: openAsDraft}) | ||
340 | } | ||
341 | |||
342 | |||
343 | //These items are not visible until pushed onto the stack, so we keep them in resources instead of items | ||
344 | resources: [ | ||
345 | //Not components so we maintain state | ||
346 | MailView { | ||
347 | id: mailView | ||
348 | anchors.fill: parent | ||
349 | Controls2.StackView.onActivated: mailButton.checked = true | ||
350 | Controls2.StackView.onDeactivated: mailButton.checked = false | ||
351 | }, | ||
352 | PeopleView { | ||
353 | id: peopleView | ||
354 | anchors.fill: parent | ||
355 | Controls2.StackView.onActivated: peopleButton.checked = true | ||
356 | Controls2.StackView.onDeactivated: peopleButton.checked = false | ||
357 | }, | ||
358 | //Not a component because otherwise we can't log stuff | ||
359 | LogView { | ||
360 | id: logView | ||
361 | anchors.fill: parent | ||
362 | Controls2.StackView.onActivated: logButton.checked = true | ||
363 | Controls2.StackView.onDeactivated: logButton.checked = false | ||
364 | } | ||
365 | ] | ||
366 | //A component so it's always destroyed when we're done | ||
367 | Component { | ||
368 | id: composerView | ||
369 | ComposerView { | ||
370 | anchors.fill: parent | ||
371 | Controls2.StackView.onActivated: composerButton.checked = true | ||
372 | Controls2.StackView.onDeactivated: composerButton.checked = false | ||
373 | } | ||
374 | } | ||
375 | Component { | ||
376 | id: accountsView | ||
377 | AccountsView { | ||
378 | anchors.fill: parent | ||
379 | Controls2.StackView.onActivated: accountsButton.checked = true | ||
380 | Controls2.StackView.onDeactivated: accountsButton.checked = false | ||
381 | } | 257 | } |
382 | } | 258 | } |
259 | |||
383 | Component { | 260 | Component { |
384 | id: loginView | 261 | id: loginView |
385 | LoginView { | 262 | Kube.Popup { |
386 | anchors.fill: parent | 263 | id: popup |
264 | property alias accountId: login.accountId | ||
265 | visible: true | ||
266 | parent: Controls2.ApplicationWindow.overlay | ||
267 | height: app.height | ||
268 | width: app.width - app.sidebarWidth | ||
269 | x: app.sidebarWidth | ||
270 | y: 0 | ||
271 | modal: true | ||
272 | closePolicy: Controls2.Popup.NoAutoClose | ||
273 | Kube.LoginAccount { | ||
274 | id: login | ||
275 | anchors { | ||
276 | fill: parent | ||
277 | bottomMargin: Kube.Units.largeSpacing | ||
278 | } | ||
279 | onDone: { | ||
280 | popup.close() | ||
281 | kubeViews.currentItem.forceActiveFocus() | ||
282 | } | ||
283 | } | ||
387 | } | 284 | } |
388 | } | 285 | } |
286 | |||
389 | } | 287 | } |
390 | } | 288 | } |
391 | //END Main content | 289 | //END Main content |
diff --git a/components/kube/qml/LogView.qml b/components/kube/qml/LogView.qml deleted file mode 100644 index 4ae1a67c..00000000 --- a/components/kube/qml/LogView.qml +++ /dev/null | |||
@@ -1,329 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Michael Bohlender, <michael.bohlender@kdemail.net> | ||
3 | * Copyright (C) 2017 Christian Mollekopf, <mollekopf@kolabsys.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | import QtQuick 2.4 | ||
21 | import QtQuick.Layouts 1.1 | ||
22 | import QtQuick.Controls 1.3 as Controls | ||
23 | import QtQuick.Controls 2.0 as Controls2 | ||
24 | import org.kube.framework 1.0 as Kube | ||
25 | |||
26 | Controls.SplitView { | ||
27 | id: root | ||
28 | |||
29 | property bool pendingError: false; | ||
30 | |||
31 | Controls2.StackView.onActivated: { | ||
32 | root.pendingError = false; | ||
33 | //Always select the latest notification | ||
34 | listView.currentIndex = 0 | ||
35 | } | ||
36 | |||
37 | Item { | ||
38 | id: accountList | ||
39 | width: parent.width/3 | ||
40 | Layout.fillHeight: true | ||
41 | |||
42 | Kube.Listener { | ||
43 | filter: Kube.Messages.notification | ||
44 | onMessageReceived: { | ||
45 | if (message.type == Kube.Notifications.error) { | ||
46 | root.pendingError = true | ||
47 | } | ||
48 | var error = {timestamp: new Date(), message: message.message, details: message.details, resource: message.resource} | ||
49 | if (logModel.count > 0) { | ||
50 | var lastEntry = logModel.get(0) | ||
51 | //Merge if we get an entry of the same subtype | ||
52 | if (lastEntry.subtype && lastEntry.subtype == message.subtype) { | ||
53 | logModel.set(0, {type: message.type, subtype: message.subtype, errors: [error].concat(lastEntry.errors)}) | ||
54 | return | ||
55 | } | ||
56 | } | ||
57 | logModel.insert(0, {type: message.type, subtype: message.subtype, errors: [error]}) | ||
58 | } | ||
59 | } | ||
60 | |||
61 | Kube.Label { | ||
62 | anchors.centerIn: parent | ||
63 | visible: listView.count == 0 | ||
64 | text: qsTr("Nothing here...") | ||
65 | } | ||
66 | |||
67 | Kube.ListView { | ||
68 | id: listView | ||
69 | anchors { | ||
70 | fill: parent | ||
71 | } | ||
72 | |||
73 | clip: true | ||
74 | |||
75 | model: ListModel { | ||
76 | id: logModel | ||
77 | objectName: "logModel" | ||
78 | } | ||
79 | |||
80 | onCurrentItemChanged: { | ||
81 | var error = currentItem.currentData.errors.get(0) | ||
82 | if (!!error.resource) { | ||
83 | details.resourceId = error.resource | ||
84 | } | ||
85 | details.message = error.message + "\n" + error.details | ||
86 | details.timestamp = error.timestamp | ||
87 | if (!!currentItem.currentData.subtype) { | ||
88 | details.subtype = currentItem.currentData.subtype | ||
89 | } else { | ||
90 | details.subtype = "" | ||
91 | } | ||
92 | } | ||
93 | |||
94 | delegate: Kube.ListDelegate { | ||
95 | border.color: Kube.Colors.buttonColor | ||
96 | border.width: 1 | ||
97 | Kube.Label { | ||
98 | id: description | ||
99 | anchors { | ||
100 | top: parent.top | ||
101 | topMargin: Kube.Units.smallSpacing | ||
102 | left: parent.left | ||
103 | leftMargin: Kube.Units.largeSpacing | ||
104 | } | ||
105 | height: Kube.Units.gridUnit | ||
106 | width: parent.width - Kube.Units.largeSpacing * 2 | ||
107 | text: model.type == Kube.Notifications.error ? qsTr("Error") : qsTr("Info") | ||
108 | } | ||
109 | |||
110 | Kube.Label { | ||
111 | id: message | ||
112 | anchors { | ||
113 | topMargin: Kube.Units.smallSpacing | ||
114 | top: description.bottom | ||
115 | left: parent.left | ||
116 | leftMargin: Kube.Units.largeSpacing | ||
117 | } | ||
118 | height: Kube.Units.gridUnit | ||
119 | width: parent.width - Kube.Units.largeSpacing * 2 | ||
120 | maximumLineCount: 1 | ||
121 | elide: Text.ElideRight | ||
122 | color: Kube.Colors.disabledTextColor | ||
123 | text: model.errors.get(0).message | ||
124 | } | ||
125 | |||
126 | Kube.Label { | ||
127 | id: date | ||
128 | |||
129 | anchors { | ||
130 | right: parent.right | ||
131 | bottom: parent.bottom | ||
132 | rightMargin: Kube.Units.smallSpacing | ||
133 | } | ||
134 | text: Qt.formatDateTime(model.errors.get(0).timestamp, " hh:mm:ss dd MMM yyyy") | ||
135 | font.italic: true | ||
136 | color: Kube.Colors.disabledTextColor | ||
137 | font.pointSize: Kube.Units.smallFontSize | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | Item { | ||
143 | id: details | ||
144 | property string subtype: "" | ||
145 | property date timestamp | ||
146 | property string message: "" | ||
147 | property string resourceId: "" | ||
148 | |||
149 | Kube.ModelIndexRetriever { | ||
150 | id: retriever | ||
151 | model: Kube.AccountsModel { | ||
152 | resourceId: details.resourceId | ||
153 | } | ||
154 | } | ||
155 | |||
156 | Loader { | ||
157 | id: detailsLoader | ||
158 | visible: message != "" | ||
159 | clip: true | ||
160 | anchors { | ||
161 | fill: parent | ||
162 | margins: Kube.Units.largeSpacing | ||
163 | } | ||
164 | property date timestamp: details.timestamp | ||
165 | property string message: details.message | ||
166 | property string resourceId: details.resourceId | ||
167 | property string accountId: retriever.currentData ? retriever.currentData.accountId : "" | ||
168 | property string accountName: retriever.currentData ? retriever.currentData.name : "" | ||
169 | |||
170 | function getComponent(subtype) { | ||
171 | if (subtype == Kube.Notifications.loginError) { | ||
172 | return loginErrorComponent | ||
173 | } | ||
174 | if (subtype == Kube.Notifications.hostNotFoundError) { | ||
175 | return hostNotFoundErrorComponent | ||
176 | } | ||
177 | if (subtype == Kube.Notifications.connectionError) { | ||
178 | return hostNotFoundErrorComponent | ||
179 | } | ||
180 | return detailsComponent | ||
181 | } | ||
182 | |||
183 | sourceComponent: getComponent(details.subtype) | ||
184 | } | ||
185 | } | ||
186 | |||
187 | Component { | ||
188 | id: detailsComponent | ||
189 | Rectangle { | ||
190 | color: Kube.Colors.viewBackgroundColor | ||
191 | GridLayout { | ||
192 | id: gridLayout | ||
193 | Layout.minimumWidth: 0 | ||
194 | anchors { | ||
195 | top: parent.top | ||
196 | left: parent.left | ||
197 | right: parent.right | ||
198 | } | ||
199 | columns: 2 | ||
200 | Kube.Label { | ||
201 | text: qsTr("Account:") | ||
202 | visible: accountName | ||
203 | } | ||
204 | Kube.Label { | ||
205 | Layout.fillWidth: true | ||
206 | text: accountName | ||
207 | visible: accountName | ||
208 | elide: Text.ElideRight | ||
209 | } | ||
210 | Kube.Label { | ||
211 | text: qsTr("Account Id:") | ||
212 | visible: accountId | ||
213 | } | ||
214 | Kube.Label { | ||
215 | text: accountId | ||
216 | visible: accountId | ||
217 | Layout.fillWidth: true | ||
218 | elide: Text.ElideRight | ||
219 | } | ||
220 | Kube.Label { | ||
221 | text: qsTr("Resource Id:") | ||
222 | visible: resourceId | ||
223 | } | ||
224 | Kube.Label { | ||
225 | text: resourceId | ||
226 | visible: resourceId | ||
227 | Layout.fillWidth: true | ||
228 | elide: Text.ElideRight | ||
229 | } | ||
230 | Kube.Label { | ||
231 | text: qsTr("Timestamp:") | ||
232 | } | ||
233 | Kube.Label { | ||
234 | text: Qt.formatDateTime(timestamp, " hh:mm:ss dd MMM yyyy") | ||
235 | Layout.fillWidth: true | ||
236 | elide: Text.ElideRight | ||
237 | } | ||
238 | Kube.Label { | ||
239 | text: qsTr("Message:") | ||
240 | Layout.alignment: Qt.AlignTop | ||
241 | } | ||
242 | Kube.Label { | ||
243 | text: message | ||
244 | Layout.fillWidth: true | ||
245 | wrapMode: Text.Wrap | ||
246 | } | ||
247 | Item { | ||
248 | Layout.columnSpan: 2 | ||
249 | Layout.fillHeight: true | ||
250 | Layout.fillWidth: true | ||
251 | } | ||
252 | } | ||
253 | |||
254 | Kube.SelectableItem { | ||
255 | layout: gridLayout | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | |||
260 | Component { | ||
261 | id: loginErrorComponent | ||
262 | Item { | ||
263 | Column { | ||
264 | anchors { | ||
265 | top: parent.top | ||
266 | left: parent.left | ||
267 | right: parent.right | ||
268 | } | ||
269 | spacing: Kube.Units.largeSpacing | ||
270 | Column { | ||
271 | Kube.Heading { | ||
272 | id: heading | ||
273 | text: qsTr("Failed to login") | ||
274 | color: Kube.Colors.warningColor | ||
275 | } | ||
276 | |||
277 | Kube.Label { | ||
278 | id: subHeadline | ||
279 | text: accountName + ": " + qsTr("Please check your credentials.") | ||
280 | color: Kube.Colors.disabledTextColor | ||
281 | wrapMode: Text.Wrap | ||
282 | } | ||
283 | } | ||
284 | Kube.Button { | ||
285 | text: qsTr("Change Password") | ||
286 | onClicked: { | ||
287 | Kube.Fabric.postMessage(Kube.Messages.componentDone, {}) | ||
288 | Kube.Fabric.postMessage(Kube.Messages.requestLogin, {accountId: accountId}) | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | |||
295 | Component { | ||
296 | id: hostNotFoundErrorComponent | ||
297 | Item { | ||
298 | Column { | ||
299 | anchors { | ||
300 | top: parent.top | ||
301 | left: parent.left | ||
302 | right: parent.right | ||
303 | } | ||
304 | spacing: Kube.Units.largeSpacing | ||
305 | Column { | ||
306 | Kube.Heading { | ||
307 | id: heading | ||
308 | text: qsTr("Host not found") | ||
309 | color: Kube.Colors.warningColor | ||
310 | } | ||
311 | |||
312 | Kube.Label { | ||
313 | id: subHeadline | ||
314 | text: accountName + ": " + qsTr("Please check your network connection and settings.") | ||
315 | color: Kube.Colors.disabledTextColor | ||
316 | wrapMode: Text.Wrap | ||
317 | } | ||
318 | } | ||
319 | Kube.Button { | ||
320 | text: qsTr("Account settings") | ||
321 | onClicked: { | ||
322 | Kube.Fabric.postMessage(Kube.Messages.componentDone, {}) | ||
323 | Kube.Fabric.postMessage(Kube.Messages.requestAccountsConfiguration, {}) | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | } | ||
diff --git a/components/kube/qml/LoginView.qml b/components/kube/qml/LoginView.qml deleted file mode 100644 index dbbed11c..00000000 --- a/components/kube/qml/LoginView.qml +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Michael Bohlender, <michael.bohlender@kdemail.net> | ||
3 | * Copyright (C) 2017 Christian Mollekopf, <mollekopf@kolabsys.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | import QtQuick 2.4 | ||
21 | import QtQuick.Layouts 1.1 | ||
22 | import QtQuick.Controls 2.0 | ||
23 | import org.kube.framework 1.0 as Kube | ||
24 | |||
25 | FocusScope { | ||
26 | id: root | ||
27 | property alias accountId: login.accountId | ||
28 | onActiveFocusChanged: { | ||
29 | if (activeFocus) { | ||
30 | popup.forceActiveFocus() | ||
31 | } | ||
32 | } | ||
33 | |||
34 | Kube.Popup { | ||
35 | id: popup | ||
36 | visible: true | ||
37 | parent: ApplicationWindow.overlay | ||
38 | height: app.height | ||
39 | width: app.width - app.sidebarWidth | ||
40 | x: app.sidebarWidth | ||
41 | y: 0 | ||
42 | modal: true | ||
43 | closePolicy: Popup.NoAutoClose | ||
44 | Kube.LoginAccount { | ||
45 | id: login | ||
46 | anchors { | ||
47 | fill: parent | ||
48 | bottomMargin: Kube.Units.largeSpacing | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | } | ||
diff --git a/components/kube/qml/MailView.qml b/components/kube/qml/MailView.qml deleted file mode 100644 index 8b2b0caf..00000000 --- a/components/kube/qml/MailView.qml +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Michael Bohlender, <michael.bohlender@kdemail.net> | ||
3 | * Copyright (C) 2017 Christian Mollekopf, <mollekopf@kolabsys.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | |||
21 | import QtQuick 2.7 | ||
22 | import QtQuick.Controls 1.3 | ||
23 | import QtQuick.Controls 2.0 as Controls2 | ||
24 | import QtQuick.Layouts 1.1 | ||
25 | |||
26 | import org.kube.framework 1.0 as Kube | ||
27 | |||
28 | FocusScope { | ||
29 | SplitView { | ||
30 | anchors.fill: parent | ||
31 | Rectangle { | ||
32 | width: Kube.Units.gridUnit * 10 | ||
33 | Layout.fillHeight: parent.height | ||
34 | color: Kube.Colors.textColor | ||
35 | |||
36 | Kube.PositiveButton { | ||
37 | id: newMailButton | ||
38 | |||
39 | anchors { | ||
40 | top: parent.top | ||
41 | left: parent.left | ||
42 | right: parent.right | ||
43 | margins: Kube.Units.largeSpacing | ||
44 | } | ||
45 | focus: true | ||
46 | text: qsTr("New Email") | ||
47 | onClicked: Kube.Fabric.postMessage(Kube.Messages.compose, {}) | ||
48 | } | ||
49 | |||
50 | Kube.InlineAccountSwitcher { | ||
51 | id: accountFolderview | ||
52 | activeFocusOnTab: true | ||
53 | anchors { | ||
54 | top: newMailButton.bottom | ||
55 | topMargin: Kube.Units.largeSpacing | ||
56 | bottom: statusBarContainer.top | ||
57 | left: newMailButton.left | ||
58 | right: parent.right | ||
59 | } | ||
60 | } | ||
61 | |||
62 | Item { | ||
63 | id: statusBarContainer | ||
64 | anchors { | ||
65 | topMargin: Kube.Units.smallSpacing | ||
66 | bottom: parent.bottom | ||
67 | left: parent.left | ||
68 | right: parent.right | ||
69 | } | ||
70 | height: childrenRect.height | ||
71 | |||
72 | Rectangle { | ||
73 | id: border | ||
74 | visible: statusBar.visible | ||
75 | anchors { | ||
76 | right: parent.right | ||
77 | left: parent.left | ||
78 | margins: Kube.Units.smallSpacing | ||
79 | } | ||
80 | height: 1 | ||
81 | color: Kube.Colors.viewBackgroundColor | ||
82 | opacity: 0.3 | ||
83 | } | ||
84 | Kube.StatusBar { | ||
85 | id: statusBar | ||
86 | accountId: accountFolderview.currentAccount | ||
87 | height: Kube.Units.gridUnit * 2 | ||
88 | anchors { | ||
89 | top: border.bottom | ||
90 | left: statusBarContainer.left | ||
91 | right: statusBarContainer.right | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | |||
97 | Rectangle { | ||
98 | width: Kube.Units.gridUnit * 18 | ||
99 | Layout.fillHeight: parent.height | ||
100 | |||
101 | color: "transparent" | ||
102 | border.width: 1 | ||
103 | border.color: Kube.Colors.buttonColor | ||
104 | |||
105 | Kube.MailListView { | ||
106 | id: mailListView | ||
107 | anchors.fill: parent | ||
108 | activeFocusOnTab: true | ||
109 | Layout.minimumWidth: Kube.Units.gridUnit * 10 | ||
110 | } | ||
111 | } | ||
112 | |||
113 | Kube.ConversationView { | ||
114 | id: mailView | ||
115 | Layout.fillWidth: true | ||
116 | Layout.fillHeight: parent.height | ||
117 | activeFocusOnTab: true | ||
118 | } | ||
119 | } | ||
120 | } | ||
diff --git a/components/kube/qml/PeopleView.qml b/components/kube/qml/PeopleView.qml deleted file mode 100644 index 3f1b9261..00000000 --- a/components/kube/qml/PeopleView.qml +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Michael Bohlender, <michael.bohlender@kdemail.net> | ||
3 | * Copyright (C) 2017 Christian Mollekopf, <mollekopf@kolabsys.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | |||
21 | import QtQuick 2.7 | ||
22 | import QtQuick.Controls 2.1 | ||
23 | import org.kube.framework 1.0 as Kube | ||
24 | |||
25 | Item { | ||
26 | |||
27 | StackView.onActivated: { | ||
28 | Kube.Fabric.postMessage(Kube.Messages.synchronize, {"type": "contacts"}) | ||
29 | } | ||
30 | |||
31 | Kube.People { | ||
32 | id: people | ||
33 | anchors { | ||
34 | fill: parent | ||
35 | margins: Kube.Units.smallSpacing | ||
36 | } | ||
37 | } | ||
38 | } | ||
diff --git a/components/kube/qml/ViewManager.qml b/components/kube/qml/ViewManager.qml new file mode 100644 index 00000000..6874107a --- /dev/null +++ b/components/kube/qml/ViewManager.qml | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2018 Christian Mollekopf, <mollekopf@kolabsys.com> | ||
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 2 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 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
17 | */ | ||
18 | |||
19 | |||
20 | import QtQuick 2.7 | ||
21 | import QtQuick.Controls 2.0 | ||
22 | /* | ||
23 | * TODO | ||
24 | * * Only replace composer if necessary (on reply, edit draft, ...) | ||
25 | * * Shutdown procedure to save draft before destruction | ||
26 | * * Separate logging from view and and make accessible to log (initialize()) call? | ||
27 | */ | ||
28 | StackView { | ||
29 | id: root | ||
30 | property string currentViewName: currentItem ? currentItem.objectName : "" | ||
31 | property variant extensionModel: null | ||
32 | property bool dontFocus: false | ||
33 | |||
34 | property var viewDict: new Object | ||
35 | function getView(name, replaceView) { | ||
36 | if (!replaceView && name in viewDict) { | ||
37 | var item = viewDict[name] | ||
38 | if (item) { | ||
39 | return item | ||
40 | } | ||
41 | } | ||
42 | var v = Qt.createComponent(extensionModel.findSource(name, "View.qml")) | ||
43 | v = v.createObject(root) | ||
44 | viewDict[name] = v | ||
45 | return v; | ||
46 | } | ||
47 | |||
48 | onCurrentItemChanged: { | ||
49 | if (currentItem && !dontFocus) { | ||
50 | currentItem.forceActiveFocus() | ||
51 | } | ||
52 | } | ||
53 | |||
54 | function showOrReplaceView(name, properties, replace) { | ||
55 | if (currentItem && currentItem.objectName == name) { | ||
56 | return | ||
57 | } | ||
58 | if (root.depth > 0) { | ||
59 | root.pop(StackView.Immediate) | ||
60 | } | ||
61 | var view = getView(name, replace) | ||
62 | var item = push(view, properties, StackView.Immediate) | ||
63 | item.parent = root | ||
64 | item.anchors.fill = root | ||
65 | item.objectName = name | ||
66 | } | ||
67 | |||
68 | function showView(name, properties) { | ||
69 | showOrReplaceView(name, properties, false) | ||
70 | } | ||
71 | |||
72 | function replaceView(name, properties) { | ||
73 | showOrReplaceView(name, properties, true) | ||
74 | } | ||
75 | |||
76 | function closeView() { | ||
77 | //The initial view remains | ||
78 | if (kubeViews.depth > 1) { | ||
79 | var item = kubeViews.pop(StackView.Immediate) | ||
80 | viewDict[item.objectName] = null | ||
81 | item.destroy() | ||
82 | } | ||
83 | } | ||
84 | } | ||
diff --git a/components/kube/tests/tst_accountsview.qml b/components/kube/tests/tst_accountsview.qml deleted file mode 100644 index 428bb4cc..00000000 --- a/components/kube/tests/tst_accountsview.qml +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU Library General Public License as | ||
6 | * published by the Free Software Foundation; either version 2, 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 Library General Public License for more details | ||
13 | * | ||
14 | * You should have received a copy of the GNU Library General Public | ||
15 | * License along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | import QtQuick 2.7 | ||
21 | import QtTest 1.0 | ||
22 | import "../qml" | ||
23 | |||
24 | TestCase { | ||
25 | id: testCase | ||
26 | width: 400 | ||
27 | height: 400 | ||
28 | name: "AccountsView" | ||
29 | |||
30 | AccountsView { | ||
31 | id: accountsView | ||
32 | } | ||
33 | |||
34 | function test_start() { | ||
35 | verify(accountsView) | ||
36 | } | ||
37 | } | ||
diff --git a/components/kube/tests/tst_composerview.qml b/components/kube/tests/tst_composerview.qml deleted file mode 100644 index 67db6ef6..00000000 --- a/components/kube/tests/tst_composerview.qml +++ /dev/null | |||
@@ -1,97 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU Library General Public License as | ||
6 | * published by the Free Software Foundation; either version 2, 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 Library General Public License for more details | ||
13 | * | ||
14 | * You should have received a copy of the GNU Library General Public | ||
15 | * License along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | import QtQuick 2.7 | ||
21 | import QtTest 1.0 | ||
22 | import "../qml" | ||
23 | import org.kube.framework 1.0 as Kube | ||
24 | import org.kube.test 1.0 | ||
25 | |||
26 | TestCase { | ||
27 | id: testCase | ||
28 | width: 400 | ||
29 | height: 400 | ||
30 | name: "ComposerView" | ||
31 | when: windowShown | ||
32 | |||
33 | Component { | ||
34 | id:composerComponent | ||
35 | ComposerView { | ||
36 | focus: true | ||
37 | } | ||
38 | } | ||
39 | |||
40 | function test_1start() { | ||
41 | var composer = createTemporaryObject(composerComponent, testCase, {}) | ||
42 | verify(composer) | ||
43 | } | ||
44 | |||
45 | function test_2verifyInitialFocus() { | ||
46 | var composer = createTemporaryObject(composerComponent, testCase, {}) | ||
47 | var newMailButton = findChild(composer, "newMailButton"); | ||
48 | verify(newMailButton) | ||
49 | verify(newMailButton.activeFocus) | ||
50 | } | ||
51 | |||
52 | function test_3sendMessage() { | ||
53 | var initialState = { | ||
54 | accounts: [{ | ||
55 | id: "account1", | ||
56 | }], | ||
57 | identities: [{ | ||
58 | account: "account1", | ||
59 | name: "Test Identity", | ||
60 | address: "identity@example.org" | ||
61 | }], | ||
62 | resources: [{ | ||
63 | id: "resource1", | ||
64 | account: "account1", | ||
65 | type: "dummy" | ||
66 | }, | ||
67 | { | ||
68 | id: "resource2", | ||
69 | account: "account1", | ||
70 | type: "mailtransport" | ||
71 | }], | ||
72 | mails:[{ | ||
73 | resource: "resource1", | ||
74 | subject: "subject", | ||
75 | body: "body", | ||
76 | to: ["to@example.org"], | ||
77 | cc: ["cc@example.org"], | ||
78 | bcc: ["bcc@example.org"], | ||
79 | draft: true | ||
80 | }] | ||
81 | } | ||
82 | TestStore.setup(initialState) | ||
83 | var composer = createTemporaryObject(composerComponent, testCase, {}) | ||
84 | |||
85 | var createdMail = TestStore.load("mail", {resource: "resource1"}) | ||
86 | |||
87 | var loadAsDraft = true | ||
88 | composer.loadMessage(createdMail, loadAsDraft) | ||
89 | var sendMailButton = findChild(composer, "sendButton") | ||
90 | verify(sendMailButton) | ||
91 | tryVerify(function(){ return sendMailButton.enabled }) | ||
92 | sendMailButton.clicked() | ||
93 | |||
94 | tryVerify(function(){ return TestStore.load("mail", {resource: "resource2"}) }) | ||
95 | tryVerify(function(){ return !TestStore.load("mail", {resource: "resource1"}) }) | ||
96 | } | ||
97 | } | ||
diff --git a/components/kube/tests/tst_logview.qml b/components/kube/tests/tst_logview.qml deleted file mode 100644 index d3326db1..00000000 --- a/components/kube/tests/tst_logview.qml +++ /dev/null | |||
@@ -1,65 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU Library General Public License as | ||
6 | * published by the Free Software Foundation; either version 2, 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 Library General Public License for more details | ||
13 | * | ||
14 | * You should have received a copy of the GNU Library General Public | ||
15 | * License along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | import QtQuick 2.7 | ||
21 | import QtQuick.Controls 2.0 | ||
22 | import QtQuick.Window 2.1 | ||
23 | import QtTest 1.0 | ||
24 | import org.kube.framework 1.0 as Kube | ||
25 | import "../qml" | ||
26 | |||
27 | TestCase { | ||
28 | id: logviewTestcase | ||
29 | width: 400 | ||
30 | height: 400 | ||
31 | name: "LogView" | ||
32 | |||
33 | LogView { | ||
34 | id: logView | ||
35 | } | ||
36 | |||
37 | function test_logview() { | ||
38 | var listModel = findChild(logView, "logModel"); | ||
39 | verify(listModel) | ||
40 | compare(listModel.count, 0) | ||
41 | //ignore progress | ||
42 | Kube.Fabric.postMessage(Kube.Messages.progressNotification, {}) | ||
43 | compare(listModel.count, 0) | ||
44 | |||
45 | Kube.Fabric.postMessage(Kube.Messages.notification, {type: Kube.Notifications.info, message: "foobar", resource: "resource"}) | ||
46 | compare(listModel.count, 1) | ||
47 | compare(logView.pendingError, false) | ||
48 | |||
49 | Kube.Fabric.postMessage(Kube.Messages.notification, {"type": Kube.Notifications.error, message: "foobar", resource: "resource"}) | ||
50 | compare(listModel.count, 2) | ||
51 | compare(logView.pendingError, true) | ||
52 | compare(listModel.get(0).type, Kube.Notifications.error) | ||
53 | compare(listModel.get(0).errors.count, 1) | ||
54 | compare(listModel.get(0).errors.get(0).message, "foobar") | ||
55 | compare(listModel.get(0).errors.get(0).resource, "resource") | ||
56 | |||
57 | Kube.Fabric.postMessage(Kube.Messages.notification, {"type": Kube.Notifications.error, "subtype": "merge", message: "merge1", resource: "resource1"}) | ||
58 | compare(listModel.count, 3) | ||
59 | Kube.Fabric.postMessage(Kube.Messages.notification, {"type": Kube.Notifications.error, "subtype": "merge", message: "merge2", resource: "resource2"}) | ||
60 | compare(listModel.count, 3) | ||
61 | compare(listModel.get(0).errors.count, 2) | ||
62 | compare(listModel.get(0).errors.get(0).message, "merge2") | ||
63 | compare(listModel.get(0).errors.get(0).resource, "resource2") | ||
64 | } | ||
65 | } | ||
diff --git a/components/kube/tests/tst_mailview.qml b/components/kube/tests/tst_mailview.qml deleted file mode 100644 index f31d574d..00000000 --- a/components/kube/tests/tst_mailview.qml +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU Library General Public License as | ||
6 | * published by the Free Software Foundation; either version 2, 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 Library General Public License for more details | ||
13 | * | ||
14 | * You should have received a copy of the GNU Library General Public | ||
15 | * License along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | import QtQuick 2.7 | ||
21 | import QtTest 1.0 | ||
22 | import "../qml" | ||
23 | |||
24 | TestCase { | ||
25 | id: testCase | ||
26 | width: 400 | ||
27 | height: 400 | ||
28 | name: "MailView" | ||
29 | |||
30 | MailView { | ||
31 | id: mailView | ||
32 | } | ||
33 | |||
34 | function test_start() { | ||
35 | verify(mailView) | ||
36 | } | ||
37 | } | ||
diff --git a/components/kube/tests/tst_peopleview.qml b/components/kube/tests/tst_peopleview.qml deleted file mode 100644 index e224b527..00000000 --- a/components/kube/tests/tst_peopleview.qml +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU Library General Public License as | ||
6 | * published by the Free Software Foundation; either version 2, 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 Library General Public License for more details | ||
13 | * | ||
14 | * You should have received a copy of the GNU Library General Public | ||
15 | * License along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | import QtQuick 2.7 | ||
21 | import QtTest 1.0 | ||
22 | import "../qml" | ||
23 | |||
24 | TestCase { | ||
25 | id: testCase | ||
26 | width: 400 | ||
27 | height: 400 | ||
28 | name: "PeopleView" | ||
29 | |||
30 | PeopleView { | ||
31 | id: peopleView | ||
32 | } | ||
33 | |||
34 | function test_start() { | ||
35 | verify(peopleView) | ||
36 | } | ||
37 | } | ||