Skip to content

Commit 85a391e

Browse files
committed
Finish xml_serialization
2 parents 4f37143 + 9daf1a2 commit 85a391e

24 files changed

Lines changed: 1696 additions & 162 deletions

omodsim/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ list(GET VERSION_LIST 1 VERSION_MINOR)
2020
list(GET VERSION_LIST 2 VERSION_PATCH)
2121

2222
# Find Qt6 or fallback to Qt5
23-
find_package(Qt6 COMPONENTS Core Gui Widgets Network PrintSupport SerialBus SerialPort Core5Compat Qml Help LinguistTools QUIET)
23+
find_package(Qt6 COMPONENTS Core Gui Widgets Network Xml PrintSupport SerialBus SerialPort Core5Compat Qml Help LinguistTools QUIET)
2424
if (NOT Qt6_FOUND)
25-
find_package(Qt5 COMPONENTS Core Gui Widgets Network PrintSupport SerialBus SerialPort Qml Help LinguistTools QUIET)
25+
find_package(Qt5 COMPONENTS Core Gui Widgets Network Xml PrintSupport SerialBus SerialPort Qml Help LinguistTools QUIET)
2626
endif()
2727

2828
if (NOT Qt6_FOUND AND NOT Qt5_FOUND)
@@ -312,7 +312,7 @@ endif()
312312

313313
# Link libraries
314314
target_sources(${PROJECT_NAME} PRIVATE resources.qrc ${HEADERS} ${SOURCES} ${UI_FILES} ${TS_FILES})
315-
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Widgets Qt::Network Qt::PrintSupport Qt::SerialBus Qt::SerialPort Qt::Qml Qt::Help)
315+
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Widgets Qt::Network Qt::Xml Qt::PrintSupport Qt::SerialBus Qt::SerialPort Qt::Qml Qt::Help)
316316

317317
if(TARGET update_translations)
318318
add_dependencies(${PROJECT_NAME} update_translations)

omodsim/connectiondetails.h

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <QModbusDevice>
77
#include <QDataStream>
88
#include <QSettings>
9+
#include <QXmlStreamWriter>
910
#include "enums.h"
1011

1112
///
@@ -72,6 +73,7 @@ inline QDataStream& operator >>(QDataStream& in, TcpConnectionParams& params)
7273
///
7374
inline QSettings& operator <<(QSettings& out, const TcpConnectionParams& params)
7475
{
76+
out.setValue("TcpParams/IPAddress", params.IPAddress);
7577
out.setValue("TcpParams/ServicePort", params.ServicePort);
7678
return out;
7779
}
@@ -84,11 +86,56 @@ inline QSettings& operator <<(QSettings& out, const TcpConnectionParams& params)
8486
///
8587
inline QSettings& operator >>(QSettings& in, TcpConnectionParams& params)
8688
{
89+
params.IPAddress = in.value("TcpParams/IPAddress", "0.0.0.0").toString();
8790
params.ServicePort = in.value("TcpParams/ServicePort", 502).toUInt();
8891
params.normalize();
8992
return in;
9093
}
9194

95+
///
96+
/// \brief operator <<
97+
/// \param xml
98+
/// \param dd
99+
/// \return
100+
///
101+
inline QXmlStreamWriter& operator <<(QXmlStreamWriter& xml, const TcpConnectionParams& params)
102+
{
103+
xml.writeStartElement("TcpConnectionParams");
104+
xml.writeAttribute("IPAddress", params.IPAddress);
105+
xml.writeAttribute("ServicePort", QString::number(params.ServicePort));
106+
xml.writeEndElement();
107+
108+
return xml;
109+
}
110+
111+
///
112+
/// \brief operator >>
113+
/// \param xml
114+
/// \param params
115+
/// \return
116+
///
117+
inline QXmlStreamReader& operator >>(QXmlStreamReader& xml, TcpConnectionParams& params)
118+
{
119+
if (xml.isStartElement() && xml.name() == QLatin1String("TcpConnectionParams")) {
120+
const QXmlStreamAttributes attributes = xml.attributes();
121+
122+
if (attributes.hasAttribute("IPAddress")) {
123+
params.IPAddress = attributes.value("IPAddress").toString();
124+
}
125+
126+
if (attributes.hasAttribute("ServicePort")) {
127+
bool ok; const quint16 port = attributes.value("ServicePort").toUShort(&ok);
128+
if (ok) params.ServicePort = port;
129+
}
130+
131+
xml.skipCurrentElement();
132+
133+
params.normalize();
134+
}
135+
136+
return xml;
137+
}
138+
92139
///
93140
/// \brief The SerialConnectionParams class
94141
///
@@ -137,6 +184,26 @@ struct SerialConnectionParams
137184
}
138185
};
139186
Q_DECLARE_METATYPE(SerialConnectionParams)
187+
DECLARE_ENUM_STRINGS(QSerialPort::Parity,
188+
{ QSerialPort::NoParity, "NO" },
189+
{ QSerialPort::EvenParity, "EVEN" },
190+
{ QSerialPort::OddParity, "ODD" },
191+
{ QSerialPort::SpaceParity, "SPACE" },
192+
{ QSerialPort::MarkParity, "MARK" },
193+
{ QSerialPort::UnknownParity,"UNKNOWN" }
194+
)
195+
DECLARE_ENUM_STRINGS(QSerialPort::StopBits,
196+
{ QSerialPort::OneStop, "1" },
197+
{ QSerialPort::OneAndHalfStop, "1.5" },
198+
{ QSerialPort::TwoStop, "2" },
199+
{ QSerialPort::UnknownStopBits, "UNKNOWN" },
200+
)
201+
DECLARE_ENUM_STRINGS(QSerialPort::FlowControl,
202+
{ QSerialPort::NoFlowControl, "NO" },
203+
{ QSerialPort::HardwareControl, "HARDWARE" },
204+
{ QSerialPort::SoftwareControl, "SOFTWARE" },
205+
{ QSerialPort::UnknownFlowControl, "UNKNOWN" },
206+
)
140207

141208
///
142209
/// \brief operator <<
@@ -191,6 +258,7 @@ inline QSettings& operator <<(QSettings& out, const SerialConnectionParams& para
191258
out.setValue("SerialParams/BaudRate", params.BaudRate);
192259
out.setValue("SerialParams/WordLength", params.WordLength);
193260
out.setValue("SerialParams/Parity", params.Parity);
261+
out.setValue("SerialParams/StopBits", params.StopBits);
194262
out.setValue("SerialParams/FlowControl", params.FlowControl);
195263
out.setValue("SerialParams/DTR", params.SetDTR);
196264
out.setValue("SerialParams/RTS", params.SetRTS);
@@ -210,6 +278,7 @@ inline QSettings& operator >>(QSettings& in, SerialConnectionParams& params)
210278
params.BaudRate = (QSerialPort::BaudRate)in.value("SerialParams/BaudRate", 9600).toUInt();
211279
params.WordLength = (QSerialPort::DataBits)in.value("SerialParams/WordLength", 8).toUInt();
212280
params.Parity = (QSerialPort::Parity)in.value("SerialParams/Parity", 0).toUInt();
281+
params.StopBits = (QSerialPort::StopBits)in.value("SerialParams/StopBits", 1).toUInt();
213282
params.FlowControl = (QSerialPort::FlowControl)in.value("SerialParams/FlowControl", 0).toUInt();
214283
params.SetDTR = in.value("SerialParams/DTR", false).toBool();
215284
params.SetRTS = in.value("SerialParams/RTS", false).toBool();
@@ -218,6 +287,82 @@ inline QSettings& operator >>(QSettings& in, SerialConnectionParams& params)
218287
return in;
219288
}
220289

290+
///
291+
/// \brief operator <<
292+
/// \param xml
293+
/// \param params
294+
/// \return
295+
///
296+
inline QXmlStreamWriter& operator <<(QXmlStreamWriter& xml, const SerialConnectionParams& params)
297+
{
298+
xml.writeStartElement("SerialConnectionParams");
299+
300+
xml.writeAttribute("PortName", params.PortName);
301+
xml.writeAttribute("BaudRate", QString::number(params.BaudRate));
302+
xml.writeAttribute("DataBits", QString::number(params.WordLength));
303+
xml.writeAttribute("Parity", enumToString(params.Parity));
304+
xml.writeAttribute("StopBits", enumToString(params.StopBits));
305+
xml.writeAttribute("FlowControl", enumToString(params.FlowControl));
306+
xml.writeAttribute("SetDTR", boolToString(params.SetDTR));
307+
xml.writeAttribute("SetRTS", boolToString(params.SetRTS));
308+
309+
xml.writeEndElement();
310+
return xml;
311+
}
312+
313+
///
314+
/// \brief operator >>
315+
/// \param xml
316+
/// \param params
317+
/// \return
318+
///
319+
inline QXmlStreamReader& operator >>(QXmlStreamReader& xml, SerialConnectionParams& params)
320+
{
321+
if (xml.isStartElement() && xml.name() == QLatin1String("SerialConnectionParams")) {
322+
const QXmlStreamAttributes attributes = xml.attributes();
323+
324+
if (attributes.hasAttribute("PortName")) {
325+
params.PortName = attributes.value("PortName").toString();
326+
}
327+
328+
if (attributes.hasAttribute("BaudRate")) {
329+
bool ok; const auto baudRate = attributes.value("ServicePort").toUInt(&ok);
330+
if (ok) params.BaudRate = static_cast<QSerialPort::BaudRate>(baudRate);
331+
}
332+
333+
if (attributes.hasAttribute("DataBits")) {
334+
bool ok; const auto wordLength = attributes.value("DataBits").toUInt(&ok);
335+
if (ok) params.WordLength = static_cast<QSerialPort::DataBits>(wordLength);
336+
}
337+
338+
if (attributes.hasAttribute("Parity")) {
339+
params.Parity = enumFromString<QSerialPort::Parity>(attributes.value("Parity").toString());
340+
}
341+
342+
if (attributes.hasAttribute("StopBits")) {
343+
params.StopBits = enumFromString<QSerialPort::StopBits>(attributes.value("StopBits").toString());
344+
}
345+
346+
if (attributes.hasAttribute("FlowControl")) {
347+
params.FlowControl = enumFromString<QSerialPort::FlowControl>(attributes.value("FlowControl").toString());
348+
}
349+
350+
if (attributes.hasAttribute("SetDTR")) {
351+
params.SetDTR = stringToBool(attributes.value("SetDTR").toString());
352+
}
353+
354+
if (attributes.hasAttribute("SetRTS")) {
355+
params.SetRTS = stringToBool(attributes.value("SetRTS").toString());
356+
}
357+
358+
xml.skipCurrentElement();
359+
360+
params.normalize();
361+
}
362+
363+
return xml;
364+
}
365+
221366
///
222367
/// \brief The ConnectionDetails class
223368
///
@@ -311,4 +456,62 @@ inline QSettings& operator >>(QSettings& in, ConnectionDetails& params)
311456
return in;
312457
}
313458

459+
///
460+
/// \brief operator <<
461+
/// \param xml
462+
/// \param cd
463+
/// \return
464+
///
465+
inline QXmlStreamWriter& operator <<(QXmlStreamWriter& xml, const ConnectionDetails& cd)
466+
{
467+
xml.writeStartElement("ConnectionDetails");
468+
xml.writeAttribute("ConnectionType", enumToString(cd.Type));
469+
470+
switch(cd.Type) {
471+
case ConnectionType::Tcp:
472+
xml << cd.TcpParams;
473+
break;
474+
case ConnectionType::Serial:
475+
xml << cd.SerialParams;
476+
break;
477+
}
478+
479+
xml.writeEndElement();
480+
return xml;
481+
}
482+
483+
///
484+
/// \brief operator >>
485+
/// \param xml
486+
/// \param cd
487+
/// \return
488+
///
489+
inline QXmlStreamReader& operator >>(QXmlStreamReader& xml, ConnectionDetails& cd)
490+
{
491+
if (xml.isStartElement() && xml.name() == QLatin1String("ConnectionDetails")) {
492+
const QXmlStreamAttributes attributes = xml.attributes();
493+
494+
if (attributes.hasAttribute("ConnectionType")) {
495+
cd.Type = enumFromString<ConnectionType>(attributes.value("ConnectionType").toString());
496+
}
497+
498+
switch(cd.Type) {
499+
case ConnectionType::Tcp:
500+
if(xml.readNextStartElement() && xml.name() == QLatin1String("TcpConnectionParams")) {
501+
xml >> cd.TcpParams;
502+
}
503+
break;
504+
case ConnectionType::Serial:
505+
if(xml.readNextStartElement() && xml.name() == QLatin1String("SerialConnectionParams")) {
506+
xml >> cd.SerialParams;
507+
}
508+
break;
509+
}
510+
511+
xml.skipCurrentElement();
512+
}
513+
514+
return xml;
515+
}
516+
314517
#endif // CONNECTIONDETAILS_H

omodsim/controls/jscriptcontrol.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,83 @@ QDataStream& operator >>(QDataStream& in, JScriptControl* ctrl)
395395

396396
return in;
397397
}
398+
399+
///
400+
/// \brief operator <<
401+
/// \param xml
402+
/// \param ctrl
403+
/// \return
404+
///
405+
QXmlStreamWriter& operator <<(QXmlStreamWriter& xml, const JScriptControl* ctrl)
406+
{
407+
if(!ctrl) return xml;
408+
409+
xml.writeStartElement("JScriptControl");
410+
411+
xml.writeStartElement("Script");
412+
xml.writeCDATA(ctrl->script());
413+
xml.writeEndElement();
414+
415+
xml.writeStartElement("VerticalSplitter");
416+
xml.writeCharacters(ctrl->ui->verticalSplitter->saveState().toBase64());
417+
xml.writeEndElement();
418+
419+
xml.writeStartElement("HorizontalSplitter");
420+
xml.writeCharacters(ctrl->ui->horizontalSplitter->saveState().toBase64());
421+
xml.writeEndElement();
422+
423+
xml.writeStartElement("AutoComplete");
424+
xml.writeAttribute("Enabled", boolToString(ctrl->isAutoCompleteEnabled()));
425+
xml.writeEndElement();
426+
427+
xml.writeEndElement(); // JScriptControl
428+
429+
return xml;
430+
}
431+
432+
///
433+
/// \brief operator >>
434+
/// \param xml
435+
/// \param ctrl
436+
/// \return
437+
///
438+
QXmlStreamReader& operator>>(QXmlStreamReader& xml, JScriptControl* ctrl)
439+
{
440+
if (!ctrl)
441+
return xml;
442+
443+
if (xml.isStartElement() && xml.name() == QLatin1String("JScriptControl")) {
444+
while (xml.readNextStartElement()) {
445+
const QStringRef name = xml.name();
446+
447+
if (name == QLatin1String("Script")) {
448+
const QString scriptText = xml.readElementText(QXmlStreamReader::IncludeChildElements);
449+
ctrl->setScript(scriptText);
450+
}
451+
else if (name == QLatin1String("VerticalSplitter")) {
452+
const QByteArray state = QByteArray::fromBase64(xml.readElementText().toLatin1());
453+
if (!state.isEmpty())
454+
ctrl->ui->verticalSplitter->restoreState(state);
455+
}
456+
else if (name == QLatin1String("HorizontalSplitter")) {
457+
const QByteArray state = QByteArray::fromBase64(xml.readElementText().toLatin1());
458+
if (!state.isEmpty())
459+
ctrl->ui->horizontalSplitter->restoreState(state);
460+
}
461+
else if (name == QLatin1String("AutoComplete")) {
462+
const QXmlStreamAttributes attrs = xml.attributes();
463+
if (attrs.hasAttribute("Enabled")) {
464+
const bool enabled = stringToBool(attrs.value("Enabled").toString());
465+
ctrl->enableAutoComplete(enabled);
466+
}
467+
xml.skipCurrentElement();
468+
}
469+
else {
470+
xml.skipCurrentElement();
471+
}
472+
}
473+
}
474+
475+
return xml;
476+
}
477+

omodsim/controls/jscriptcontrol.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <QTimer>
55
#include <QJSEngine>
66
#include <QPlainTextEdit>
7+
#include <QXmlStreamWriter>
78
#include "console.h"
89
#include "script.h"
910
#include "storage.h"
@@ -22,9 +23,13 @@ class JScriptControl : public QWidget
2223

2324
friend QSettings& operator <<(QSettings& out, const JScriptControl* ctrl);
2425
friend QSettings& operator >>(QSettings& in, JScriptControl* ctrl);
26+
2527
friend QDataStream& operator <<(QDataStream& out, const JScriptControl* ctrl);
2628
friend QDataStream& operator >>(QDataStream& in, JScriptControl* ctrl);
2729

30+
friend QXmlStreamWriter& operator <<(QXmlStreamWriter& xml, const JScriptControl* ctrl);
31+
friend QXmlStreamReader& operator >>(QXmlStreamReader& xml, JScriptControl* ctrl);
32+
2833
public:
2934
explicit JScriptControl(QWidget *parent = nullptr);
3035
~JScriptControl();

omodsim/datasimulator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ void DataSimulator::randomSimulation(DataDisplayMode mode, quint8 deviceId, QMod
196196
{
197197
case QModbusDataUnit::Coils:
198198
case QModbusDataUnit::DiscreteInputs:
199-
value = generateRandom<quint16>(params.Range.from(), params.Range.to() + 1);
199+
value = generateRandom<quint16>(0, 2);
200200
break;
201201

202202
case QModbusDataUnit::HoldingRegisters:

0 commit comments

Comments
 (0)