summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/kube/contents/ui/Kube.qml11
-rw-r--r--components/kube/contents/ui/LogView.qml232
-rw-r--r--framework/src/sinkfabric.cpp22
3 files changed, 260 insertions, 5 deletions
diff --git a/components/kube/contents/ui/Kube.qml b/components/kube/contents/ui/Kube.qml
index 438666d0..115123b7 100644
--- a/components/kube/contents/ui/Kube.qml
+++ b/components/kube/contents/ui/Kube.qml
@@ -132,6 +132,10 @@ Controls2.ApplicationWindow {
132 iconName: Kube.Icons.user_inverted 132 iconName: Kube.Icons.user_inverted
133 onClicked: kubeViews.setPeopleView() 133 onClicked: kubeViews.setPeopleView()
134 } 134 }
135 Kube.IconButton {
136 iconName: Kube.Icons.error_inverted
137 onClicked: kubeViews.setLogView()
138 }
135 } 139 }
136 Column { 140 Column {
137 anchors { 141 anchors {
@@ -173,6 +177,9 @@ Controls2.ApplicationWindow {
173 function setAccountsView() { 177 function setAccountsView() {
174 kubeViews.push({item: accountsView, replace: true, immediate: true}) 178 kubeViews.push({item: accountsView, replace: true, immediate: true})
175 } 179 }
180 function setLogView() {
181 kubeViews.push({item: logView, replace: true, immediate: true})
182 }
176 183
177 function openComposer() { 184 function openComposer() {
178 kubeViews.push({item: composerView, immediate: true}) 185 kubeViews.push({item: composerView, immediate: true})
@@ -187,6 +194,10 @@ Controls2.ApplicationWindow {
187 PeopleView { 194 PeopleView {
188 id: peopleView 195 id: peopleView
189 } 196 }
197 //Not a component because otherwise we can't log stuff
198 LogView {
199 id: logView
200 }
190 //A component so it's always destroyed when we're done 201 //A component so it's always destroyed when we're done
191 Component { 202 Component {
192 id: composerView 203 id: composerView
diff --git a/components/kube/contents/ui/LogView.qml b/components/kube/contents/ui/LogView.qml
new file mode 100644
index 00000000..a9b70c59
--- /dev/null
+++ b/components/kube/contents/ui/LogView.qml
@@ -0,0 +1,232 @@
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
20import QtQuick 2.4
21import QtQuick.Layouts 1.1
22import QtQuick.Controls 1.3 as Controls
23import QtQuick.Controls 2.0 as Controls2
24import org.kube.framework 1.0 as Kube
25
26Controls.SplitView {
27 Item {
28 id: accountList
29 width: parent.width/2
30 Layout.fillHeight: true
31
32 Kube.Listener {
33 filter: Kube.Messages.notification
34 onMessageReceived: {
35 logModel.insert(0, {message: message.message, timestamp: new Date(), resource: message.resource});
36 }
37 }
38
39 Item {
40 id: statusBar
41 anchors {
42 topMargin: Kube.Units.smallSpacing
43 top: parent.top
44 left: parent.left
45 right: parent.right
46 }
47
48 height: Kube.Units.gridUnit * 2
49
50 Repeater {
51 model: Kube.AccountsModel {
52 id: accountsModel
53 }
54
55 Column {
56 anchors.fill: statusBar
57 spacing: Kube.Units.smallSpacing
58 Row {
59 Kube.Label {
60 color: Kube.Colors.textColor
61 text: "Account: " + model.name
62 }
63 Kube.Label {
64 id: statusText
65 color: Kube.Colors.textColor
66 visible: false
67 states: [
68 State {
69 name: "disconnected"; when: accountsModel.status == Kube.AccountsModel.OfflineStatus
70 PropertyChanges { target: statusText; text: "Offline"; visible: true }
71 },
72 State {
73 name: "busy"; when: accountsModel.status == Kube.AccountsModel.BusyStatus
74 PropertyChanges { target: statusText; text: "Busy"; visible: true }
75 PropertyChanges { target: progressBar; visible: true }
76 }
77 ]
78 }
79 }
80 Controls2.ProgressBar {
81 id: progressBar
82 indeterminate: true
83 visible: false
84 height: Kube.Units.smallSpacing
85 width: parent.width
86
87 background: Rectangle {
88 color: Kube.Colors.backgroundColor
89 radius: 3
90 }
91
92 contentItem: Item {
93 Rectangle {
94 width: progressBar.visualPosition * parent.width
95 height: parent.height
96 radius: 2
97 color: Kube.Colors.highlightColor
98 }
99 }
100
101
102 Kube.Listener {
103 filter: Kube.Messages.progressNotification
104 onMessageReceived: {
105 progressBar.indeterminate = false
106 progressBar.from = 0
107 progressBar.to = message.total
108 progressBar.value = message.progress
109 }
110 }
111 }
112 }
113 }
114 }
115
116 ListView {
117 id: listView
118
119 anchors {
120 top: statusBar.bottom
121 left: parent.left
122 right: parent.right
123 bottom: parent.bottom
124 topMargin: Kube.Units.largeSpacing
125 }
126
127 clip: true
128
129 model: ListModel {
130 id: logModel
131 }
132
133 onCurrentItemChanged: {
134 details.resourceId = currentItem.currentData.resource
135 details.message = currentItem.currentData.message
136 details.timestamp = currentItem.currentData.timestamp
137 }
138
139 delegate: Rectangle {
140 property variant currentData: model
141 height: Kube.Units.gridUnit * 3
142 width: listView.width
143
144 border.color: Kube.Colors.buttonColor
145 border.width: 1
146 color: listView.currentIndex == index ? Kube.Colors.highlightColor : Kube.Colors.viewBackgroundColor
147
148 Kube.Label {
149 id: resource
150 anchors {
151 top: parent.top
152 topMargin: Kube.Units.smallSpacing
153 left: parent.left
154 leftMargin: Kube.Units.largeSpacing
155 }
156 height: Kube.Units.gridUnit
157 width: parent.width - Kube.Units.largeSpacing * 2
158 text: "Resource: " + model.resource
159 }
160
161 Kube.Label {
162 id: message
163 anchors {
164 topMargin: Kube.Units.smallSpacing
165 top: resource.bottom
166 left: parent.left
167 leftMargin: Kube.Units.largeSpacing
168 }
169 height: Kube.Units.gridUnit
170 width: parent.width - Kube.Units.largeSpacing * 2
171 maximumLineCount: 1
172 elide: Text.ElideRight
173
174 text: model.message
175 }
176
177 Kube.Label {
178 id: date
179
180 anchors {
181 right: parent.right
182 bottom: parent.bottom
183 }
184 text: Qt.formatDateTime(model.timestamp, " hh:mm:ss dd MMM yyyy")
185 font.italic: true
186 color: Kube.Colors.disabledTextColor
187 font.pointSize: 9
188 }
189
190 MouseArea {
191 id: mouseArea
192 anchors.fill: parent
193 onClicked: {
194 listView.currentIndex = index
195 }
196 }
197 }
198 }
199 }
200 Rectangle {
201 id: details
202 property date timestamp
203 property string message
204 property variant resourceId
205 GridLayout {
206 anchors.fill: parent
207 columns: 2
208 Kube.Label {
209 text: "Resource:"
210 }
211 Kube.Label {
212 text: details.resourceId
213 }
214 Kube.Label {
215 text: "Timestamp:"
216 }
217 Kube.Label {
218 text: Qt.formatDateTime(details.timestamp, " hh:mm:ss dd MMM yyyy")
219 }
220 Kube.Label {
221 text: "Message:"
222 }
223 Kube.Label {
224 text: details.message
225 }
226 Item {
227 Layout.columnSpan: 2
228 Layout.fillHeight: true
229 }
230 }
231 }
232}
diff --git a/framework/src/sinkfabric.cpp b/framework/src/sinkfabric.cpp
index 67d37292..f8c7e351 100644
--- a/framework/src/sinkfabric.cpp
+++ b/framework/src/sinkfabric.cpp
@@ -144,11 +144,23 @@ public:
144 return; 144 return;
145 } 145 }
146 } else if (notification.type == Sink::Notification::Error) { 146 } else if (notification.type == Sink::Notification::Error) {
147 if (notification.code == Sink::ApplicationDomain::ConnectionError) { 147 message["type"] = Notification::Warning;
148 message["type"] = Notification::Warning; 148 message["resource"] = QString{notification.resource};
149 message["message"] = "Failed to connect to server."; 149 switch(notification.code) {
150 } else { 150 case Sink::ApplicationDomain::ConnectionError:
151 return; 151 message["message"] = "Failed to connect to server.";
152 break;
153 case Sink::ApplicationDomain::NoServerError:
154 message["message"] = "Host not found.";
155 break;
156 case Sink::ApplicationDomain::LoginError:
157 message["message"] = "Failed to login.";
158 break;
159 case Sink::ApplicationDomain::ConfigurationError:
160 message["message"] = "Configuration error.";
161 break;
162 default:
163 message["message"] = "An unknown error occurred: " + notification.message;
152 } 164 }
153 } else if (notification.type == Sink::Notification::Info) { 165 } else if (notification.type == Sink::Notification::Info) {
154 if (notification.code == Sink::ApplicationDomain::TransmissionSuccess) { 166 if (notification.code == Sink::ApplicationDomain::TransmissionSuccess) {