QGIS API Documentation 3.41.0-Master (fda2aa46e9a)
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#include "moc_qgslayoutviewtooleditnodes.cpp"
19#include "qgslayoutview.h"
20#include "qgslayout.h"
22#include "qgslayoutundostack.h"
23
30
32{
33 if ( mNodesItem && mNodesItemIndex != -1 )
34 {
35 layout()->undoStack()->beginCommand( mNodesItem, tr( "Remove Item Node" ) );
36 if ( mNodesItem->removeNode( mNodesItemIndex ) )
37 {
39 if ( mNodesItem->nodesSize() > 0 )
40 {
41 mNodesItemIndex = mNodesItem->selectedNode();
42 // setSelectedNode( mNodesItem, mNodesItemIndex );
43 }
44 else
45 {
46 mNodesItemIndex = -1;
47 mNodesItem = nullptr;
48 }
49 if ( mNodesItem )
50 mNodesItem->update();
51 }
52 else
53 {
55 }
56 }
57}
58
60{
61 displayNodes( true );
63}
64
66{
67 if ( event->button() != Qt::LeftButton )
68 {
69 event->ignore();
70 return;
71 }
72
73 const QList<QGraphicsItem *> itemsAtCursorPos = view()->items( event->pos().x(), event->pos().y(),
74 mMoveContentSearchRadius,
75 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(),
162 mMoveContentSearchRadius,
163 mMoveContentSearchRadius );
164
165 if ( itemsAtCursorPos.isEmpty() )
166 return;
167
168 bool rc = false;
169 for ( QGraphicsItem *graphicsItem : itemsAtCursorPos )
170 {
171 QgsLayoutNodesItem *item = dynamic_cast<QgsLayoutNodesItem *>( graphicsItem );
172
173 if ( item && !item->isLocked() )
174 {
175 layout()->undoStack()->beginCommand( item, tr( "Add Item Node" ) );
176 rc = item->addNode( event->layoutPoint() );
177
178 if ( rc )
179 {
181 mNodesItem = item;
182 mNodesItemIndex = mNodesItem->nodeAtPosition( event->layoutPoint() );
183 }
184 else
186 }
187
188 if ( rc )
189 break;
190 }
191
192 if ( rc )
193 {
194 setSelectedNode( mNodesItem, mNodesItemIndex );
195 mNodesItem->update();
196 }
197}
198
200{
201 if ( mNodesItem && mNodesItemIndex != -1 && ( event->key() == Qt::Key_Left
202 || event->key() == Qt::Key_Right
203 || event->key() == Qt::Key_Up
204 || event->key() == Qt::Key_Down ) )
205 {
206 QPointF currentPos;
207
208 if ( mNodesItem->nodePosition( mNodesItemIndex, currentPos ) )
209 {
210 QPointF delta = view()->deltaForKeyEvent( event );
211
212 currentPos.setX( currentPos.x() + delta.x() );
213 currentPos.setY( currentPos.y() + delta.y() );
214
215 layout()->undoStack()->beginCommand( mNodesItem, tr( "Move Item Node" ), QgsLayoutItem::UndoNodeMove );
216 mNodesItem->moveNode( mNodesItemIndex, currentPos );
218 layout()->update();
219 }
220 }
221 else
222 {
223 event->ignore();
224 }
225}
226
228{
229 displayNodes( false );
230 deselectNodes();
232}
233
235{
236 QList< QgsLayoutItem * > items;
237 if ( mNodesItem )
238 items << mNodesItem;
239 return items;
240}
241
242void QgsLayoutViewToolEditNodes::displayNodes( bool display )
243{
244 QList<QgsLayoutNodesItem *> nodesShapes;
245 layout()->layoutItems( nodesShapes );
246
247 for ( QgsLayoutNodesItem *item : std::as_const( nodesShapes ) )
248 {
249 item->setDisplayNodes( display );
250 item->update();
251 }
252}
253
254void QgsLayoutViewToolEditNodes::deselectNodes()
255{
256 QList<QgsLayoutNodesItem *> nodesShapes;
257 layout()->layoutItems( nodesShapes );
258
259 for ( QgsLayoutNodesItem *item : std::as_const( nodesShapes ) )
260 {
261 item->deselectNode();
262 item->update();
263 }
264}
265
266void QgsLayoutViewToolEditNodes::setSelectedNode( QgsLayoutNodesItem *shape, int index )
267{
268 QList<QgsLayoutNodesItem *> nodesShapes;
269 layout()->layoutItems( nodesShapes );
270
271 for ( QgsLayoutNodesItem *item : std::as_const( nodesShapes ) )
272 {
273 if ( item == shape )
274 {
275 item->setSelectedNode( index );
276 layout()->setSelectedItem( item );
277 item->update();
278 }
279 else
280 {
281 item->deselectNode();
282 item->update();
283 }
284 }
285
286}
287
@ 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 QgsLayoutViewMouseEvent is the result of a user interaction with the mouse on 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.
Abstract base class for all layout view tools.
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.
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:120
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 ...