47
47
#include " qgslayout3dmapwidget.h"
48
48
#endif
49
49
50
+ /* *
51
+ * Attempts to find the best guess at a map item to link \a referenceItem to,
52
+ * by:
53
+ * 1. Prioritising a selected map
54
+ * 2. If no selection, prioritising the topmost map the item was drawn over
55
+ * 3. If still none, use the layout's reference map (or biggest map)
56
+ */
57
+ QgsLayoutItemMap *findSensibleDefaultLinkedMapItem ( QgsLayoutItem *referenceItem )
58
+ {
59
+ // start by trying to find a selected map
60
+ QList<QgsLayoutItemMap *> mapItems;
61
+ referenceItem->layout ()->layoutItems ( mapItems );
62
+
63
+ QgsLayoutItemMap *targetMap = nullptr ;
64
+ for ( QgsLayoutItemMap *map : qgis::as_const ( mapItems ) )
65
+ {
66
+ if ( map->isSelected () )
67
+ {
68
+ return map;
69
+ }
70
+ }
71
+
72
+ // nope, no selection... hm, was the item drawn over a map? If so, use the topmost intersecting one
73
+ double largestZValue = std::numeric_limits< double >::lowest ();
74
+ for ( QgsLayoutItemMap *map : qgis::as_const ( mapItems ) )
75
+ {
76
+ if ( map->collidesWithItem ( referenceItem ) && map->zValue () > largestZValue )
77
+ {
78
+ targetMap = map;
79
+ largestZValue = map->zValue ();
80
+ }
81
+ }
82
+ if ( targetMap )
83
+ return targetMap;
84
+
85
+ // ah frick it, just use the reference (or biggest!) map
86
+ return referenceItem->layout ()->referenceMap ();
87
+ }
88
+
50
89
void QgsLayoutAppUtils::registerGuiForKnownItemTypes ()
51
90
{
52
91
QgsLayoutItemGuiRegistry *registry = QgsGui::layoutItemGuiRegistry ();
@@ -153,29 +192,8 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes()
153
192
QgsLayoutItemLegend *legend = qobject_cast< QgsLayoutItemLegend * >( item );
154
193
Q_ASSERT ( legend );
155
194
156
- QList<QgsLayoutItemMap *> mapItems;
157
- legend->layout ()->layoutItems ( mapItems );
158
-
159
195
// try to find a good map to link the legend with by default
160
- // start by trying to find a selected map
161
- QgsLayoutItemMap *targetMap = nullptr ;
162
- for ( QgsLayoutItemMap *map : qgis::as_const ( mapItems ) )
163
- {
164
- if ( map->isSelected () )
165
- {
166
- targetMap = map;
167
- break ;
168
- }
169
- }
170
- // otherwise just use first map
171
- if ( !targetMap && !mapItems.isEmpty () )
172
- {
173
- targetMap = mapItems.at ( 0 );
174
- }
175
- if ( targetMap )
176
- {
177
- legend->setLinkedMap ( targetMap );
178
- }
196
+ legend->setLinkedMap ( findSensibleDefaultLinkedMapItem ( legend ) );
179
197
180
198
legend->updateLegend ();
181
199
} );
@@ -194,26 +212,8 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes()
194
212
QgsLayoutItemScaleBar *scalebar = qobject_cast< QgsLayoutItemScaleBar * >( item );
195
213
Q_ASSERT ( scalebar );
196
214
197
- QList<QgsLayoutItemMap *> mapItems;
198
- scalebar->layout ()->layoutItems ( mapItems );
199
-
200
215
// try to find a good map to link the scalebar with by default
201
- // start by trying to find a selected map
202
- QgsLayoutItemMap *targetMap = nullptr ;
203
- for ( QgsLayoutItemMap *map : qgis::as_const ( mapItems ) )
204
- {
205
- if ( map->isSelected () )
206
- {
207
- targetMap = map;
208
- break ;
209
- }
210
- }
211
- // otherwise just use first map
212
- if ( !targetMap && !mapItems.isEmpty () )
213
- {
214
- targetMap = mapItems.at ( 0 );
215
- }
216
- if ( targetMap )
216
+ if ( QgsLayoutItemMap *targetMap = findSensibleDefaultLinkedMapItem ( scalebar ) )
217
217
{
218
218
scalebar->setLinkedMap ( targetMap );
219
219
scalebar->applyDefaultSize ( scalebar->guessUnits () );
@@ -222,6 +222,34 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes()
222
222
223
223
registry->addLayoutItemGuiMetadata ( scalebarItemMetadata.release () );
224
224
225
+
226
+ // north arrow
227
+ std::unique_ptr< QgsLayoutItemGuiMetadata > northArrowMetadata = qgis::make_unique< QgsLayoutItemGuiMetadata>(
228
+ QgsLayoutItemRegistry::LayoutPicture, QObject::tr ( " North Arrow" ), QgsApplication::getThemeIcon ( QStringLiteral ( " /north_arrow.svg" ) ),
229
+ [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
230
+ {
231
+ return new QgsLayoutPictureWidget ( qobject_cast< QgsLayoutItemPicture * >( item ) );
232
+ }, createRubberBand );
233
+ northArrowMetadata->setItemCreationFunction ( []( QgsLayout * layout )->QgsLayoutItem *
234
+ {
235
+ std::unique_ptr< QgsLayoutItemPicture > picture = qgis::make_unique< QgsLayoutItemPicture >( layout );
236
+ picture->setNorthMode ( QgsLayoutItemPicture::GridNorth );
237
+ picture->setPicturePath ( QStringLiteral ( " :/images/north_arrows/layout_default_north_arrow.svg" ) );
238
+ return picture.release ();
239
+ } );
240
+ northArrowMetadata->setItemAddedToLayoutFunction ( [ = ]( QgsLayoutItem * item )
241
+ {
242
+ QgsLayoutItemPicture *picture = qobject_cast< QgsLayoutItemPicture * >( item );
243
+ Q_ASSERT ( picture );
244
+
245
+ QList<QgsLayoutItemMap *> mapItems;
246
+ picture->layout ()->layoutItems ( mapItems );
247
+
248
+ // try to find a good map to link the north arrow with by default
249
+ picture->setLinkedMap ( findSensibleDefaultLinkedMapItem ( picture ) );
250
+ } );
251
+ registry->addLayoutItemGuiMetadata ( northArrowMetadata.release () );
252
+
225
253
// shape items
226
254
227
255
auto createShapeWidget =
@@ -271,7 +299,6 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes()
271
299
} );
272
300
registry->addLayoutItemGuiMetadata ( arrowMetadata.release () );
273
301
274
-
275
302
// node items
276
303
277
304
std::unique_ptr< QgsLayoutItemGuiMetadata > polygonMetadata = qgis::make_unique< QgsLayoutItemGuiMetadata >(
0 commit comments