55#include " ConnectionIdHash.hpp"
66#include " Definitions.hpp"
77#include " Export.hpp"
8+ #include " GroupGraphicsObject.hpp"
9+ #include " NodeGroup.hpp"
10+ #include " UndoCommands.hpp"
811
9- #include " QUuidStdHash.hpp"
10-
11- #include < QtCore/QUuid>
12+ #include < QtCore/QJsonObject>
1213#include < QtWidgets/QGraphicsScene>
1314#include < QtWidgets/QMenu>
1415
@@ -27,6 +28,11 @@ class AbstractNodePainter;
2728class ConnectionGraphicsObject ;
2829class NodeGraphicsObject ;
2930class NodeStyle ;
31+ class DeleteCommand ;
32+ class CopyCommand ;
33+ class NodeGroup ;
34+ class GroupGraphicsObject ;
35+ struct ConnectionId ;
3036
3137// / An instance of QGraphicsScene, holds connections and nodes.
3238class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
@@ -62,6 +68,17 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
6268
6369 QUndoStack &undoStack ();
6470
71+ /* *
72+ * @brief Setter for the _groupingEnabled flag.
73+ * @param boolean to set or not the flag.
74+ */
75+ void setGroupingEnabled (bool enabled);
76+
77+ /* *
78+ * @brief Getter for the _groupingEnabled flag.
79+ */
80+ bool groupingEnabled () const { return _groupingEnabled; }
81+
6582public:
6683 /* *
6784 * @brief Creates a "draft" instance of ConnectionGraphicsObject.
@@ -87,6 +104,83 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
87104 // / Deletes all the nodes. Connections are removed automatically.
88105 void clearScene ();
89106
107+ /* *
108+ * @brief Creates a list of the connections that are incident only to nodes within a
109+ * given group.
110+ * @param groupID ID of the desired group.
111+ * @return List of (pointers of) connections whose both endpoints belong to members of
112+ * the specified group.
113+ */
114+ std::vector<std::shared_ptr<ConnectionId>> connectionsWithinGroup (GroupId groupID);
115+ /* *
116+ * @brief Creates a group in the scene containing the given nodes.
117+ * @param nodes Reference to the list of nodes to be included in the group.
118+ * @param name Group's name.
119+ * @param groupId Group's id.
120+ * @return Pointer to the newly-created group.
121+ */
122+ std::weak_ptr<NodeGroup> createGroup (std::vector<NodeGraphicsObject *> &nodes,
123+ QString name = QStringLiteral(" " ),
124+ GroupId groupId = InvalidGroupId);
125+
126+ /* *
127+ * @brief Creates a group in the scene containing the currently selected nodes.
128+ * @param name Group's name
129+ * @return Pointer to the newly-created group.
130+ */
131+ std::weak_ptr<NodeGroup> createGroupFromSelection (QString groupName = QStringLiteral(" " ));
132+
133+ /* *
134+ * @brief Restores a group from a JSON object.
135+ * @param groupJson JSON object containing the group data.
136+ * @return Pair consisting of a pointer to the newly-created group and the mapping
137+ * between old and new nodes.
138+ */
139+ std::pair<std::weak_ptr<NodeGroup>, std::unordered_map<GroupId, GroupId>> restoreGroup (
140+ QJsonObject const &groupJson);
141+
142+ /* *
143+ * @brief Returns a const reference to the mapping of existing groups.
144+ */
145+ std::unordered_map<GroupId, std::shared_ptr<NodeGroup>> const &groups () const ;
146+
147+ /* *
148+ * @brief Loads a group from a file specified by the user.
149+ * @return Pointer to the newly-created group.
150+ */
151+ std::weak_ptr<NodeGroup> loadGroupFile ();
152+
153+ /* *
154+ * @brief Saves a group in a .group file.
155+ * @param groupID Group's id.
156+ */
157+ void saveGroupFile (GroupId groupID);
158+
159+ /* *
160+ * @brief Calculates the selected nodes.
161+ * @return Vector containing the NodeGraphicsObject pointers related to the selected nodes.
162+ */
163+ std::vector<NodeGraphicsObject *> selectedNodes () const ;
164+
165+ /* *
166+ * @brief Calculates the selected groups.
167+ * @return Vector containing the GroupGraphicsObject pointers related to the selected groups.
168+ */
169+ std::vector<GroupGraphicsObject *> selectedGroups () const ;
170+
171+ /* *
172+ * @brief Adds a node to a group, if both node and group exists.
173+ * @param nodeId Node's id.
174+ * @param groupId Group's id.
175+ */
176+ void addNodeToGroup (NodeId nodeId, GroupId groupId);
177+
178+ /* *
179+ * @brief Removes a node from a group, if the node exists and is within a group.
180+ * @param nodeId Node's id.
181+ */
182+ void removeNodeFromGroup (NodeId nodeId);
183+
90184public:
91185 /* *
92186 * @returns NodeGraphicsObject associated with the given nodeId.
@@ -111,6 +205,17 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
111205 */
112206 virtual QMenu *createSceneMenu (QPointF const scenePos);
113207
208+ /* *
209+ * @brief Creates the default menu when a node is selected.
210+ */
211+ QMenu *createStdMenu (QPointF const scenePos);
212+
213+ /* *
214+ * @brief Creates the menu when a group is selected.
215+ * @param groupGo reference to the GroupGraphicsObject related to the selected group.
216+ */
217+ QMenu *createGroupMenu (QPointF const scenePos, GroupGraphicsObject *groupGo);
218+
114219Q_SIGNALS:
115220 void modified (BasicGraphicsScene *);
116221 void nodeMoved (NodeId const nodeId, QPointF const &newLocation);
@@ -141,6 +246,24 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
141246 // / Redraws adjacent nodes for given `connectionId`
142247 void updateAttachedNodes (ConnectionId const connectionId, PortType const portType);
143248
249+ /* *
250+ * @brief Loads a JSON object that represents a node, with the option
251+ * to keep the stored node id or generate a new one.
252+ * @param nodeJson The JSON object representing a node.
253+ * @param keepOriginalId If true, the loaded node will have the same id as the one stored in
254+ * the file; otherwise, a new id will be generated
255+ * @return A reference to the NodeGraphicsObject related to the loaded node.
256+ */
257+ NodeGraphicsObject &loadNodeToMap (QJsonObject nodeJson, bool keepOriginalId = false );
258+
259+ /* *
260+ * @brief Loads a connection between nodes from a JSON file.
261+ * @param connectionJson JSON object that stores the connection's endpoints.
262+ * @param nodeIdMap Map of nodes (i.e. all possible endpoints).
263+ */
264+ void loadConnectionToMap (QJsonObject const &connectionJson,
265+ std::unordered_map<NodeId, NodeId> const &nodeIdMap);
266+
144267public Q_SLOTS:
145268 // / Slot called when the `connectionId` is erased form the AbstractGraphModel.
146269 virtual void onConnectionDeleted (ConnectionId const connectionId);
@@ -155,21 +278,37 @@ public Q_SLOTS:
155278 virtual void onNodeClicked (NodeId const nodeId);
156279 virtual void onModelReset ();
157280
281+ /* *
282+ * @brief Slot called to trigger the copy command action.
283+ */
284+ void onCopySelectedObjects () { undoStack ().push (new CopyCommand (this )); }
285+
286+ /* *
287+ * @brief Slot called to trigger the delete command action.
288+ */
289+ void onDeleteSelectedObjects () { undoStack ().push (new DeleteCommand (this )); }
290+
158291private:
159292 AbstractGraphModel &_graphModel;
160293
161294 using UniqueNodeGraphicsObject = std::unique_ptr<NodeGraphicsObject>;
162295 using UniqueConnectionGraphicsObject = std::unique_ptr<ConnectionGraphicsObject>;
296+ using SharedGroup = std::shared_ptr<NodeGroup>;
163297
164298 std::unordered_map<NodeId, UniqueNodeGraphicsObject> _nodeGraphicsObjects;
165299 std::unordered_map<ConnectionId, UniqueConnectionGraphicsObject> _connectionGraphicsObjects;
300+ GroupId nextGroupId ();
301+
302+ std::unordered_map<GroupId, SharedGroup> _groups{};
303+ GroupId _nextGroupId{0 };
166304 std::unique_ptr<ConnectionGraphicsObject> _draftConnection;
167305 std::unique_ptr<AbstractNodeGeometry> _nodeGeometry;
168306 std::unique_ptr<AbstractNodePainter> _nodePainter;
169307 std::unique_ptr<AbstractConnectionPainter> _connectionPainter;
170308 bool _nodeDrag;
171309 QUndoStack *_undoStack;
172310 Qt::Orientation _orientation;
311+ bool _groupingEnabled;
173312};
174313
175314} // namespace QtNodes
0 commit comments