Skip to content

Commit 5d5c858

Browse files
committedNov 7, 2017
Start restoring grids/overviews
1 parent 7f0142c commit 5d5c858

21 files changed

+6069
-247
lines changed
 

‎python/core/core_auto.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@
409409
%Include layout/qgslayoutitem.sip
410410
%Include layout/qgslayoutitemgroup.sip
411411
%Include layout/qgslayoutitemmap.sip
412+
%Include layout/qgslayoutitemmapgrid.sip
413+
%Include layout/qgslayoutitemmapitem.sip
414+
%Include layout/qgslayoutitemmapoverview.sip
412415
%Include layout/qgslayoutitemnodeitem.sip
413416
%Include layout/qgslayoutitempage.sip
414417
%Include layout/qgslayoutitempolygon.sip

‎python/core/layout/qgslayoutitem.sip

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
5252

5353
enum UndoCommand
5454
{
55+
UndoNone,
5556
UndoIncrementalMove,
5657
UndoIncrementalResize,
5758
UndoStrokeColor,
@@ -550,6 +551,30 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
550551
\param factor zoom factor, where > 1 results in a zoom in and < 1 results in a zoom out
551552
\param point item point for zoom center
552553
.. seealso:: moveContent()
554+
%End
555+
556+
void beginCommand( const QString &commandText, UndoCommand command = UndoNone );
557+
%Docstring
558+
Starts new undo command for this item.
559+
The ``commandText`` should be a capitalized, imperative tense description (e.g. "Add Map Item").
560+
If specified, multiple consecutive commands for this item with the same ``command`` will
561+
be collapsed into a single undo command in the layout history.
562+
.. seealso:: endCommand()
563+
.. seealso:: cancelCommand()
564+
%End
565+
566+
void endCommand();
567+
%Docstring
568+
Completes the current item command and push it onto the layout's undo stack.
569+
.. seealso:: beginCommand()
570+
.. seealso:: cancelCommand()
571+
%End
572+
573+
void cancelCommand();
574+
%Docstring
575+
Cancels the current item command and discards it.
576+
.. seealso:: beginCommand()
577+
.. seealso:: endCommand()
553578
%End
554579

555580
public slots:

‎python/core/layout/qgslayoutitemmap.sip

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,41 @@ Returns true if the map contains layers with blend modes or flattened layers for
370370
.. seealso:: atlasMargin
371371
%End
372372

373+
QgsLayoutItemMapGridStack *grids();
374+
%Docstring
375+
Returns the map item's grid stack, which is used to control how grids
376+
are drawn over the map's contents.
377+
.. seealso:: grid()
378+
:rtype: QgsLayoutItemMapGridStack
379+
%End
380+
381+
QgsLayoutItemMapGrid *grid();
382+
%Docstring
383+
Returns the map item's first grid. This is a convenience function.
384+
.. seealso:: grids()
385+
:rtype: QgsLayoutItemMapGrid
386+
%End
387+
388+
QgsLayoutItemMapOverviewStack *overviews();
389+
%Docstring
390+
Returns the map item's overview stack, which is used to control how overviews
391+
are drawn over the map's contents.
392+
:return: pointer to overview stack
393+
.. seealso:: overview()
394+
:rtype: QgsLayoutItemMapOverviewStack
395+
%End
396+
397+
QgsLayoutItemMapOverview *overview();
398+
%Docstring
399+
Returns the map item's first overview. This is a convenience function.
400+
:return: pointer to first overview for map item
401+
.. seealso:: overviews()
402+
:rtype: QgsLayoutItemMapOverview
403+
%End
404+
405+
virtual QgsExpressionContext createExpressionContext() const;
406+
407+
373408
protected:
374409

375410
virtual void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = 0 );
@@ -389,13 +424,9 @@ True if a draw is already in progress
389424

390425

391426

392-
393427
virtual QRectF boundingRect() const;
394428

395429

396-
virtual QgsExpressionContext createExpressionContext() const;
397-
398-
399430
double mapUnitsToLayoutUnits() const;
400431
%Docstring
401432
Returns the conversion factor from map units to layout units.
@@ -404,7 +435,6 @@ True if a draw is already in progress
404435
:rtype: float
405436
%End
406437

407-
408438
QPolygonF transformedMapPolygon() const;
409439
%Docstring
410440
Returns extent that considers rotation and shift with mOffsetX / mOffsetY

‎python/core/layout/qgslayoutitemmapgrid.sip

Lines changed: 765 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/layout/qgslayoutitemmapitem.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
class QgsLayoutItemMapItem : QgsLayoutObject
13+
{
14+
%Docstring
15+
An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
16+
.. versionadded:: 3.0
17+
%End
18+
19+
%TypeHeaderCode
20+
#include "qgslayoutitemmapitem.h"
21+
%End
22+
public:
23+
24+
QgsLayoutItemMapItem( const QString &name, QgsLayoutItemMap *map );
25+
%Docstring
26+
Constructor for QgsLayoutItemMapItem, attached to the specified ``map``.
27+
28+
The ``name`` argument gives a friendly display name for the item.
29+
%End
30+
31+
virtual void draw( QPainter *painter ) = 0;
32+
%Docstring
33+
Draws the item on to a destination ``painter``.
34+
%End
35+
36+
virtual bool writeXml( QDomElement &element, QDomDocument &document ) const;
37+
%Docstring
38+
Stores map item state in a DOM element, where ``element`` is the DOM element
39+
corresponding to a 'LayoutMap' tag.
40+
.. seealso:: readXml()
41+
:rtype: bool
42+
%End
43+
44+
virtual bool readXml( const QDomElement &element, const QDomDocument &doc );
45+
%Docstring
46+
Sets the map item state from a DOM document, where ``element`` is the DOM
47+
node corresponding to a 'LayoutMapGrid' tag.
48+
.. seealso:: writeXml()
49+
:rtype: bool
50+
%End
51+
52+
void setMap( QgsLayoutItemMap *map );
53+
%Docstring
54+
Sets the corresponding layout ``map`` for the item.
55+
.. seealso:: map()
56+
%End
57+
58+
const QgsLayoutItemMap *map() const;
59+
%Docstring
60+
Returns the layout item map for the item.
61+
.. seealso:: setMap()
62+
:rtype: QgsLayoutItemMap
63+
%End
64+
65+
QString id() const;
66+
%Docstring
67+
Returns the unique id for the map item.
68+
:rtype: str
69+
%End
70+
71+
void setName( const QString &name );
72+
%Docstring
73+
Sets the friendly display ``name`` for the item.
74+
.. seealso:: name()
75+
%End
76+
77+
QString name() const;
78+
%Docstring
79+
Returns the friendly display name for the item.
80+
.. seealso:: setName()
81+
:rtype: str
82+
%End
83+
84+
void setEnabled( bool enabled );
85+
%Docstring
86+
Controls whether the item will be drawn. Set ``enabled`` to true to enable drawing of the item.
87+
.. seealso:: enabled()
88+
%End
89+
90+
bool enabled() const;
91+
%Docstring
92+
Returns whether the item will be drawn.
93+
.. seealso:: setEnabled()
94+
:rtype: bool
95+
%End
96+
97+
virtual bool usesAdvancedEffects() const;
98+
%Docstring
99+
Returns true if the item is drawn using advanced effects, such as blend modes.
100+
:rtype: bool
101+
%End
102+
103+
protected:
104+
105+
106+
107+
108+
109+
};
110+
111+
112+
113+
class QgsLayoutItemMapItemStack
114+
{
115+
%Docstring
116+
A collection of map items which are drawn above the map content in a
117+
QgsLayoutItemMap. The item stack controls which items are drawn and the
118+
order they are drawn in.
119+
.. versionadded:: 3.0
120+
.. seealso:: QgsLayoutItemMapItem
121+
%End
122+
123+
%TypeHeaderCode
124+
#include "qgslayoutitemmapitem.h"
125+
%End
126+
public:
127+
128+
QgsLayoutItemMapItemStack( QgsLayoutItemMap *map );
129+
%Docstring
130+
Constructor for QgsLayoutItemMapItemStack, attached to the
131+
specified ``map``.
132+
%End
133+
134+
virtual ~QgsLayoutItemMapItemStack();
135+
136+
int size() const;
137+
%Docstring
138+
Returns the number of items in the stack.
139+
:rtype: int
140+
%End
141+
142+
virtual bool writeXml( QDomElement &element, QDomDocument &doc ) const;
143+
%Docstring
144+
Stores the state of the item stack in a DOM node, where ``element`` is the DOM element corresponding to a 'LayoutMap' tag.
145+
Returns true if write was successful.
146+
.. seealso:: readXml()
147+
:rtype: bool
148+
%End
149+
150+
virtual bool readXml( const QDomElement &element, const QDomDocument &doc ) = 0;
151+
%Docstring
152+
Sets the item stack's state from a DOM document, where ``element`` is a DOM node corresponding to a 'LayoutMap' tag.
153+
Returns true if read was successful.
154+
.. seealso:: writeXml()
155+
:rtype: bool
156+
%End
157+
158+
void drawItems( QPainter *painter );
159+
%Docstring
160+
Draws the items from the stack on a specified ``painter``.
161+
%End
162+
163+
bool containsAdvancedEffects() const;
164+
%Docstring
165+
Returns whether any items within the stack contain advanced effects,
166+
such as blending modes.
167+
:rtype: bool
168+
%End
169+
170+
protected:
171+
172+
void addItem( QgsLayoutItemMapItem *item /Transfer/ );
173+
%Docstring
174+
Adds a new map item to the stack and takes ownership of the item.
175+
The item will be added to the end of the stack, and rendered
176+
above any existing map items already present in the stack.
177+
.. note::
178+
179+
After adding an item to the stack update()
180+
should be called for the QgsLayoutItemMap to prevent rendering artifacts.
181+
.. seealso:: removeItem()
182+
%End
183+
184+
void removeItem( const QString &itemId );
185+
%Docstring
186+
Removes an item which matching ``itemId`` from the stack and deletes the corresponding QgsLayoutItemMapItem
187+
.. note::
188+
189+
After removing an item from the stack, update()
190+
should be called for the QgsLayoutItemMap to prevent rendering artifacts.
191+
.. seealso:: addItem()
192+
%End
193+
194+
void moveItemUp( const QString &itemId );
195+
%Docstring
196+
Moves an item which matching ``itemId`` up the stack, causing it to be rendered above other items.
197+
.. note::
198+
199+
After moving an item within the stack, update() should be
200+
called for the QgsLayoutItemMap to redraw the map with the new item stack order.
201+
.. seealso:: moveItemDown()
202+
%End
203+
204+
void moveItemDown( const QString &itemId );
205+
%Docstring
206+
Moves an item which matching ``itemId`` up the stack, causing it to be rendered above other items.
207+
.. note::
208+
209+
After moving an item within the stack, update() should be
210+
called for the QgsLayoutItemMap to redraw the map with the new item stack order.
211+
.. seealso:: moveItemUp()
212+
%End
213+
214+
QgsLayoutItemMapItem *item( const QString &itemId ) const;
215+
%Docstring
216+
Returns a reference to an item which matching ``itemId`` within the stack.
217+
.. seealso:: constItem()
218+
:rtype: QgsLayoutItemMapItem
219+
%End
220+
221+
QgsLayoutItemMapItem *item( int index ) const;
222+
%Docstring
223+
Returns a reference to the item at the specified ``index`` within the stack.
224+
.. seealso:: constItem
225+
:rtype: QgsLayoutItemMapItem
226+
%End
227+
228+
229+
QList< QgsLayoutItemMapItem * > asList() const;
230+
%Docstring
231+
Returns a list of QgsLayoutItemMapItems contained by the stack.
232+
:rtype: list of QgsLayoutItemMapItem
233+
%End
234+
235+
protected:
236+
237+
238+
239+
void removeItems();
240+
%Docstring
241+
Clears the item stack and deletes all QgsLayoutItemMapItems contained
242+
by the stack
243+
%End
244+
};
245+
246+
247+
/************************************************************************
248+
* This file has been generated automatically from *
249+
* *
250+
* src/core/layout/qgslayoutitemmapitem.h *
251+
* *
252+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
253+
************************************************************************/
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/layout/qgslayoutitemmapoverview.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
13+
class QgsLayoutItemMapOverviewStack : QgsLayoutItemMapItemStack
14+
{
15+
%Docstring
16+
A collection of overviews which are drawn above the map content in a
17+
QgsLayoutItemMap. The overview stack controls which overviews are drawn and the
18+
order they are drawn in.
19+
.. versionadded:: 3.0
20+
.. seealso:: QgsLayoutItemMapOverview
21+
%End
22+
23+
%TypeHeaderCode
24+
#include "qgslayoutitemmapoverview.h"
25+
%End
26+
public:
27+
28+
QgsLayoutItemMapOverviewStack( QgsLayoutItemMap *map );
29+
%Docstring
30+
Constructor for QgsLayoutItemMapOverviewStack, attached to the specified
31+
``map``.
32+
%End
33+
34+
void addOverview( QgsLayoutItemMapOverview *overview /Transfer/ );
35+
%Docstring
36+
Adds a new map ``overview`` to the stack and takes ownership of the overview.
37+
The overview will be added to the end of the stack, and rendered
38+
above any existing map overviews already present in the stack.
39+
.. note::
40+
41+
After adding a overview to the stack, update()
42+
should be called for the QgsLayoutItemMap to prevent rendering artifacts.
43+
.. seealso:: removeOverview()
44+
%End
45+
46+
void removeOverview( const QString &overviewId );
47+
%Docstring
48+
Removes an overview with matching overviewId from the stack and deletes the corresponding QgsLayoutItemMapOverview
49+
.. note::
50+
51+
After removing an overview from the stack, update()
52+
should be called for the QgsLayoutItemMap to prevent rendering artifacts.
53+
.. seealso:: addOverview()
54+
%End
55+
56+
void moveOverviewUp( const QString &overviewId );
57+
%Docstring
58+
Moves an overview with matching overviewId up the stack, causing it to be rendered above other overviews.
59+
.. note::
60+
61+
After moving an overview within the stack, update() should be
62+
called for the QgsLayoutItemMap to redraw the map with the new overview stack order.
63+
.. seealso:: moveOverviewDown()
64+
%End
65+
66+
void moveOverviewDown( const QString &overviewId );
67+
%Docstring
68+
Moves an overview with matching overviewId down the stack, causing it to be rendered below other overviews.
69+
.. note::
70+
71+
After moving an overview within the stack, update() should be
72+
called for the QgsLayoutItemMap to redraw the map with the new overview stack order.
73+
.. seealso:: moveOverviewUp()
74+
%End
75+
76+
QgsLayoutItemMapOverview *overview( const QString &overviewId ) const;
77+
%Docstring
78+
Returns a reference to an overview with matching overviewId within the stack.
79+
.. seealso:: constOverview()
80+
:rtype: QgsLayoutItemMapOverview
81+
%End
82+
83+
QgsLayoutItemMapOverview *overview( const int index ) const;
84+
%Docstring
85+
Returns a reference to an overview at the specified ``index`` within the stack.
86+
.. seealso:: constOverview()
87+
:rtype: QgsLayoutItemMapOverview
88+
%End
89+
90+
QgsLayoutItemMapOverview &operator[]( int index );
91+
92+
QList< QgsLayoutItemMapOverview * > asList() const;
93+
%Docstring
94+
Returns a list of QgsLayoutItemMapOverviews contained by the stack.
95+
:rtype: list of QgsLayoutItemMapOverview
96+
%End
97+
virtual bool readXml( const QDomElement &elem, const QDomDocument &doc );
98+
99+
100+
};
101+
102+
class QgsLayoutItemMapOverview : QgsLayoutItemMapItem
103+
{
104+
%Docstring
105+
An individual overview which is drawn above the map content in a
106+
QgsLayoutItemMap, and shows the extent of another QgsLayoutItemMap.
107+
.. versionadded:: 3.0
108+
.. seealso:: QgsLayoutItemMapOverviewStack
109+
%End
110+
111+
%TypeHeaderCode
112+
#include "qgslayoutitemmapoverview.h"
113+
%End
114+
public:
115+
116+
QgsLayoutItemMapOverview( const QString &name, QgsLayoutItemMap *map );
117+
%Docstring
118+
Constructor for QgsLayoutItemMapOverview.
119+
\param name friendly display name for overview
120+
\param map QgsLayoutItemMap the overview is attached to
121+
%End
122+
123+
virtual void draw( QPainter *painter );
124+
125+
virtual bool writeXml( QDomElement &elem, QDomDocument &doc ) const;
126+
127+
virtual bool readXml( const QDomElement &itemElem, const QDomDocument &doc );
128+
129+
virtual bool usesAdvancedEffects() const;
130+
131+
132+
void setFrameMapUuid( const QString &uuid );
133+
%Docstring
134+
Sets overview frame map ``uuid``. Set an empty ``uuid`` to disable
135+
the overview frame.
136+
.. seealso:: frameMapUuid()
137+
.. seealso:: setFrameMap()
138+
%End
139+
140+
QString frameMapUuid() const;
141+
%Docstring
142+
Returns the uuid of source map, or an empty string if no map set.
143+
.. seealso:: setFrameMapUuid()
144+
.. seealso:: frameMap()
145+
:rtype: str
146+
%End
147+
148+
void setFrameMap( QgsLayoutItemMap *map );
149+
%Docstring
150+
Sets the ``map`` to show the overview extent of.
151+
.. seealso:: frameMap()
152+
%End
153+
154+
QgsLayoutItemMap *frameMap();
155+
%Docstring
156+
Returns the source map to show the overview extent of.
157+
.. seealso:: setFrameMap()
158+
:rtype: QgsLayoutItemMap
159+
%End
160+
161+
void setFrameSymbol( QgsFillSymbol *symbol /Transfer/ );
162+
%Docstring
163+
Sets the fill ``symbol`` used for drawing the overview extent. Ownership
164+
is transferred to the overview.
165+
.. seealso:: frameSymbol()
166+
%End
167+
168+
QgsFillSymbol *frameSymbol();
169+
%Docstring
170+
Returns the fill symbol used for drawing the overview extent.
171+
.. seealso:: setFrameSymbol()
172+
:rtype: QgsFillSymbol
173+
%End
174+
175+
QPainter::CompositionMode blendMode() const;
176+
%Docstring
177+
Retrieves the blending mode used for drawing the overview.
178+
.. seealso:: setBlendMode()
179+
:rtype: QPainter.CompositionMode
180+
%End
181+
182+
void setBlendMode( const QPainter::CompositionMode mode );
183+
%Docstring
184+
Sets the blending ``mode`` used for drawing the overview.
185+
.. seealso:: blendMode()
186+
%End
187+
188+
bool inverted() const;
189+
%Docstring
190+
Returns whether the overview frame is inverted, ie, whether the shaded area is drawn outside
191+
the extent of the overview map.
192+
.. seealso:: setInverted()
193+
:rtype: bool
194+
%End
195+
196+
void setInverted( const bool inverted );
197+
%Docstring
198+
Sets whether the overview frame is ``inverted``, ie, whether the shaded area is drawn outside
199+
the extent of the overview map.
200+
.. seealso:: inverted()
201+
%End
202+
203+
bool centered() const;
204+
%Docstring
205+
Returns whether the extent of the map is forced to center on the overview.
206+
.. seealso:: setCentered()
207+
:rtype: bool
208+
%End
209+
210+
void setCentered( const bool centered );
211+
%Docstring
212+
Sets whether the extent of the map is forced to center on the overview
213+
.. seealso:: centered()
214+
%End
215+
216+
void connectSignals();
217+
%Docstring
218+
Reconnects signals for overview map, so that overview correctly follows changes to source
219+
map's extent.
220+
%End
221+
222+
public slots:
223+
224+
void overviewExtentChanged();
225+
%Docstring
226+
Handles recentering of the map and redrawing of the map's overview
227+
%End
228+
229+
};
230+
231+
/************************************************************************
232+
* This file has been generated automatically from *
233+
* *
234+
* src/core/layout/qgslayoutitemmapoverview.h *
235+
* *
236+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
237+
************************************************************************/

‎python/core/layout/qgslayoututils.sip

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ class QgsLayoutUtils
8787
:rtype: float
8888
%End
8989

90-
9190
};
9291

9392
/************************************************************************

‎src/app/layout/qgslayoutmapwidget.cpp

Lines changed: 109 additions & 143 deletions
Large diffs are not rendered by default.

‎src/app/layout/qgslayoutmapwidget.h

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020

2121
#include "ui_qgslayoutmapwidgetbase.h"
2222
#include "qgslayoutitemwidget.h"
23+
#include "qgslayoutitemmapgrid.h"
2324

2425
class QgsMapLayer;
2526
class QgsLayoutItemMap;
26-
class QgsLayoutMapGrid;
27-
class QgsLayoutMapOverview;
27+
class QgsLayoutItemMapOverview;
2828

2929
/**
3030
* \ingroup app
@@ -46,7 +46,7 @@ class QgsLayoutMapWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutM
4646
void mKeepLayerListCheckBox_stateChanged( int state );
4747
void mKeepLayerStylesCheckBox_stateChanged( int state );
4848
void mDrawCanvasItemsCheckBox_stateChanged( int state );
49-
void overviewMapChanged( QgsComposerItem *item );
49+
void overviewMapChanged( QgsLayoutItem *item );
5050
void mOverviewFrameStyleButton_clicked();
5151
void mOverviewBlendModeComboBox_currentIndexChanged( int index );
5252
void mOverviewInvertCheckbox_toggled( bool state );
@@ -69,7 +69,7 @@ class QgsLayoutMapWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutM
6969
void mGridUpButton_clicked();
7070
void mGridDownButton_clicked();
7171

72-
QgsLayoutMapGrid *currentGrid();
72+
QgsLayoutItemMapGrid *currentGrid();
7373
void mDrawGridCheckBox_toggled( bool state );
7474
void mGridListWidget_currentItemChanged( QListWidgetItem *current, QListWidgetItem *previous );
7575
void mGridListWidget_itemChanged( QListWidgetItem *item );
@@ -80,12 +80,12 @@ class QgsLayoutMapWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutM
8080
void mRemoveOverviewPushButton_clicked();
8181
void mOverviewUpButton_clicked();
8282
void mOverviewDownButton_clicked();
83-
QgsLayoutMapOverview *currentOverview();
83+
QgsLayoutItemMapOverview *currentOverview();
8484
void mOverviewCheckBox_toggled( bool state );
8585
void mOverviewListWidget_currentItemChanged( QListWidgetItem *current, QListWidgetItem *previous );
8686
void mOverviewListWidget_itemChanged( QListWidgetItem *item );
8787
void setOverviewItemsEnabled( bool enabled );
88-
void setOverviewItems( const QgsLayoutMapOverview *overview );
88+
void setOverviewItems( QgsLayoutItemMapOverview *overview );
8989
void blockOverviewItemsSignals( bool block );
9090

9191
protected:
@@ -130,23 +130,21 @@ class QgsLayoutMapWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutM
130130

131131
void rotationChanged( double value );
132132

133-
#if 0 //TODO
134-
void handleChangedFrameDisplay( QgsComposerMapGrid::BorderSide border, const QgsComposerMapGrid::DisplayMode mode );
135-
void handleChangedAnnotationDisplay( QgsComposerMapGrid::BorderSide border, const QString &text );
136-
void handleChangedAnnotationPosition( QgsComposerMapGrid::BorderSide border, const QString &text );
137-
void handleChangedAnnotationDirection( QgsComposerMapGrid::BorderSide border, QgsComposerMapGrid::AnnotationDirection direction );
138-
#endif
133+
void handleChangedFrameDisplay( QgsLayoutItemMapGrid::BorderSide border, const QgsLayoutItemMapGrid::DisplayMode mode );
134+
void handleChangedAnnotationDisplay( QgsLayoutItemMapGrid::BorderSide border, const QString &text );
135+
void handleChangedAnnotationPosition( QgsLayoutItemMapGrid::BorderSide border, const QString &text );
136+
void handleChangedAnnotationDirection( QgsLayoutItemMapGrid::BorderSide border, QgsLayoutItemMapGrid::AnnotationDirection direction );
137+
139138
void insertFrameDisplayEntries( QComboBox *c );
140139
void insertAnnotationDisplayEntries( QComboBox *c );
141140
void insertAnnotationPositionEntries( QComboBox *c );
142141
void insertAnnotationDirectionEntries( QComboBox *c );
143142

144-
#if 0 //TODO
145-
void initFrameDisplayBox( QComboBox *c, QgsComposerMapGrid::DisplayMode display );
146-
void initAnnotationDisplayBox( QComboBox *c, QgsComposerMapGrid::DisplayMode display );
147-
void initAnnotationPositionBox( QComboBox *c, QgsComposerMapGrid::AnnotationPosition pos );
148-
void initAnnotationDirectionBox( QComboBox *c, QgsComposerMapGrid::AnnotationDirection dir );
149-
#endif
143+
void initFrameDisplayBox( QComboBox *c, QgsLayoutItemMapGrid::DisplayMode display );
144+
void initAnnotationDisplayBox( QComboBox *c, QgsLayoutItemMapGrid::DisplayMode display );
145+
void initAnnotationPositionBox( QComboBox *c, QgsLayoutItemMapGrid::AnnotationPosition pos );
146+
void initAnnotationDirectionBox( QComboBox *c, QgsLayoutItemMapGrid::AnnotationDirection dir );
147+
150148
//! Enables or disables the atlas margin and predefined scales radio depending on the atlas coverage layer type
151149
void toggleAtlasScalingOptionsByLayerType();
152150

@@ -164,7 +162,7 @@ class QgsLayoutMapWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutM
164162

165163
void loadOverviewEntries();
166164

167-
void updateOverviewFrameSymbolMarker( const QgsLayoutMapOverview *overview );
165+
void updateOverviewFrameSymbolMarker( const QgsLayoutItemMapOverview *overview );
168166

169167
void storeCurrentLayerSet();
170168

‎src/core/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@ SET(QGIS_CORE_SRCS
370370
layout/qgslayoutitemgroup.cpp
371371
layout/qgslayoutitemgroupundocommand.cpp
372372
layout/qgslayoutitemmap.cpp
373+
layout/qgslayoutitemmapgrid.cpp
374+
layout/qgslayoutitemmapitem.cpp
375+
layout/qgslayoutitemmapoverview.cpp
373376
layout/qgslayoutitemnodeitem.cpp
374377
layout/qgslayoutitempage.cpp
375378
layout/qgslayoutitempolygon.cpp
@@ -725,6 +728,9 @@ SET(QGIS_CORE_MOC_HDRS
725728
layout/qgslayoutitemgroup.h
726729
layout/qgslayoutitemgroupundocommand.h
727730
layout/qgslayoutitemmap.h
731+
layout/qgslayoutitemmapgrid.h
732+
layout/qgslayoutitemmapitem.h
733+
layout/qgslayoutitemmapoverview.h
728734
layout/qgslayoutitemnodeitem.h
729735
layout/qgslayoutitempage.h
730736
layout/qgslayoutitempolygon.h

‎src/core/layout/qgslayoutitem.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,26 @@ void QgsLayoutItem::zoomContent( double, QPointF )
812812

813813
}
814814

815+
void QgsLayoutItem::beginCommand( const QString &commandText, UndoCommand command )
816+
{
817+
if ( !mLayout )
818+
return;
819+
820+
mLayout->undoStack()->beginCommand( this, commandText, command );
821+
}
822+
823+
void QgsLayoutItem::endCommand()
824+
{
825+
if ( mLayout )
826+
mLayout->undoStack()->endCommand();
827+
}
828+
829+
void QgsLayoutItem::cancelCommand()
830+
{
831+
if ( mLayout )
832+
mLayout->undoStack()->cancelCommand();
833+
}
834+
815835
QgsLayoutPoint QgsLayoutItem::applyDataDefinedPosition( const QgsLayoutPoint &position )
816836
{
817837
if ( !mLayout )

‎src/core/layout/qgslayoutitem.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
8585
//! Layout item undo commands, used for collapsing undo commands
8686
enum UndoCommand
8787
{
88+
UndoNone = -1, //!< No command suppression
8889
UndoIncrementalMove = 1, //!< Layout item incremental movement, e.g. as a result of a keypress
8990
UndoIncrementalResize, //!< Incremental resize
9091
UndoStrokeColor, //!< Stroke color adjustment
@@ -550,6 +551,30 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
550551
*/
551552
virtual void zoomContent( double factor, QPointF point );
552553

554+
/**
555+
* Starts new undo command for this item.
556+
* The \a commandText should be a capitalized, imperative tense description (e.g. "Add Map Item").
557+
* If specified, multiple consecutive commands for this item with the same \a command will
558+
* be collapsed into a single undo command in the layout history.
559+
* \see endCommand()
560+
* \see cancelCommand()
561+
*/
562+
void beginCommand( const QString &commandText, UndoCommand command = UndoNone );
563+
564+
/**
565+
* Completes the current item command and push it onto the layout's undo stack.
566+
* \see beginCommand()
567+
* \see cancelCommand()
568+
*/
569+
void endCommand();
570+
571+
/**
572+
* Cancels the current item command and discards it.
573+
* \see beginCommand()
574+
* \see endCommand()
575+
*/
576+
void cancelCommand();
577+
553578
public slots:
554579

555580
/**

‎src/core/layout/qgslayoutitemmap.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ bool QgsLayoutItemMap::containsWmsLayer() const
385385
bool QgsLayoutItemMap::containsAdvancedEffects() const
386386
{
387387
//check easy things first
388-
#if 0 //TODO
388+
389389
//overviews
390390
if ( mOverviewStack->containsAdvancedEffects() )
391391
{
@@ -397,7 +397,6 @@ bool QgsLayoutItemMap::containsAdvancedEffects() const
397397
{
398398
return true;
399399
}
400-
#endif
401400

402401
QgsMapSettings ms;
403402
ms.setLayers( layersToRender() );
@@ -456,6 +455,26 @@ double QgsLayoutItemMap::atlasMargin( const QgsLayoutObject::PropertyValueType v
456455
}
457456
}
458457

458+
QgsLayoutItemMapGrid *QgsLayoutItemMap::grid()
459+
{
460+
if ( mGridStack->size() < 1 )
461+
{
462+
QgsLayoutItemMapGrid *grid = new QgsLayoutItemMapGrid( tr( "Grid %1" ).arg( 1 ), this );
463+
mGridStack->addGrid( grid );
464+
}
465+
return mGridStack->grid( 0 );
466+
}
467+
468+
QgsLayoutItemMapOverview *QgsLayoutItemMap::overview()
469+
{
470+
if ( mOverviewStack->size() < 1 )
471+
{
472+
QgsLayoutItemMapOverview *overview = new QgsLayoutItemMapOverview( tr( "Overview %1" ).arg( 1 ), this );
473+
mOverviewStack->addOverview( overview );
474+
}
475+
return mOverviewStack->overview( 0 );
476+
}
477+
459478
void QgsLayoutItemMap::draw( QgsRenderContext &, const QStyleOptionGraphicsItem * )
460479
{
461480
}
@@ -555,7 +574,6 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
555574

556575
painter->setClipRect( thisPaintRect, Qt::NoClip );
557576

558-
#if 0 //TODO
559577
if ( shouldDrawPart( OverviewMapExtent ) )
560578
{
561579
mOverviewStack->drawItems( painter );
@@ -564,7 +582,6 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
564582
{
565583
mGridStack->drawItems( painter );
566584
}
567-
#endif
568585

569586
//draw canvas items
570587
drawAnnotations( painter );
@@ -801,13 +818,7 @@ QPolygonF QgsLayoutItemMap::transformedMapPolygon() const
801818
{
802819
double dx = mXOffset;
803820
double dy = mYOffset;
804-
//qWarning("offset");
805-
//qWarning(QString::number(dx).toLocal8Bit().data());
806-
//qWarning(QString::number(dy).toLocal8Bit().data());
807821
transformShift( dx, dy );
808-
//qWarning("transformed:");
809-
//qWarning(QString::number(dx).toLocal8Bit().data());
810-
//qWarning(QString::number(dy).toLocal8Bit().data());
811822
QPolygonF poly = visibleExtentPolygon();
812823
poly.translate( -dx, -dy );
813824
return poly;
@@ -874,10 +885,8 @@ void QgsLayoutItemMap::updateBoundingRect()
874885
double bottomExtension = 0.0;
875886
double leftExtension = 0.0;
876887

877-
#if 0 //TODO
878888
if ( mGridStack )
879889
mGridStack->calculateMaxGridExtension( topExtension, rightExtension, bottomExtension, leftExtension );
880-
#endif
881890

882891
topExtension = std::max( topExtension, frameExtension );
883892
rightExtension = std::max( rightExtension, frameExtension );

‎src/core/layout/qgslayoutitemmap.h

Lines changed: 41 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "qgslayoutitemregistry.h"
2323
#include "qgsmaplayerref.h"
2424
#include "qgsmaprenderercustompainterjob.h"
25+
#include "qgslayoutitemmapgrid.h"
26+
#include "qgslayoutitemmapoverview.h"
2527

2628
class QgsAnnotation;
2729

@@ -364,6 +366,36 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
364366
*/
365367
void setAtlasMargin( double margin ) { mAtlasMargin = margin; }
366368

369+
/**
370+
* Returns the map item's grid stack, which is used to control how grids
371+
* are drawn over the map's contents.
372+
* \see grid()
373+
*/
374+
QgsLayoutItemMapGridStack *grids() { return mGridStack.get(); }
375+
376+
/**
377+
* Returns the map item's first grid. This is a convenience function.
378+
* \see grids()
379+
*/
380+
QgsLayoutItemMapGrid *grid();
381+
382+
/**
383+
* Returns the map item's overview stack, which is used to control how overviews
384+
* are drawn over the map's contents.
385+
* \returns pointer to overview stack
386+
* \see overview()
387+
*/
388+
QgsLayoutItemMapOverviewStack *overviews() { return mOverviewStack.get(); }
389+
390+
/**
391+
* Returns the map item's first overview. This is a convenience function.
392+
* \returns pointer to first overview for map item
393+
* \see overviews()
394+
*/
395+
QgsLayoutItemMapOverview *overview();
396+
397+
QgsExpressionContext createExpressionContext() const override;
398+
367399
protected:
368400

369401
void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = nullptr ) override;
@@ -376,23 +408,13 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
376408
//! True if a draw is already in progress
377409
bool isDrawing() const {return mDrawing;}
378410

379-
#if 0
380-
//! Sets new scene rectangle bounds and recalculates hight and extent
381-
void setSceneRect( const QRectF &rectangle ) override;
382-
411+
#if 0 //TODO
383412

384413
/**
385414
* Sets new Extent for the current atlas preview and changes width, height (and implicitly also scale).
386415
Atlas preview extents are only temporary, and are regenerated whenever the atlas feature changes
387416
*/
388417
void setNewAtlasFeatureExtent( const QgsRectangle &extent );
389-
#endif
390-
391-
#if 0
392-
QgsRectangle extent() const {return mExtent;}
393-
#endif
394-
395-
#if 0
396418

397419
/**
398420
* Stores state in Dom node
@@ -407,64 +429,19 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
407429
* \param doc is Dom document
408430
*/
409431
bool readXml( const QDomElement &itemElem, const QDomDocument &doc ) override;
410-
411-
/**
412-
* Returns the map item's grid stack, which is used to control how grids
413-
* are drawn over the map's contents.
414-
* \returns pointer to grid stack
415-
* \see grid()
416-
*/
417-
QgsComposerMapGridStack *grids() { return mGridStack; }
418-
419-
/**
420-
* Returns the map item's first grid. This is a convenience function.
421-
* \returns pointer to first grid for map item
422-
* \see grids()
423-
*/
424-
QgsComposerMapGrid *grid();
425-
426-
/**
427-
* Returns the map item's overview stack, which is used to control how overviews
428-
* are drawn over the map's contents.
429-
* \returns pointer to overview stack
430-
* \see overview()
431-
*/
432-
QgsComposerMapOverviewStack *overviews() { return mOverviewStack; }
433-
434-
/**
435-
* Returns the map item's first overview. This is a convenience function.
436-
* \returns pointer to first overview for map item
437-
* \see overviews()
438-
*/
439-
QgsComposerMapOverview *overview();
440432
#endif
441433

434+
442435
// In case of annotations, the bounding rectangle can be larger than the map item rectangle
443436
QRectF boundingRect() const override;
444437

445-
#if 0
446-
// reimplement setFrameStrokeWidth, so that updateBoundingRect() is called after setting the frame width
447-
virtual void setFrameStrokeWidth( const double strokeWidth ) override;
448-
#endif
449-
QgsExpressionContext createExpressionContext() const override;
450-
451438
/**
452439
* Returns the conversion factor from map units to layout units.
453440
* This is calculated using the width of the map item and the width of the
454441
* current visible map extent.
455442
*/
456443
double mapUnitsToLayoutUnits() const;
457444

458-
#if 0
459-
460-
/**
461-
* Get the number of layers that this item requires for exporting as layers
462-
* \returns 0 if this item is to be placed on the same layer as the previous item,
463-
* 1 if it should be placed on its own layer, and >1 if it requires multiple export layers
464-
*/
465-
int numberExportLayers() const override;
466-
#endif
467-
468445
//! Returns extent that considers rotation and shift with mOffsetX / mOffsetY
469446
QPolygonF transformedMapPolygon() const;
470447

@@ -513,11 +490,10 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
513490

514491
//! Unique identifier
515492
int mMapId = 1;
516-
#if 0
517-
QgsComposerMapGridStack *mGridStack = nullptr;
518493

519-
QgsComposerMapOverviewStack *mOverviewStack = nullptr;
520-
#endif
494+
std::unique_ptr< QgsLayoutItemMapGridStack > mGridStack;
495+
std::unique_ptr< QgsLayoutItemMapOverviewStack > mOverviewStack;
496+
521497
// Map region in map units really used for rendering
522498
// It can be the same as mUserExtent, but it can be bigger in on dimension if mCalculate==Scale,
523499
// so that full rectangle in paper is used.
@@ -607,13 +583,11 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
607583
//! Removes layer ids from mLayerSet that are no longer present in the qgis main map
608584
void syncLayerSet();
609585

610-
#if 0
611586
//! Returns first map grid or creates an empty one if none
612-
const QgsComposerMapGrid *constFirstMapGrid() const;
587+
const QgsLayoutItemMapGrid *constFirstMapGrid() const;
613588

614589
//! Returns first map overview or creates an empty one if none
615-
const QgsComposerMapOverview *constFirstMapOverview() const;
616-
#endif
590+
const QgsLayoutItemMapOverview *constFirstMapOverview() const;
617591

618592
//! Current bounding rectangle. This is used to check if notification to the graphics scene is necessary
619593
QRectF mCurrentRectangle;
@@ -681,7 +655,8 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
681655
*/
682656
void refreshMapExtents( const QgsExpressionContext *context = nullptr );
683657

684-
friend class QgsLayoutMapOverview; //to access mXOffset, mYOffset
658+
friend class QgsLayoutItemMapGrid;
659+
friend class QgsLayoutItemMapOverview;
685660
friend class TestQgsLayoutMap;
686661

687662
};

‎src/core/layout/qgslayoutitemmapgrid.cpp

Lines changed: 2357 additions & 0 deletions
Large diffs are not rendered by default.

‎src/core/layout/qgslayoutitemmapgrid.h

Lines changed: 1009 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
/***************************************************************************
2+
qgslayoutitemmapitem.cpp
3+
-------------------
4+
begin : October 2017
5+
copyright : (C) 2017 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgslayoutitemmapitem.h"
19+
#include "qgslayoutitemmap.h"
20+
#include <QUuid>
21+
22+
QgsLayoutItemMapItem::QgsLayoutItemMapItem( const QString &name, QgsLayoutItemMap *map )
23+
: QgsLayoutObject( map->layout() )
24+
, mName( name )
25+
, mMap( map )
26+
, mUuid( QUuid::createUuid().toString() )
27+
, mEnabled( true )
28+
{
29+
30+
}
31+
32+
bool QgsLayoutItemMapItem::writeXml( QDomElement &element, QDomDocument &document ) const
33+
{
34+
Q_UNUSED( document );
35+
element.setAttribute( QStringLiteral( "uuid" ), mUuid );
36+
element.setAttribute( QStringLiteral( "name" ), mName );
37+
element.setAttribute( QStringLiteral( "show" ), mEnabled );
38+
return true;
39+
}
40+
41+
bool QgsLayoutItemMapItem::readXml( const QDomElement &itemElem, const QDomDocument &doc )
42+
{
43+
Q_UNUSED( doc );
44+
mUuid = itemElem.attribute( QStringLiteral( "uuid" ) );
45+
mName = itemElem.attribute( QStringLiteral( "name" ) );
46+
mEnabled = ( itemElem.attribute( QStringLiteral( "show" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) );
47+
return true;
48+
}
49+
50+
void QgsLayoutItemMapItem::setMap( QgsLayoutItemMap *map )
51+
{
52+
mMap = map;
53+
}
54+
55+
const QgsLayoutItemMap *QgsLayoutItemMapItem::map() const
56+
{
57+
return mMap;
58+
}
59+
60+
void QgsLayoutItemMapItem::setName( const QString &name )
61+
{
62+
mName = name;
63+
}
64+
65+
QString QgsLayoutItemMapItem::name() const
66+
{
67+
return mName;
68+
}
69+
70+
void QgsLayoutItemMapItem::setEnabled( const bool enabled )
71+
{
72+
mEnabled = enabled;
73+
}
74+
75+
bool QgsLayoutItemMapItem::enabled() const
76+
{
77+
return mEnabled;
78+
}
79+
80+
bool QgsLayoutItemMapItem::usesAdvancedEffects() const
81+
{
82+
return false;
83+
}
84+
85+
//
86+
// QgsLayoutItemMapItemStack
87+
//
88+
89+
QgsLayoutItemMapItemStack::QgsLayoutItemMapItemStack( QgsLayoutItemMap *map )
90+
: mMap( map )
91+
{
92+
93+
}
94+
95+
QgsLayoutItemMapItemStack::~QgsLayoutItemMapItemStack()
96+
{
97+
removeItems();
98+
}
99+
100+
void QgsLayoutItemMapItemStack::addItem( QgsLayoutItemMapItem *item )
101+
{
102+
mItems.append( item );
103+
}
104+
105+
void QgsLayoutItemMapItemStack::removeItem( const QString &itemId )
106+
{
107+
for ( int i = mItems.size() - 1; i >= 0; --i )
108+
{
109+
if ( mItems.at( i )->id() == itemId )
110+
{
111+
delete mItems.takeAt( i );
112+
return;
113+
}
114+
}
115+
}
116+
117+
void QgsLayoutItemMapItemStack::moveItemUp( const QString &itemId )
118+
{
119+
QgsLayoutItemMapItem *targetItem = item( itemId );
120+
if ( !targetItem )
121+
{
122+
return;
123+
}
124+
125+
int index = mItems.indexOf( targetItem );
126+
if ( index >= mItems.size() - 1 )
127+
{
128+
return;
129+
}
130+
mItems.swap( index, index + 1 );
131+
}
132+
133+
void QgsLayoutItemMapItemStack::moveItemDown( const QString &itemId )
134+
{
135+
QgsLayoutItemMapItem *targetItem = item( itemId );
136+
if ( !targetItem )
137+
{
138+
return;
139+
}
140+
141+
int index = mItems.indexOf( targetItem );
142+
if ( index < 1 )
143+
{
144+
return;
145+
}
146+
mItems.swap( index, index - 1 );
147+
}
148+
149+
QgsLayoutItemMapItem *QgsLayoutItemMapItemStack::item( const QString &itemId ) const
150+
{
151+
for ( QgsLayoutItemMapItem *item : mItems )
152+
{
153+
if ( item->id() == itemId )
154+
{
155+
return item;
156+
}
157+
}
158+
159+
return nullptr;
160+
}
161+
162+
QgsLayoutItemMapItem *QgsLayoutItemMapItemStack::item( const int index ) const
163+
{
164+
if ( index < mItems.length() )
165+
{
166+
return mItems.at( index );
167+
}
168+
169+
return nullptr;
170+
}
171+
172+
QgsLayoutItemMapItem &QgsLayoutItemMapItemStack::operator[]( int idx )
173+
{
174+
return *mItems[idx];
175+
}
176+
177+
QList<QgsLayoutItemMapItem *> QgsLayoutItemMapItemStack::asList() const
178+
{
179+
QList< QgsLayoutItemMapItem * > list;
180+
for ( QgsLayoutItemMapItem *item : mItems )
181+
{
182+
list.append( item );
183+
}
184+
return list;
185+
}
186+
187+
bool QgsLayoutItemMapItemStack::writeXml( QDomElement &elem, QDomDocument &doc ) const
188+
{
189+
//write item stack
190+
for ( QgsLayoutItemMapItem *item : mItems )
191+
{
192+
item->writeXml( elem, doc );
193+
}
194+
195+
return true;
196+
}
197+
198+
void QgsLayoutItemMapItemStack::drawItems( QPainter *painter )
199+
{
200+
if ( !painter )
201+
{
202+
return;
203+
}
204+
205+
for ( QgsLayoutItemMapItem *item : qgis::as_const( mItems ) )
206+
{
207+
item->draw( painter );
208+
}
209+
}
210+
211+
bool QgsLayoutItemMapItemStack::containsAdvancedEffects() const
212+
{
213+
for ( QgsLayoutItemMapItem *item : mItems )
214+
{
215+
if ( item->enabled() && item->usesAdvancedEffects() )
216+
{
217+
return true;
218+
}
219+
}
220+
return false;
221+
}
222+
223+
void QgsLayoutItemMapItemStack::removeItems()
224+
{
225+
qDeleteAll( mItems );
226+
mItems.clear();
227+
}
228+
229+
230+
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
/***************************************************************************
2+
qgslayoutitemmapitem.h
3+
-------------------
4+
begin : October 2017
5+
copyright : (C) 2017 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
#ifndef QGSLAYOUTITEMMAPITEM_H
18+
#define QGSLAYOUTITEMMAPITEM_H
19+
20+
#include "qgis_core.h"
21+
#include "qgis_sip.h"
22+
#include "qgslayoutobject.h"
23+
24+
class QgsLayoutItemMap;
25+
26+
/**
27+
* \ingroup core
28+
* \class QgsLayoutItemMapItem
29+
* \brief An item which is drawn inside a QgsLayoutItemMap, e.g., a grid or map overview.
30+
* \since QGIS 3.0
31+
*/
32+
class CORE_EXPORT QgsLayoutItemMapItem : public QgsLayoutObject
33+
{
34+
Q_OBJECT
35+
36+
public:
37+
38+
/**
39+
* Constructor for QgsLayoutItemMapItem, attached to the specified \a map.
40+
*
41+
* The \a name argument gives a friendly display name for the item.
42+
*/
43+
QgsLayoutItemMapItem( const QString &name, QgsLayoutItemMap *map );
44+
45+
/**
46+
* Draws the item on to a destination \a painter.
47+
*/
48+
virtual void draw( QPainter *painter ) = 0;
49+
50+
/**
51+
* Stores map item state in a DOM element, where \a element is the DOM element
52+
* corresponding to a 'LayoutMap' tag.
53+
* \see readXml()
54+
*/
55+
virtual bool writeXml( QDomElement &element, QDomDocument &document ) const;
56+
57+
/**
58+
* Sets the map item state from a DOM document, where \a element is the DOM
59+
* node corresponding to a 'LayoutMapGrid' tag.
60+
* \see writeXml()
61+
*/
62+
virtual bool readXml( const QDomElement &element, const QDomDocument &doc );
63+
64+
/**
65+
* Sets the corresponding layout \a map for the item.
66+
* \see map()
67+
*/
68+
void setMap( QgsLayoutItemMap *map );
69+
70+
/**
71+
* Returns the layout item map for the item.
72+
* \see setMap()
73+
*/
74+
const QgsLayoutItemMap *map() const;
75+
76+
/**
77+
* Returns the unique id for the map item.
78+
*/
79+
QString id() const { return mUuid; }
80+
81+
/**
82+
* Sets the friendly display \a name for the item.
83+
* \see name()
84+
*/
85+
void setName( const QString &name );
86+
87+
/**
88+
* Returns the friendly display name for the item.
89+
* \see setName()
90+
*/
91+
QString name() const;
92+
93+
/**
94+
* Controls whether the item will be drawn. Set \a enabled to true to enable drawing of the item.
95+
* \see enabled()
96+
*/
97+
void setEnabled( bool enabled );
98+
99+
/**
100+
* Returns whether the item will be drawn.
101+
* \see setEnabled()
102+
*/
103+
bool enabled() const;
104+
105+
/**
106+
* Returns true if the item is drawn using advanced effects, such as blend modes.
107+
*/
108+
virtual bool usesAdvancedEffects() const;
109+
110+
protected:
111+
112+
//! Friendly display name
113+
QString mName;
114+
115+
//! Associated map
116+
QgsLayoutItemMap *mMap = nullptr;
117+
118+
//! Unique id
119+
QString mUuid;
120+
121+
//! True if item is to be displayed on map
122+
bool mEnabled;
123+
124+
};
125+
126+
127+
128+
/**
129+
* \ingroup core
130+
* \class QgsLayoutItemMapItemStack
131+
* \brief A collection of map items which are drawn above the map content in a
132+
* QgsLayoutItemMap. The item stack controls which items are drawn and the
133+
* order they are drawn in.
134+
* \since QGIS 3.0
135+
* \see QgsLayoutItemMapItem
136+
*/
137+
class CORE_EXPORT QgsLayoutItemMapItemStack
138+
{
139+
public:
140+
141+
/**
142+
* Constructor for QgsLayoutItemMapItemStack, attached to the
143+
* specified \a map.
144+
*/
145+
QgsLayoutItemMapItemStack( QgsLayoutItemMap *map );
146+
147+
virtual ~QgsLayoutItemMapItemStack();
148+
149+
/**
150+
* Returns the number of items in the stack.
151+
*/
152+
int size() const { return mItems.size(); }
153+
154+
/**
155+
* Stores the state of the item stack in a DOM node, where \a element is the DOM element corresponding to a 'LayoutMap' tag.
156+
* Returns true if write was successful.
157+
* \see readXml()
158+
*/
159+
virtual bool writeXml( QDomElement &element, QDomDocument &doc ) const;
160+
161+
/**
162+
* Sets the item stack's state from a DOM document, where \a element is a DOM node corresponding to a 'LayoutMap' tag.
163+
* Returns true if read was successful.
164+
* \see writeXml()
165+
*/
166+
virtual bool readXml( const QDomElement &element, const QDomDocument &doc ) = 0;
167+
168+
/**
169+
* Draws the items from the stack on a specified \a painter.
170+
*/
171+
void drawItems( QPainter *painter );
172+
173+
/**
174+
* Returns whether any items within the stack contain advanced effects,
175+
* such as blending modes.
176+
*/
177+
bool containsAdvancedEffects() const;
178+
179+
protected:
180+
181+
/**
182+
* Adds a new map item to the stack and takes ownership of the item.
183+
* The item will be added to the end of the stack, and rendered
184+
* above any existing map items already present in the stack.
185+
* \note After adding an item to the stack update()
186+
* should be called for the QgsLayoutItemMap to prevent rendering artifacts.
187+
* \see removeItem()
188+
*/
189+
void addItem( QgsLayoutItemMapItem *item SIP_TRANSFER );
190+
191+
/**
192+
* Removes an item which matching \a itemId from the stack and deletes the corresponding QgsLayoutItemMapItem
193+
* \note After removing an item from the stack, update()
194+
* should be called for the QgsLayoutItemMap to prevent rendering artifacts.
195+
* \see addItem()
196+
*/
197+
void removeItem( const QString &itemId );
198+
199+
/**
200+
* Moves an item which matching \a itemId up the stack, causing it to be rendered above other items.
201+
* \note After moving an item within the stack, update() should be
202+
* called for the QgsLayoutItemMap to redraw the map with the new item stack order.
203+
* \see moveItemDown()
204+
*/
205+
void moveItemUp( const QString &itemId );
206+
207+
/**
208+
* Moves an item which matching \a itemId up the stack, causing it to be rendered above other items.
209+
* \note After moving an item within the stack, update() should be
210+
* called for the QgsLayoutItemMap to redraw the map with the new item stack order.
211+
* \see moveItemUp()
212+
*/
213+
void moveItemDown( const QString &itemId );
214+
215+
/**
216+
* Returns a reference to an item which matching \a itemId within the stack.
217+
* \see constItem()
218+
*/
219+
QgsLayoutItemMapItem *item( const QString &itemId ) const;
220+
221+
/**
222+
* Returns a reference to the item at the specified \a index within the stack.
223+
* \see constItem
224+
*/
225+
QgsLayoutItemMapItem *item( int index ) const;
226+
227+
/**
228+
* Returns a reference to an item at the specified \a index within the stack.
229+
* \see constItem()
230+
* \see item()
231+
* \note not available in Python bindings
232+
*/
233+
QgsLayoutItemMapItem &operator[]( int index ) SIP_SKIP;
234+
235+
/**
236+
* Returns a list of QgsLayoutItemMapItems contained by the stack.
237+
*/
238+
QList< QgsLayoutItemMapItem * > asList() const;
239+
240+
protected:
241+
242+
QList< QgsLayoutItemMapItem * > mItems;
243+
244+
QgsLayoutItemMap *mMap = nullptr;
245+
246+
/**
247+
* Clears the item stack and deletes all QgsLayoutItemMapItems contained
248+
* by the stack
249+
*/
250+
void removeItems();
251+
};
252+
253+
#endif //QGSLAYOUTITEMMAPITEM_H
254+

‎src/core/layout/qgslayoutitemmapoverview.cpp

Lines changed: 400 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
/***************************************************************************
2+
qgslayoutitemmapoverview.h
3+
--------------------
4+
begin : October 2017
5+
copyright : (C) 2017 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QgsLayoutItemMapOVERVIEW_H
19+
#define QgsLayoutItemMapOVERVIEW_H
20+
21+
#include "qgis_core.h"
22+
#include "qgis_sip.h"
23+
#include "qgis.h"
24+
#include "qgslayoutitemmapitem.h"
25+
#include "qgssymbol.h"
26+
#include <QString>
27+
#include <QObject>
28+
#include <QPainter>
29+
30+
class QDomDocument;
31+
class QDomElement;
32+
class QgsLayoutItemMapOverview;
33+
34+
/**
35+
* \ingroup core
36+
* \class QgsLayoutItemMapOverviewStack
37+
* \brief A collection of overviews which are drawn above the map content in a
38+
* QgsLayoutItemMap. The overview stack controls which overviews are drawn and the
39+
* order they are drawn in.
40+
* \since QGIS 3.0
41+
* \see QgsLayoutItemMapOverview
42+
*/
43+
class CORE_EXPORT QgsLayoutItemMapOverviewStack : public QgsLayoutItemMapItemStack
44+
{
45+
public:
46+
47+
/**
48+
* Constructor for QgsLayoutItemMapOverviewStack, attached to the specified
49+
* \a map.
50+
*/
51+
QgsLayoutItemMapOverviewStack( QgsLayoutItemMap *map );
52+
53+
/**
54+
* Adds a new map \a overview to the stack and takes ownership of the overview.
55+
* The overview will be added to the end of the stack, and rendered
56+
* above any existing map overviews already present in the stack.
57+
* \note After adding a overview to the stack, update()
58+
* should be called for the QgsLayoutItemMap to prevent rendering artifacts.
59+
* \see removeOverview()
60+
*/
61+
void addOverview( QgsLayoutItemMapOverview *overview SIP_TRANSFER );
62+
63+
/**
64+
* Removes an overview with matching overviewId from the stack and deletes the corresponding QgsLayoutItemMapOverview
65+
* \note After removing an overview from the stack, update()
66+
* should be called for the QgsLayoutItemMap to prevent rendering artifacts.
67+
* \see addOverview()
68+
*/
69+
void removeOverview( const QString &overviewId );
70+
71+
/**
72+
* Moves an overview with matching overviewId up the stack, causing it to be rendered above other overviews.
73+
* \note After moving an overview within the stack, update() should be
74+
* called for the QgsLayoutItemMap to redraw the map with the new overview stack order.
75+
* \see moveOverviewDown()
76+
*/
77+
void moveOverviewUp( const QString &overviewId );
78+
79+
/**
80+
* Moves an overview with matching overviewId down the stack, causing it to be rendered below other overviews.
81+
* \note After moving an overview within the stack, update() should be
82+
* called for the QgsLayoutItemMap to redraw the map with the new overview stack order.
83+
* \see moveOverviewUp()
84+
*/
85+
void moveOverviewDown( const QString &overviewId );
86+
87+
/**
88+
* Returns a reference to an overview with matching overviewId within the stack.
89+
* \see constOverview()
90+
*/
91+
QgsLayoutItemMapOverview *overview( const QString &overviewId ) const;
92+
93+
/**
94+
* Returns a reference to an overview at the specified \a index within the stack.
95+
* \see constOverview()
96+
*/
97+
QgsLayoutItemMapOverview *overview( const int index ) const;
98+
99+
/**
100+
* Returns a reference to an overview at the specified \a index within the stack.
101+
* \see constOverview()
102+
* \see overview()
103+
*/
104+
QgsLayoutItemMapOverview &operator[]( int index );
105+
106+
/**
107+
* Returns a list of QgsLayoutItemMapOverviews contained by the stack.
108+
*/
109+
QList< QgsLayoutItemMapOverview * > asList() const;
110+
bool readXml( const QDomElement &elem, const QDomDocument &doc ) override;
111+
112+
};
113+
114+
/**
115+
* \ingroup core
116+
* \class QgsLayoutItemMapOverview
117+
* \brief An individual overview which is drawn above the map content in a
118+
* QgsLayoutItemMap, and shows the extent of another QgsLayoutItemMap.
119+
* \since QGIS 3.0
120+
* \see QgsLayoutItemMapOverviewStack
121+
*/
122+
class CORE_EXPORT QgsLayoutItemMapOverview : public QgsLayoutItemMapItem
123+
{
124+
Q_OBJECT
125+
126+
public:
127+
128+
/**
129+
* Constructor for QgsLayoutItemMapOverview.
130+
* \param name friendly display name for overview
131+
* \param map QgsLayoutItemMap the overview is attached to
132+
*/
133+
QgsLayoutItemMapOverview( const QString &name, QgsLayoutItemMap *map );
134+
135+
void draw( QPainter *painter ) override;
136+
bool writeXml( QDomElement &elem, QDomDocument &doc ) const override;
137+
bool readXml( const QDomElement &itemElem, const QDomDocument &doc ) override;
138+
bool usesAdvancedEffects() const override;
139+
140+
/**
141+
* Sets overview frame map \a uuid. Set an empty \a uuid to disable
142+
* the overview frame.
143+
* \see frameMapUuid()
144+
* \see setFrameMap()
145+
*/
146+
void setFrameMapUuid( const QString &uuid );
147+
148+
/**
149+
* Returns the uuid of source map, or an empty string if no map set.
150+
* \see setFrameMapUuid()
151+
* \see frameMap()
152+
*/
153+
QString frameMapUuid() const { return mFrameMapId; }
154+
155+
/**
156+
* Sets the \a map to show the overview extent of.
157+
* \see frameMap()
158+
*/
159+
void setFrameMap( QgsLayoutItemMap *map );
160+
161+
/**
162+
* Returns the source map to show the overview extent of.
163+
* \see setFrameMap()
164+
*/
165+
QgsLayoutItemMap *frameMap();
166+
167+
/**
168+
* Sets the fill \a symbol used for drawing the overview extent. Ownership
169+
* is transferred to the overview.
170+
* \see frameSymbol()
171+
*/
172+
void setFrameSymbol( QgsFillSymbol *symbol SIP_TRANSFER );
173+
174+
/**
175+
* Returns the fill symbol used for drawing the overview extent.
176+
* \see setFrameSymbol()
177+
*/
178+
QgsFillSymbol *frameSymbol();
179+
180+
/**
181+
* Returns the fill symbol used for drawing the overview extent.
182+
* \see setFrameSymbol()
183+
* \note not available in Python bindings
184+
*/
185+
const QgsFillSymbol *frameSymbol() const; SIP_SKIP
186+
187+
/**
188+
* Retrieves the blending mode used for drawing the overview.
189+
* \see setBlendMode()
190+
*/
191+
QPainter::CompositionMode blendMode() const { return mBlendMode; }
192+
193+
/**
194+
* Sets the blending \a mode used for drawing the overview.
195+
* \see blendMode()
196+
*/
197+
void setBlendMode( const QPainter::CompositionMode mode );
198+
199+
/**
200+
* Returns whether the overview frame is inverted, ie, whether the shaded area is drawn outside
201+
* the extent of the overview map.
202+
* \see setInverted()
203+
*/
204+
bool inverted() const { return mInverted; }
205+
206+
/**
207+
* Sets whether the overview frame is \a inverted, ie, whether the shaded area is drawn outside
208+
* the extent of the overview map.
209+
* \see inverted()
210+
*/
211+
void setInverted( const bool inverted );
212+
213+
/**
214+
* Returns whether the extent of the map is forced to center on the overview.
215+
* \see setCentered()
216+
*/
217+
bool centered() const { return mCentered; }
218+
219+
/**
220+
* Sets whether the extent of the map is forced to center on the overview
221+
* \see centered()
222+
*/
223+
void setCentered( const bool centered );
224+
225+
/**
226+
* Reconnects signals for overview map, so that overview correctly follows changes to source
227+
* map's extent.
228+
*/
229+
void connectSignals();
230+
231+
public slots:
232+
233+
/**
234+
* Handles recentering of the map and redrawing of the map's overview
235+
*/
236+
void overviewExtentChanged();
237+
238+
private:
239+
240+
QgsLayoutItemMapOverview() = delete;
241+
242+
//! Uuid of map which displays its extent rectangle into this composer map (overview map functionality). Empty if not present.
243+
QString mFrameMapId;
244+
245+
//! Drawing style for overview farme
246+
std::unique_ptr< QgsFillSymbol > mFrameSymbol;
247+
248+
//! Blend mode for overview
249+
QPainter::CompositionMode mBlendMode = QPainter::CompositionMode_SourceOver;
250+
251+
//! True if overview is inverted
252+
bool mInverted = false;
253+
254+
//! True if map is centered on overview
255+
bool mCentered = false;
256+
257+
//! Creates default overview symbol
258+
void createDefaultFrameSymbol();
259+
260+
};
261+
262+
#endif // QgsLayoutItemMapOVERVIEW_H

‎src/core/layout/qgslayoututils.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ class CORE_EXPORT QgsLayoutUtils
9595
*/
9696
static double relativePosition( const double position, const double beforeMin, const double beforeMax, const double afterMin, const double afterMax );
9797

98-
9998
};
10099

101100
#endif //QGSLAYOUTUTILS_H

0 commit comments

Comments
 (0)
Please sign in to comment.