27#include <QPainterPath>
35QJsonObject stateLayoutToJson(
const State *state)
38 res[u
"label"] = state->
label();
39 res[u
"x"] = state->
pos().x();
40 res[u
"y"] = state->
pos().y();
41 res[u
"width"] = state->
width();
42 res[u
"height"] = state->
height();
46QJsonObject transitionLayoutToJson(
const Transition *transition)
49 res[u
"label"] = transition->
label();
50 res[u
"x"] = transition->
pos().x();
51 res[u
"y"] = transition->
pos().y();
54 lbr[u
"x"] = labelRect.x();
55 lbr[u
"y"] = labelRect.y();
56 lbr[u
"width"] = labelRect.width();
57 lbr[u
"height"] = labelRect.height();
58 res[u
"labelBoundingRect"] = lbr;
60 QDataStream ds(&shapeData, QIODevice::WriteOnly);
61 ds << transition->
shape();
62 res[u
"shape"] = QLatin1String(shapeData.toBase64());
66void importStateLayout(
const QJsonObject &data,
State *state)
68 const auto x = data.find(u
"x");
72 const auto y = data.find(u
"y");
76 const auto width = data.find(u
"width");
77 if (width == data.end())
80 const auto height = data.find(u
"height");
81 if (height == data.end())
84 state->
setPos(QPointF((*x).toDouble(), (*y).toDouble()));
85 state->
setWidth((*width).toDouble());
89bool isValidState(
const QJsonObject &data,
const State *state)
91 return data.value(u
"label") == state->
label() && data.contains(u
"x") && data.contains(u
"y") && data.contains(u
"width") && data.contains(u
"height");
94bool isValidTransition(
const QJsonObject &data,
const Transition *state)
96 return data.value(u
"label") == state->
label() && data.contains(u
"x") && data.contains(u
"y") && data.contains(u
"labelBoundingRect") && data.contains(u
"shape");
99void importTransitionLayout(
const QJsonObject &data,
Transition *transition)
101 const auto x = data.find(u
"x");
105 const auto y = data.find(u
"y");
109 const auto lbrIt = data.find(u
"labelBoundingRect");
110 if (lbrIt == data.end())
113 const auto shape = data.find(u
"shape");
114 if (shape == data.end())
117 transition->
setPos(QPointF((*x).toDouble(), (*y).toDouble()));
118 QJsonObject lbr = (*lbrIt).toObject();
120 lbr[u
"y"].toDouble(),
121 lbr[u
"width"].toDouble(),
122 lbr[u
"height"].toDouble()));
123 QByteArray shapeData = QByteArray::fromBase64((*shape).toString().toLatin1());
124 QPainterPath shapePath;
125 QDataStream ds(&shapeData, QIODevice::ReadOnly);
134 importStateLayout(data, state);
136 const QJsonArray states = data.value(u
"childStates").toArray();
137 for (
int i = 0; i < states.size() && i < state->childStates().size(); ++i) {
142 const QJsonArray transitions = data.value(u
"transitions").toArray();
143 for (
int i = 0; i < transitions.size() && i < state->transitions().size(); ++i) {
145 importTransitionLayout(transitions.at(i).toObject(), child);
151 QJsonObject res = stateLayoutToJson(state);
155 for (
const State *child : childStates) {
158 res[u
"childStates"] = states;
160 QJsonArray transitions;
161 const auto stateTransitions = state->
transitions();
162 for (
const Transition *child : stateTransitions) {
163 transitions.push_back(transitionLayoutToJson(child));
165 res[u
"transitions"] = transitions;
172 if (!isValidState(data, state))
175 const QJsonArray states = data.value(u
"childStates").toArray();
179 for (
int i = 0; i < states.size(); ++i) {
181 if (!
matches(states.at(i).toObject(), child))
185 const QJsonArray transitions = data.value(u
"transitions").toArray();
186 if (transitions.size() != state->
transitions().size())
189 for (
int i = 0; i < transitions.size(); ++i) {
191 if (!isValidTransition(transitions.at(i).toObject(), child))
void setPos(const QPointF &pos)
QPointF pos
The position of the element from the top-left corner.
void setWidth(qreal width)
void setHeight(qreal height)
QList< Transition * > transitions() const
QList< State * > childStates() const
void setShape(const QPainterPath &shape)
void setLabelBoundingRect(const QRectF &rect)
QPainterPath shape
The exact shape of this transition.
KDSME_CORE_EXPORT void importLayout(const QJsonObject &data, State *state)
Import layout data to set properties of state and its children.
KDSME_CORE_EXPORT QJsonObject exportLayout(const State *state)
Export layout of state into a machine-parsable JSON format.
KDSME_CORE_EXPORT bool matches(const QJsonObject &data, State *state)
Check if the ids in data still match the ids from the object tree represented by state.