KDStateMachineEditor API Documentation 2.1
Loading...
Searching...
No Matches
editcontroller.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 "editcontroller.h"
18
20#include "command_p.h"
21#include "state.h"
22#include "transition.h"
23#include "layoutimportexport.h"
24#include "kdsmeconstants.h"
26#include "statemachinescene.h"
27
28#include <QUrl>
29#include "debug.h"
30#include <QJsonDocument>
31#include <QJsonObject>
32
33using namespace KDSME;
34
35struct EditController::Private
36{
37 Private();
38
39 bool m_editModeEnabled;
40};
41
42EditController::Private::Private()
43 : m_editModeEnabled(false)
44{
45}
46
48 : AbstractController(parent)
49 , d(new Private)
50{
51}
52
56
58{
59 return d->m_editModeEnabled;
60}
61
62void EditController::setEditModeEnabled(bool editModeEnabled)
63{
64 if (d->m_editModeEnabled == editModeEnabled)
65 return;
66
67 d->m_editModeEnabled = editModeEnabled;
68 Q_EMIT editModeEnabledChanged(d->m_editModeEnabled);
69}
70
71bool EditController::sendDragEnterEvent(Element *sender, Element *target, const QPoint &pos, const QList<QUrl> &urls) // clazy:exclude=function-args-by-value
72{
73 Q_UNUSED(pos);
74
75 qCDebug(KDSME_VIEW) << "sender=" << sender << "target=" << target << "pos=" << pos << "urls=" << urls;
76
77 // For the case a Transition is dragged onto a State that
78 // State will turns into the new source/target of the transition.
79 if (qobject_cast<Transition *>(sender)) {
80 return qobject_cast<State *>(target);
81 }
82
83 // No sender means we expect a URL to be given.
84 if (urls.isEmpty()) {
85 qCDebug(KDSME_VIEW) << "No urls";
86 return false;
87 }
88
89 // we only accept one item only for now
90 const QUrl &url = urls.first();
91 if (url.scheme() != QStringLiteral(KDSME_QML_URI_PREFIX)) {
92 qCDebug(KDSME_VIEW) << "Unexpected Url Schema=" << url.scheme();
93 return false;
94 }
95
96 return true;
97}
98
99// TODO should we probably either move that command to kdstatemachine/commands
100// for reuse or even extend the existing CreateElementCommand to set optionally
101// an initial position/geometry?
102class CreateAndPositionCommand : public Command
103{
104 Q_OBJECT
105public:
106 CreateAndPositionCommand(StateMachineScene *view, Element::Type type, Element *targetElement, QPointF pos)
107 : Command(view->stateModel())
108 , m_view(view)
109 , m_createcmd(new CreateElementCommand(view->stateModel(), type))
110 , m_pos(pos)
111 {
112 m_createcmd->setParentElement(targetElement);
113 setText(m_createcmd->text());
114 }
115 void redo() override
116 {
117 // save the current layout
118 Q_ASSERT(m_view->rootState());
119 const QJsonDocument doc(LayoutImportExport::exportLayout(m_view->rootState()));
120
121 m_createcmd->redo();
122
123 Element *element = m_createcmd->createdElement();
124 if (!element) // creating the element failed, abort here
125 return;
126
127 LayoutImportExport::importLayout(doc.object(), m_view->rootState());
128
129 // move the new element to its position and set a sane initial size
130 ModifyElementCommand poscmd(element);
131 QPointF pos = m_pos;
132 const QSizeF size = element->preferredSize();
133 if (size.width() > 0)
134 pos.setX(qMax<qreal>(0, pos.x() - size.width() / 2));
135 if (size.height() > 0)
136 pos.setY(qMax<qreal>(0, pos.y() - size.height() / 2));
137 poscmd.setGeometry(QRectF(pos, size));
138 poscmd.redo();
139
140 // Mark the new Element as current one what means the item is selected
141 // as if a user clicked on it.
142 m_view->setCurrentItem(element);
143 }
144 void undo() override
145 {
146 m_createcmd->undo();
147 }
148
149private:
150 StateMachineScene *m_view;
151 QScopedPointer<CreateElementCommand> m_createcmd;
152 QPointF m_pos;
153};
154
155bool EditController::sendDropEvent(Element *sender, Element *target, const QPoint &pos, const QList<QUrl> &urls) // clazy:exclude=function-args-by-value
156{
157 Q_UNUSED(sender);
158 Q_UNUSED(pos);
159
160 qCDebug(KDSME_VIEW) << "sender=" << sender << "target=" << target << "pos=" << pos << "urls=" << urls;
161
162 if (urls.isEmpty()) {
163 qCDebug(KDSME_VIEW) << "No urls";
164 return false;
165 }
166
167 // we only accept one item only for now
168 const QUrl &url = urls.first();
169 if (url.scheme() != QStringLiteral(KDSME_QML_URI_PREFIX)) {
170 qCDebug(KDSME_VIEW) << "Unexpected Url Schema=" << url.scheme();
171 return false;
172 }
173
174 const QString str = url.toString(QUrl::RemoveScheme);
175 const QString typeString = str.split(u'/').last();
176 if (typeString.isEmpty())
177 return false;
178
179 const Element::Type type = Element::stringToType(qPrintable(typeString));
180
181 // TODO: Try to decouple more
182 auto view = stateMachineView()->scene();
183 auto *cmd = new CreateAndPositionCommand(view, type, target, QPointF(pos));
185
186 return true;
187}
188
189#include "editcontroller.moc"
KDSME::StateMachineView * stateMachineView
void editModeEnabledChanged(bool editModeEnabled)
EditController(StateMachineView *parent=nullptr)
bool sendDragEnterEvent(KDSME::Element *sender, KDSME::Element *target, const QPoint &pos, const QList< QUrl > &urls)
bool sendDropEvent(KDSME::Element *sender, KDSME::Element *target, const QPoint &pos, const QList< QUrl > &urls)
void setEditModeEnabled(bool editModeEnabled)
static Q_INVOKABLE KDSME::Element::Type stringToType(const char *type)
Definition element.cpp:234
QSizeF preferredSize() const
Definition element.cpp:173
Command for modifying properties of KDSME::Element.
Widget for displaying a KDSME::StateMachine in a Qt Quick based view.
KDSME::StateMachineScene * scene
Q_INVOKABLE void sendCommand(KDSME::Command *cmd) const
#define KDSME_QML_URI_PREFIX
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.

© 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