testexecutor-ui 0.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. testexecutor/VERSION +1 -0
  2. testexecutor/__init__.py +6 -0
  3. testexecutor/control/TestListenerApi.py +56 -0
  4. testexecutor/control/TestSuiteListener.py +249 -0
  5. testexecutor/control/__init__.py +0 -0
  6. testexecutor/model/GenericListModel.py +63 -0
  7. testexecutor/model/InstructionsModel.py +351 -0
  8. testexecutor/model/KeyValueModel.py +177 -0
  9. testexecutor/model/MultiTestWindowModel.py +184 -0
  10. testexecutor/model/ResultModel.py +314 -0
  11. testexecutor/model/TestSuiteControlModel.py +139 -0
  12. testexecutor/model/TestSuiteGroup.py +105 -0
  13. testexecutor/model/TestSuiteModel.py +301 -0
  14. testexecutor/model/__init__.py +0 -0
  15. testexecutor/model/selector/FilterGroupModel.py +90 -0
  16. testexecutor/model/selector/FilterModel.py +251 -0
  17. testexecutor/model/selector/MultiSelectDetails.py +106 -0
  18. testexecutor/model/selector/MultiSelectListModel.py +48 -0
  19. testexecutor/model/selector/__init__.py +0 -0
  20. testexecutor/ui/IdentificationWidget.qml +40 -0
  21. testexecutor/ui/InputWidget.qml +74 -0
  22. testexecutor/ui/InstructionWidget.qml +185 -0
  23. testexecutor/ui/KeyValueItem.qml +194 -0
  24. testexecutor/ui/KeyValueItemConfig.qml +41 -0
  25. testexecutor/ui/KeyValueList.qml +49 -0
  26. testexecutor/ui/MultiTestWidget.qml +48 -0
  27. testexecutor/ui/MultiTestWindow.qml +88 -0
  28. testexecutor/ui/ResultItem.qml +199 -0
  29. testexecutor/ui/ResultItemConfig.qml +46 -0
  30. testexecutor/ui/ResultList.qml +58 -0
  31. testexecutor/ui/TestSuiteConfig.qml +95 -0
  32. testexecutor/ui/TestSuiteController.qml +54 -0
  33. testexecutor/ui/TestSuiteWidget.qml +350 -0
  34. testexecutor/ui/selector/FilterItem.qml +75 -0
  35. testexecutor/ui/selector/FilterItemConfig.qml +24 -0
  36. testexecutor/ui/selector/FilterMultiSelectorItem.qml +169 -0
  37. testexecutor/ui/selector/FilterMultiSelectorItemConfig.qml +22 -0
  38. testexecutor/ui/selector/FilterMultiSelectorList.qml +50 -0
  39. testexecutor/ui/selector/HeaderConfig.qml +24 -0
  40. testexecutor/ui/selector/SectionConfig.qml +24 -0
  41. testexecutor/ui/selector/SectionDelegate.qml +85 -0
  42. testexecutor/ui/selector/SelectorHeader.qml +43 -0
  43. testexecutor/ui/selector/SuiteList.qml +150 -0
  44. testexecutor/ui/selector/SuiteSelector.qml +71 -0
  45. testexecutor/ui/selector/SuiteSelectorConfig.qml +38 -0
  46. testexecutor/ui/selector/TestConfig.qml +22 -0
  47. testexecutor/ui/selector/TestDelegate.qml +75 -0
  48. testexecutor/ui/te-64x64.ico +0 -0
  49. testexecutor_ui-0.6.1.dist-info/LICENSE +204 -0
  50. testexecutor_ui-0.6.1.dist-info/METADATA +27 -0
  51. testexecutor_ui-0.6.1.dist-info/NOTICE +3 -0
  52. testexecutor_ui-0.6.1.dist-info/RECORD +54 -0
  53. testexecutor_ui-0.6.1.dist-info/WHEEL +5 -0
  54. testexecutor_ui-0.6.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,350 @@
1
+ /*
2
+ * Copyright 2020 Direkt, Australia
3
+ * Copyright 2021 Direkt Embedded Pty Ltd
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import QtQuick
19
+ import QtQuick.Controls
20
+ import QtQuick.Layouts
21
+ import QtQuick.Window
22
+ import QtQuick.Dialogs
23
+
24
+ Item {
25
+ id: suite_container
26
+ property var tswModel
27
+ property int duration: 0
28
+ property int internal_duration: 0
29
+ property var config: TestSuiteConfig{}
30
+ property var about
31
+
32
+ Frame {
33
+ bottomPadding: 8
34
+ padding: 4
35
+ width: parent.width
36
+ height: parent.height
37
+
38
+ background: Rectangle {
39
+ id: frameRectangle
40
+ color: "transparent"
41
+ anchors.fill: parent
42
+ }
43
+
44
+ ColumnLayout {
45
+ id: testSuiteColumn
46
+ anchors.fill: parent
47
+
48
+ Rectangle {
49
+ id: rectangleTitle
50
+ Layout.maximumHeight: parent.height * config.proportion.title
51
+ Layout.minimumHeight: parent.height * 0.04
52
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
53
+ Layout.fillWidth: true
54
+ color: frameRectangle.color
55
+
56
+ Text {
57
+ id: suiteTitle
58
+ text: tswModel.testsuite.title
59
+ font.weight: Font.ExtraBold
60
+ anchors.fill: parent
61
+ horizontalAlignment: Text.AlignHCenter
62
+ font.pixelSize: parent.height
63
+ font.bold: true
64
+ font.family: "Arial"
65
+ clip: true
66
+ }
67
+ MouseArea {
68
+ anchors.fill: parent
69
+ onClicked: { aboutDialog.open() }
70
+ }
71
+ }
72
+
73
+ IdentificationWidget {
74
+ id: identifierWidget
75
+ Layout.maximumHeight: parent.height * 0.5
76
+ Layout.preferredHeight: parent.height * (config ? config.proportion.identification : 0.3)
77
+ Layout.minimumHeight: 0
78
+ Layout.alignment: Qt.AlignLeft | Qt.AlignTop
79
+ clip: false
80
+ Layout.fillWidth: true
81
+ identifiers: tswModel.testsuite.identifiers
82
+ color: config ? config.identification.color : "#e5e2e2"
83
+ itemConfig: config ? config.identification.item : ""
84
+ }
85
+
86
+ InputWidget {
87
+ id: inputWidget
88
+ Layout.maximumHeight: parent.height * 0.2
89
+ Layout.preferredHeight: parent.height * (config ? config.proportion.input : 0.05)
90
+ Layout.minimumHeight: 0
91
+ Layout.alignment: Qt.AlignLeft | Qt.AlignTop
92
+ clip: false
93
+ Layout.fillWidth: true
94
+ Binding {
95
+ target: tswModel.testsuite
96
+ property: "newid"
97
+ value: inputWidget.inputid
98
+ }
99
+ color: config ? config.identification.color : "#e5e2e2"
100
+ enabled: identifierWidget.enabled || instructionWidget.control_enabled
101
+ hidden: tswModel.testsuite.instructions.input_hidden
102
+ onEnabledChanged: {
103
+ var allowed = (config && config.input) ? config.input.allow_focus : false
104
+ if (enabled && allowed)
105
+ inputWidget.inputFocus();
106
+ }
107
+ }
108
+
109
+ InstructionWidget {
110
+ id: instructionWidget
111
+ Layout.minimumHeight: parent.height * 0.3
112
+ Layout.preferredHeight: parent.height * config.proportion.instructions
113
+ Layout.maximumHeight: parent.height * 0.7
114
+ clip: true
115
+ Layout.fillWidth: true
116
+ model: tswModel.testsuite.instructions
117
+ color: config ? interactionColour(config.instructions.color.active) : "yellow"
118
+ proportion: config ? config.instructions.proportion : {"header": 0.1, "textHeight": 0.07, "control": 0.02}
119
+ }
120
+
121
+ ResultList {
122
+ results: tswModel.testsuite.results
123
+ id: testList
124
+ Layout.fillWidth: true
125
+ Layout.fillHeight: true
126
+ Layout.alignment: Qt.AlignLeft | Qt.AlignTop
127
+ transformOrigin: Item.Center
128
+ clip: true
129
+ viewableCount: config.results.viewableCount
130
+ color: config.results.color
131
+ itemConfig: config.results.item
132
+ }
133
+ Item {
134
+ id: buttonContainer
135
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
136
+ // The Item wrapper is to allow TextField pixelSize to reference the parents height.
137
+ Layout.preferredHeight: parent.height * config.proportion.status
138
+ Layout.minimumHeight: parent.height * config.proportion.status
139
+ Layout.maximumHeight: parent.height * config.proportion.status
140
+ Layout.fillWidth: true
141
+ GridLayout {
142
+ anchors.fill: parent
143
+ columns: 3
144
+ rows: 1
145
+ Button {
146
+ id: control_button
147
+ width: parent.width
148
+ height: parent.height * 0.8
149
+ text: ""
150
+ Layout.column: 1
151
+ Layout.columnSpan: 1
152
+ enabled: false
153
+ padding: 0
154
+ spacing: 3
155
+ font.pixelSize: parent.height * 0.7
156
+ onClicked: {
157
+ /*
158
+ * Call the action 'event' on the test suite model with the text of the button as defined
159
+ * in the configuration
160
+ */
161
+ if (suite_container.state === "running" || suite_container.state === "starting") {
162
+ actionDialog.action = control_button.text
163
+ actionDialog.open()
164
+ } else {
165
+ tswModel.testsuite.action(control_button.text)
166
+ }
167
+ }
168
+ contentItem: Text {
169
+ text: control_button.text
170
+ font: control_button.font
171
+ opacity: enabled ? 1.0 : 0.3
172
+ //color: control_button.down ? "#17a81a" : "#21be2b"
173
+ horizontalAlignment: Text.AlignHCenter
174
+ verticalAlignment: Text.AlignVCenter
175
+ elide: Text.ElideNone
176
+ clip: true
177
+ }
178
+ }
179
+ Timer {
180
+ interval: 1000;
181
+ running: state === "running" || state === "stopping";
182
+ repeat: true
183
+ onTriggered: {
184
+ duration = duration + 1
185
+ }
186
+ }
187
+ Text {
188
+ id: suiteProgress
189
+ color: "#e5e2e2"
190
+ text: formatTime(duration)
191
+ Layout.fillWidth: false
192
+ Layout.column: 2
193
+ Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
194
+ Layout.columnSpan: 1
195
+ verticalAlignment: Text.AlignVCenter
196
+ horizontalAlignment: Text.AlignRight
197
+ font.pixelSize: parent.height / 1.2
198
+ anchors.rightMargin: 0
199
+ clip: true
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ state: tswModel.testsuite.suitestate
206
+
207
+ states: [
208
+ State {
209
+ name: "idle"
210
+ PropertyChanges { target: control_button; text: config.states.idle.button.text; enabled: true }
211
+ PropertyChanges { target: instructionWidget; enabled: true }
212
+ PropertyChanges { target: identifierWidget; enabled: true }
213
+ PropertyChanges { target: frameRectangle; color: suiteResultColour(config.states.idle.color.default) }
214
+ PropertyChanges { target: suite_container; internal_duration: setDuration(0) }
215
+ },
216
+ State {
217
+ name: "ready"
218
+ PropertyChanges { target: control_button; text: config.states.ready.button.text; enabled: true }
219
+ PropertyChanges { target: instructionWidget; enabled: true }
220
+ PropertyChanges { target: identifierWidget; enabled: true }
221
+ PropertyChanges { target: frameRectangle; color: suiteRunningColour(config.states.ready.color) }
222
+ },
223
+ State {
224
+ name: "running"
225
+ PropertyChanges { target: control_button; text: config.states.running.button.text; enabled: true }
226
+ PropertyChanges { target: instructionWidget; enabled: true }
227
+ PropertyChanges { target: identifierWidget; enabled: false }
228
+ PropertyChanges { target: frameRectangle; color: suiteRunningColour(config.states.running.color) }
229
+ },
230
+ State {
231
+ name: "starting"
232
+ PropertyChanges { target: control_button; text: config.states.running.button.text; enabled: false }
233
+ PropertyChanges { target: instructionWidget; enabled: false }
234
+ PropertyChanges { target: frameRectangle; color: suiteRunningColour(config.states.running.color) }
235
+ },
236
+ State {
237
+ name: "stopping"
238
+ PropertyChanges { target: control_button; text: config.states.stopped.button.text; enabled: false }
239
+ PropertyChanges { target: instructionWidget; enabled: true }
240
+ PropertyChanges { target: identifierWidget; enabled: false }
241
+ PropertyChanges { target: frameRectangle; color: config.states.stopped.color }
242
+ },
243
+ State {
244
+ name: "stopped"
245
+ PropertyChanges { target: control_button; text: config.states.stopped.button.text; enabled: true }
246
+ PropertyChanges { target: instructionWidget; enabled: false }
247
+ PropertyChanges { target: identifierWidget; enabled: true }
248
+ PropertyChanges { target: frameRectangle; color: config.states.stopped.color }
249
+ },
250
+ State {
251
+ name: "end"
252
+ PropertyChanges { target: control_button; text: config.states.idle.button.text; enabled: true }
253
+ PropertyChanges { target: instructionWidget; enabled: true }
254
+ PropertyChanges { target: identifierWidget; enabled: true }
255
+ PropertyChanges { target: frameRectangle; color: suiteResultColour(config.states.idle.color.default) }
256
+ },
257
+ State {
258
+ name: "restart"
259
+ PropertyChanges { target: control_button; text: config.states.idle.button.text; enabled: true }
260
+ PropertyChanges { target: instructionWidget; enabled: true }
261
+ PropertyChanges { target: identifierWidget; enabled: true }
262
+ PropertyChanges { target: frameRectangle; color: suiteResultColour(config.states.idle.color.default) }
263
+ }
264
+ ]
265
+
266
+ Dialog {
267
+ id: actionDialog
268
+ property var action
269
+ title: "There Are Tests Running"
270
+ Label {
271
+ id: testWarning
272
+ text: "Do you want to " + control_button.text + "?"
273
+ font.pixelSize: suite_container.width * 0.05 > 11 ? suite_container.width * 0.05:11
274
+ }
275
+ font.pixelSize: suite_container.width * 0.05 > 11 ? suite_container.width * 0.05:11
276
+ standardButtons: Dialog.Yes | Dialog.No
277
+ onAccepted: {
278
+ tswModel.testsuite.action(action)
279
+ }
280
+ implicitWidth: testWarning.width * 2
281
+ anchors.centerIn: Overlay.overlay
282
+ }
283
+
284
+ Dialog {
285
+ id: aboutDialog
286
+ title: "About"
287
+ Label {
288
+ id: aboutLabel
289
+ text: about
290
+ }
291
+ standardButtons: Dialog.Ok
292
+ implicitWidth: aboutLabel.width * 1.3
293
+ anchors.centerIn: Overlay.overlay
294
+ }
295
+ function setDuration(secs)
296
+ {
297
+ // This is a workaround so the duration property set in the state change
298
+ // actually takes affect.
299
+ suite_container.duration = secs
300
+ return secs
301
+ }
302
+ function suiteRunningColour(defaultColor)
303
+ {
304
+ var colour = defaultColor;
305
+ if (tswModel.testsuite.suite_colours.running)
306
+ {
307
+ colour = tswModel.testsuite.suite_colours.running
308
+ }
309
+ return colour;
310
+ }
311
+ function suiteResultColour(defaultColor)
312
+ {
313
+ var colour = defaultColor;
314
+ if (tswModel.testsuite.result === "Pass")
315
+ {
316
+ colour = config.states.idle.color.pass
317
+ }
318
+ else if (tswModel.testsuite.result === "Fail")
319
+ {
320
+ colour = config.states.idle.color.fail
321
+ }
322
+ return colour;
323
+ }
324
+ function interactionColour(defaultColor)
325
+ {
326
+ var colour = defaultColor;
327
+ if (tswModel.testsuite.suite_colours.interaction)
328
+ {
329
+ colour = tswModel.testsuite.suite_colours.interaction
330
+ }
331
+ return colour;
332
+ }
333
+ function formatTime(timeInSeconds) {
334
+ var pad = function(num, size) { return ('000' + num).slice(size * -1); },
335
+ time = parseFloat(timeInSeconds).toFixed(3),
336
+ hours = Math.floor(time / 60 / 60),
337
+ minutes = Math.floor(time / 60) % 60,
338
+ seconds = Math.floor(time - minutes * 60),
339
+ milliseconds = time.slice(-3);
340
+
341
+ var s = pad(seconds, 2);
342
+ if (timeInSeconds >= 60*60) {
343
+ s = pad(hours, 2) + ':' + pad(minutes, 2) + ':' + pad(seconds, 2)
344
+ } else if (timeInSeconds >= 60){
345
+ s = pad(minutes, 2) + ':' + pad(seconds, 2)
346
+ }
347
+
348
+ return s;
349
+ }
350
+ }
@@ -0,0 +1,75 @@
1
+ /*
2
+ * Copyright 2020 Sipke Vriend, Australia
3
+ * Copyright 2021 Direkt Embedded Pty Ltd
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import QtQuick
19
+ import QtQuick.Layouts
20
+ import QtQuick.Controls
21
+
22
+ Item {
23
+ id: filterItem
24
+ width: content.paintedWidth + control.width + 10
25
+ height: 30
26
+ property var config: FilterItemConfig{}
27
+ signal remove(int index)
28
+
29
+ Rectangle {
30
+ id: filterItemRectangle
31
+ color: Boolean(config) ? filterItem.config.background.color: "white"
32
+ border.width: 1
33
+ border.color: Boolean(config) ? config.border.color : "darkgray"
34
+ anchors.fill: parent
35
+ RowLayout {
36
+ anchors.rightMargin: 3
37
+ anchors.leftMargin: 3
38
+ anchors.bottomMargin: 3
39
+ anchors.topMargin: 3
40
+ anchors.fill: parent
41
+ Text {
42
+ id: content
43
+ text: modelData
44
+ font.pixelSize: parent.height * 0.7
45
+ Layout.fillWidth: true
46
+ Layout.fillHeight: true
47
+ }
48
+ Button {
49
+ id: control
50
+ text: "-"
51
+ Layout.fillHeight: true
52
+ Layout.preferredHeight: parent.height * 0.8
53
+ font.wordSpacing: 0
54
+ font.pixelSize: parent.height > 0 ? parent.height * 0.7 : 10
55
+ font.weight: Font.ExtraBold
56
+ Layout.maximumWidth: 30
57
+ Layout.preferredWidth: 20
58
+ Layout.minimumWidth: 10
59
+ background: Rectangle {
60
+ border.width: control.activeFocus ? 2 : 1
61
+ border.color: "darkgray"
62
+ radius: 4
63
+ gradient: Gradient {
64
+ GradientStop { position: 0 ; color: control.pressed ? config.button.gradient.start.pressed : config.button.gradient.start.off }
65
+ GradientStop { position: 1 ; color: control.pressed ? config.button.gradient.end.pressed : config.button.gradient.end.off }
66
+ }
67
+ }
68
+ onClicked: {
69
+ filterItem.remove(index)
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Copyright 2021 Direkt Embedded Pty Ltd
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import QtQuick
18
+
19
+ Item {
20
+ property var background: {"color": "snow"}
21
+ property var border: {"color": "darkgray"}
22
+ property var button: {"gradient": {"start": {"off": "white", "pressed": "white"},
23
+ "end": {"off": "gray", "pressed": "orange"}} }
24
+ }
@@ -0,0 +1,169 @@
1
+ /*
2
+ * Copyright 2020 Sipke Vriend, Australia
3
+ * Copyright 2021 Direkt Embedded Pty Ltd
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /*
19
+ * A View for selection tests to run
20
+ */
21
+
22
+ import QtQuick
23
+ import QtQuick.Layouts
24
+ import QtQuick.Controls
25
+
26
+ Item {
27
+ id: filterSelector
28
+ property int viewableCount: 5
29
+ property var filterItem
30
+ property var tooltipText: "Select item to filter with"
31
+ property var config: FilterMultiSelectorItemConfig{}
32
+ signal changed()
33
+ width: 600
34
+ height: 30
35
+
36
+ Frame {
37
+ padding: 2
38
+ width: parent.width
39
+ height: parent.height
40
+
41
+ RowLayout {
42
+ anchors.fill: parent
43
+ Rectangle {
44
+ id: valueRectangle
45
+ Layout.fillHeight: true
46
+ Layout.preferredWidth: parent.width * 0.2
47
+ Layout.minimumWidth: parent.width * 0.05
48
+ Layout.maximumWidth: parent.width * 0.5
49
+ color: Boolean(config) ? config.list.background.color : "lightgray"
50
+ border.width: 1
51
+ border.color: Boolean(config) ? config.list.border.color : "black"
52
+ ComboBox {
53
+ id: comboControl
54
+ height: parent.height
55
+ wheelEnabled: true
56
+ //editable: true
57
+ width: parent.width
58
+ font.pixelSize: parent.height * 0.7
59
+ bottomPadding: height * 0.1
60
+ leftPadding: 2
61
+ rightPadding: 0
62
+ contentItem: Text {
63
+ leftPadding: 0
64
+ rightPadding: comboControl.indicator.width + comboControl.spacing
65
+ text: comboControl.displayText
66
+ font: comboControl.font
67
+ verticalAlignment: Text.AlignVCenter
68
+ elide: Text.ElideRight
69
+ }
70
+
71
+ ToolTip {
72
+ visible: comboControl.hovered
73
+ timeout: 3000
74
+ delay: 500
75
+ contentItem:
76
+ Column {
77
+ Text {
78
+ text: filterSelector.tooltipText
79
+ font.pixelSize: filterListRectangle.height * 0.7
80
+ font.weight: Font.ExtraBold
81
+ }
82
+ }
83
+ }
84
+
85
+ textRole: "display"
86
+ delegate: ItemDelegate {
87
+ width: comboControl.width
88
+ contentItem: Text {
89
+ text: model.display
90
+ font: comboControl.font
91
+ elide: Text.ElideRight
92
+ verticalAlignment: Text.AlignVCenter
93
+ padding: 0
94
+ }
95
+ highlighted: comboControl.highlightedIndex === index
96
+ }
97
+
98
+ background: Rectangle {
99
+ border.width: 1
100
+ border.color: valueRectangle.border.color
101
+ }
102
+ model: filterItem.proposed
103
+ onActivated: {
104
+ var v = comboControl.currentText
105
+ if (v) {
106
+ //filterListView.model.insert(0, {text: v})
107
+ filterListView.model.prepend(v)
108
+ }
109
+ }
110
+ }
111
+ }
112
+ Rectangle {
113
+ id: filterListRectangle
114
+ Layout.fillHeight: true
115
+ color: Boolean(config) ? valueRectangle.color : "lightgray"
116
+ Layout.fillWidth: true
117
+
118
+ Text {
119
+ color: "#8e8a8a"
120
+ text: filterItem.name
121
+ font.pixelSize: parent.height * 0.7
122
+ font.weight: Font.Light
123
+ font.italic: true
124
+ verticalAlignment: Text.AlignVCenter
125
+ horizontalAlignment: Text.AlignHCenter
126
+ anchors.fill: parent
127
+ }
128
+
129
+ ListView {
130
+ id: filterListView
131
+ anchors.fill: parent
132
+ orientation: ListView.Horizontal
133
+ spacing: 1
134
+ snapMode: ListView.NoSnap
135
+ boundsBehavior: Flickable.StopAtBounds
136
+ //currentIndex: model ? model.currentTestIndex : 0
137
+ highlightFollowsCurrentItem: true
138
+ delegate: FilterItem {
139
+ height: filterListView.height
140
+ Component.onCompleted: {
141
+ if (model.currentTestIndex === -1) {
142
+ filterListView.positionViewAtEnd();
143
+ }
144
+ filterSelector.changed()
145
+ }
146
+ onRemove: function(index) {
147
+ filterListView.model.remove(index)
148
+ filterSelector.changed()
149
+ }
150
+ config: filterSelector.config.item
151
+ }
152
+ ScrollBar.horizontal: ScrollBar {
153
+ policy: ScrollBar.AsNeeded
154
+ }
155
+ model: filterItem.selected
156
+ }
157
+ }
158
+ }
159
+ }
160
+
161
+ Component.onCompleted: parseConfigStr()
162
+
163
+ function parseConfigStr() {
164
+ if (typeof contextFilterSelectorItemConfig !== "undefined") {
165
+ var json = JSON.parse(contextFilterSelectorItemConfig)
166
+ filterSelector.config = json
167
+ }
168
+ }
169
+ }
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright 2021 Direkt Embedded Pty Ltd
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import QtQuick
18
+
19
+ Item {
20
+ property var list: {"background": {"color": "lightgray"}, "border": {"color": "darkgray"}}
21
+ property var item: FilterItemConfig{}
22
+ }
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Copyright 2020 Sipke Vriend, Australia
3
+ * Copyright 2021 Direkt Embedded Pty Ltd
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ import QtQuick
19
+
20
+ Item {
21
+ id: filterList
22
+ width: 400
23
+ height: 100
24
+ clip: true
25
+ property var filters
26
+ property int viewableCount: -1
27
+ property var itemConfig
28
+ signal changed()
29
+
30
+ Rectangle {
31
+ id: filterRectangle
32
+ anchors.fill: parent
33
+
34
+ ListView {
35
+ id: filterListView
36
+ clip: true
37
+ snapMode: ListView.NoSnap
38
+ boundsBehavior: Flickable.StopAtBounds
39
+ anchors.fill: parent
40
+ delegate: FilterMultiSelectorItem {
41
+ height: (filterList.viewableCount <= 0) ? (filterListView.height / filterListView.count) : (filterListView.height / viewableCount)
42
+ width: parent.width
43
+ filterItem: model.filter
44
+ onChanged: filterList.changed()
45
+ }
46
+ model: filters
47
+ }
48
+ }
49
+ }
50
+