QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgslayoutviewtooladditem.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutviewtooladditem.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 "qgsapplication.h"
18 #include "qgslayoutview.h"
19 #include "qgslayout.h"
20 #include "qgslayoutitemregistry.h"
22 #include "qgslogger.h"
24 #include "qgsgui.h"
27 #include "qgssettings.h"
28 #include "qgslayoutundostack.h"
29 #include <QGraphicsRectItem>
30 #include <QPen>
31 #include <QBrush>
32 #include <QMouseEvent>
33 
35  : QgsLayoutViewTool( view, tr( "Add item" ) )
36 {
38  setCursor( Qt::CrossCursor );
39 }
40 
42 {
43  mItemMetadataId = metadataId;
44 }
45 
47 {
48  if ( event->button() != Qt::LeftButton )
49  {
50  event->ignore();
51  return;
52  }
53 
54  mDrawing = true;
55  mMousePressStartPos = event->pos();
56  mMousePressStartLayoutPos = event->layoutPoint();
57  mRubberBand.reset( QgsGui::layoutItemGuiRegistry()->createItemRubberBand( mItemMetadataId, view() ) );
58  if ( mRubberBand )
59  {
60  connect( mRubberBand.get(), &QgsLayoutViewRubberBand::sizeChanged, this, [ = ]( const QString & size )
61  {
62  view()->pushStatusMessage( size );
63  } );
64  mRubberBand->start( event->snappedPoint(), event->modifiers() );
65  }
66 }
67 
69 {
70  if ( mDrawing && mRubberBand )
71  {
72  mRubberBand->update( event->snappedPoint(), event->modifiers() );
73  }
74  else
75  {
76  event->ignore();
77  }
78 }
79 
81 {
82  if ( event->button() != Qt::LeftButton || !mDrawing )
83  {
84  event->ignore();
85  return;
86  }
87  mDrawing = false;
88 
89  QRectF rect = mRubberBand ? mRubberBand->finish( event->snappedPoint(), event->modifiers() ) : QRectF();
90 
91  QString undoText;
92  if ( QgsLayoutItemAbstractGuiMetadata *metadata = QgsGui::layoutItemGuiRegistry()->itemMetadata( mItemMetadataId ) )
93  {
94  undoText = tr( "Create %1" ).arg( metadata->visibleName() );
95  }
96  else
97  {
98  undoText = tr( "Create Item" );
99  }
100  layout()->undoStack()->beginMacro( undoText );
101 
102  QgsLayoutItem *item = QgsGui::layoutItemGuiRegistry()->createItem( mItemMetadataId, layout() );
103  if ( !item )
104  {
105  layout()->undoStack()->endMacro();
106  return;
107  }
108 
109  // click? or click-and-drag?
110  bool clickOnly = !isClickAndDrag( mMousePressStartPos, event->pos() );
111  if ( clickOnly && mRubberBand )
112  {
114  dlg.setLayout( layout() );
115  dlg.setItemPosition( QgsLayoutPoint( event->snappedPoint(), layout()->units() ) );
116  if ( dlg.exec() )
117  {
118  item->setReferencePoint( dlg.referencePoint() );
119  item->attemptResize( dlg.itemSize() );
120  item->attemptMove( dlg.itemPosition(), true, false, dlg.page() );
121  }
122  else
123  {
124  delete item;
125  layout()->undoStack()->endMacro();
126  return;
127  }
128  }
129  else if ( mRubberBand )
130  {
131  item->attemptResize( QgsLayoutSize( rect.width(), rect.height(), QgsUnitTypes::LayoutMillimeters ) );
132  item->attemptMove( QgsLayoutPoint( rect.left(), rect.top(), QgsUnitTypes::LayoutMillimeters ) );
133  }
134  else
135  {
136  // item type doesn't use rubber bands -- e.g. marker items
137  item->attemptMove( QgsLayoutPoint( mMousePressStartLayoutPos, layout()->units() ) );
138  }
139 
140  // record last created item size
141  if ( mRubberBand )
142  {
143  QgsSettings settings;
144  settings.setValue( QStringLiteral( "LayoutDesigner/lastItemWidth" ), item->sizeWithUnits().width() );
145  settings.setValue( QStringLiteral( "LayoutDesigner/lastItemHeight" ), item->sizeWithUnits().height() );
146  settings.setEnumValue( QStringLiteral( "LayoutDesigner/lastSizeUnit" ), item->sizeWithUnits().units() );
147  }
148 
149  QgsGui::layoutItemGuiRegistry()->newItemAddedToLayout( mItemMetadataId, item );
150 
151  // it's possible (in certain circumstances, e.g. when adding frame items) that this item
152  // has already been added to the layout
153  if ( item->scene() != layout() )
154  layout()->addLayoutItem( item );
155  layout()->setSelectedItem( item );
156 
157  layout()->undoStack()->endMacro();
158  emit createdItem();
159 }
160 
162 {
163  if ( mDrawing )
164  {
165  // canceled mid operation
166  if ( mRubberBand )
167  mRubberBand->finish();
168  mDrawing = false;
169  }
171 }
172 
174 {
175  return mItemMetadataId;
176 }
QgsLayoutItemGuiRegistry::newItemAddedToLayout
void newItemAddedToLayout(int metadataId, QgsLayoutItem *item)
Called when a newly created item of the associated metadata metadataId has been added to a layout.
Definition: qgslayoutitemguiregistry.cpp:98
QgsLayout::addLayoutItem
void addLayoutItem(QgsLayoutItem *item)
Adds an item to the layout.
Definition: qgslayout.cpp:540
QgsLayout::undoStack
QgsLayoutUndoStack * undoStack()
Returns a pointer to the layout's undo stack, which manages undo/redo states for the layout and it's ...
Definition: qgslayout.cpp:686
qgslayoutundostack.h
QgsLayoutSize::width
double width() const
Returns the width of the size.
Definition: qgslayoutsize.h:76
QgsLayoutSize::units
QgsUnitTypes::LayoutUnit units() const
Returns the units for the size.
Definition: qgslayoutsize.h:103
QgsLayout::setSelectedItem
void setSelectedItem(QgsLayoutItem *item)
Clears any selected items and sets item as the current selection.
Definition: qgslayout.cpp:159
QgsLayoutViewTool::FlagSnaps
@ FlagSnaps
Tool utilizes snapped coordinates.
Definition: qgslayoutviewtool.h:65
qgsgui.h
QgsLayoutUndoStack::endMacro
void endMacro()
Ends a macro command.
Definition: qgslayoutundostack.cpp:36
qgslayoutview.h
QgsLayoutViewTool::setFlags
void setFlags(QgsLayoutViewTool::Flags flags)
Sets the combination of flags that will be used for the tool.
Definition: qgslayoutviewtool.cpp:64
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QgsLayoutViewToolAddItem::layoutPressEvent
void layoutPressEvent(QgsLayoutViewMouseEvent *event) override
Mouse press event for overriding.
Definition: qgslayoutviewtooladditem.cpp:46
qgslayoutviewmouseevent.h
QgsLayoutViewRubberBand::sizeChanged
void sizeChanged(const QString &size)
Emitted when the size of the rubber band is changed.
QgsLayoutItem::sizeWithUnits
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
Definition: qgslayoutitem.h:671
QgsLayoutViewTool::deactivate
virtual void deactivate()
Called when tool is deactivated.
Definition: qgslayoutviewtool.cpp:130
qgslayoutnewitempropertiesdialog.h
QgsLayoutItemPropertiesDialog::setLayout
void setLayout(QgsLayout *layout)
Sets the layout associated with the dialog.
Definition: qgslayoutnewitempropertiesdialog.cpp:182
QgsLayoutViewToolAddItem::deactivate
void deactivate() override
Called when tool is deactivated.
Definition: qgslayoutviewtooladditem.cpp:161
QgsLayoutItemPropertiesDialog::setItemPosition
void setItemPosition(QgsLayoutPoint position)
Sets the item position to show in the dialog.
Definition: qgslayoutnewitempropertiesdialog.cpp:62
QgsLayoutItemPropertiesDialog::page
int page() const
Returns the page number for the new item.
Definition: qgslayoutnewitempropertiesdialog.cpp:82
qgsapplication.h
QgsLayoutViewToolAddItem::QgsLayoutViewToolAddItem
QgsLayoutViewToolAddItem(QgsLayoutView *view)
Constructs a QgsLayoutViewToolAddItem for the given layout view.
Definition: qgslayoutviewtooladditem.cpp:34
qgslayoutviewrubberband.h
QgsLayoutItemPropertiesDialog::itemPosition
QgsLayoutPoint itemPosition() const
Returns the current item position defined by the dialog.
Definition: qgslayoutnewitempropertiesdialog.cpp:77
QgsLayoutItemPropertiesDialog::referencePoint
QgsLayoutItem::ReferencePoint referencePoint() const
Returns the item reference point defined by the dialog.
Definition: qgslayoutnewitempropertiesdialog.cpp:99
QgsSettings::setEnumValue
void setEnumValue(const QString &key, const T &value, const Section section=NoSection)
Set the value of a setting based on an enum.
Definition: qgssettings.h:304
QgsLayoutViewToolAddItem::layoutMoveEvent
void layoutMoveEvent(QgsLayoutViewMouseEvent *event) override
Mouse move event for overriding.
Definition: qgslayoutviewtooladditem.cpp:68
qgslayoutitemguiregistry.h
QgsLayoutViewToolAddItem::itemMetadataId
int itemMetadataId() const
Returns the item metadata id for items created by the tool.
Definition: qgslayoutviewtooladditem.cpp:173
QgsLayoutViewTool::view
QgsLayoutView * view() const
Returns the view associated with the tool.
Definition: qgslayoutviewtool.cpp:38
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:289
QgsLayoutItem
Base class for graphical items within a QgsLayout.
Definition: qgslayoutitem.h:113
QgsLayoutViewTool::layout
QgsLayout * layout() const
Returns the layout associated with the tool.
Definition: qgslayoutviewtool.cpp:43
QgsLayoutViewMouseEvent::snappedPoint
QPointF snappedPoint() const
Returns the snapped event point location in layout coordinates.
Definition: qgslayoutviewmouseevent.h:78
QgsLayoutItemGuiRegistry::createItem
QgsLayoutItem * createItem(int metadataId, QgsLayout *layout) const
Creates a new instance of a layout item given the item metadata metadataId, target layout.
Definition: qgslayoutitemguiregistry.cpp:85
qgslayout.h
QgsLayoutUndoStack::beginMacro
void beginMacro(const QString &commandText)
Starts a macro command, with the given descriptive commandText.
Definition: qgslayoutundostack.cpp:30
QgsLayoutViewToolAddItem::setItemMetadataId
void setItemMetadataId(int metadataId)
Sets the item metadata metadataId for items created by the tool.
Definition: qgslayoutviewtooladditem.cpp:41
QgsLayoutViewToolAddItem::layoutReleaseEvent
void layoutReleaseEvent(QgsLayoutViewMouseEvent *event) override
Mouse release event for overriding.
Definition: qgslayoutviewtooladditem.cpp:80
QgsLayoutSize::height
double height() const
Returns the height of the size.
Definition: qgslayoutsize.h:90
QgsLayoutItem::attemptMove
virtual void attemptMove(const QgsLayoutPoint &point, bool useReferencePoint=true, bool includesFrame=false, int page=-1)
Attempts to move the item to a specified point.
Definition: qgslayoutitem.cpp:466
QgsLayoutItem::setReferencePoint
void setReferencePoint(ReferencePoint point)
Sets the reference point for positioning of the layout item.
Definition: qgslayoutitem.cpp:414
QgsLayoutViewTool::isClickAndDrag
bool isClickAndDrag(QPoint startViewPoint, QPoint endViewPoint) const
Returns true if a mouse press/release operation which started at startViewPoint and ended at endViewP...
Definition: qgslayoutviewtool.cpp:31
QgsLayoutItemPropertiesDialog::itemSize
QgsLayoutSize itemSize() const
Returns the item size defined by the dialog.
Definition: qgslayoutnewitempropertiesdialog.cpp:94
QgsLayoutViewTool
Abstract base class for all layout view tools.
Definition: qgslayoutviewtool.h:47
QgsLayoutItemAbstractGuiMetadata
Stores GUI metadata about one layout item class.
Definition: qgslayoutitemguiregistry.h:47
qgssettings.h
QgsLayoutItem::attemptResize
virtual void attemptResize(const QgsLayoutSize &size, bool includesFrame=false)
Attempts to resize the item to a specified target size.
Definition: qgslayoutitem.cpp:428
QgsLayoutView
A graphical widget to display and interact with QgsLayouts.
Definition: qgslayoutview.h:50
QgsLayoutSize
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
Definition: qgslayoutsize.h:41
QgsUnitTypes::LayoutMillimeters
@ LayoutMillimeters
Millimeters.
Definition: qgsunittypes.h:182
qgslogger.h
qgslayoutviewtooladditem.h
QgsLayoutViewTool::setCursor
void setCursor(const QCursor &cursor)
Sets a user defined cursor for use when the tool is active.
Definition: qgslayoutviewtool.cpp:115
QgsLayoutPoint
This class provides a method of storing points, consisting of an x and y coordinate,...
Definition: qgslayoutpoint.h:40
QgsLayoutViewMouseEvent
A QgsLayoutViewMouseEvent is the result of a user interaction with the mouse on a QgsLayoutView.
Definition: qgslayoutviewmouseevent.h:36
qgslayoutitemregistry.h
QgsGui::layoutItemGuiRegistry
static QgsLayoutItemGuiRegistry * layoutItemGuiRegistry()
Returns the global layout item GUI registry, used for registering the GUI behavior of layout items.
Definition: qgsgui.cpp:99
QgsLayoutViewToolAddItem::createdItem
void createdItem()
Emitted when an item has been created using the tool.
QgsLayoutItemPropertiesDialog
A dialog for configuring properties like the size and position of layout items.
Definition: qgslayoutnewitempropertiesdialog.h:37