QGIS API Documentation 3.99.0-Master (21b3aa880ba)
Loading...
Searching...
No Matches
qgslayoutviewtooleditnodes.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayoutviewtooleditnodes.cpp
3 ---------------------------
4 Date : July 2017
5 Copyright : (C) 2017 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgslayout.h"
20#include "qgslayoutundostack.h"
21#include "qgslayoutview.h"
23
24#include "moc_qgslayoutviewtooleditnodes.cpp"
25
32
34{
35 if ( mNodesItem && mNodesItemIndex != -1 )
36 {
37 layout()->undoStack()->beginCommand( mNodesItem, tr( "Remove Item Node" ) );
38 if ( mNodesItem->removeNode( mNodesItemIndex ) )
39 {
41 if ( mNodesItem->nodesSize() > 0 )
42 {
43 mNodesItemIndex = mNodesItem->selectedNode();
44 // setSelectedNode( mNodesItem, mNodesItemIndex );
45 }
46 else
47 {
48 mNodesItemIndex = -1;
49 mNodesItem = nullptr;
50 }
51 if ( mNodesItem )
52 mNodesItem->update();
53 }
54 else
55 {
57 }
58 }
59}
60
62{
63 displayNodes( true );
65}
66
68{
69 if ( event->button() != Qt::LeftButton )
70 {
71 event->ignore();
72 return;
73 }
74
75 const QList<QGraphicsItem *> itemsAtCursorPos = view()->items( event->pos().x(), event->pos().y(), mMoveContentSearchRadius, mMoveContentSearchRadius );
76 if ( itemsAtCursorPos.isEmpty() )
77 return;
78
79 mNodesItemIndex = -1;
80 mNodesItem = nullptr;
81 isMoving = false;
82
83 for ( QGraphicsItem *graphicsItem : itemsAtCursorPos )
84 {
85 QgsLayoutNodesItem *item = dynamic_cast<QgsLayoutNodesItem *>( graphicsItem );
86
87 if ( item && !item->isLocked() )
88 {
89 int index = item->nodeAtPosition( event->layoutPoint() );
90 if ( index != -1 )
91 {
92 mNodesItemIndex = index;
93 mNodesItem = item;
94 mMoveContentStartPos = event->layoutPoint();
95 }
96 }
97
98 if ( mNodesItem && mNodesItemIndex != -1 )
99 {
100 layout()->undoStack()->beginCommand( mNodesItem, tr( "Move Item Node" ) );
101 setSelectedNode( mNodesItem, mNodesItemIndex );
102 isMoving = true;
103 break;
104 }
105 }
106}
107
109{
110 if ( !isMoving )
111 {
112 event->ignore();
113 return;
114 }
115
116 if ( mNodesItem && mNodesItemIndex != -1 && event->layoutPoint() != mMoveContentStartPos )
117 {
118 mNodesItem->moveNode( mNodesItemIndex, event->snappedPoint() );
119 }
120}
121
123{
124 if ( event->button() != Qt::LeftButton || !isMoving )
125 {
126 event->ignore();
127 return;
128 }
129
130 isMoving = false;
131 if ( mNodesItemIndex != -1 )
132 {
133 if ( event->layoutPoint() != mMoveContentStartPos )
134 {
136 }
137 else
138 {
140 }
141 }
142}
143
145{
146 if ( event->button() != Qt::LeftButton )
147 {
148 event->ignore();
149 return;
150 }
151
152 // erase status previously set by the mousePressEvent method
153 if ( mNodesItemIndex != -1 )
154 {
155 mNodesItem = nullptr;
156 mNodesItemIndex = -1;
157 deselectNodes();
158 }
159
160 // search items in layout
161 const QList<QGraphicsItem *> itemsAtCursorPos = view()->items( event->pos().x(), event->pos().y(), mMoveContentSearchRadius, mMoveContentSearchRadius );
162
163 if ( itemsAtCursorPos.isEmpty() )
164 return;
165
166 bool rc = false;
167 for ( QGraphicsItem *graphicsItem : itemsAtCursorPos )
168 {
169 QgsLayoutNodesItem *item = dynamic_cast<QgsLayoutNodesItem *>( graphicsItem );
170
171 if ( item && !item->isLocked() )
172 {
173 layout()->undoStack()->beginCommand( item, tr( "Add Item Node" ) );
174 rc = item->addNode( event->layoutPoint() );
175
176 if ( rc )
177 {
179 mNodesItem = item;
180 mNodesItemIndex = mNodesItem->nodeAtPosition( event->layoutPoint() );
181 }
182 else
184 }
185
186 if ( rc )
187 break;
188 }
189
190 if ( rc )
191 {
192 setSelectedNode( mNodesItem, mNodesItemIndex );
193 mNodesItem->update();
194 }
195}
196
198{
199 if ( mNodesItem && mNodesItemIndex != -1 && ( event->key() == Qt::Key_Left || event->key() == Qt::Key_Right || event->key() == Qt::Key_Up || event->key() == Qt::Key_Down ) )
200 {
201 QPointF currentPos;
202
203 if ( mNodesItem->nodePosition( mNodesItemIndex, currentPos ) )
204 {
205 QPointF delta = view()->deltaForKeyEvent( event );
206
207 currentPos.setX( currentPos.x() + delta.x() );
208 currentPos.setY( currentPos.y() + delta.y() );
209
210 layout()->undoStack()->beginCommand( mNodesItem, tr( "Move Item Node" ), QgsLayoutItem::UndoNodeMove );
211 mNodesItem->moveNode( mNodesItemIndex, currentPos );
213 layout()->update();
214 }
215 }
216 else
217 {
218 event->ignore();
219 }
220}
221
223{
224 displayNodes( false );
225 deselectNodes();
227}
228
230{
231 QList<QgsLayoutItem *> items;
232 if ( mNodesItem )
233 items << mNodesItem;
234 return items;
235}
236
237void QgsLayoutViewToolEditNodes::displayNodes( bool display )
238{
239 QList<QgsLayoutNodesItem *> nodesShapes;
240 layout()->layoutItems( nodesShapes );
241
242 for ( QgsLayoutNodesItem *item : std::as_const( nodesShapes ) )
243 {
244 item->setDisplayNodes( display );
245 item->update();
246 }
247}
248
249void QgsLayoutViewToolEditNodes::deselectNodes()
250{
251 QList<QgsLayoutNodesItem *> nodesShapes;
252 layout()->layoutItems( nodesShapes );
253
254 for ( QgsLayoutNodesItem *item : std::as_const( nodesShapes ) )
255 {
256 item->deselectNode();
257 item->update();
258 }
259}
260
261void QgsLayoutViewToolEditNodes::setSelectedNode( QgsLayoutNodesItem *shape, int index )
262{
263 QList<QgsLayoutNodesItem *> nodesShapes;
264 layout()->layoutItems( nodesShapes );
265
266 for ( QgsLayoutNodesItem *item : std::as_const( nodesShapes ) )
267 {
268 if ( item == shape )
269 {
270 item->setSelectedNode( index );
271 layout()->setSelectedItem( item );
272 item->update();
273 }
274 else
275 {
276 item->deselectNode();
277 item->update();
278 }
279 }
280}
@ UndoNodeMove
Node move.
bool isLocked() const
Returns true if the item is locked, and cannot be interacted with using the mouse.
An abstract layout item that provides generic methods for node based shapes such as polygon or polyli...
bool addNode(QPointF point, bool checkArea=true, double radius=10)
Add a node in current shape.
int nodeAtPosition(QPointF point, bool searchInRadius=true, double radius=10) const
Search for the nearest node in the shape within a maximal area.
void endCommand()
Saves final state of an object and pushes the active command to the undo history.
void cancelCommand()
Cancels the active command, discarding it without pushing to the undo history.
void beginCommand(QgsLayoutUndoObjectInterface *object, const QString &commandText, int id=0)
Begins a new undo command for the specified object.
A mouse event which is the result of a user interaction with a QgsLayoutView.
QPointF snappedPoint() const
Returns the snapped event point location in layout coordinates.
QPointF layoutPoint() const
Returns the event point location in layout coordinates.
void layoutMoveEvent(QgsLayoutViewMouseEvent *event) override
Mouse move event for overriding.
void layoutDoubleClickEvent(QgsLayoutViewMouseEvent *event) override
Mouse double-click event for overriding.
void activate() override
Called when tool is set as the currently active layout tool.
QList< QgsLayoutItem * > ignoredSnapItems() const override
Returns a list of items which should be ignored while snapping events for this tool.
void layoutPressEvent(QgsLayoutViewMouseEvent *event) override
Mouse press event for overriding.
QgsLayoutViewToolEditNodes(QgsLayoutView *view)
Constructor for QgsLayoutViewToolEditNodes.
void keyPressEvent(QKeyEvent *event) override
Key press event for overriding.
void layoutReleaseEvent(QgsLayoutViewMouseEvent *event) override
Mouse release event for overriding.
void deactivate() override
Called when tool is deactivated.
void deleteSelectedNode()
Deletes the selected node from the item.
void setCursor(const QCursor &cursor)
Sets a user defined cursor for use when the tool is active.
QgsLayoutView * view() const
Returns the view associated with the tool.
virtual void deactivate()
Called when tool is deactivated.
void setFlags(QgsLayoutViewTool::Flags flags)
Sets the combination of flags that will be used for the tool.
@ FlagSnaps
Tool utilizes snapped coordinates.
virtual void activate()
Called when tool is set as the currently active layout tool.
QgsLayout * layout() const
Returns the layout associated with the tool.
QgsLayoutViewTool(QgsLayoutView *view, const QString &name)
Constructor for QgsLayoutViewTool, taking a layout view and tool name as parameters.
A graphical widget to display and interact with QgsLayouts.
QPointF deltaForKeyEvent(QKeyEvent *event)
Returns the delta (in layout coordinates) by which to move items for the given key event.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Definition qgslayout.h:121
void setSelectedItem(QgsLayoutItem *item)
Clears any selected items and sets item as the current selection.
QgsLayoutUndoStack * undoStack()
Returns a pointer to the layout's undo stack, which manages undo/redo states for the layout and it's ...