1 | // Copyright (C) 2018 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include <private/opcuarelativenodepath_p.h> |
5 | #include <private/opcuanodeid_p.h> |
6 | |
7 | #include <QtOpcUa/qopcuaclient.h> |
8 | #include <QLoggingCategory> |
9 | #include <QMetaEnum> |
10 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | /*! |
14 | \qmltype RelativeNodePath |
15 | \inqmlmodule QtOpcUa |
16 | \brief Specifies a relative node path element. |
17 | \since QtOpcUa 5.12 |
18 | |
19 | \code |
20 | import QtOpcUa as QtOpcUa |
21 | |
22 | QtOpcUa.RelativeNodePath { |
23 | ns: "Test Namespace" |
24 | browseName: "SomeName" |
25 | } |
26 | \endcode |
27 | |
28 | \sa Node, NodeId, RelativeNodeId |
29 | */ |
30 | |
31 | /*! |
32 | \qmlproperty NodeId RelativeNodePath::ns |
33 | |
34 | Namespace name of this path element. |
35 | The identifier can be the index as a number or the name as string. |
36 | A string which can be converted to an integer is considered a namespace index. |
37 | */ |
38 | |
39 | /*! |
40 | \qmlproperty NodeId RelativeNodePath::browseName |
41 | |
42 | Browse name of this path element. |
43 | */ |
44 | |
45 | /*! |
46 | \qmlproperty bool RelativeNodePath::includeSubtypes |
47 | |
48 | Whether subtypes are included when matching this path element. |
49 | The default value of this property is \c true. |
50 | */ |
51 | |
52 | /*! |
53 | \qmlproperty bool RelativeNodePath::isInverse |
54 | |
55 | Whether the reference to follow is inverse. |
56 | The default value of this property is \c false. |
57 | */ |
58 | |
59 | /*! |
60 | \qmlproperty QOpcUa::ReferenceTypeId RelativeNodePath::referenceType |
61 | |
62 | Type of reference when matching this path element. |
63 | This can be a \l QOpcUa::ReferenceTypeId or a \l NodeId. |
64 | The default value of this property is \c Constants.ReferenceTypeId.References. |
65 | */ |
66 | |
67 | Q_DECLARE_LOGGING_CATEGORY(QT_OPCUA_PLUGINS_QML) |
68 | |
69 | OpcUaRelativeNodePath::OpcUaRelativeNodePath(QObject *parent) : QObject(parent) |
70 | { |
71 | connect(sender: &m_browseNode, signal: &UniversalNode::namespaceNameChanged, context: this, slot: &OpcUaRelativeNodePath::nodeNamespaceChanged); |
72 | connect(sender: &m_browseNode, signal: &UniversalNode::nodeIdentifierChanged, context: this, slot: &OpcUaRelativeNodePath::browseNameChanged); |
73 | } |
74 | |
75 | const QString &OpcUaRelativeNodePath::nodeNamespace() const |
76 | { |
77 | return m_browseNode.namespaceName(); |
78 | } |
79 | |
80 | const QString &OpcUaRelativeNodePath::browseName() const |
81 | { |
82 | return m_browseNode.nodeIdentifier(); |
83 | } |
84 | |
85 | QVariant OpcUaRelativeNodePath::referenceType() const |
86 | { |
87 | return m_referenceType; |
88 | } |
89 | |
90 | bool OpcUaRelativeNodePath::includeSubtypes() const |
91 | { |
92 | return m_includeSubtypes; |
93 | } |
94 | |
95 | void OpcUaRelativeNodePath::setNodeNamespace(QString ns) |
96 | { |
97 | m_browseNode.setNamespace(ns); |
98 | } |
99 | |
100 | void OpcUaRelativeNodePath::setBrowseName(QString browseName) |
101 | { |
102 | m_browseNode.setNodeIdentifier(browseName); |
103 | } |
104 | |
105 | void OpcUaRelativeNodePath::setReferenceType(const QVariant &referenceType) |
106 | { |
107 | bool valid = false; |
108 | |
109 | if (referenceType.userType() == qMetaTypeId<QObject*>() && qobject_cast<OpcUaNodeId*>(object: referenceType.value<QObject*>())) |
110 | valid = true; |
111 | else if (referenceType.userType() == QMetaType::Int && QMetaEnum::fromType<QOpcUa::ReferenceTypeId>().valueToKey(value: referenceType.toInt())) |
112 | valid = true; |
113 | |
114 | if (!valid) { |
115 | qCWarning(QT_OPCUA_PLUGINS_QML) << "Invalid reference type:"<< referenceType; |
116 | return; |
117 | } |
118 | |
119 | if (m_referenceType == referenceType) |
120 | return; |
121 | |
122 | m_referenceType = referenceType; |
123 | emit referenceTypeChanged(); |
124 | } |
125 | |
126 | void OpcUaRelativeNodePath::setIncludeSubtypes(bool includeSubtypes) |
127 | { |
128 | if (m_includeSubtypes == includeSubtypes) |
129 | return; |
130 | |
131 | m_includeSubtypes = includeSubtypes; |
132 | emit includeSubtypesChanged(includeSubtypes: m_includeSubtypes); |
133 | } |
134 | |
135 | bool OpcUaRelativeNodePath::isInverse() const |
136 | { |
137 | return m_isInverse; |
138 | } |
139 | |
140 | QOpcUaRelativePathElement OpcUaRelativeNodePath::toRelativePathElement(QOpcUaClient *client) const |
141 | { |
142 | m_browseNode.resolveNamespaceNameToIndex(client); |
143 | |
144 | QOpcUaRelativePathElement x; |
145 | x.setIsInverse(isInverse()); |
146 | x.setIncludeSubtypes(includeSubtypes()); |
147 | x.setTargetName(m_browseNode.toQualifiedName()); |
148 | if (m_referenceType.userType() == QMetaType::Int |
149 | || m_referenceType.userType() == qMetaTypeId<QOpcUa::ReferenceTypeId>()) |
150 | x.setReferenceTypeId(m_referenceType.value<QOpcUa::ReferenceTypeId>()); |
151 | else |
152 | x.setReferenceTypeId(m_referenceType.toString()); |
153 | |
154 | return x; |
155 | } |
156 | |
157 | void OpcUaRelativeNodePath::setIsInverse(bool isInverse) |
158 | { |
159 | if (m_isInverse == isInverse) |
160 | return; |
161 | |
162 | m_isInverse = isInverse; |
163 | emit isInverseChanged(isInverse: m_isInverse); |
164 | } |
165 | |
166 | QT_END_NAMESPACE |
167 |