aboutsummaryrefslogtreecommitdiffstats
path: root/demo/Main.qml
diff options
context:
space:
mode:
Diffstat (limited to 'demo/Main.qml')
-rw-r--r--demo/Main.qml222
1 files changed, 152 insertions, 70 deletions
diff --git a/demo/Main.qml b/demo/Main.qml
index 361e3bd..2cfa577 100644
--- a/demo/Main.qml
+++ b/demo/Main.qml
@@ -9,61 +9,72 @@ import Bobink
ApplicationWindow {
id: root
- width: 800
- height: 900
- visible: true
- title: "Bobink Demo"
property bool autoConnectFailed: false
property bool showPkiSettings: false
+ height: 900
+ title: "Bobink Demo"
+ visible: true
+ width: 800
+
Connections {
- target: Bobink
- function onServersChanged() {
- debugConsole.appendLog("Discovered server list updated");
+ function onCertificateTrustRequested(certInfo) {
+ certTrustDialog.certInfo = certInfo;
+ certTrustDialog.open();
}
+
function onConnectedChanged() {
debugConsole.appendLog("Connected: " + Bobink.connected);
if (Bobink.connected) {
root.autoConnectFailed = false;
Bobink.stopDiscovery();
stack.push("NodePage.qml", {
- stackRef: stack,
- pageNumber: 1,
- logFunction: debugConsole.appendLog
- });
+ stackRef: stack,
+ pageNumber: 1,
+ logFunction: debugConsole.appendLog
+ });
} else {
stack.pop(null);
}
}
+
function onConnectionError(message) {
debugConsole.appendLog("Connection error: " + message);
root.autoConnectFailed = true;
}
- function onStatusMessage(message) {
- debugConsole.appendLog(message);
- }
+
function onDiscoveringChanged() {
debugConsole.appendLog("Discovering: " + Bobink.discovering);
}
- function onCertificateTrustRequested(certInfo) {
- certTrustDialog.certInfo = certInfo;
- certTrustDialog.open();
+
+ function onServersChanged() {
+ debugConsole.appendLog("Discovered server list updated");
}
+
+ function onStatusMessage(message) {
+ debugConsole.appendLog(message);
+ }
+
+ target: Bobink
}
Dialog {
id: certTrustDialog
+
property string certInfo
+
anchors.centerIn: parent
- title: "Certificate Trust"
modal: true
standardButtons: Dialog.Yes | Dialog.No
+ title: "Certificate Trust"
+
+ onAccepted: Bobink.acceptCertificate()
+ onRejected: Bobink.rejectCertificate()
+
Label {
text: certTrustDialog.certInfo
}
- onAccepted: Bobink.acceptCertificate()
- onRejected: Bobink.rejectCertificate()
}
ColumnLayout {
@@ -72,11 +83,13 @@ ApplicationWindow {
StackView {
id: stack
- Layout.fillWidth: true
+
Layout.fillHeight: true
+ Layout.fillWidth: true
initialItem: Page {
id: connectionPage
+
Component.onCompleted: {
Bobink.discoveryUrl = discoveryUrlField.text;
Bobink.startDiscovery();
@@ -84,32 +97,44 @@ ApplicationWindow {
OpcUaAuth {
id: auth
- mode: authModeCombo.currentValue
- username: usernameField.text
- password: passwordField.text
+
certPath: Bobink.certFile
keyPath: Bobink.keyFile
+ mode: authModeCombo.currentValue
+ password: passwordField.text
+ username: usernameField.text
}
FileDialog {
id: certFileDialog
- title: "Select Certificate"
+
currentFolder: "file://" + trustFolderField.text
nameFilters: ["DER certificates (*.der)", "All files (*)"]
- onAccepted: certFileField.text = selectedFile.toString().replace("file://", "")
+ title: "Select Certificate"
+
+ onAccepted: certFileField.text = selectedFile.toString(
+ ).replace("file://", "")
}
+
FileDialog {
id: keyFileDialog
- title: "Select Private Key"
+
currentFolder: "file://" + trustFolderField.text
nameFilters: ["Key files (*.pem *.crt)", "All files (*)"]
- onAccepted: keyFileField.text = selectedFile.toString().replace("file://", "")
+ title: "Select Private Key"
+
+ onAccepted: keyFileField.text = selectedFile.toString(
+ ).replace("file://", "")
}
+
FolderDialog {
id: trustFolderDialog
- title: "Select Trust Folder"
+
currentFolder: "file://" + trustFolderField.text
- onAccepted: trustFolderField.text = selectedFolder.toString().replace("file://", "")
+ title: "Select Trust Folder"
+
+ onAccepted: trustFolderField.text = selectedFolder.toString(
+ ).replace("file://", "")
}
ColumnLayout {
@@ -118,23 +143,27 @@ ApplicationWindow {
spacing: 12
Label {
- text: "Discovery URL"
font.bold: true
+ text: "Discovery URL"
}
RowLayout {
TextField {
id: discoveryUrlField
+
Layout.fillWidth: true
text: "opc.tcp://localhost:4840"
}
+
Button {
text: Bobink.discovering ? "Stop" : "Discover"
+
onClicked: {
if (Bobink.discovering) {
Bobink.stopDiscovery();
} else {
- Bobink.discoveryUrl = discoveryUrlField.text;
+ Bobink.discoveryUrl
+ = discoveryUrlField.text;
Bobink.startDiscovery();
}
}
@@ -142,114 +171,148 @@ ApplicationWindow {
}
Label {
- text: Bobink.discovering ? "Discovering... (" + Bobink.servers.length + " found)" : Bobink.servers.length + " server(s)"
font.italic: true
+ text: Bobink.discovering ? "Discovering... ("
+ + Bobink.servers.length
+ + " found)" :
+ Bobink.servers.length
+ + " server(s)"
}
ListView {
id: serverListView
+
Layout.fillWidth: true
Layout.preferredHeight: 100
clip: true
model: Bobink.servers
+
+ ScrollBar.vertical: ScrollBar {
+ policy: ScrollBar.AsNeeded
+ }
delegate: ItemDelegate {
id: serverDelegate
+
required property var modelData
+
width: ListView.view.width
+
contentItem: ColumnLayout {
spacing: 2
+
Label {
text: serverDelegate.modelData.serverName
}
+
Label {
- text: serverDelegate.modelData.applicationUri
+ Layout.fillWidth: true
color: "gray"
+ elide: Text.ElideRight
font.italic: true
font.pointSize: 8
- elide: Text.ElideRight
- Layout.fillWidth: true
+ text: serverDelegate.modelData.applicationUri
}
}
+
onClicked: {
if (modelData.discoveryUrls.length > 0)
- serverUrlField.text = modelData.discoveryUrls[0];
+ serverUrlField.text
+ = modelData.discoveryUrls[0];
}
}
- ScrollBar.vertical: ScrollBar {
- policy: ScrollBar.AsNeeded
- }
}
RowLayout {
Label {
- text: "PKI"
font.bold: true
+ text: "PKI"
}
+
Label {
- text: Bobink.certFile ? " (" + Bobink.certFile.split("/").pop() + ")" : " (no certificate found)"
- font.italic: true
color: Bobink.certFile ? "green" : "gray"
+ font.italic: true
+ text: Bobink.certFile ? " ("
+ + Bobink.certFile.split(
+ "/").pop() + ")" :
+ " (no certificate found)"
}
+
Item {
Layout.fillWidth: true
}
+
Button {
text: root.showPkiSettings ? "Hide" : "Configure"
- onClicked: root.showPkiSettings = !root.showPkiSettings
+
+ onClicked: root.showPkiSettings =
+ !root.showPkiSettings
}
}
GridLayout {
- columns: 3
Layout.fillWidth: true
+ columns: 3
visible: root.showPkiSettings
Label {
text: "Certificate:"
}
+
TextField {
id: certFileField
+
Layout.fillWidth: true
- text: Bobink.certFile
placeholderText: "Client certificate (.der)"
+ text: Bobink.certFile
}
+
Button {
text: "Browse"
+
onClicked: certFileDialog.open()
}
Label {
text: "Private key:"
}
+
TextField {
id: keyFileField
+
Layout.fillWidth: true
- text: Bobink.keyFile
placeholderText: "Private key (.pem, .crt)"
+ text: Bobink.keyFile
}
+
Button {
text: "Browse"
+
onClicked: keyFileDialog.open()
}
Label {
text: "Trust folder:"
}
+
TextField {
id: trustFolderField
+
Layout.fillWidth: true
text: Bobink.pkiDir
}
+
Button {
text: "Browse"
+
onClicked: trustFolderDialog.open()
}
}
Button {
- text: "Apply PKI"
Layout.fillWidth: true
+ text: "Apply PKI"
visible: root.showPkiSettings
+
onClicked: {
Bobink.pkiDir = trustFolderField.text;
Bobink.certFile = certFileField.text;
@@ -259,26 +322,26 @@ ApplicationWindow {
}
Label {
- text: "Server URL"
font.bold: true
+ text: "Server URL"
}
TextField {
id: serverUrlField
+
Layout.fillWidth: true
placeholderText: "opc.tcp://..."
}
Label {
- text: "Authentication"
font.bold: true
+ text: "Authentication"
}
ComboBox {
id: authModeCombo
+
Layout.fillWidth: true
- textRole: "text"
- valueRole: "mode"
model: [
{
text: "Anonymous",
@@ -293,33 +356,42 @@ ApplicationWindow {
mode: OpcUaAuth.Certificate
}
]
+ textRole: "text"
+ valueRole: "mode"
}
GridLayout {
- columns: 2
- visible: authModeCombo.currentValue === OpcUaAuth.UserPass
Layout.fillWidth: true
+ columns: 2
+ visible: authModeCombo.currentValue
+ === OpcUaAuth.UserPass
Label {
text: "Username:"
}
+
TextField {
id: usernameField
+
Layout.fillWidth: true
}
+
Label {
text: "Password:"
}
+
TextField {
id: passwordField
+
Layout.fillWidth: true
echoMode: TextInput.Password
}
}
Button {
- text: "Connect"
Layout.fillWidth: true
+ text: "Connect"
+
onClicked: {
root.autoConnectFailed = false;
Bobink.auth = auth;
@@ -329,24 +401,24 @@ ApplicationWindow {
}
Label {
- text: "Direct Connect"
font.bold: true
+ text: "Direct Connect"
visible: root.autoConnectFailed
}
GridLayout {
- columns: 2
Layout.fillWidth: true
+ columns: 2
visible: root.autoConnectFailed
Label {
text: "Security policy:"
}
+
ComboBox {
id: securityPolicyCombo
+
Layout.fillWidth: true
- textRole: "text"
- valueRole: "policy"
model: [
{
text: "Basic256Sha256",
@@ -361,16 +433,18 @@ ApplicationWindow {
policy: Bobink.Aes256_Sha256_RsaPss
}
]
+ textRole: "text"
+ valueRole: "policy"
}
Label {
text: "Security mode:"
}
+
ComboBox {
id: securityModeCombo
+
Layout.fillWidth: true
- textRole: "text"
- valueRole: "mode"
model: [
{
text: "Sign & Encrypt",
@@ -385,17 +459,22 @@ ApplicationWindow {
mode: Bobink.None
}
]
+ textRole: "text"
+ valueRole: "mode"
}
}
Button {
- text: "Direct Connect"
Layout.fillWidth: true
+ text: "Direct Connect"
visible: root.autoConnectFailed
+
onClicked: {
Bobink.auth = auth;
Bobink.serverUrl = serverUrlField.text;
- Bobink.connectDirect(securityPolicyCombo.currentValue, securityModeCombo.currentValue);
+ Bobink.connectDirect(
+ securityPolicyCombo.currentValue,
+ securityModeCombo.currentValue);
}
}
@@ -408,11 +487,6 @@ ApplicationWindow {
Rectangle {
id: debugConsole
- Layout.fillWidth: true
- Layout.preferredHeight: 120
- color: "#1e1e1e"
- border.color: "#444"
- radius: 4
function appendLog(msg) {
let ts = new Date().toLocaleTimeString(Qt.locale(), "HH:mm:ss");
@@ -420,17 +494,25 @@ ApplicationWindow {
debugLog.cursorPosition = debugLog.text.length;
}
+ Layout.fillWidth: true
+ Layout.preferredHeight: 120
+ border.color: "#444"
+ color: "#1e1e1e"
+ radius: 4
+
ScrollView {
anchors.fill: parent
anchors.margins: 4
+
TextArea {
id: debugLog
- readOnly: true
+
+ background: null
color: "#cccccc"
font.family: "monospace"
font.pointSize: 9
+ readOnly: true
wrapMode: TextEdit.Wrap
- background: null
}
}
}