TouchPortal-CPP-API  v1.0.0
Touch Portal Plugin API Client for C++ and Qt
TPClientQt.h
1/*
2TPClientQt - Touch Poral Plugin API network client for C++/Qt-based plugins.
3Copyright Maxim Paperno; all rights reserved.
4
5Dual licensed under the terms of either the GNU General Public License (GPL)
6or the GNU Lesser General Public License (LGPL), as published by the Free Software
7Foundation, either version 3 of the Licenses, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14Copies of the GNU GPL and LGPL are available at <http://www.gnu.org/licenses/>.
15
16This project may also use 3rd-party Open Source software under the terms
17of their respective licenses. The copyright notice above does not apply
18to any 3rd-party components used within.
19*/
20
21#pragma once
22
23#include <QObject>
24#include <QAbstractSocket>
25#include <QByteArray>
26#include <QLoggingCategory>
27#include <QJsonArray>
28#include <QJsonDocument>
29#include <QJsonObject>
30#include <QJsonValue>
31#include <QVariant>
32
33#define TP_CLIENT_VERSION_STR "1.0.0"
34
35// The client can be built as a dynamic library by defining `TPCLIENT_BUILD_DLL` (exports symbols),
36// or the header can be used when linking to a DLL by defining `TPCLIENT_USE_DLL` (imports symbols).
37// By default we assume the full source is being included directly in a build, or being built as a static lib.
38#if !defined(TPCLIENT_LIB_EXPORT)
39 #if defined(TPCLIENT_BUILD_DLL)
40 #define TPCLIENT_LIB_EXPORT Q_DECL_EXPORT
41 #elif defined(TPCLIENT_USE_DLL)
42 #define TPCLIENT_LIB_EXPORT Q_DECL_IMPORT
43 #else
44 #define TPCLIENT_LIB_EXPORT
45 #endif
46#endif
47
48Q_DECLARE_LOGGING_CATEGORY(lcTPC);
49
50/**
51The `TPClientQt` class is a simple TCP/IP network client for usage in Touch Portal plugins which wish to utilize the `Qt` C++ library/framework.
52
53\note Familiarity with the [Touch Portal API](https://www.touch-portal.com/api) is assumed throughout this documentation.
54The client performs no error checking in terms of what the user tries to send to TP, and in most cases delivers only the JSON data as it came from TP (parsed into `QJson*` types).
55
56Messages from TP are delivered via the `message(MessageType, const QJsonObject &)` signal, which identifies the message type with an enumerator and
57passes the message data on as a `QJsonObject`. Beyond determining the message type, no other processing is done on the incoming data.
58
59Sending messages to TP can be done at 3 different levels:
60- The (very overloaded) methods provided by this class which have names eponymous with the corresponding TP API message types. Eg: `stateUpdate()`, `showNotification()`, etc.
61- Arbitrary JSON object via the `send()` method or from a serialized `QVariantMap` via `sendMap()`;
62- Raw bytes with the `write()` method.
63
64The client emits `connected()`, `disconnected()`, and `error()` signals to notify the plugin of connection status and network state changes.
65Disconnections may happen spontaneously for a number of reasons (socket error, TP quitting, etc). Notably, `error()` is emitted if the initial connection to Touch Portal fails.
66
67\note It is the responsibility of the plugin itself to take appropriate termination actions when the connection to TP is lost/closed, either on purpose or due to error,
68and especially if/when TP sends the `closePlugin` message (which expects the plugin process to exit).
69
70Some static convenience functions are provided for dealing with action/connector data coming from TP (for retrieving individual data values or coercing the incoming
71arrays into more user-friendly structures). See the `actionData*()` function references.
72
73The client depends on the `QtCore` and `QtNetwork` libraries/modules. Tested with Qt versions `5.12.12`, `5.15.7`, `6.4.1`.
74
75Some minimal logging is performed via `QLoggingCategory` named "TPClientQt". By default, in Debug builds (`QT_DEBUG` defined) Debug-level messages (and above) are emitted,
76while on other builds the minimum level is set to Warning.
77This can be controlled as usual per Qt logging categories, eg. with `QT_LOGGING_RULES` env. var, config file, or eg. `QLoggingCategory::setFilterRules("TPClientQt.info = true");`.
78
79__NOTE:__ \n
80All methods and functions in this class are reentrant. Not thread-safe: do not attempt to send messages from multiple threads w/out serializing the access (mutex, etc).
81
82The TPClientQt itself can be moved into a new thread if desired, as long as the above conditions remain true.
83*/
84class TPCLIENT_LIB_EXPORT TPClientQt : public QObject
85{
86 Q_OBJECT
87 public:
88 //! This enumeration is used in the `message()` signal to indicate message type. The names match the Touch Portal API message names, with the exception of `Unknown`.
89 //! This is a strongly typed enum class because some of the names are common words. It is registered with Qt meta system and is suitable for queued signals/slots.
90 enum class MessageType : short {
91 Unknown, //!< An unknown event, perhaps from a newer version of TP which isn't supported yet.
92 info, //!< The initial connection event, sent after pairing with TP.
93 settings, //!< Emitted for 'info' and 'settings' message type; value/settings array is flattened to QJsonObject of {'setting name': 'value', ...} pairs.
94 action, //!< An action click/touch event.
95 down, //!< Action button press event.
96 up, //!< Action button release event.
97 connectorChange, //!< Connector value change
98 shortConnectorIdNotification, //!< Connector ID mapping event.
99 listChange, //!< Action data choice change event.
100 broadcast, //!< Page change event.
101 notificationOptionClicked, //!< User clicked an option in a notification.
102 closePlugin, //!< Plugin STOP event. It is the responsibility of the plugin to initiate disconnection after this message is received.
103 };
104 Q_ENUM(MessageType)
105
106 //! Structure to hold information about current Touch Portal session. Populated from the initial 'info' message properties upon connection.
107 //! Member names are eponymous with the properties of the 'info' message (except `paired`, see note on that).
108 //! This struct is registered with Qt meta system and is suitable for queued signals/slots. \sa tpInfo()
109 struct TPInfo {
110 bool paired = false; //!< true if actively connected to TP; expects that 'status' == 'paired' in initial 'info' message. Reset to `false` when disconnected from TP.
111 uint16_t sdkVersion = 0; //!< Supported SDK version.
112 uint32_t tpVersionCode = 0; //!< Numeric Touch Portal version.
113 uint32_t pluginVersion = 0; //!< Numeric plugin version read from entry.tp file.
114 QString tpVersionString; //!< Touch Portal version number as text.
115 QString status; //!< The 'status' property from initial 'info' message (typically "paired"); This does _not_ get changed after disconnection (see `paired`).
116 };
117
118 //! Structure for action/connector data id = value pairs sent from TP. Each action/connector sends an array of these.
119 //! Used with some convenience functions in this class. \sa actionDataItem(), actionDataToItemArray()
121 QString id; //!< ID of the action data member.
122 QString value; //!< Current value of the data member.
123 };
124
125 //! The constructor creates the instance but does not attempt any connections.
126 //! The `pluginId` will be used in the initial pairing message sent to Touch Portal, and must match ID in the plugin's entry.tp config file.
127 //! You could pass a null ID here and set it later with `setPluginId()`, but an ID _is_ required before trying to connect to TP.
128 //! \sa connect()
129 explicit TPClientQt(const char *pluginId, QObject *parent = nullptr);
130 ~TPClientQt();
131
132 // Properties
133 //! \{
134
135 //! Returns true if connected to Touch Portal, false otherwise.
136 bool isConnected() const;
137 //! Returns the current state of the TCP/IP network socket used to communicate with Touch Portal.
138 QAbstractSocket::SocketState socketState() const;
139 //! Returns the current TCP/IP network socket error, if any. \sa QAbstractSocket::error()
140 QAbstractSocket::SocketError socketError() const;
141 //! Returns the current TCP/IP network error, if any, as a human-readable string. \sa QIODevice::errorString()
142 QString errorString() const;
143 //! Returns information about the currently connected Touch Portal instance. This data is saved from the initial connection's 'info' message. \sa TPInfo struct.
144 //! \note This reference becomes invalid when `connect()` is called.
145 const TPClientQt::TPInfo &tpInfo() const;
146
147 //! Returns the plugin ID set in constructor or with `setPluginId()`.
148 QString pluginId() const;
149 //! Alternate way to set or change the plugin ID. **This cannot be changed when connected to TP.** Returns `false` if that is attempted or if `pluginId` is null or empty.
150 bool setPluginId(const char *pluginId);
151
152 //! Returns the currently set Touch Portal host name/address string. This is either the default or one explicitly set with `setHostProperties()`;
153 QString hostName() const;
154 //! Returns the currently set Touch Portal host port. This is either the default or one explicitly set with `setHostProperties()`;
155 uint16_t hostPort() const;
156 //! Set the Touch Portal host name/address and port number for connection. `nameOrAddress` can be a IPv4 dotted address or a host name which will be resolved.
157 //! Default host is "127.0.0.1" (local computer) and port # 12136 (TP's default for plugin API). Call this method with no arguments to reset both properties to their defaults.
158 //! Changing these settings when already connected to TP has no effect until the next connection attempt. \sa hostName(), hostPort()
159 void setHostProperties(const QString &nameOrAddress = QStringLiteral("127.0.0.1"), uint16_t port = 12136);
160
161 //! Returns the currently set connection timeout value, in milliseconds. This is either the default or one explicitly set with `setConnectionTimeout()`.
162 int connectionTimeout() const;
163 //! Sets the timeout value for the initial pairing 'info' message to be received from Touch Portal, in milliseconds. An `error()` signal will be sent if connection fails after this period.
164 //! A timeout of `<= 0` will make the client _not_ wait for a successful pair response from TP and will assume it is connected as long as the network socket is open.
165 //! The default value is 10000 (10s). Call this method with no argument to reset the timeout value to default. \sa connectionTimeout()
166 void setConnectionTimeout(int timeoutMs = 10000);
167
168 //! \}
169
170 Q_SIGNALS:
171 //! Emitted upon successful connection and pairing with Touch Portal. Data from the initial pairing 'info' message is passed in `tpInfo`
172 //! struct along with the initial `settings` object. `settings` object is the original settings array sent from Touch Portal but flattened
173 //! to `QJsonObject` of `{'setting name': 'value', ...}` pairs. \sa TPInfo, MessageType::settings
174 void connected(const TPClientQt::TPInfo &tpInfo, const QJsonObject &settings);
175 //! Emitted upon disconnection from Touch Portal, either from an explicit call to `close()` **or** if the connection is closed unexpectedly,
176 //! by the remote host (eg. Touch Portal exits) or some other unrecoverable socket error. It is the responsibility of the plugin to take
177 //! any appropriate action after a disconnection or error event. The last error, if any, can be retrieved via `socketError()` method.
179 //! Emitted in case of error upon initial connection or unexpected termination. This would typically be what is reported by the `QTcpSocket` being used,
180 //! but during initial connection attempt it may also return one of:
181 //! * `QAbstractSocket::ConnectionRefusedError` - Touch Portal refused connection with an invalid status in 'info' message.
182 //! * `QAbstractSocket::SocketTimeoutError` - Network connection was established but Touch Portal didn't respond to our 'pair' message within the `connectionTimeout()` period.
183 //! * `QAbstractSocket::OperationError` - Parameter validation error, eg. pluginId is null.
184 void error(QAbstractSocket::SocketError error);
185 //! Emitted when any message is received from Touch Portal. Refer to the TP API for specifics of each message type and what data to expect
186 //! in the JSON `message` object. The `type` is simply derived from the 'type' value found in each TP message, or `TPClientQt::MessageType::Unknown`
187 //! if the message type wasn't recognized (eg. TP is using a newer API than this client supports).
188 void message(TPClientQt::MessageType type, const QJsonObject &message);
189
190 public:
191 // Convenience methods / High level API; primary overloads, not for signal/slots connections.
192 //! \{
193
194 //! Send a state update with given `id` and `value` strings.
195 inline void stateUpdate(const char *id, const char *value) const;
196 //! Create a new dynamic state with given `id`, `parentGroup`, `description` and default value strings. Passing `nullptr` to `defaultValue` is same as using an empty string.
197 inline void createState(const char *id, const char *parentGroup, const char *desc, const char *defaultValue) const;
198 //! Create a new dynamic state with given `id`, `parentGroup`, `description` and default value strings.
199 inline void createState(const std::string &id, const std::string &parentGroup, const std::string &desc, const std::string &defaultValue = "") const { createState(id.c_str(), parentGroup.c_str(), desc.c_str(), defaultValue.c_str()); }
200 //! Create a new dynamic state with given `id`, `description` and default value strings. Passing `nullptr` to `defaultValue` is same as using an empty string.
201 inline void createState(const char *id, const char *desc, const char *defaultValue) const { createState(id, nullptr, desc, defaultValue); }
202 //! Create a new dynamic state with given `id`, `description` and default value strings.
203 inline void createState(const std::string &id, const std::string &desc, const std::string &defaultValue = "") const { createState(id.c_str(), nullptr, desc.c_str(), defaultValue.c_str()); }
204 //! Delete (remove) a dynamic state with given `id` string.
205 inline void removeState(const char *id) const;
206 //! Delete (remove) a dynamic state with given `id` string.
207 inline void removeState(const std::string &id) const { removeState(id.c_str()); }
208
209 //! Update a list of action data choices for action data with given `id` using a `QJsonArray` of strings. `QJsonArray` is most efficient as it requires no further conversion before sending.
210 inline void choiceUpdate(const char *id, const QJsonArray &values) const;
211 //! Update a list of action data choices for action data with given `id` using a vector of const char strings.
212 inline void choiceUpdate(const char *id, const QVector<const char *> &values) const { choiceUpdate(id, stringContainerToJsonArray(values)); }
213 //! Update a list of action data choices for action data with given `id` using a list of QStrings.
214 inline void choiceUpdate(const char *id, const QStringList &values) const { choiceUpdate(id, QJsonArray::fromStringList(values)); }
215 //! Update a list of action data choices for action data with given `id` using a `std::vector` of `std::string` types.
216 inline void choiceUpdate(const std::string &id, const std::vector<std::string> &values) const { choiceUpdate(id.c_str(), stringContainerToJsonArray(values)); }
217 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a `QJsonArray` of strings. `QJsonArray` is most efficient as it requires no further conversion before sending.
218 inline void choiceUpdate(const char *id, const char *instanceId, const QJsonArray &values) const;
219 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a vector of const char strings.
220 inline void choiceUpdate(const char *id, const char *instanceId, const QVector<const char *> &values) const { choiceUpdate(id, instanceId, stringContainerToJsonArray(values)); }
221 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a vector of const char strings.
222 inline void choiceUpdate(const char *id, const char *instanceId, const QStringList &values) const { choiceUpdate(id, instanceId, QJsonArray::fromStringList(values)); }
223 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a `std::vector` of `std::string` types.
224 inline void choiceUpdate(const std::string &id, const std::string &instanceId, const std::vector<std::string> &values) const { choiceUpdate(id.c_str(), instanceId.c_str(), stringContainerToJsonArray(values)); }
225
226 //! Update a Connector value with given `shortId` as reported by TP. Valid value range is 0-100.
227 inline void connectorUpdate(const char *shortId, uint8_t value) const;
228 //! Update a Connector value with given `shortId` as reported by TP. Valid value range is 0-100.
229 inline void connectorUpdate(const std::string &shortId, uint8_t value) const { connectorUpdate(shortId.c_str(), value); }
230
231 //! Update a Connector value with given full `connectortId` (see TP API docs for details). Valid value range is 0-100.
232 //! If `addPrefix` is set to `true` then the string `"pc_" + the plugin ID + "_"` is prepended to the given `connectorId` value.
233 inline void connectorUpdate(const char *connectortId, uint8_t value, bool addPrefix) const;
234 //! Update a Connector value with given full `connectortId` (see TP API docs for details). Valid value range is 0-100.
235 //! If `addPrefix` is set to `true` then the string `"pc_" + the plugin ID + "_"` is prepended to the given `connectorId` value.
236 inline void connectorUpdate(const std::string &connectortId, uint8_t value, bool addPrefix) const { connectorUpdate(connectortId.c_str(), value, addPrefix); }
237 //! Update a Connector value with given `connectortId`. This overload takes a mapping of action data id/value pairs and builds up the long connectorId string for you
238 //! (see TP API docs for details on long connectorId format). Valid value range is 0-100.
239 //! If `addPrefix` is set to `true` then the string `"pc_" + the plugin ID + "_"` is prepended to the given `connectorId` value.
240 inline void connectorUpdate(const char *connectortId, const QMap<const char*, const char*> &nvPairs, uint8_t value, bool addPrefix = true) const;
241
242 //! Update a plugin setting value with given `name` to `value`.
243 inline void settingUpdate(const char *name, const char *value) const;
244 //! Update a plugin setting value with given `name` to `value`.
245 inline void settingUpdate(const std::string &name, const std::string &value) const { settingUpdate(name.c_str(), value.c_str()); }
246
247 //! Send a notification message to TP. See TP SDK documentation for details on each field. The `options` variant list should be some kind of array containing
248 //! the notification option `id` and `title` pairs/objects, for example a `QJsonArray<QJsonObject>({'id', 'title'})`.
249 inline void showNotification(const char *notificationId, const char *title, const char *msg, const QJsonArray &options) const;
250 //! Send a notification message to TP. See TP SDK documentation for details on each field. The `options` variant list should be some kind of array containing
251 //! the notification option `id` and `title` pairs/objects, for example a `QVariantList<QVariantMap>({'id', 'title'})`.
252 inline void showNotification(const char *notificationId, const char *title, const char *msg, const QVariantList &options) const { showNotification(notificationId, title, msg, QJsonArray::fromVariantList(options)); }
253 //! Send a notification message to TP. See TP SDK documentation for details on each field. The options are passed as an array of id/title pairs which are converted to appropriate JSON objects, eg: `{'id': pair.first, 'title': pair.second}`.
254 inline void showNotification(const char *notificationId, const char *title, const char *msg, const QVector<QPair<const char*, const char *>> &options) const;
255 //! Send a notification message to TP. See TP SDK documentation for details on each field. The options are passed as an array of id/title pairs which are converted to appropriate JSON objects, eg: `{'id': pair.first, 'title': pair.second}`.
256 inline void showNotification(const char *notificationId, const char *title, const char *msg, const std::vector<std::pair<const char*, const char *>> &options) const;
257 //! Send a notification message to TP. See TP SDK documentation for details on each field. The options are passed as an array of id/title pairs which are converted to appropriate JSON objects, eg: `{'id': pair.first, 'title': pair.second}`.
258 inline void showNotification(const std::string &notificationId, const std::string &title, const std::string &msg, const std::vector<std::pair<std::string, std::string>> &options) const;
259
260 //! \}
261
262 // Low level API
263 //! \{
264 //! Low-level API: Serializes a JSON object to UTF8 bytes. `object` should contain one TP message. This can be then be sent to TP via `write()` method.
265 QByteArray encode(const QJsonObject &object) const { return QJsonDocument(object).toJson(QJsonDocument::Compact); }
266 //! \}
267
268 public Q_SLOTS:
269#define qsvPrintable(SV) (SV).toUtf8().constData()
270
271 // Connection handlers
272 //! \{
273
274 //! Initiate a connection to Touch Portal. The plugin ID (set in constructor or with `setPluginId()` must be valid.
275 //! This first tries to open a network socket connection, and if that succeeds then the initial 'pair' message is sent to Touch Portal.
276 //! Upon actual successful pairing, meaning an 'info' message response was received from TP with 'status' == "paired", the `connected()` signal is emitted.
277 //! If either the initial socket connection or pairing with TP fails within the `connectionTimeout()` period, then the `error(QAbstractSocket::SocketError)` signal is emitted.
278 //! If `connectionTimeout()` is `<= 0` then the client will not wait for a successful pair response from TP and will assume it is connected as long as the network socket is open.
279 //! \sa error() signal, connectionTimeout(), setConnectionTimeout()
280 void connect();
281 //! Initiate a connection to Touch Portal. The plugin ID (set in constructor or with `setPluginId()` must be valid.
282 //! This is a "shortcut" method which first calls `setConnectionTimeout(timeout)` and `setHostProperties(host, port)` before calling `connect()`.
283 //! To ignore any of the arguments (not change the corresponding TPClientQt properties), pass `timeout < 0`, `host = QString()` (default), and/or `port = 0` (default).
284 //! \sa connect()
285 inline void connect(int timeout, const QString &host = QString(), uint16_t port = 0);
286 //! Initiates disconnection from Touch Portal. This flushes and gracefully closes any open network sockets.
287 //! The `disconnected()` signal will be emitted upon actual disconnection (which may not be immediate).
288 //! Returns immediately if the connection isn't already open.
289 void disconnect() const;
290
291 //! \}
292
293 // Low level API
294 //! \{
295
296 //! Low-level API: Send JSON message data to Touch Portal. `object` should contain one TP message.
297 //! All other methods for sending structured data are conveniences for this method.
298 inline void send(const QJsonObject &object) const { write(encode(object)); }
299 //! Low-level API: Send a JSON representation of a variant map to Touch Portal. `map` should contain one TP message. The map is serialized as QJsonObject type.
300 inline void sendMap(const QVariantMap &map) const { write(encode(QJsonObject::fromVariantMap(map))); }
301 //! Low-level API: Write UTF-8 bytes directly to Touch Portal. `data` should contain one TP message in the form of a serialized (UTF8 text) JSON object.
302 //! A newline is automatically added after `data` is sent (as per TP API specs). All messages are ultimately sent via this method.
303 void write(const QByteArray &data) const;
304
305 //! \}
306
307 // Convenience methods / High level API, Overloads & Slots
308 //! \{
309
310 //! Send a state update with given `id` and `value` strings.
311 inline void stateUpdate(const QByteArray &id, const QByteArray &value) const { stateUpdate(id.constData(), value.constData()); }
312 //! Send a state update with given `id` and `value` strings.
313 inline void stateUpdate(QStringView id, QStringView value) const { stateUpdate(qsvPrintable(id), qsvPrintable(value)); }
314
315 //! Create a new dynamic state with given `id`, `parentGroup`, `description` and `defaultValue` strings
316 inline void createState(const QByteArray &id, const QByteArray &parentGroup, const QByteArray &desc, const QByteArray &defaultValue) const { createState(id.constData(), parentGroup.constData(), desc.constData(), defaultValue.constData()); }
317 //! Create a new dynamic state with given `id`, `parentGroup`, `description` and `defaultValue` strings
318 inline void createState(QStringView id, QStringView parentGroup, QStringView desc, QStringView defaultValue) const { createState(qsvPrintable(id), qsvPrintable(parentGroup), qsvPrintable(desc), qsvPrintable(defaultValue)); }
319 //! Create a new dynamic state with given `id`, `description` and `defaultValue` strings.
320 inline void createState(const QByteArray &id, const QByteArray &desc, const QByteArray &defaultValue) const { createState(id.constData(), nullptr, desc.constData(), defaultValue.constData()); }
321 //! Create a new dynamic state with given `id`, `description` and `defaultValue` strings.
322 inline void createState(QStringView id, QStringView desc, QStringView defaultValue) const { createState(qsvPrintable(id), nullptr, qsvPrintable(desc), qsvPrintable(defaultValue)); }
323
324 //! Delete (remove) a dynamic state with given `id` string.
325 inline void removeState(const QByteArray &id) const { removeState(id.constData()); }
326 //! Delete (remove) a dynamic state with given `id` string.
327 inline void removeState(QStringView id) const { removeState(qsvPrintable(id)); }
328
329 //! Update a list of action data choices for action data with given `id` using a `QJsonArray` of strings. `QJsonArray` is most efficient as it requires no further conversion before sending.
330 inline void choiceUpdate(const QByteArray &id, const QJsonArray &values) const { choiceUpdate(id.constData(), values); }
331 //! Update a list of action data choices for action data with given `id` using a vector of `QByteArray` types.
332 inline void choiceUpdate(const QByteArray &id, const QVector<QByteArray> &values) const { choiceUpdate(id.constData(), stringContainerToJsonArray(values)); }
333 //! Update a list of action data choices for action data with given `id` using a list of `QString`s.
334 inline void choiceUpdate(const QByteArray &id, const QStringList &values) const { choiceUpdate(id.constData(), QJsonArray::fromStringList(values)); }
335#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) || defined(DOXYGEN)
336 //! Update a list of action data choices for action data with given `id` using a `QByteArray` list.
337 //! \note This method only exists on Qt < v6. With v6+ `QByteArrayList` is the same as `QVector<QByteArray>`.
338 inline void choiceUpdate(const QByteArray &id, const QByteArrayList &values) const { choiceUpdate(id.constData(), stringContainerToJsonArray(values)); }
339#endif
340 //! Update a list of action data choices for action data with given `id` using a vector of `QJsonArray` of strings. `QJsonArray` is most efficient as it requires no further conversion before sending.
341 inline void choiceUpdate(QStringView id, const QJsonArray &values) const { choiceUpdate(qsvPrintable(id), values); }
342 //! Update a list of action data choices for action data with given `id` using a vector of `QStringView`-compatible types.
343 inline void choiceUpdate(QStringView id, const QVector<QStringView> &values) const { choiceUpdate(qsvPrintable(id), stringContainerToJsonArray(values)); }
344 //! Update a list of action data choices for action data with given `id` using a list of `QString`s.
345 inline void choiceUpdate(QStringView id, const QStringList &values) const { choiceUpdate(qsvPrintable(id), QJsonArray::fromStringList(values)); }
346 //! Update a list of action data choices for action data with given `id` using a `QByteArray` list.
347 inline void choiceUpdate(QStringView id, const QByteArrayList &values) const { choiceUpdate(qsvPrintable(id), stringContainerToJsonArray(values)); }
348
349 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a `QJsonArray` of strings. `QJsonArray` is most efficient as it requires no further conversion before sending.
350 inline void choiceUpdate(const QByteArray &id, const QByteArray &instanceId, const QJsonArray &values) const { choiceUpdate(id.constData(), instanceId.constData(), values); }
351 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a vector of `QByteArray` types.
352 inline void choiceUpdate(const QByteArray &id, const QByteArray &instanceId, const QVector<QByteArray> &values) const { choiceUpdate(id.constData(), instanceId.constData(), stringContainerToJsonArray(values)); }
353 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a list of `QString`s.
354 inline void choiceUpdate(const QByteArray &id, const QByteArray &instanceId, const QStringList &values) const { choiceUpdate(id.constData(), instanceId.constData(), QJsonArray::fromStringList(values)); }
355#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) || defined(DOXYGEN)
356 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a `QByteArray` list.
357 //! \note This method only exists on Qt < v6. With v6+ `QByteArrayList` is the same as `QVector<QByteArray>`.
358 inline void choiceUpdate(const QByteArray &id, const QByteArray &instanceId, const QByteArrayList &values) const { choiceUpdate(id.constData(), instanceId.constData(), stringContainerToJsonArray(values)); }
359#endif
360 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a `QJsonArray` of strings. `QJsonArray` is most efficient as it requires no further conversion before sending.
361 inline void choiceUpdate(QStringView id, QStringView instanceId, const QJsonArray &values) const { choiceUpdate(qsvPrintable(id), qsvPrintable(instanceId), values); }
362 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a vector of `QStringView`-compatible types.
363 inline void choiceUpdate(QStringView id, QStringView instanceId, const QVector<QStringView> &values) const { choiceUpdate(qsvPrintable(id), qsvPrintable(instanceId), stringContainerToJsonArray(values)); }
364 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a list of `QString`s.
365 inline void choiceUpdate(QStringView id, QStringView instanceId, const QStringList &values) const { choiceUpdate(qsvPrintable(id), qsvPrintable(instanceId), QJsonArray::fromStringList(values)); }
366 //! Update a list of action data choices for action data with given `id` and specific `instanceId` reported by TP, using a `QByteArray` list.
367 inline void choiceUpdate(QStringView id, QStringView instanceId, const QByteArrayList &values) const { choiceUpdate(qsvPrintable(id), qsvPrintable(instanceId), stringContainerToJsonArray(values)); }
368
369 //! Update a Connector value with given `shortId` as reported by TP. Valid value range is 0-100.
370 inline void connectorUpdate(const QByteArray &shortId, uint8_t value) const { connectorUpdate(shortId.constData(), value); }
371 //! Update a Connector value with given `shortId` as reported by TP. Valid value range is 0-100.
372 inline void connectorUpdate(QStringView shortId, uint8_t value) const { connectorUpdate(qsvPrintable(shortId), value); }
373
374 //! Update a Connector value with given full `connectortId` (see TP API docs for details). Valid value range is 0-100.
375 //! If `addPrefix` is set to `true` then the string `"pc_" + the plugin ID + "_"` is prepended to the given `connectorId` value.
376 inline void connectorUpdate(const QByteArray &connectortId, uint8_t value, bool addPrefix) const { connectorUpdate(connectortId.constData(), value, addPrefix); }
377 //! Update a Connector value with given full `connectortId` (see TP API docs for details). Valid value range is 0-100.
378 //! If `addPrefix` is set to `true` then the string `"pc_" + the plugin ID + "_"` is prepended to the given `connectorId` value.
379 inline void connectorUpdate(QStringView connectortId, uint8_t value, bool addPrefix) const { connectorUpdate(qsvPrintable(connectortId), value, addPrefix); }
380 //! Update a Connector value with given `connectortId`. This overload takes a mapping of action data id/value pairs and builds up the long connectorId string for you
381 //! (see TP API docs for details on long connectorId format). Valid value range is 0-100.
382 //! If `addPrefix` is set to `true` then the string `"pc_" + the plugin ID + "_"` is prepended to the given `connectorId` value.
383 inline void connectorUpdate(const QByteArray &connectortId, const QMap<const QByteArray, const QByteArray> &nvPairs, uint8_t value, bool addPrefix = true) const;
384 //! Update a Connector value with given `connectortId`. This overload takes a mapping of action data id/value pairs and builds up the long connectorId string for you
385 //! (see TP API docs for details on long connectorId format). Valid value range is 0-100.
386 //! If `addPrefix` is set to `true` then the string `"pc_" + the plugin ID + "_"` is prepended to the given `connectorId` value.
387 inline void connectorUpdate(QStringView connectortId, const QMap<QStringView, QStringView> &nvPairs, uint8_t value, bool addPrefix = true) const;
388
389 //! Update a plugin setting value with given `name` to `value`.
390 inline void settingUpdate(const QByteArray &name, const QByteArray &value) const { settingUpdate(name.constData(), value.constData()); }
391 //! Update a plugin setting value with given `name` to `value`.
392 inline void settingUpdate(QStringView name, QStringView value) const { settingUpdate(qsvPrintable(name), qsvPrintable(value)); }
393
394 //! Send a notification message to TP. See TP SDK documentation for details on each field. The `options` variant list should be some kind of array containing
395 //! the notification option `id` and `title` pairs/objects, for example a `QVariantList<QVariantMap({'id', 'title'})>`.
396 inline void showNotification(const QByteArray &notificationId, const QByteArray &title, const QByteArray &msg, const QJsonArray &options) const { showNotification(notificationId.constData(), title.constData(), msg.constData(), options); }
397 //! Send a notification message to TP. See TP SDK documentation for details on each field. The `options` variant list should be some kind of array containing
398 //! the notification option `id` and `title` pairs/objects, for example a `QVariantList<QVariantMap({'id', 'title'})>`.
399 inline void showNotification(const QByteArray &notificationId, const QByteArray &title, const QByteArray &msg, const QVariantList &options) const { showNotification(notificationId.constData(), title.constData(), msg.constData(), QJsonArray::fromVariantList(options)); }
400 //! Send a notification message to TP. See TP SDK documentation for details on each field. The `options` variant list should be some kind of array containing
401 //! the notification option `id` and `title` pairs/objects, for example a `QVariantList<QVariantMap({'id', 'title'})>`.
402 inline void showNotification(QStringView notificationId, QStringView title, QStringView msg, const QVariantList &options) const { showNotification(qsvPrintable(notificationId), qsvPrintable(title), qsvPrintable(msg), options); }
403 //! Send a notification message to TP. See TP SDK documentation for details on each field. The options are passed as an array of id/title pairs which are converted to appropriate JSON objects, eg: `{'id': pair.first, 'title': pair.second}`.
404 inline void showNotification(const QByteArray &notificationId, const QByteArray &title, const QByteArray &msg, const QVector<QPair<QLatin1String, QStringView>> &options) const;
405 //! Send a notification message to TP. See TP SDK documentation for details on each field. The options are passed as an array of id/title pairs which are converted to appropriate JSON objects, eg: `{'id': pair.first, 'title': pair.second}`.
406 inline void showNotification(QStringView notificationId, QStringView title, QStringView msg, const QVector<QPair<QStringView, QStringView> > &options) const;
407
408 //! \}
409
410 public:
411 // Static helper functions
412 //! \{
413
414 //! Returns the action data object (id and value as `ActionDataItem` struct) at given index in the given array of action/connector data values (as sent from TP),
415 //! or the optional `defaultItem` item if the index is out of bounds (or a default-constructed `ActionDataItem` if `defaultItem` is not provided).
416 static inline ActionDataItem actionDataItem(int index, const QJsonArray &data, const ActionDataItem &defaultItem = ActionDataItem());
417 //! Returns the 'value' member of the action data object at given index in the given array of action/connector data values (as sent from TP),
418 //! or the given `defaultValue` if the data member doesn't exist in the array (or for some reason doesn't have a 'value' member).
419 static inline QString actionDataValue(int index, const QJsonArray &data, const QString &defaultValue = QLatin1String(""));
420 //! Returns the 'value' member of the action data object with given id in the given array of action/connector data values (as sent from TP),
421 //! or the given `defaultValue` if the data member doesn't exist in the array (or for some reason doesn't have a 'value' member).
422 //! \note This has to loop over the data array until the member with given `id` is found (or not). If needing named data values
423 //! more than once per action processing, it would likely be more efficient to use `actionDataToMap()` and store the result.
424 static inline QString actionDataValue(const char *id, const QJsonArray &data, const QString &defaultValue = QLatin1String(""));
425 //! Convert JSON array of action data objects: [ { 'id': id, 'value': value }, ... ] to a vector of `ActionDataItem` types.
426 //! If `separator` is not zero, the data IDs will be split on this character and only the last part will be saved in the returned `ActionDataItem`s' id.
427 static inline QVector<ActionDataItem> actionDataToItemArray(const QJsonArray &data, char separator = 0);
428 //! Flattens array of objects: [ { 'id': id, 'value': value }, ... ] to a single mapping of { {id, value}, ... } (assuming each data id key is unique).
429 //! This allows simplified lookup by data ID string (vs. index), and is also iterable. The returned map does not preserve the original data order.
430 //! If `separator` is not zero, the data IDs will be split on this character and only the last part will be saved in the returned map's key names.
431 static inline QMap<QString, QString> actionDataToMap(const QJsonArray &data, char separator = 0);
432
433 //! \}
434
435 private Q_SLOTS:
436 void onReadyRead();
437
438 private:
439 struct Private;
440 friend struct Private;
441 Private * const d;
442
443 template <typename Vect, typename T = typename Vect::value_type>
444 QJsonArray stringContainerToJsonArray(const Vect &list) const
445 {
446 QJsonArray ret;
447 for (typename Vect::const_iterator it = list.cbegin(); it != list.cend(); ++it) {
448 const T &val = static_cast<T>(* it);
449 if constexpr (std::is_same_v<T, QStringView>)
450 ret.append(val.toString());
451 else if constexpr (std::is_same_v<T, QByteArray>)
452 ret.append(QString(val));
453 else if constexpr (std::is_same_v<T, std::string>)
454 ret.append(val.c_str());
455 else if constexpr (std::is_same_v<T, std::wstring>)
456 ret.append(QString::fromStdWString(val));
457 else
458 ret.append(QJsonValue(val));
459 }
460 return ret;
461 }
462
463 template <typename Vect,
464 typename Pair = typename Vect::value_type,
465 typename Key = std::remove_const_t<typename Pair::first_type>,
466 typename Val = std::remove_const_t<typename Pair::second_type> >
467 QJsonArray arrayOfObjectsToJsonArray(const Vect &list) const
468 {
469 QJsonArray ret;
470 for (typename Vect::const_iterator it = list.cbegin(); it != list.cend(); ++it) {
471 const Key &key = static_cast<Key>(it->first);
472 const Val &val = static_cast<Val>(it->second);
473 QJsonValue jval;
474 if constexpr (std::is_same_v<Val, QStringView>)
475 jval = val.toString();
476 else if constexpr (std::is_same_v<Val, QByteArray>)
477 jval = QString(val);
478 else if constexpr (std::is_same_v<Val, std::string>)
479 jval = val.c_str();
480 else if constexpr (std::is_same_v<Val, std::wstring>)
481 jval = QString::fromStdWString(val);
482 else
483 jval = val;
484
485 if constexpr (std::is_same_v<Key, QStringView>)
486 ret.append({ {key.toString(), jval} });
487 else if constexpr (std::is_same_v<Key, std::string>)
488 ret.append({ {QString::fromStdString(key), jval} });
489 else
490 ret.append({ {QString(key), jval} });
491 }
492 return ret;
493 }
494};
495
496inline
497void TPClientQt::connect(int timeout, const QString &host, uint16_t port)
498{
499 if (timeout > -1)
500 setConnectionTimeout(timeout);
501 setHostProperties(host, port);
502 connect();
503}
504
505inline
506void TPClientQt::stateUpdate(const char *id, const char *value) const
507{
508 send({
509 {"type", "stateUpdate"},
510 {"id", id},
511 {"value", value}
512 });
513}
514
515inline
516void TPClientQt::createState(const char *id, const char *parentGroup, const char *desc, const char *defaultValue) const
517{
518 send({
519 {"type", "createState"},
520 {"id", id},
521 {"desc", desc ? desc : ""},
522 {"defaultValue", defaultValue ? defaultValue : ""},
523 {"parentGroup", parentGroup ? parentGroup : ""}
524 });
525}
526
527inline
528void TPClientQt::removeState(const char *id) const
529{
530 send({
531 {"type", "removeState"},
532 {"id", id},
533 });
534}
535
536inline
537void TPClientQt::choiceUpdate(const char *id, const QJsonArray &values) const
538{
539 send({
540 {"type", "choiceUpdate"},
541 {"id", id},
542 {"value", values}
543 });
544}
545
546inline
547void TPClientQt::choiceUpdate(const char *id, const char *instanceId, const QJsonArray &values) const
548{
549 send({
550 {"type", "choiceUpdate"},
551 {"id", id},
552 {"instanceId", instanceId},
553 {"value", values}
554 });
555}
556
557inline
558void TPClientQt::connectorUpdate(const char *shortId, uint8_t value) const
559{
560 send({
561 {"type", "connectorUpdate"},
562 {"shortId", shortId},
563 {"value", value}
564 });
565}
566
567inline
568void TPClientQt::connectorUpdate(const char *connectortId, uint8_t value, bool addPrefix) const
569{
570 send({
571 {"type", "connectorUpdate"},
572 {"connectorId", addPrefix ? qsvPrintable("pc_" + pluginId() + '_' + connectortId) : connectortId},
573 {"value", value}
574 });
575}
576
577inline
578void TPClientQt::connectorUpdate(const char *connectortId, const QMap<const char *, const char *> &nvPairs, uint8_t value, bool addPrefix) const
579{
580 QString fullId(connectortId);
581 for (auto nvp = nvPairs.cbegin(), en = nvPairs.cend(); nvp != en; ++nvp)
582 fullId += '|' + QByteArray(nvp.key()) + '=' + QByteArray(nvp.value());
583 connectorUpdate(fullId.toUtf8(), value, addPrefix);
584}
585
586inline
587void TPClientQt::connectorUpdate(const QByteArray &connectortId, const QMap<const QByteArray, const QByteArray> &nvPairs, uint8_t value, bool addPrefix) const
588{
589 QString fullId(connectortId);
590 for (auto nvp = nvPairs.cbegin(), en = nvPairs.cend(); nvp != en; ++nvp)
591 fullId += '|' + nvp.key() + '=' + nvp.value();
592 connectorUpdate(fullId.constData(), value, addPrefix);
593}
594
595inline
596void TPClientQt::connectorUpdate(QStringView connectortId, const QMap<QStringView, QStringView> &nvPairs, uint8_t value, bool addPrefix) const
597{
598 QString fullId(connectortId.toString());
599 for (auto nvp = nvPairs.cbegin(), en = nvPairs.cend(); nvp != en; ++nvp)
600 fullId += '|' + nvp.key() + '=' + nvp.value();
601 connectorUpdate(fullId.toUtf8(), value, addPrefix);
602}
603
604inline
605void TPClientQt::settingUpdate(const char *name, const char *value) const
606{
607 send({
608 {"type", "settingUpdate"},
609 {"name", name},
610 {"value", value}
611 });
612}
613
614inline
615void TPClientQt::showNotification(const char *notificationId, const char *title, const char *msg, const QJsonArray &options) const
616{
617 send({
618 {"type", "showNotification"},
619 {"notificationId", notificationId},
620 {"title", title},
621 {"msg", msg},
622 {"options", options}
623 });
624}
625
626inline
627void TPClientQt::showNotification(const char *notificationId, const char *title, const char *msg, const QVector<QPair<const char *, const char *> > &options) const
628{
629 showNotification(notificationId, title, msg, arrayOfObjectsToJsonArray(options));
630}
631
632inline
633void TPClientQt::showNotification(const char *notificationId, const char *title, const char *msg, const std::vector<std::pair<const char *, const char *> > &options) const
634{
635 showNotification(notificationId, title, msg, arrayOfObjectsToJsonArray(options));
636}
637
638inline void TPClientQt::showNotification(const std::string &notificationId, const std::string &title, const std::string &msg, const std::vector<std::pair<std::string, std::string> > &options) const
639{
640 showNotification(notificationId.c_str(), title.c_str(), msg.c_str(), arrayOfObjectsToJsonArray(options));
641}
642
643inline
644void TPClientQt::showNotification(const QByteArray &notificationId, const QByteArray &title, const QByteArray &msg, const QVector<QPair<QLatin1String, QStringView> > &options) const
645{
646 showNotification(notificationId.constData(), title.constData(), msg.constData(), arrayOfObjectsToJsonArray(options));
647}
648
649inline
650void TPClientQt::showNotification(QStringView notificationId, QStringView title, QStringView msg, const QVector<QPair<QStringView, QStringView> > &options) const
651{
652 showNotification(notificationId.toUtf8(), title.toUtf8(), msg.toUtf8(), arrayOfObjectsToJsonArray(options));
653}
654
655
656// static
657inline
658TPClientQt::ActionDataItem TPClientQt::actionDataItem(int index, const QJsonArray &data, const ActionDataItem &defaultItem)
659{
660 // QJsonArray::at(i) = "The returned QJsonValue is Undefined, if i is out of bounds."
661 if (data.at(index).isObject()) {
662 const QJsonObject &o = data.at(index).toObject();
663 return { o.value(QLatin1String("id")).toString(), o.value(QLatin1String("value")).toString() };
664 }
665 return defaultItem;
666}
667
668// static
669inline
670QString TPClientQt::actionDataValue(int index, const QJsonArray &data, const QString &defaultValue)
671{
672 return TPClientQt::actionDataItem(index, data, {QString(), defaultValue}).value;
673}
674
675// static
676inline
677QString TPClientQt::actionDataValue(const char *id, const QJsonArray &data, const QString &defaultValue)
678{
679 for (const QJsonValue &v : data) {
680 const QJsonObject o = v.toObject();
681 if (o.value(QLatin1String("id")).toString() == QString(id))
682 return o.value(QLatin1String("value")).toString(defaultValue);
683 }
684 return defaultValue;
685}
686
687#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
688#define QtSkipEmptyParts QString::SkipEmptyParts
689#else
690#define QtSkipEmptyParts Qt::SkipEmptyParts
691#endif
692
693// static
694inline
695QVector<TPClientQt::ActionDataItem> TPClientQt::actionDataToItemArray(const QJsonArray &data, char separator)
696{
697 QVector<ActionDataItem> ret;
698 ret.reserve(data.size());
699 for (const QJsonValue &v : data) {
700 const QJsonObject &vObj = v.toObject();
701 if (!vObj.isEmpty() && vObj.contains(QLatin1String("id"))) {
702 QString key = vObj.value(QLatin1String("id")).toString();
703 if (separator)
704 key = key.split(separator, QtSkipEmptyParts).last();
705 ret << ActionDataItem({ key, vObj.value(QLatin1String("value")).toString() });
706 }
707 }
708 return ret;
709}
710
711// static
712inline
713QMap<QString, QString> TPClientQt::actionDataToMap(const QJsonArray &data, char separator)
714{
715 QMap<QString, QString> ret;
716 for (const QJsonValue &v : data) {
717 const QJsonObject vObj = v.toObject();
718 if (!vObj.isEmpty() && vObj.contains(QLatin1String("id"))) {
719 QString key = vObj.value(QLatin1String("id")).toString();
720 if (separator)
721 key = key.split(separator, QtSkipEmptyParts).last();
722 ret.insert(key, vObj.value(QLatin1String("value")).toString());
723 }
724 }
725 return ret;
726}
727
728#undef QtSkipEmptyParts
729#undef qsvPrintable
730
731Q_DECLARE_METATYPE(TPClientQt::MessageType)
732Q_DECLARE_METATYPE(TPClientQt::TPInfo)
The TPClientQt class is a simple TCP/IP network client for usage in Touch Portal plugins which wish t...
Definition: TPClientQt.h:85
static ActionDataItem actionDataItem(int index, const QJsonArray &data, const ActionDataItem &defaultItem=ActionDataItem())
Returns the action data object (id and value as ActionDataItem struct) at given index in the given ar...
Definition: TPClientQt.h:658
QString tpVersionString
Touch Portal version number as text.
Definition: TPClientQt.h:114
void stateUpdate(QStringView id, QStringView value) const
Send a state update with given id and value strings.
Definition: TPClientQt.h:313
void choiceUpdate(QStringView id, const QJsonArray &values) const
Update a list of action data choices for action data with given id using a vector of QJsonArray of st...
Definition: TPClientQt.h:341
QString value
Current value of the data member.
Definition: TPClientQt.h:122
void choiceUpdate(const char *id, const char *instanceId, const QStringList &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:222
void connect()
Initiate a connection to Touch Portal. The plugin ID (set in constructor or with setPluginId() must b...
Definition: TPClientQt.cpp:237
void connectorUpdate(QStringView shortId, uint8_t value) const
Update a Connector value with given shortId as reported by TP. Valid value range is 0-100.
Definition: TPClientQt.h:372
void choiceUpdate(const QByteArray &id, const QByteArray &instanceId, const QJsonArray &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:350
void choiceUpdate(const QByteArray &id, const QByteArray &instanceId, const QVector< QByteArray > &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:352
void removeState(const char *id) const
Delete (remove) a dynamic state with given id string.
Definition: TPClientQt.h:528
static QVector< ActionDataItem > actionDataToItemArray(const QJsonArray &data, char separator=0)
Convert JSON array of action data objects: [ { 'id': id, 'value': value }, ... ] to a vector of Actio...
Definition: TPClientQt.h:695
void choiceUpdate(QStringView id, const QStringList &values) const
Update a list of action data choices for action data with given id using a list of QStrings.
Definition: TPClientQt.h:345
void send(const QJsonObject &object) const
Low-level API: Send JSON message data to Touch Portal. object should contain one TP message....
Definition: TPClientQt.h:298
void choiceUpdate(QStringView id, const QVector< QStringView > &values) const
Update a list of action data choices for action data with given id using a vector of QStringView-comp...
Definition: TPClientQt.h:343
void connectorUpdate(const std::string &connectortId, uint8_t value, bool addPrefix) const
Update a Connector value with given full connectortId (see TP API docs for details)....
Definition: TPClientQt.h:236
void settingUpdate(const char *name, const char *value) const
Update a plugin setting value with given name to value.
Definition: TPClientQt.h:605
void sendMap(const QVariantMap &map) const
Low-level API: Send a JSON representation of a variant map to Touch Portal. map should contain one TP...
Definition: TPClientQt.h:300
void choiceUpdate(const QByteArray &id, const QByteArray &instanceId, const QStringList &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:354
void choiceUpdate(const QByteArray &id, const QJsonArray &values) const
Update a list of action data choices for action data with given id using a QJsonArray of strings....
Definition: TPClientQt.h:330
void createState(QStringView id, QStringView parentGroup, QStringView desc, QStringView defaultValue) const
Create a new dynamic state with given id, parentGroup, description and defaultValue strings.
Definition: TPClientQt.h:318
void choiceUpdate(QStringView id, QStringView instanceId, const QVector< QStringView > &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:363
void createState(const QByteArray &id, const QByteArray &desc, const QByteArray &defaultValue) const
Create a new dynamic state with given id, description and defaultValue strings.
Definition: TPClientQt.h:320
void choiceUpdate(const QByteArray &id, const QStringList &values) const
Update a list of action data choices for action data with given id using a list of QStrings.
Definition: TPClientQt.h:334
void createState(const std::string &id, const std::string &parentGroup, const std::string &desc, const std::string &defaultValue="") const
Create a new dynamic state with given id, parentGroup, description and default value strings.
Definition: TPClientQt.h:199
void choiceUpdate(const char *id, const char *instanceId, const QVector< const char * > &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:220
void showNotification(const QByteArray &notificationId, const QByteArray &title, const QByteArray &msg, const QVariantList &options) const
Send a notification message to TP. See TP SDK documentation for details on each field....
Definition: TPClientQt.h:399
void stateUpdate(const char *id, const char *value) const
Send a state update with given id and value strings.
Definition: TPClientQt.h:506
void choiceUpdate(const std::string &id, const std::vector< std::string > &values) const
Update a list of action data choices for action data with given id using a std::vector of std::string...
Definition: TPClientQt.h:216
void choiceUpdate(const std::string &id, const std::string &instanceId, const std::vector< std::string > &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:224
void connectorUpdate(const char *shortId, uint8_t value) const
Update a Connector value with given shortId as reported by TP. Valid value range is 0-100.
Definition: TPClientQt.h:558
void stateUpdate(const QByteArray &id, const QByteArray &value) const
Send a state update with given id and value strings.
Definition: TPClientQt.h:311
void connectorUpdate(const QByteArray &connectortId, uint8_t value, bool addPrefix) const
Update a Connector value with given full connectortId (see TP API docs for details)....
Definition: TPClientQt.h:376
void settingUpdate(const QByteArray &name, const QByteArray &value) const
Update a plugin setting value with given name to value.
Definition: TPClientQt.h:390
void disconnected()
Emitted upon disconnection from Touch Portal, either from an explicit call to close() or if the conne...
void choiceUpdate(QStringView id, QStringView instanceId, const QByteArrayList &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:367
void settingUpdate(QStringView name, QStringView value) const
Update a plugin setting value with given name to value.
Definition: TPClientQt.h:392
void error(QAbstractSocket::SocketError error)
Emitted in case of error upon initial connection or unexpected termination. This would typically be w...
void connectorUpdate(const QByteArray &shortId, uint8_t value) const
Update a Connector value with given shortId as reported by TP. Valid value range is 0-100.
Definition: TPClientQt.h:370
void createState(const std::string &id, const std::string &desc, const std::string &defaultValue="") const
Create a new dynamic state with given id, description and default value strings.
Definition: TPClientQt.h:203
void removeState(QStringView id) const
Delete (remove) a dynamic state with given id string.
Definition: TPClientQt.h:327
void choiceUpdate(const QByteArray &id, const QByteArrayList &values) const
Update a list of action data choices for action data with given id using a QByteArray list.
Definition: TPClientQt.h:338
void createState(QStringView id, QStringView desc, QStringView defaultValue) const
Create a new dynamic state with given id, description and defaultValue strings.
Definition: TPClientQt.h:322
void connected(const TPClientQt::TPInfo &tpInfo, const QJsonObject &settings)
Emitted upon successful connection and pairing with Touch Portal. Data from the initial pairing 'info...
void choiceUpdate(const char *id, const QStringList &values) const
Update a list of action data choices for action data with given id using a list of QStrings.
Definition: TPClientQt.h:214
void setHostProperties(const QString &nameOrAddress=QStringLiteral("127.0.0.1"), uint16_t port=12136)
Set the Touch Portal host name/address and port number for connection. nameOrAddress can be a IPv4 do...
Definition: TPClientQt.cpp:224
void choiceUpdate(QStringView id, QStringView instanceId, const QJsonArray &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:361
void removeState(const QByteArray &id) const
Delete (remove) a dynamic state with given id string.
Definition: TPClientQt.h:325
QString id
ID of the action data member.
Definition: TPClientQt.h:121
void choiceUpdate(const QByteArray &id, const QVector< QByteArray > &values) const
Update a list of action data choices for action data with given id using a vector of QByteArray types...
Definition: TPClientQt.h:332
QString pluginId() const
Returns the plugin ID set in constructor or with setPluginId().
Definition: TPClientQt.cpp:204
void createState(const QByteArray &id, const QByteArray &parentGroup, const QByteArray &desc, const QByteArray &defaultValue) const
Create a new dynamic state with given id, parentGroup, description and defaultValue strings.
Definition: TPClientQt.h:316
void connectorUpdate(QStringView connectortId, uint8_t value, bool addPrefix) const
Update a Connector value with given full connectortId (see TP API docs for details)....
Definition: TPClientQt.h:379
void showNotification(const char *notificationId, const char *title, const char *msg, const QVariantList &options) const
Send a notification message to TP. See TP SDK documentation for details on each field....
Definition: TPClientQt.h:252
MessageType
This enumeration is used in the message() signal to indicate message type. The names match the Touch ...
Definition: TPClientQt.h:90
void removeState(const std::string &id) const
Delete (remove) a dynamic state with given id string.
Definition: TPClientQt.h:207
void settingUpdate(const std::string &name, const std::string &value) const
Update a plugin setting value with given name to value.
Definition: TPClientQt.h:245
QString status
The 'status' property from initial 'info' message (typically "paired"); This does not get changed aft...
Definition: TPClientQt.h:115
static QString actionDataValue(int index, const QJsonArray &data, const QString &defaultValue=QLatin1String(""))
Returns the 'value' member of the action data object at given index in the given array of action/conn...
Definition: TPClientQt.h:670
void choiceUpdate(QStringView id, const QByteArrayList &values) const
Update a list of action data choices for action data with given id using a QByteArray list.
Definition: TPClientQt.h:347
void choiceUpdate(const char *id, const QJsonArray &values) const
Update a list of action data choices for action data with given id using a QJsonArray of strings....
Definition: TPClientQt.h:537
void choiceUpdate(const QByteArray &id, const QByteArray &instanceId, const QByteArrayList &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:358
void createState(const char *id, const char *desc, const char *defaultValue) const
Create a new dynamic state with given id, description and default value strings. Passing nullptr to d...
Definition: TPClientQt.h:201
void connectorUpdate(const std::string &shortId, uint8_t value) const
Update a Connector value with given shortId as reported by TP. Valid value range is 0-100.
Definition: TPClientQt.h:229
void choiceUpdate(QStringView id, QStringView instanceId, const QStringList &values) const
Update a list of action data choices for action data with given id and specific instanceId reported b...
Definition: TPClientQt.h:365
void message(TPClientQt::MessageType type, const QJsonObject &message)
Emitted when any message is received from Touch Portal. Refer to the TP API for specifics of each mes...
QByteArray encode(const QJsonObject &object) const
Low-level API: Serializes a JSON object to UTF8 bytes. object should contain one TP message....
Definition: TPClientQt.h:265
void showNotification(QStringView notificationId, QStringView title, QStringView msg, const QVariantList &options) const
Send a notification message to TP. See TP SDK documentation for details on each field....
Definition: TPClientQt.h:402
void createState(const char *id, const char *parentGroup, const char *desc, const char *defaultValue) const
Create a new dynamic state with given id, parentGroup, description and default value strings....
Definition: TPClientQt.h:516
void showNotification(const char *notificationId, const char *title, const char *msg, const QJsonArray &options) const
Send a notification message to TP. See TP SDK documentation for details on each field....
Definition: TPClientQt.h:615
void choiceUpdate(const char *id, const QVector< const char * > &values) const
Update a list of action data choices for action data with given id using a vector of const char strin...
Definition: TPClientQt.h:212
static QMap< QString, QString > actionDataToMap(const QJsonArray &data, char separator=0)
Flattens array of objects: [ { 'id': id, 'value': value }, ... ] to a single mapping of { {id,...
Definition: TPClientQt.h:713
void showNotification(const QByteArray &notificationId, const QByteArray &title, const QByteArray &msg, const QJsonArray &options) const
Send a notification message to TP. See TP SDK documentation for details on each field....
Definition: TPClientQt.h:396
void setConnectionTimeout(int timeoutMs=10000)
Sets the timeout value for the initial pairing 'info' message to be received from Touch Portal,...
Definition: TPClientQt.cpp:232
Structure for action/connector data id = value pairs sent from TP. Each action/connector sends an arr...
Definition: TPClientQt.h:120
Structure to hold information about current Touch Portal session. Populated from the initial 'info' m...
Definition: TPClientQt.h:109