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.
- testexecutor/VERSION +1 -0
- testexecutor/__init__.py +6 -0
- testexecutor/control/TestListenerApi.py +56 -0
- testexecutor/control/TestSuiteListener.py +249 -0
- testexecutor/control/__init__.py +0 -0
- testexecutor/model/GenericListModel.py +63 -0
- testexecutor/model/InstructionsModel.py +351 -0
- testexecutor/model/KeyValueModel.py +177 -0
- testexecutor/model/MultiTestWindowModel.py +184 -0
- testexecutor/model/ResultModel.py +314 -0
- testexecutor/model/TestSuiteControlModel.py +139 -0
- testexecutor/model/TestSuiteGroup.py +105 -0
- testexecutor/model/TestSuiteModel.py +301 -0
- testexecutor/model/__init__.py +0 -0
- testexecutor/model/selector/FilterGroupModel.py +90 -0
- testexecutor/model/selector/FilterModel.py +251 -0
- testexecutor/model/selector/MultiSelectDetails.py +106 -0
- testexecutor/model/selector/MultiSelectListModel.py +48 -0
- testexecutor/model/selector/__init__.py +0 -0
- testexecutor/ui/IdentificationWidget.qml +40 -0
- testexecutor/ui/InputWidget.qml +74 -0
- testexecutor/ui/InstructionWidget.qml +185 -0
- testexecutor/ui/KeyValueItem.qml +194 -0
- testexecutor/ui/KeyValueItemConfig.qml +41 -0
- testexecutor/ui/KeyValueList.qml +49 -0
- testexecutor/ui/MultiTestWidget.qml +48 -0
- testexecutor/ui/MultiTestWindow.qml +88 -0
- testexecutor/ui/ResultItem.qml +199 -0
- testexecutor/ui/ResultItemConfig.qml +46 -0
- testexecutor/ui/ResultList.qml +58 -0
- testexecutor/ui/TestSuiteConfig.qml +95 -0
- testexecutor/ui/TestSuiteController.qml +54 -0
- testexecutor/ui/TestSuiteWidget.qml +350 -0
- testexecutor/ui/selector/FilterItem.qml +75 -0
- testexecutor/ui/selector/FilterItemConfig.qml +24 -0
- testexecutor/ui/selector/FilterMultiSelectorItem.qml +169 -0
- testexecutor/ui/selector/FilterMultiSelectorItemConfig.qml +22 -0
- testexecutor/ui/selector/FilterMultiSelectorList.qml +50 -0
- testexecutor/ui/selector/HeaderConfig.qml +24 -0
- testexecutor/ui/selector/SectionConfig.qml +24 -0
- testexecutor/ui/selector/SectionDelegate.qml +85 -0
- testexecutor/ui/selector/SelectorHeader.qml +43 -0
- testexecutor/ui/selector/SuiteList.qml +150 -0
- testexecutor/ui/selector/SuiteSelector.qml +71 -0
- testexecutor/ui/selector/SuiteSelectorConfig.qml +38 -0
- testexecutor/ui/selector/TestConfig.qml +22 -0
- testexecutor/ui/selector/TestDelegate.qml +75 -0
- testexecutor/ui/te-64x64.ico +0 -0
- testexecutor_ui-0.6.1.dist-info/LICENSE +204 -0
- testexecutor_ui-0.6.1.dist-info/METADATA +27 -0
- testexecutor_ui-0.6.1.dist-info/NOTICE +3 -0
- testexecutor_ui-0.6.1.dist-info/RECORD +54 -0
- testexecutor_ui-0.6.1.dist-info/WHEEL +5 -0
- 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
|
+
|