mirror of
https://github.com/Serial-Studio/Serial-Studio.git
synced 2025-01-15 05:22:53 +08:00
Implement #83 with backwards compatiblity
This commit is contained in:
parent
f9bed1ab10
commit
4d5eac980e
@ -40,7 +40,7 @@ Item {
|
||||
//
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing * 2
|
||||
spacing: app.spacing
|
||||
anchors.margins: (app.spacing * 1.5) - 5
|
||||
|
||||
//
|
||||
|
@ -100,21 +100,6 @@ FramelessWindow.CustomWindow {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window drag handler
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
DragHandler {
|
||||
grabPermissions: TapHandler.CanTakeOverFromAnything
|
||||
onActiveChanged: {
|
||||
if (active)
|
||||
root.startSystemMove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
|
@ -513,7 +513,6 @@ FramelessWindow.CustomWindow {
|
||||
}
|
||||
|
||||
Button {
|
||||
checkable: true
|
||||
icon.color: palette.text
|
||||
opacity: enabled ? 1 : 0.5
|
||||
Layout.maximumWidth: height
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <AppInfo.h>
|
||||
#include <IO/Manager.h>
|
||||
#include <JSON/Generator.h>
|
||||
#include <JSON/FrameInfo.h>
|
||||
#include <Misc/Utilities.h>
|
||||
#include <Misc/TimerEvents.h>
|
||||
|
||||
@ -150,7 +151,7 @@ void Export::writeValues()
|
||||
// Get project title & cell values
|
||||
auto dateTime = m_jsonList.first().rxDateTime;
|
||||
auto json = m_jsonList.first().jsonDocument.object();
|
||||
auto projectTitle = json.value("t").toVariant().toString();
|
||||
auto projectTitle = JFI_Value(json, "title", "t").toString();
|
||||
|
||||
// Validate JSON & title
|
||||
if (json.isEmpty() || projectTitle.isEmpty())
|
||||
@ -162,35 +163,26 @@ void Export::writeValues()
|
||||
// Get cell titles & values
|
||||
StringList titles;
|
||||
StringList values;
|
||||
auto groups = json.value("g").toArray();
|
||||
auto groups = JFI_Value(json, "groups", "g").toArray();
|
||||
for (int i = 0; i < groups.count(); ++i)
|
||||
{
|
||||
// Get group & dataset array
|
||||
auto group = groups.at(i).toObject();
|
||||
auto datasets = group.value("d").toArray();
|
||||
auto datasets = JFI_Value(group, "datasets", "d").toArray();
|
||||
if (group.isEmpty() || datasets.isEmpty())
|
||||
continue;
|
||||
|
||||
// Get group title
|
||||
auto groupTitle = group.value("t").toVariant().toString();
|
||||
auto groupTitle = JFI_Value(group, "title", "t").toVariant().toString();
|
||||
|
||||
// Get dataset titles & values
|
||||
for (int j = 0; j < datasets.count(); ++j)
|
||||
{
|
||||
// Get dataset object & fields
|
||||
auto dataset = datasets.at(j).toObject();
|
||||
auto datasetTitle = dataset.value("t").toVariant().toString();
|
||||
auto datasetUnits = dataset.value("u").toVariant().toString();
|
||||
auto datasetValue = dataset.value("v").toVariant().toString();
|
||||
|
||||
datasetTitle = datasetTitle.replace("\n", "");
|
||||
datasetUnits = datasetUnits.replace("\n", "");
|
||||
datasetValue = datasetValue.replace("\n", "");
|
||||
datasetTitle = datasetTitle.replace("\r", "");
|
||||
datasetUnits = datasetUnits.replace("\r", "");
|
||||
datasetValue = datasetValue.replace("\r", "");
|
||||
|
||||
if (datasetTitle.isEmpty())
|
||||
continue;
|
||||
auto datasetTitle = JFI_Value(dataset, "title", "t").toString();
|
||||
auto datasetUnits = JFI_Value(dataset, "units", "u").toString();
|
||||
auto datasetValue = JFI_Value(dataset, "value", "v").toString();
|
||||
|
||||
// Construct dataset title from group, dataset title & units
|
||||
QString title;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <IO/Manager.h>
|
||||
#include <Misc/Utilities.h>
|
||||
#include <JSON/Generator.h>
|
||||
#include <JSON/FrameInfo.h>
|
||||
|
||||
namespace CSV
|
||||
{
|
||||
@ -560,31 +561,35 @@ QJsonDocument Player::getJsonFrame(const int row)
|
||||
|
||||
// Replace JSON title
|
||||
auto json = jsonTemplate.object();
|
||||
json["t"] = tr("Replay of %1").arg(filename());
|
||||
if (json.contains("t"))
|
||||
json["t"] = tr("Replay of %1").arg(filename());
|
||||
else
|
||||
json["title"] = tr("Replay of %1").arg(filename());
|
||||
|
||||
// Replace values in JSON with values in row using the model.
|
||||
// This is very ugly code, somebody please fix it :(
|
||||
auto groups = json.value("g").toArray();
|
||||
auto groups = JFI_Value(json, "groups", "g").toArray();
|
||||
foreach (auto groupKey, m_model.keys())
|
||||
{
|
||||
for (int i = 0; i < groups.count(); ++i)
|
||||
{
|
||||
auto group = groups.at(i).toObject();
|
||||
|
||||
if (group.value("t") == groupKey)
|
||||
if (JFI_Value(group, "title", "t") == groupKey)
|
||||
{
|
||||
auto datasetKeys = m_model.value(groupKey);
|
||||
auto datasets = group.value("d").toArray();
|
||||
auto datasets = JFI_Value(group, "datasets", "d").toArray();
|
||||
foreach (auto datasetKey, datasetKeys)
|
||||
{
|
||||
for (int j = 0; j < datasets.count(); ++j)
|
||||
{
|
||||
auto dataset = datasets.at(j).toObject();
|
||||
if (dataset.value("t") == datasetKey)
|
||||
if (JFI_Value(dataset, "title", "t") == datasetKey)
|
||||
{
|
||||
auto value = values.at(getDatasetIndex(groupKey, datasetKey));
|
||||
dataset.remove("v");
|
||||
dataset.insert("v", value);
|
||||
dataset.remove("value");
|
||||
dataset.insert("value", value);
|
||||
}
|
||||
|
||||
datasets.replace(j, dataset);
|
||||
@ -592,7 +597,8 @@ QJsonDocument Player::getJsonFrame(const int row)
|
||||
}
|
||||
|
||||
group.remove("d");
|
||||
group.insert("d", datasets);
|
||||
group.remove("datasets");
|
||||
group.insert("datasets", datasets);
|
||||
}
|
||||
|
||||
groups.replace(i, group);
|
||||
@ -601,7 +607,8 @@ QJsonDocument Player::getJsonFrame(const int row)
|
||||
|
||||
// Update groups from JSON
|
||||
json.remove("g");
|
||||
json.insert("g", groups);
|
||||
json.remove("groups");
|
||||
json.insert("groups", groups);
|
||||
|
||||
// Return new JSON document
|
||||
return QJsonDocument(json);
|
||||
|
@ -22,10 +22,10 @@
|
||||
|
||||
#include "Dataset.h"
|
||||
#include "Generator.h"
|
||||
#include "FrameInfo.h"
|
||||
|
||||
namespace JSON
|
||||
{
|
||||
|
||||
Dataset::Dataset(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_fft(false)
|
||||
@ -156,37 +156,20 @@ QJsonObject Dataset::jsonData() const
|
||||
*/
|
||||
bool Dataset::read(const QJsonObject &object)
|
||||
{
|
||||
static QJSEngine JAVASCRIPT_ENGINE;
|
||||
|
||||
if (!object.isEmpty())
|
||||
{
|
||||
auto fft = object.value("fft").toVariant().toBool();
|
||||
auto led = object.value("led").toVariant().toBool();
|
||||
auto log = object.value("log").toVariant().toBool();
|
||||
auto graph = object.value("g").toVariant().toBool();
|
||||
auto title = object.value("t").toVariant().toString();
|
||||
auto value = object.value("v").toVariant().toString();
|
||||
auto units = object.value("u").toVariant().toString();
|
||||
auto widget = object.value("w").toVariant().toString();
|
||||
auto min = object.value("min").toVariant().toString();
|
||||
auto max = object.value("max").toVariant().toString();
|
||||
auto alarm = object.value("alarm").toVariant().toString();
|
||||
auto fftSamples = object.value("fftSamples").toVariant().toInt();
|
||||
|
||||
min = min.replace("\n", "");
|
||||
min = min.replace("\r", "");
|
||||
max = max.replace("\n", "");
|
||||
max = max.replace("\r", "");
|
||||
title = title.replace("\n", "");
|
||||
title = title.replace("\r", "");
|
||||
value = value.replace("\n", "");
|
||||
value = value.replace("\r", "");
|
||||
units = units.replace("\n", "");
|
||||
units = units.replace("\r", "");
|
||||
alarm = alarm.replace("\n", "");
|
||||
alarm = alarm.replace("\r", "");
|
||||
widget = widget.replace("\n", "");
|
||||
widget = widget.replace("\r", "");
|
||||
auto fft = JFI_Value(object, "fft").toBool();
|
||||
auto led = JFI_Value(object, "led").toBool();
|
||||
auto log = JFI_Value(object, "log").toBool();
|
||||
auto min = JFI_Value(object, "min").toString();
|
||||
auto max = JFI_Value(object, "max").toString();
|
||||
auto alarm = JFI_Value(object, "alarm").toString();
|
||||
auto graph = JFI_Value(object, "graph", "g").toBool();
|
||||
auto title = JFI_Value(object, "title", "t").toString();
|
||||
auto value = JFI_Value(object, "value", "v").toString();
|
||||
auto units = JFI_Value(object, "units", "u").toString();
|
||||
auto widget = JFI_Value(object, "widget", "w").toString();
|
||||
auto fftSamples = JFI_Value(object, "fftSamples").toInt();
|
||||
|
||||
if (!value.isEmpty() && !title.isEmpty())
|
||||
{
|
||||
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "Editor.h"
|
||||
#include "FrameInfo.h"
|
||||
#include "Generator.h"
|
||||
#include "IO/Manager.h"
|
||||
#include "Misc/Utilities.h"
|
||||
@ -302,10 +303,10 @@ bool Editor::saveJsonFile()
|
||||
|
||||
// Create JSON document & add properties
|
||||
QJsonObject json;
|
||||
json.insert("t", title());
|
||||
json.insert("s", separator());
|
||||
json.insert("fe", frameEndSequence());
|
||||
json.insert("fs", frameStartSequence());
|
||||
json.insert("title", title());
|
||||
json.insert("separator", separator());
|
||||
json.insert("frameEnd", frameEndSequence());
|
||||
json.insert("frameStart", frameStartSequence());
|
||||
|
||||
// Create group array
|
||||
QJsonArray groups;
|
||||
@ -313,8 +314,8 @@ bool Editor::saveJsonFile()
|
||||
{
|
||||
// Create group
|
||||
QJsonObject group;
|
||||
group.insert("t", groupTitle(i));
|
||||
group.insert("w", groupWidget(i));
|
||||
group.insert("title", groupTitle(i));
|
||||
group.insert("widget", groupWidget(i));
|
||||
|
||||
// Create dataset array
|
||||
QJsonArray datasets;
|
||||
@ -322,30 +323,30 @@ bool Editor::saveJsonFile()
|
||||
{
|
||||
// Create dataset
|
||||
QJsonObject dataset;
|
||||
dataset.insert("t", datasetTitle(i, j));
|
||||
dataset.insert("u", datasetUnits(i, j));
|
||||
dataset.insert("g", datasetGraph(i, j));
|
||||
dataset.insert("led", datasetLED(i, j));
|
||||
dataset.insert("w", datasetWidget(i, j));
|
||||
dataset.insert("fft", datasetFftPlot(i, j));
|
||||
dataset.insert("log", datasetLogPlot(i, j));
|
||||
dataset.insert("v", "%" + QString::number(datasetIndex(i, j)));
|
||||
dataset.insert("title", datasetTitle(i, j));
|
||||
dataset.insert("units", datasetUnits(i, j));
|
||||
dataset.insert("graph", datasetGraph(i, j));
|
||||
dataset.insert("widget", datasetWidget(i, j));
|
||||
dataset.insert("min", datasetWidgetMin(i, j).toDouble());
|
||||
dataset.insert("max", datasetWidgetMax(i, j).toDouble());
|
||||
dataset.insert("alarm", datasetWidgetAlarm(i, j).toDouble());
|
||||
dataset.insert("fftSamples", datasetFFTSamples(i, j).toInt());
|
||||
dataset.insert("value", "%" + QString::number(datasetIndex(i, j)));
|
||||
|
||||
// Add dataset to array
|
||||
datasets.append(dataset);
|
||||
}
|
||||
|
||||
// Add datasets to group
|
||||
group.insert("d", datasets);
|
||||
group.insert("datasets", datasets);
|
||||
groups.append(group);
|
||||
}
|
||||
|
||||
// Add groups array to JSON
|
||||
json.insert("g", groups);
|
||||
json.insert("groups", groups);
|
||||
|
||||
// Write JSON data to file
|
||||
file.write(QJsonDocument(json).toJson(QJsonDocument::Indented));
|
||||
@ -740,10 +741,10 @@ void Editor::openJsonFile(const QString &path)
|
||||
|
||||
// Read data from JSON document
|
||||
auto json = document.object();
|
||||
setTitle(json.value("t").toString());
|
||||
setSeparator(json.value("s").toString());
|
||||
setFrameEndSequence(json.value("fe").toString());
|
||||
setFrameStartSequence(json.value("fs").toString());
|
||||
setTitle(JFI_Value(json, "title", "t").toString());
|
||||
setSeparator(JFI_Value(json, "separator", "s").toString());
|
||||
setFrameEndSequence(JFI_Value(json, "frameEnd", "fe").toString());
|
||||
setFrameStartSequence(JFI_Value(json, "frameStart", "fs").toString());
|
||||
|
||||
// Modify IO manager settings
|
||||
auto manager = IO::Manager::getInstance();
|
||||
@ -755,48 +756,47 @@ void Editor::openJsonFile(const QString &path)
|
||||
JSON::Generator::getInstance()->setOperationMode(JSON::Generator::kManual);
|
||||
|
||||
// Read groups from JSON document
|
||||
auto groups = json.value("g").toArray();
|
||||
for (int group = 0; group < groups.count(); ++group)
|
||||
auto groups = JFI_Value(json, "groups", "g").toArray();
|
||||
for (int g = 0; g < groups.count(); ++g)
|
||||
{
|
||||
// Get JSON group data
|
||||
auto jsonGroup = groups.at(group).toObject();
|
||||
auto group = groups.at(g).toObject();
|
||||
|
||||
// Register group with C++ model
|
||||
addGroup();
|
||||
setGroupTitle(group, jsonGroup.value("t").toString());
|
||||
setGroupWidgetData(group, jsonGroup.value("w").toString());
|
||||
setGroupTitle(g, JFI_Value(group, "title", "t").toString());
|
||||
setGroupWidgetData(g, JFI_Value(group, "widget", "w").toString());
|
||||
|
||||
// Get JSON group datasets
|
||||
auto jsonDatasets = jsonGroup.value("d").toArray();
|
||||
for (int dataset = 0; dataset < jsonDatasets.count(); ++dataset)
|
||||
auto datasets = JFI_Value(group, "datasets", "d").toArray();
|
||||
for (int d = 0; d < datasets.count(); ++d)
|
||||
{
|
||||
// Get dataset JSON data
|
||||
auto jsonDataset = jsonDatasets.at(dataset).toObject();
|
||||
auto dataset = datasets.at(d).toObject();
|
||||
|
||||
// Register dataset with C++ model
|
||||
addDataset(group);
|
||||
setDatasetGraph(group, dataset, jsonDataset.value("g").toBool());
|
||||
setDatasetLED(group, dataset, jsonDataset.value("led").toBool());
|
||||
setDatasetTitle(group, dataset, jsonDataset.value("t").toString());
|
||||
setDatasetUnits(group, dataset, jsonDataset.value("u").toString());
|
||||
setDatasetFftPlot(group, dataset, jsonDataset.value("fft").toBool());
|
||||
setDatasetLogPlot(group, dataset, jsonDataset.value("log").toBool());
|
||||
setDatasetWidgetData(group, dataset, jsonDataset.value("w").toString());
|
||||
setDatasetFFTSamples(
|
||||
group, dataset, QString::number(jsonDataset.value("fftSamples").toInt()));
|
||||
addDataset(g);
|
||||
setDatasetLED(g, d, JFI_Value(dataset, "led").toBool());
|
||||
setDatasetFftPlot(g, d, JFI_Value(dataset, "fft").toBool());
|
||||
setDatasetLogPlot(g, d, JFI_Value(dataset, "log").toBool());
|
||||
setDatasetGraph(g, d, JFI_Value(dataset, "graph", "g").toBool());
|
||||
setDatasetTitle(g, d, JFI_Value(dataset, "title", "t").toString());
|
||||
setDatasetUnits(g, d, JFI_Value(dataset, "units", "u").toString());
|
||||
setDatasetFFTSamples(g, d, JFI_Value(dataset, "fftSamples").toString());
|
||||
setDatasetWidgetData(g, d, JFI_Value(dataset, "widget", "w").toString());
|
||||
|
||||
// Get max/min texts
|
||||
auto min = jsonDataset.value("min").toDouble();
|
||||
auto max = jsonDataset.value("max").toDouble();
|
||||
auto alarm = jsonDataset.value("alarm").toDouble();
|
||||
setDatasetWidgetMin(group, dataset, QString::number(min));
|
||||
setDatasetWidgetMax(group, dataset, QString::number(max));
|
||||
setDatasetWidgetAlarm(group, dataset, QString::number(alarm));
|
||||
auto min = JFI_Value(dataset, "min").toDouble();
|
||||
auto max = JFI_Value(dataset, "max").toDouble();
|
||||
auto alarm = JFI_Value(dataset, "alarm").toDouble();
|
||||
setDatasetWidgetMin(g, d, QString::number(min));
|
||||
setDatasetWidgetMax(g, d, QString::number(max));
|
||||
setDatasetWidgetAlarm(g, d, QString::number(alarm));
|
||||
|
||||
// Calculate dataset index
|
||||
auto index = jsonDataset.value("v").toString();
|
||||
auto index = JFI_Value(dataset, "value", "v").toString();
|
||||
index.replace("%", "");
|
||||
setDatasetIndex(group, dataset, index.toInt());
|
||||
setDatasetIndex(g, d, index.toInt());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "Frame.h"
|
||||
#include "FrameInfo.h"
|
||||
|
||||
namespace JSON
|
||||
{
|
||||
@ -91,12 +92,8 @@ bool Frame::read(const QJsonObject &object)
|
||||
clear();
|
||||
|
||||
// Get title & groups array
|
||||
auto title = object.value("t").toString();
|
||||
auto groups = object.value("g").toArray();
|
||||
|
||||
// Remove line breaks from title
|
||||
title = title.replace("\n", "");
|
||||
title = title.replace("\r", "");
|
||||
auto title = JFI_Value(object, "title", "t").toString();
|
||||
auto groups = JFI_Value(object, "groups", "g").toArray();
|
||||
|
||||
// We need to have a project title and at least one group
|
||||
if (!title.isEmpty() && !groups.isEmpty())
|
||||
|
@ -71,3 +71,34 @@ JFI_Object JFI_CreateNew(const quint64 n, const QDateTime &t, const QJsonDocumen
|
||||
info.jsonDocument = d;
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the value of the first element that corresponds to given @a key
|
||||
*/
|
||||
QJsonValue JFI_Value(const QJsonObject &object, const QString key)
|
||||
{
|
||||
return JFI_Value(object, StringList { key });
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the value of the first element that matches one of the given @a keys
|
||||
*/
|
||||
QJsonValue JFI_Value(const QJsonObject &object, const StringList keys)
|
||||
{
|
||||
for (int i = 0; i < keys.count(); ++i)
|
||||
{
|
||||
auto tag = keys.at(i);
|
||||
if (object.contains(tag))
|
||||
return object.value(tag);
|
||||
}
|
||||
|
||||
return QJsonValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the value of the first element that corresponds to key @c a or key @c b
|
||||
*/
|
||||
QJsonValue JFI_Value(const QJsonObject &object, const QString a, const QString b)
|
||||
{
|
||||
return JFI_Value(object, StringList { a, b });
|
||||
}
|
||||
|
@ -24,8 +24,13 @@
|
||||
|
||||
#include <QVector>
|
||||
#include <QDateTime>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "DataTypes.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
quint64 frameNumber;
|
||||
@ -38,3 +43,7 @@ extern void JFI_SortList(QVector<JFI_Object> *list);
|
||||
extern JFI_Object JFI_Empty(const quint64 n = 0);
|
||||
extern JFI_Object JFI_CreateNew(const quint64 n, const QDateTime &t,
|
||||
const QJsonDocument &d);
|
||||
|
||||
extern QJsonValue JFI_Value(const QJsonObject &object, const QString key);
|
||||
extern QJsonValue JFI_Value(const QJsonObject &object, const StringList keys);
|
||||
extern QJsonValue JFI_Value(const QJsonObject &object, const QString a, const QString b);
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "Editor.h"
|
||||
#include "Generator.h"
|
||||
#include "FrameInfo.h"
|
||||
|
||||
#include <CSV/Player.h>
|
||||
#include <IO/Manager.h>
|
||||
@ -354,19 +355,19 @@ void Generator::processFrame(const QByteArray &data, const quint64 frame,
|
||||
|
||||
// Calculate dynamically generated values
|
||||
auto root = jsonDocument.object();
|
||||
auto groups = root.value("g").toArray();
|
||||
auto groups = JFI_Value(root, "groups", "g").toArray();
|
||||
for (int i = 0; i < groups.count(); ++i)
|
||||
{
|
||||
// Get group
|
||||
auto group = groups.at(i).toObject();
|
||||
|
||||
// Evaluate each dataset of the current group
|
||||
auto datasets = group.value("d").toArray();
|
||||
auto datasets = JFI_Value(group, "datasets", "d").toArray();
|
||||
for (int j = 0; j < datasets.count(); ++j)
|
||||
{
|
||||
// Get dataset object & value
|
||||
auto dataset = datasets.at(j).toObject();
|
||||
auto value = dataset.value("v").toString();
|
||||
auto value = JFI_Value(root, "value", "v").toString();
|
||||
|
||||
// Evaluate code in dataset value (if any)
|
||||
auto jsValue = m_engine.evaluate(value);
|
||||
@ -375,20 +376,23 @@ void Generator::processFrame(const QByteArray &data, const quint64 frame,
|
||||
if (!jsValue.isError())
|
||||
{
|
||||
dataset.remove("v");
|
||||
dataset.insert("v", jsValue.toString());
|
||||
dataset.remove("value");
|
||||
dataset.insert("value", jsValue.toString());
|
||||
datasets.replace(j, dataset);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace group datasets
|
||||
group.remove("d");
|
||||
group.insert("d", datasets);
|
||||
group.remove("datasets");
|
||||
group.insert("datasets", datasets);
|
||||
groups.replace(i, group);
|
||||
}
|
||||
|
||||
// Replace root document group objects
|
||||
root.remove("g");
|
||||
root.insert("g", groups);
|
||||
root.remove("groups");
|
||||
root.insert("groups", groups);
|
||||
|
||||
// Create JSON document
|
||||
document = QJsonDocument(root);
|
||||
@ -453,19 +457,19 @@ void JSONWorker::process()
|
||||
|
||||
// Calculate dynamically generated values
|
||||
auto root = jsonDocument.object();
|
||||
auto groups = root.value("g").toArray();
|
||||
auto groups = JFI_Value(root, "groups", "g").toArray();
|
||||
for (int i = 0; i < groups.count(); ++i)
|
||||
{
|
||||
// Get group
|
||||
auto group = groups.at(i).toObject();
|
||||
|
||||
// Evaluate each dataset of the current group
|
||||
auto datasets = group.value("d").toArray();
|
||||
auto datasets = JFI_Value(group, "datasets", "d").toArray();
|
||||
for (int j = 0; j < datasets.count(); ++j)
|
||||
{
|
||||
// Get dataset object & value
|
||||
auto dataset = datasets.at(j).toObject();
|
||||
auto value = dataset.value("v").toString();
|
||||
auto value = JFI_Value(root, "value", "v").toString();
|
||||
|
||||
// Evaluate code in dataset value (if any)
|
||||
auto jsValue = m_engine->evaluate(value);
|
||||
@ -474,20 +478,23 @@ void JSONWorker::process()
|
||||
if (!jsValue.isError())
|
||||
{
|
||||
dataset.remove("v");
|
||||
dataset.insert("v", jsValue.toString());
|
||||
dataset.remove("value");
|
||||
dataset.insert("value", jsValue.toString());
|
||||
datasets.replace(j, dataset);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace group datasets
|
||||
group.remove("d");
|
||||
group.insert("d", datasets);
|
||||
group.remove("datasets");
|
||||
group.insert("datasets", datasets);
|
||||
groups.replace(i, group);
|
||||
}
|
||||
|
||||
// Replace root document group objects
|
||||
root.remove("g");
|
||||
root.insert("g", groups);
|
||||
root.remove("groups");
|
||||
root.insert("groups", groups);
|
||||
|
||||
// Create JSON document
|
||||
document = QJsonDocument(root);
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "Group.h"
|
||||
#include "Dataset.h"
|
||||
#include "FrameInfo.h"
|
||||
|
||||
namespace JSON
|
||||
{
|
||||
@ -97,14 +98,9 @@ bool Group::read(const QJsonObject &object)
|
||||
{
|
||||
if (!object.isEmpty())
|
||||
{
|
||||
auto array = object.value("d").toArray();
|
||||
auto title = object.value("t").toVariant().toString();
|
||||
auto widget = object.value("w").toVariant().toString();
|
||||
|
||||
title = title.replace("\n", "");
|
||||
title = title.replace("\r", "");
|
||||
widget = widget.replace("\n", "");
|
||||
widget = widget.replace("\r", "");
|
||||
auto title = JFI_Value(object, "title", "t").toString();
|
||||
auto array = JFI_Value(object, "datasets", "d").toArray();
|
||||
auto widget = JFI_Value(object, "widget", "w").toString();
|
||||
|
||||
if (!title.isEmpty() && !array.isEmpty())
|
||||
{
|
||||
|
@ -126,15 +126,15 @@ int Client::mqttVersion() const
|
||||
{
|
||||
switch (m_client.version())
|
||||
{
|
||||
case QMQTT::V3_1_0:
|
||||
return 0;
|
||||
break;
|
||||
case QMQTT::V3_1_1:
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
case QMQTT::V3_1_0:
|
||||
return 0;
|
||||
break;
|
||||
case QMQTT::V3_1_1:
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,8 +254,9 @@ StringList Client::mqttVersions() const
|
||||
*/
|
||||
StringList Client::sslProtocols() const
|
||||
{
|
||||
return StringList { tr("System default"), "TLS v1.0", "TLS v1.1", "TLS v1.2 (or later)",
|
||||
"DTLS v1.0", "DTLS v1.2", "DTLS v1.2 (or later)" };
|
||||
return StringList { tr("System default"), "TLS v1.0", "TLS v1.1",
|
||||
"TLS v1.2 (or later)", "DTLS v1.0", "DTLS v1.2",
|
||||
"DTLS v1.2 (or later)" };
|
||||
}
|
||||
|
||||
/**
|
||||
@ -270,14 +271,11 @@ StringList Client::certificateModes() const
|
||||
* Prompts the user to select a *.ca file and loads the certificate
|
||||
* into the SSL configuration.
|
||||
*/
|
||||
void Client::loadCaFile() {
|
||||
void Client::loadCaFile()
|
||||
{
|
||||
// Prompt user to select a CA file
|
||||
auto path = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
tr("Select CA file"),
|
||||
QDir::homePath(),
|
||||
"*.ca"
|
||||
);
|
||||
auto path = QFileDialog::getOpenFileName(Q_NULLPTR, tr("Select CA file"),
|
||||
QDir::homePath(), "*.ca");
|
||||
|
||||
// Try to load the *.ca file
|
||||
loadCaFile(path);
|
||||
@ -382,7 +380,8 @@ void Client::setTopic(const QString &topic)
|
||||
* Reads the CA file in the given @a path and loads it into the
|
||||
* SSL configuration handler for the MQTT connection.
|
||||
*/
|
||||
void Client::loadCaFile(const QString &path) {
|
||||
void Client::loadCaFile(const QString &path)
|
||||
{
|
||||
// Empty path, abort
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
@ -390,15 +389,16 @@ void Client::loadCaFile(const QString &path) {
|
||||
// Try to read file contents
|
||||
QByteArray data;
|
||||
QFile file(path);
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
if (file.open(QFile::ReadOnly))
|
||||
{
|
||||
data = file.readAll();
|
||||
file.close();
|
||||
}
|
||||
|
||||
// Read error, alert user
|
||||
else {
|
||||
Misc::Utilities::showMessageBox(tr("Cannot open CA file!"),
|
||||
file.errorString());
|
||||
else
|
||||
{
|
||||
Misc::Utilities::showMessageBox(tr("Cannot open CA file!"), file.errorString());
|
||||
file.close();
|
||||
return;
|
||||
}
|
||||
@ -412,31 +412,33 @@ void Client::loadCaFile(const QString &path) {
|
||||
/**
|
||||
* Changes the SSL protocol version to use for the MQTT connection.
|
||||
*/
|
||||
void Client::setSslProtocol(const int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
m_sslConfiguration.setProtocol(QSsl::SecureProtocols);
|
||||
break;
|
||||
case 1:
|
||||
m_sslConfiguration.setProtocol(QSsl::TlsV1_0);
|
||||
break;
|
||||
case 2:
|
||||
m_sslConfiguration.setProtocol(QSsl::TlsV1_1);
|
||||
break;
|
||||
case 3:
|
||||
m_sslConfiguration.setProtocol(QSsl::TlsV1_3OrLater);
|
||||
break;
|
||||
case 4:
|
||||
m_sslConfiguration.setProtocol(QSsl::DtlsV1_0);
|
||||
break;
|
||||
case 5:
|
||||
m_sslConfiguration.setProtocol(QSsl::DtlsV1_2);
|
||||
break;
|
||||
case 6:
|
||||
m_sslConfiguration.setProtocol(QSsl::DtlsV1_2OrLater);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
void Client::setSslProtocol(const int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
m_sslConfiguration.setProtocol(QSsl::SecureProtocols);
|
||||
break;
|
||||
case 1:
|
||||
m_sslConfiguration.setProtocol(QSsl::TlsV1_0);
|
||||
break;
|
||||
case 2:
|
||||
m_sslConfiguration.setProtocol(QSsl::TlsV1_1);
|
||||
break;
|
||||
case 3:
|
||||
m_sslConfiguration.setProtocol(QSsl::TlsV1_3OrLater);
|
||||
break;
|
||||
case 4:
|
||||
m_sslConfiguration.setProtocol(QSsl::DtlsV1_0);
|
||||
break;
|
||||
case 5:
|
||||
m_sslConfiguration.setProtocol(QSsl::DtlsV1_2);
|
||||
break;
|
||||
case 6:
|
||||
m_sslConfiguration.setProtocol(QSsl::DtlsV1_2OrLater);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
emit sslProtocolChanged();
|
||||
@ -463,8 +465,8 @@ void Client::setSslEnabled(const bool enabled)
|
||||
*/
|
||||
void Client::setCertificateMode(const int index)
|
||||
{
|
||||
switch (index) {
|
||||
|
||||
switch (index)
|
||||
{
|
||||
}
|
||||
|
||||
emit certificateModeChanged();
|
||||
@ -506,14 +508,14 @@ void Client::setMqttVersion(const int versionIndex)
|
||||
{
|
||||
switch (versionIndex)
|
||||
{
|
||||
case 0:
|
||||
m_client.setVersion(QMQTT::V3_1_0);
|
||||
break;
|
||||
case 1:
|
||||
m_client.setVersion(QMQTT::V3_1_1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 0:
|
||||
m_client.setVersion(QMQTT::V3_1_0);
|
||||
break;
|
||||
case 1:
|
||||
m_client.setVersion(QMQTT::V3_1_1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
emit mqttVersionChanged();
|
||||
@ -595,99 +597,99 @@ void Client::onError(const QMQTT::ClientError error)
|
||||
|
||||
switch (error)
|
||||
{
|
||||
case QMQTT::UnknownError:
|
||||
str = tr("Unknown error");
|
||||
break;
|
||||
case QMQTT::SocketConnectionRefusedError:
|
||||
str = tr("Connection refused");
|
||||
break;
|
||||
case QMQTT::SocketRemoteHostClosedError:
|
||||
str = tr("Remote host closed the connection");
|
||||
break;
|
||||
case QMQTT::SocketHostNotFoundError:
|
||||
str = tr("Host not found");
|
||||
break;
|
||||
case QMQTT::SocketAccessError:
|
||||
str = tr("Socket access error");
|
||||
break;
|
||||
case QMQTT::SocketResourceError:
|
||||
str = tr("Socket resource error");
|
||||
break;
|
||||
case QMQTT::SocketTimeoutError:
|
||||
str = tr("Socket timeout");
|
||||
break;
|
||||
case QMQTT::SocketDatagramTooLargeError:
|
||||
str = tr("Socket datagram too large");
|
||||
break;
|
||||
case QMQTT::SocketNetworkError:
|
||||
str = tr("Network error");
|
||||
break;
|
||||
case QMQTT::SocketAddressInUseError:
|
||||
str = tr("Address in use");
|
||||
break;
|
||||
case QMQTT::SocketAddressNotAvailableError:
|
||||
str = tr("Address not available");
|
||||
break;
|
||||
case QMQTT::SocketUnsupportedSocketOperationError:
|
||||
str = tr("Unsupported socket operation");
|
||||
break;
|
||||
case QMQTT::SocketUnfinishedSocketOperationError:
|
||||
str = tr("Unfinished socket operation");
|
||||
break;
|
||||
case QMQTT::SocketProxyAuthenticationRequiredError:
|
||||
str = tr("Proxy authentication required");
|
||||
break;
|
||||
case QMQTT::SocketSslHandshakeFailedError:
|
||||
str = tr("SSL handshake failed");
|
||||
break;
|
||||
case QMQTT::SocketProxyConnectionRefusedError:
|
||||
str = tr("Proxy connection refused");
|
||||
break;
|
||||
case QMQTT::SocketProxyConnectionClosedError:
|
||||
str = tr("Proxy connection closed");
|
||||
break;
|
||||
case QMQTT::SocketProxyConnectionTimeoutError:
|
||||
str = tr("Proxy connection timeout");
|
||||
break;
|
||||
case QMQTT::SocketProxyNotFoundError:
|
||||
str = tr("Proxy not found");
|
||||
break;
|
||||
case QMQTT::SocketProxyProtocolError:
|
||||
str = tr("Proxy protocol error");
|
||||
break;
|
||||
case QMQTT::SocketOperationError:
|
||||
str = tr("Operation error");
|
||||
break;
|
||||
case QMQTT::SocketSslInternalError:
|
||||
str = tr("SSL internal error");
|
||||
break;
|
||||
case QMQTT::SocketSslInvalidUserDataError:
|
||||
str = tr("Invalid SSL user data");
|
||||
break;
|
||||
case QMQTT::SocketTemporaryError:
|
||||
str = tr("Socket temprary error");
|
||||
break;
|
||||
case QMQTT::MqttUnacceptableProtocolVersionError:
|
||||
str = tr("Unacceptable MQTT protocol");
|
||||
break;
|
||||
case QMQTT::MqttIdentifierRejectedError:
|
||||
str = tr("MQTT identifier rejected");
|
||||
break;
|
||||
case QMQTT::MqttServerUnavailableError:
|
||||
str = tr("MQTT server unavailable");
|
||||
break;
|
||||
case QMQTT::MqttBadUserNameOrPasswordError:
|
||||
str = tr("Bad MQTT username or password");
|
||||
break;
|
||||
case QMQTT::MqttNotAuthorizedError:
|
||||
str = tr("MQTT authorization error");
|
||||
break;
|
||||
case QMQTT::MqttNoPingResponse:
|
||||
str = tr("MQTT no ping response");
|
||||
break;
|
||||
default:
|
||||
str = "";
|
||||
break;
|
||||
case QMQTT::UnknownError:
|
||||
str = tr("Unknown error");
|
||||
break;
|
||||
case QMQTT::SocketConnectionRefusedError:
|
||||
str = tr("Connection refused");
|
||||
break;
|
||||
case QMQTT::SocketRemoteHostClosedError:
|
||||
str = tr("Remote host closed the connection");
|
||||
break;
|
||||
case QMQTT::SocketHostNotFoundError:
|
||||
str = tr("Host not found");
|
||||
break;
|
||||
case QMQTT::SocketAccessError:
|
||||
str = tr("Socket access error");
|
||||
break;
|
||||
case QMQTT::SocketResourceError:
|
||||
str = tr("Socket resource error");
|
||||
break;
|
||||
case QMQTT::SocketTimeoutError:
|
||||
str = tr("Socket timeout");
|
||||
break;
|
||||
case QMQTT::SocketDatagramTooLargeError:
|
||||
str = tr("Socket datagram too large");
|
||||
break;
|
||||
case QMQTT::SocketNetworkError:
|
||||
str = tr("Network error");
|
||||
break;
|
||||
case QMQTT::SocketAddressInUseError:
|
||||
str = tr("Address in use");
|
||||
break;
|
||||
case QMQTT::SocketAddressNotAvailableError:
|
||||
str = tr("Address not available");
|
||||
break;
|
||||
case QMQTT::SocketUnsupportedSocketOperationError:
|
||||
str = tr("Unsupported socket operation");
|
||||
break;
|
||||
case QMQTT::SocketUnfinishedSocketOperationError:
|
||||
str = tr("Unfinished socket operation");
|
||||
break;
|
||||
case QMQTT::SocketProxyAuthenticationRequiredError:
|
||||
str = tr("Proxy authentication required");
|
||||
break;
|
||||
case QMQTT::SocketSslHandshakeFailedError:
|
||||
str = tr("SSL handshake failed");
|
||||
break;
|
||||
case QMQTT::SocketProxyConnectionRefusedError:
|
||||
str = tr("Proxy connection refused");
|
||||
break;
|
||||
case QMQTT::SocketProxyConnectionClosedError:
|
||||
str = tr("Proxy connection closed");
|
||||
break;
|
||||
case QMQTT::SocketProxyConnectionTimeoutError:
|
||||
str = tr("Proxy connection timeout");
|
||||
break;
|
||||
case QMQTT::SocketProxyNotFoundError:
|
||||
str = tr("Proxy not found");
|
||||
break;
|
||||
case QMQTT::SocketProxyProtocolError:
|
||||
str = tr("Proxy protocol error");
|
||||
break;
|
||||
case QMQTT::SocketOperationError:
|
||||
str = tr("Operation error");
|
||||
break;
|
||||
case QMQTT::SocketSslInternalError:
|
||||
str = tr("SSL internal error");
|
||||
break;
|
||||
case QMQTT::SocketSslInvalidUserDataError:
|
||||
str = tr("Invalid SSL user data");
|
||||
break;
|
||||
case QMQTT::SocketTemporaryError:
|
||||
str = tr("Socket temprary error");
|
||||
break;
|
||||
case QMQTT::MqttUnacceptableProtocolVersionError:
|
||||
str = tr("Unacceptable MQTT protocol");
|
||||
break;
|
||||
case QMQTT::MqttIdentifierRejectedError:
|
||||
str = tr("MQTT identifier rejected");
|
||||
break;
|
||||
case QMQTT::MqttServerUnavailableError:
|
||||
str = tr("MQTT server unavailable");
|
||||
break;
|
||||
case QMQTT::MqttBadUserNameOrPasswordError:
|
||||
str = tr("Bad MQTT username or password");
|
||||
break;
|
||||
case QMQTT::MqttNotAuthorizedError:
|
||||
str = tr("MQTT authorization error");
|
||||
break;
|
||||
case QMQTT::MqttNoPingResponse:
|
||||
str = tr("MQTT no ping response");
|
||||
break;
|
||||
default:
|
||||
str = "";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!str.isEmpty())
|
||||
|
@ -50,10 +50,10 @@ enum MQTTClientMode
|
||||
* Implements a simple MQTT client, which allows Serial Studio to upload received frames
|
||||
* to a MQTT broker so that other devices and/or services can make use of that
|
||||
* information. By acting as a MQTT subscriber, Serial Studio can display & process frames
|
||||
* from a remote Serial Studio instance. As you might notice, this has a lot of
|
||||
* interesting applications.
|
||||
* from a remote Serial Studio instance that is setup as a MQTT publisher. As you might
|
||||
* notice, this has a lot of interesting applications.
|
||||
*
|
||||
* For example, you can receive frames from a CanSat mission and display them allmost in
|
||||
* For example, you can receive frames from a CanSat mission and display them almost in
|
||||
* real-time in another location, such as the "ground control" centre or by the media team
|
||||
* which streams the GCS display on the internet as the mission is developing.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user