KDStateMachineEditor API Documentation 2.1
Loading...
Searching...
No Matches
scxmlexporter.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDAB State Machine Editor Library.
3
4 SPDX-FileCopyrightText: 2014 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 Author: Kevin Funk <kevin.funk@kdab.com>
6
7 SPDX-License-Identifier: LGPL-2.1-only OR LicenseRef-KDAB-KDStateMachineEditor
8
9 Licensees holding valid commercial KDAB State Machine Editor Library
10 licenses may use this file in accordance with the KDAB State Machine Editor
11 Library License Agreement provided with the Software.
12
13 Contact info@kdab.com if any conditions of this licensing are not clear to you.
14*/
15
16#include "scxmlexporter.h"
17
18#include "objecthelper.h"
19#include "element.h"
20#include "elementutil.h"
21#include "state.h"
22#include "transition.h"
23
24#include "debug.h"
25#include <QXmlStreamWriter>
26
27using namespace KDSME;
28
29struct ScxmlExporter::Private
30{
31 Private(QByteArray *array, ScxmlExporter *q);
32 Private(QIODevice *device, ScxmlExporter *q);
33
34 void init();
35
36 bool writeStateMachine(StateMachine *machine);
37 bool writeState(State *state);
38 bool writeStateInner(State *state);
39 bool writeTransition(const Transition *transition);
40
42 QXmlStreamWriter m_writer;
43};
44
45ScxmlExporter::Private::Private(QByteArray *array, ScxmlExporter *q)
46 : q(q)
47 , m_writer(array)
48{
49 init();
50}
51
52ScxmlExporter::Private::Private(QIODevice *device, ScxmlExporter *q)
53 : q(q)
54 , m_writer(device)
55{
56 init();
57}
58
60 : d(new Private(array, this))
61{
62}
63
65 : d(new Private(device, this))
66{
67}
68
72
73void ScxmlExporter::Private::init()
74{
75 m_writer.setAutoFormatting(true);
76}
77
79{
80 setErrorString(QString());
81
82 if (!machine) {
83 setErrorString(QStringLiteral("Null machine instance passed"));
84 return false;
85 }
86
87 if (d->m_writer.hasError()) {
88 setErrorString(QStringLiteral("Setting up XML writer failed"));
89 return false;
90 }
91
92 return d->writeStateMachine(machine);
93}
94
95bool ScxmlExporter::Private::writeStateMachine(StateMachine *machine)
96{
97 Q_ASSERT(machine);
98
99
100 // TODO: Check if preconditions are met, e.g. that all state labels are unique?
101
102 m_writer.writeStartDocument();
103 m_writer.writeStartElement(QStringLiteral("scxml"));
104 m_writer.writeDefaultNamespace(QStringLiteral("http://www.w3.org/2005/07/scxml"));
105 m_writer.writeAttribute(QStringLiteral("version"), QStringLiteral("1.0"));
106 if (!writeStateInner(machine))
107 return false;
108 m_writer.writeEndElement();
109 m_writer.writeEndDocument();
110 return !m_writer.hasError();
111}
112
113bool ScxmlExporter::Private::writeState(State *state)
114{
115 if (qobject_cast<PseudoState *>(state)) {
116 return true; // pseudo states are ignored
117 }
118
119 m_writer.writeStartElement(QStringLiteral("state"));
120 if (!writeStateInner(state))
121 return false;
122 m_writer.writeEndElement();
123 return true;
124}
125
126bool ScxmlExporter::Private::writeStateInner(State *state)
127{
128 if (state->label().isEmpty()) {
129 q->setErrorString(QStringLiteral("Encountered empty label for state: %1").arg(ObjectHelper::displayString(state)));
130 return false;
131 }
132
133 if (qobject_cast<StateMachine *>(state)) {
134 m_writer.writeAttribute(QStringLiteral("name"), state->label());
135 } else {
136 m_writer.writeAttribute(QStringLiteral("id"), state->label());
137 }
138
139 if (State *initial = ElementUtil::findInitialState(state)) {
140 if (initial->label().isEmpty()) {
141 q->setErrorString(QStringLiteral("Encountered empty label for state: %1").arg(ObjectHelper::displayString(initial)));
142 return false;
143 }
144 m_writer.writeAttribute(QStringLiteral("initial"), initial->label());
145 }
146
147 const auto stateTransitions = state->transitions();
148 for (const Transition *transition : stateTransitions) {
149 writeTransition(transition);
150 }
151
152 const auto childStates = state->childStates();
153 return std::all_of(childStates.begin(), childStates.end(),
154 [this](State *child) { return writeState(child); });
155}
156
157bool ScxmlExporter::Private::writeTransition(const Transition *transition)
158{
159 m_writer.writeStartElement(QStringLiteral("transition"));
160 m_writer.writeAttribute(QStringLiteral("event"), transition->label());
161 if (const State *targetState = transition->targetState()) {
162 m_writer.writeAttribute(QStringLiteral("target"), targetState->label());
163 }
164 m_writer.writeEndElement();
165 return true;
166}
void setErrorString(const QString &errorString)
QString label
Definition element.h:40
ScxmlExporter(QByteArray *array)
virtual bool exportMachine(StateMachine *machine) override
QList< Transition * > transitions() const
Definition state.cpp:98
QList< State * > childStates() const
Definition state.cpp:93
KDSME::State * targetState
Definition transition.h:27
KDSME_CORE_EXPORT State * findInitialState(const State *state)
KDSME_CORE_EXPORT QString displayString(const QObject *object, DisplayOption option=NoStrip)

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDStateMachineEditor
Create Qt State Machine metacode using a graphical user interface
https://github.com/KDAB/KDStateMachineEditor
Generated on Tue Jul 15 2025 15:21:47 for KDStateMachineEditor API Documentation by doxygen 1.9.8