QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgslayoutguiutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayoutapputils.cpp
3 ---------------------
4 Date : October 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
16#include "qgslayoutguiutils.h"
17#include "qgsgui.h"
21#include "qgslayoutitemshape.h"
22#include "qgslayoutmapwidget.h"
25#include "qgslayoutitemmap.h"
28#include "qgslayoutitemmarker.h"
33#include "qgslayoutitemlabel.h"
36#include "qgslayoutitemlegend.h"
39#include "qgslayoutframe.h"
40#include "qgslayoutitemhtml.h"
41#include "qgslayouthtmlwidget.h"
48#include "qgsmapcanvas.h"
49#include "qgsplot.h"
50#include "qgsfontutils.h"
51
61{
62 // start by trying to find a selected map
63 QList<QgsLayoutItemMap *> mapItems;
64 referenceItem->layout()->layoutItems( mapItems );
65
66 QgsLayoutItemMap *targetMap = nullptr;
67 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
68 {
69 if ( map->isSelected() )
70 {
71 return map;
72 }
73 }
74
75 // nope, no selection... hm, was the item drawn over a map? If so, use the topmost intersecting one
76 double largestZValue = std::numeric_limits< double >::lowest();
77 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
78 {
79 if ( map->collidesWithItem( referenceItem ) && map->zValue() > largestZValue )
80 {
81 targetMap = map;
82 largestZValue = map->zValue();
83 }
84 }
85 if ( targetMap )
86 return targetMap;
87
88 // ah frick it, just use the reference (or biggest!) map
89 return referenceItem->layout()->referenceMap();
90}
91
93{
95
96 registry->addItemGroup( QgsLayoutItemGuiGroup( QStringLiteral( "shapes" ), QObject::tr( "Shape" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicShape.svg" ) ) ) );
97 registry->addItemGroup( QgsLayoutItemGuiGroup( QStringLiteral( "nodes" ), QObject::tr( "Node Item" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddNodesItem.svg" ) ) ) );
98
99 auto createRubberBand = ( []( QgsLayoutView * view )->QgsLayoutViewRubberBand *
100 {
101 return new QgsLayoutViewRectangularRubberBand( view );
102 } );
103 auto createEllipseBand = ( []( QgsLayoutView * view )->QgsLayoutViewRubberBand *
104 {
105 return new QgsLayoutViewEllipticalRubberBand( view );
106 } );
107 auto createTriangleBand = ( []( QgsLayoutView * view )->QgsLayoutViewRubberBand *
108 {
109 return new QgsLayoutViewTriangleRubberBand( view );
110 } );
111
112#if 0
113 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutItem + 1002, QStringLiteral( "test" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLabel.svg" ) ), nullptr, createRubberBand ) );
114#endif
115
116 // map item
117
118 auto mapItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutMap, QObject::tr( "Map" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddMap.svg" ) ),
119 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
120 {
121 return new QgsLayoutMapWidget( qobject_cast< QgsLayoutItemMap * >( item ), mapCanvas );
122 }, createRubberBand );
123 mapItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & )
124 {
125 QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( item );
126 Q_ASSERT( map );
127
128 //get the color for map canvas background and set map background color accordingly
129 map->setBackgroundColor( QgsProject::instance()->backgroundColor() );
130
131 if ( mapCanvas )
132 {
133 map->setMapRotation( mapCanvas->rotation() );
134 map->zoomToExtent( mapCanvas->mapSettings().visibleExtent() );
135 }
136
137 // auto assign a unique id to map items
138 QList<QgsLayoutItemMap *> mapsList;
139 if ( map->layout() )
140 map->layout()->layoutItems( mapsList );
141
142 int counter = mapsList.size() + 1;
143 bool existing = false;
144 while ( true )
145 {
146 existing = false;
147 for ( QgsLayoutItemMap *otherMap : std::as_const( mapsList ) )
148 {
149 if ( map == otherMap )
150 continue;
151
152 if ( otherMap->id() == QObject::tr( "Map %1" ).arg( counter ) )
153 {
154 existing = true;
155 break;
156 }
157 }
158 if ( existing )
159 counter++;
160 else
161 break;
162 }
163 map->setId( QObject::tr( "Map %1" ).arg( counter ) );
164 } );
165 registry->addLayoutItemGuiMetadata( mapItemMetadata.release() );
166
167 // picture item
168
169 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutPicture, QObject::tr( "Picture" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddImage.svg" ) ),
170 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
171 {
172 return new QgsLayoutPictureWidget( qobject_cast< QgsLayoutItemPicture * >( item ) );
173 }, createRubberBand ) );
174
175
176 // label item
177
178 auto labelItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutLabel, QObject::tr( "Label" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionLabel.svg" ) ),
179 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
180 {
181 return new QgsLayoutLabelWidget( qobject_cast< QgsLayoutItemLabel * >( item ) );
182 }, createRubberBand );
183 labelItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & properties )
184 {
185 QgsLayoutItemLabel *label = qobject_cast< QgsLayoutItemLabel * >( item );
186 Q_ASSERT( label );
187
188 label->setText( properties.value( QStringLiteral( "expression" ) ).toString().isEmpty() ? QObject::tr( "Lorem ipsum" ) : QStringLiteral( "[% %1 %]" ).arg( properties.value( QStringLiteral( "expression" ) ).toString() ) );
189 if ( QApplication::isRightToLeft() )
190 {
191 label->setHAlign( Qt::AlignRight );
192 }
193 QSizeF minSize = label->sizeForText();
194 QSizeF currentSize = label->rect().size();
195
196 //make sure label size is sufficient to fit text
197 double labelWidth = std::max( minSize.width(), currentSize.width() );
198 double labelHeight = std::max( minSize.height(), currentSize.height() );
199 label->attemptSetSceneRect( QRectF( label->pos().x(), label->pos().y(), labelWidth, labelHeight ) );
200 } );
201
202 registry->addLayoutItemGuiMetadata( labelItemMetadata.release() );
203
204
205 // legend item
206
207 auto legendItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutLegend, QObject::tr( "Legend" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLegend.svg" ) ),
208 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
209 {
210 return new QgsLayoutLegendWidget( qobject_cast< QgsLayoutItemLegend * >( item ), mapCanvas );
211 }, createRubberBand );
212 legendItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & )
213 {
214 QgsLayoutItemLegend *legend = qobject_cast< QgsLayoutItemLegend * >( item );
215 Q_ASSERT( legend );
216
217 // try to find a good map to link the legend with by default
219
220 if ( QApplication::isRightToLeft() )
221 {
222 // for right-to-left locales, use an appropriate default layout
223 legend->setSymbolAlignment( Qt::AlignRight );
224 legend->rstyle( QgsLegendStyle::Group ).setAlignment( Qt::AlignRight );
225 legend->rstyle( QgsLegendStyle::Subgroup ).setAlignment( Qt::AlignRight );
226 legend->rstyle( QgsLegendStyle::SymbolLabel ).setAlignment( Qt::AlignRight );
227 legend->setTitleAlignment( Qt::AlignRight );
228 }
229
230 //set default legend font from settings
231 QgsSettings settings;
232 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
233 if ( !defaultFontString.isEmpty() )
234 {
235 QFont font;
236 QgsFontUtils::setFontFamily( font, defaultFontString );
237
239 f.setFont( font );
241
242 f = legend->rstyle( QgsLegendStyle::Group ).textFormat();
243 f.setFont( font );
245
247 f.setFont( font );
249
251 f.setFont( font );
253 }
254
255 legend->updateLegend();
256 } );
257
258 registry->addLayoutItemGuiMetadata( legendItemMetadata.release() );
259
260 // scalebar item
261
262 auto scalebarItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutScaleBar, QObject::tr( "Scale Bar" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionScaleBar.svg" ) ),
263 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
264 {
265 return new QgsLayoutScaleBarWidget( qobject_cast< QgsLayoutItemScaleBar * >( item ) );
266 }, createRubberBand );
267 scalebarItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & )
268 {
269 QgsLayoutItemScaleBar *scalebar = qobject_cast< QgsLayoutItemScaleBar * >( item );
270 Q_ASSERT( scalebar );
271
272 // try to find a good map to link the scalebar with by default
273 if ( QgsLayoutItemMap *targetMap = findSensibleDefaultLinkedMapItem( scalebar ) )
274 {
275 scalebar->setLinkedMap( targetMap );
276 scalebar->applyDefaultSize( scalebar->guessUnits() );
277 }
278 } );
279
280 registry->addLayoutItemGuiMetadata( scalebarItemMetadata.release() );
281
282
283 // north arrow
284 std::unique_ptr< QgsLayoutItemGuiMetadata > northArrowMetadata = std::make_unique< QgsLayoutItemGuiMetadata>(
285 QgsLayoutItemRegistry::LayoutPicture, QObject::tr( "North Arrow" ), QgsApplication::getThemeIcon( QStringLiteral( "/north_arrow.svg" ) ),
286 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
287 {
288 return new QgsLayoutPictureWidget( qobject_cast< QgsLayoutItemPicture * >( item ) );
289 }, createRubberBand );
290 northArrowMetadata->setItemCreationFunction( []( QgsLayout * layout )->QgsLayoutItem *
291 {
292
293 // count how many existing north arrows are already in layout
294 QList< QgsLayoutItemPicture * > pictureItems;
295 layout->layoutItems( pictureItems );
296 int northArrowCount = 0;
297
298 QgsSettings settings;
299 const QString defaultPath = settings.value( QStringLiteral( "LayoutDesigner/defaultNorthArrow" ), QStringLiteral( ":/images/north_arrows/layout_default_north_arrow.svg" ), QgsSettings::Gui ).toString();
300
301 for ( QgsLayoutItemPicture *p : std::as_const( pictureItems ) )
302 {
303 // look for pictures which use the default north arrow svg
304 if ( p->picturePath() == defaultPath )
305 northArrowCount++;
306 }
307
308 std::unique_ptr< QgsLayoutItemPicture > picture = std::make_unique< QgsLayoutItemPicture >( layout );
309 picture->setNorthMode( QgsLayoutItemPicture::GridNorth );
310 picture->setPicturePath( defaultPath );
311 // set an id by default, so that north arrows are discernible in layout item lists
312 picture->setId( northArrowCount > 0 ? QObject::tr( "North Arrow %1" ).arg( northArrowCount + 1 ) : QObject::tr( "North Arrow" ) );
313 return picture.release();
314 } );
315 northArrowMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & )
316 {
317 QgsLayoutItemPicture *picture = qobject_cast< QgsLayoutItemPicture * >( item );
318 Q_ASSERT( picture );
319
320 QList<QgsLayoutItemMap *> mapItems;
321 picture->layout()->layoutItems( mapItems );
322
323 // try to find a good map to link the north arrow with by default
324 picture->setLinkedMap( findSensibleDefaultLinkedMapItem( picture ) );
325 } );
326 registry->addLayoutItemGuiMetadata( northArrowMetadata.release() );
327
328 // shape items
329
330 auto createShapeWidget =
332 {
333 return new QgsLayoutShapeWidget( qobject_cast< QgsLayoutItemShape * >( item ) );
334 };
335
336 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Rectangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), createShapeWidget, createRubberBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout * layout )->QgsLayoutItem*
337 {
338 std::unique_ptr< QgsLayoutItemShape > shape = std::make_unique< QgsLayoutItemShape >( layout );
339 shape->setShapeType( QgsLayoutItemShape::Rectangle );
340 return shape.release();
341 } ) );
342 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Ellipse" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicCircle.svg" ) ), createShapeWidget, createEllipseBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout * layout )->QgsLayoutItem*
343 {
344 std::unique_ptr< QgsLayoutItemShape > shape = std::make_unique< QgsLayoutItemShape >( layout );
345 shape->setShapeType( QgsLayoutItemShape::Ellipse );
346 return shape.release();
347 } ) );
348 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Triangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicTriangle.svg" ) ), createShapeWidget, createTriangleBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout * layout )->QgsLayoutItem*
349 {
350 std::unique_ptr< QgsLayoutItemShape > shape = std::make_unique< QgsLayoutItemShape >( layout );
351 shape->setShapeType( QgsLayoutItemShape::Triangle );
352 return shape.release();
353 } ) );
354
355 // marker
356 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutMarker, QObject::tr( "Marker" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddMarker.svg" ) ),
357 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
358 {
359 return new QgsLayoutMarkerWidget( qobject_cast< QgsLayoutItemMarker * >( item ) );
360 }, nullptr ) );
361
362 // arrow
363 std::unique_ptr< QgsLayoutItemGuiMetadata > arrowMetadata = std::make_unique< QgsLayoutItemGuiMetadata>(
364 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Arrow" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddArrow.svg" ) ),
365 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
366 {
367 return new QgsLayoutPolylineWidget( qobject_cast< QgsLayoutItemPolyline * >( item ) );
368 }, createRubberBand, QString(), true );
369 arrowMetadata->setItemCreationFunction( []( QgsLayout * layout )->QgsLayoutItem *
370 {
371 std::unique_ptr< QgsLayoutItemPolyline > arrow = std::make_unique< QgsLayoutItemPolyline >( layout );
372 arrow->setEndMarker( QgsLayoutItemPolyline::ArrowHead );
373 return arrow.release();
374 } );
375 arrowMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPathItem*
376 {
377 std::unique_ptr< QGraphicsPathItem > band = std::make_unique< QGraphicsPathItem >();
378 band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
379 band->setZValue( QgsLayout::ZViewTool );
380 return band.release();
381 } );
382 registry->addLayoutItemGuiMetadata( arrowMetadata.release() );
383
384 // node items
385
386 std::unique_ptr< QgsLayoutItemGuiMetadata > polygonMetadata = std::make_unique< QgsLayoutItemGuiMetadata >(
387 QgsLayoutItemRegistry::LayoutPolygon, QObject::tr( "Polygon" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolygon.svg" ) ),
388 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
389 {
390 return new QgsLayoutPolygonWidget( qobject_cast< QgsLayoutItemPolygon * >( item ) );
391 }, createRubberBand, QStringLiteral( "nodes" ), true );
392 polygonMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPolygonItem*
393 {
394 std::unique_ptr< QGraphicsPolygonItem > band = std::make_unique< QGraphicsPolygonItem >();
395 band->setBrush( Qt::NoBrush );
396 band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
397 band->setZValue( QgsLayout::ZViewTool );
398 return band.release();
399 } );
400 registry->addLayoutItemGuiMetadata( polygonMetadata.release() );
401
402 std::unique_ptr< QgsLayoutItemGuiMetadata > polylineMetadata = std::make_unique< QgsLayoutItemGuiMetadata>(
403 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Polyline" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolyline.svg" ) ),
404 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
405 {
406 return new QgsLayoutPolylineWidget( qobject_cast< QgsLayoutItemPolyline * >( item ) );
407 }, createRubberBand, QStringLiteral( "nodes" ), true );
408 polylineMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPathItem*
409 {
410 std::unique_ptr< QGraphicsPathItem > band = std::make_unique< QGraphicsPathItem >();
411 band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
412 band->setZValue( QgsLayout::ZViewTool );
413 return band.release();
414 } );
415 registry->addLayoutItemGuiMetadata( polylineMetadata.release() );
416
417
418 // html item
419
420 auto htmlItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutHtml, QObject::tr( "HTML" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddHtml.svg" ) ),
421 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
422 {
423 return new QgsLayoutHtmlWidget( qobject_cast< QgsLayoutFrame * >( item ) );
424 }, createRubberBand );
425 htmlItemMetadata->setItemCreationFunction( [ = ]( QgsLayout * layout )->QgsLayoutItem *
426 {
427 std::unique_ptr< QgsLayoutItemHtml > htmlMultiFrame = std::make_unique< QgsLayoutItemHtml >( layout );
428 QgsLayoutItemHtml *html = htmlMultiFrame.get();
429 layout->addMultiFrame( htmlMultiFrame.release() );
430 std::unique_ptr< QgsLayoutFrame > frame = std::make_unique< QgsLayoutFrame >( layout, html );
431 QgsLayoutFrame *f = frame.get();
432 html->addFrame( frame.release() );
433 // cppcheck-suppress returnDanglingLifetime
434 return f;
435 } );
436 registry->addLayoutItemGuiMetadata( htmlItemMetadata.release() );
437
438 // attribute table item
439
440 auto attributeTableItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutAttributeTable, QObject::tr( "Attribute Table" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddTable.svg" ) ),
441 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
442 {
443 return new QgsLayoutAttributeTableWidget( qobject_cast< QgsLayoutFrame * >( item ) );
444 }, createRubberBand );
445 attributeTableItemMetadata->setItemCreationFunction( [ = ]( QgsLayout * layout )->QgsLayoutItem *
446 {
447 std::unique_ptr< QgsLayoutItemAttributeTable > tableMultiFrame = std::make_unique< QgsLayoutItemAttributeTable >( layout );
448 QgsLayoutItemAttributeTable *table = tableMultiFrame.get();
449
450 //set first vector layer from layer registry as table source
451 QMap<QString, QgsMapLayer *> layerMap = layout->project()->mapLayers();
452 for ( auto it = layerMap.constBegin() ; it != layerMap.constEnd(); ++it )
453 {
454 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ) )
455 {
456 table->setVectorLayer( vl );
457 break;
458 }
459 }
460
461 //set default table fonts from settings
462 QgsSettings settings;
463 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
464 if ( !defaultFontString.isEmpty() )
465 {
466 QgsTextFormat format;
467 QFont f = format.font();
468 QgsFontUtils::setFontFamily( f, defaultFontString );
469 format.setFont( f );
470 tableMultiFrame->setContentTextFormat( format );
471 f.setBold( true );
472 format.setFont( f );
473 tableMultiFrame->setHeaderTextFormat( format );
474 }
475
476 layout->addMultiFrame( tableMultiFrame.release() );
477 std::unique_ptr< QgsLayoutFrame > frame = std::make_unique< QgsLayoutFrame >( layout, table );
478 QgsLayoutFrame *f = frame.get();
479 table->addFrame( frame.release() );
480 // cppcheck-suppress returnDanglingLifetime
481 return f;
482 } );
483 registry->addLayoutItemGuiMetadata( attributeTableItemMetadata.release() );
484
485 // manual table item
486
487 auto manualTableItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutManualTable, QObject::tr( "Fixed Table" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddManualTable.svg" ) ),
488 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
489 {
490 return new QgsLayoutManualTableWidget( qobject_cast< QgsLayoutFrame * >( item ) );
491 }, createRubberBand );
492 manualTableItemMetadata->setItemCreationFunction( [ = ]( QgsLayout * layout )->QgsLayoutItem *
493 {
494 std::unique_ptr< QgsLayoutItemManualTable > tableMultiFrame = std::make_unique< QgsLayoutItemManualTable >( layout );
495 QgsLayoutItemManualTable *table = tableMultiFrame.get();
496
497 // initially start with a 2x2 empty table
498 QgsTableContents contents;
499 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
500 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
501 table->setTableContents( contents );
502
503 //set default table fonts from settings
504 QgsSettings settings;
505 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
506 if ( !defaultFontString.isEmpty() )
507 {
508 QgsTextFormat format;
509 QFont f = format.font();
510 QgsFontUtils::setFontFamily( f, defaultFontString );
511 format.setFont( f );
512 tableMultiFrame->setContentTextFormat( format );
513 f.setBold( true );
514 format.setFont( f );
515 tableMultiFrame->setHeaderTextFormat( format );
516 }
517
518 layout->addMultiFrame( tableMultiFrame.release() );
519
520 std::unique_ptr< QgsLayoutFrame > frame = std::make_unique< QgsLayoutFrame >( layout, table );
521 QgsLayoutFrame *f = frame.get();
522 table->addFrame( frame.release() );
523 // cppcheck-suppress returnDanglingLifetime
524 return f;
525 } );
526 registry->addLayoutItemGuiMetadata( manualTableItemMetadata.release() );
527
528
529 // elevation profile item
530
531 auto elevationProfileItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutElevationProfile, QObject::tr( "Elevation Profile" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionElevationProfile.svg" ) ),
532 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
533 {
534 return new QgsLayoutElevationProfileWidget( qobject_cast< QgsLayoutItemElevationProfile * >( item ) );
535 }, createRubberBand );
536 elevationProfileItemMetadata->setItemCreationFunction( [ = ]( QgsLayout * layout )->QgsLayoutItem *
537 {
538 std::unique_ptr< QgsLayoutItemElevationProfile > profileItem = std::make_unique< QgsLayoutItemElevationProfile >( layout );
539
540 //set default fonts from settings
541 QgsSettings settings;
542 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
543 if ( !defaultFontString.isEmpty() )
544 {
545 QgsTextFormat format = profileItem->plot()->xAxis().textFormat();
546 QFont f = format.font();
547 QgsFontUtils::setFontFamily( f, defaultFontString );
548 format.setFont( f );
549 profileItem->plot()->xAxis().setTextFormat( format );
550
551 format = profileItem->plot()->yAxis().textFormat();
552 f = format.font();
553 QgsFontUtils::setFontFamily( f, defaultFontString );
554 format.setFont( f );
555 profileItem->plot()->yAxis().setTextFormat( format );
556 }
557 return profileItem.release();
558 } );
559 registry->addLayoutItemGuiMetadata( elevationProfileItemMetadata.release() );
560
561}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
static QgsLayoutItemGuiRegistry * layoutItemGuiRegistry()
Returns the global layout item GUI registry, used for registering the GUI behavior of layout items.
Definition: qgsgui.cpp:134
A widget for configuring layout attribute table items.
A widget for layout elevation profile item settings.
Base class for frame items, which form a layout multiframe item.
static void registerGuiForKnownItemTypes(QgsMapCanvas *mapCanvas)
Registers the GUI handlers for known layout item types.
A widget for configuring layout html items.
A layout table subclass that displays attributes from a vector layer.
void setVectorLayer(QgsVectorLayer *layer)
Sets the vector layer from which to display feature attributes.
A base class for property widgets for layout items.
Stores GUI metadata about a group of layout item classes.
Convenience metadata class that uses static functions to handle layout item GUI behavior.
Registry of available layout item GUI behavior.
bool addItemGroup(const QgsLayoutItemGuiGroup &group)
Registers a new item group with the registry.
bool addLayoutItemGuiMetadata(QgsLayoutItemAbstractGuiMetadata *metadata)
Registers the gui metadata for a new layout item type.
A layout multiframe subclass for HTML content.
A layout item subclass for text labels.
void setHAlign(Qt::AlignmentFlag alignment)
Sets the horizontal alignment of the label.
QSizeF sizeForText() const
Returns the required item size (in layout units) for the label's text to fill the item.
void setText(const QString &text)
Sets the label's preset text.
A layout item subclass for map legends.
void updateLegend()
Updates the model and all legend entries.
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map to associate with the legend.
void setSymbolAlignment(Qt::AlignmentFlag alignment)
Sets the alignment for placement of legend symbols.
QgsLegendStyle & rstyle(QgsLegendStyle::Style s)
Returns reference to modifiable legend style.
void setTitleAlignment(Qt::AlignmentFlag alignment)
Sets the alignment of the legend title.
A layout table subclass that displays manually entered (and formatted) content.
void setTableContents(const QgsTableContents &contents)
Sets the contents of the table.
Layout graphical items for displaying a map.
void zoomToExtent(const QgsRectangle &extent)
Zooms the map so that the specified extent is fully visible within the map item.
void setMapRotation(double rotation)
Sets the rotation for the map - this does not affect the layout item shape, only the way the map is d...
A layout item subclass that displays SVG files or raster format images (jpg, png, ....
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map object for rotation.
@ GridNorth
Align to grid north.
@ ArrowHead
Show arrow marker.
@ LayoutManualTable
Manual (fixed) table.
@ LayoutElevationProfile
Elevation profile item (since QGIS 3.30)
@ LayoutAttributeTable
Attribute table.
@ LayoutPolyline
Polyline shape item.
@ LayoutScaleBar
Scale bar item.
@ LayoutItem
Base class for items.
@ LayoutHtml
Html multiframe item.
@ LayoutPolygon
Polygon shape item.
A layout item subclass for scale bars.
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map item linked to the scalebar.
Qgis::DistanceUnit guessUnits() const
Attempts to guess the most reasonable unit choice for the scalebar, given the current linked map's sc...
void applyDefaultSize(Qgis::DistanceUnit units=Qgis::DistanceUnit::Meters)
Applies the default size to the scale bar (scale bar 1/5 of map item width)
@ Ellipse
Ellipse shape.
@ Rectangle
Rectangle shape.
@ Triangle
Triangle shape.
Base class for graphical items within a QgsLayout.
void setBackgroundColor(const QColor &color)
Sets the background color for this item.
virtual void setId(const QString &id)
Set the item's id name.
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item's position and size to match the passed rect in layout coordinates.
A widget for layout item settings.
A widget for configuring layout manual table items.
Input widget for the configuration of QgsLayoutItemMap.
A widget for configuring layout shape items.
virtual void addFrame(QgsLayoutFrame *frame, bool recalcFrameSizes=true)
Adds a frame to the multiframe.
const QgsLayout * layout() const
Returns the layout the object is attached to.
A widget for configuring layout picture items.
Input widget for QgsLayoutItemPolygon.
Input widget for QgsLayoutItemPolyline.
A widget to define the properties of a QgsLayoutItemScaleBar.
A widget for configuring layout shape items.
QgsLayoutViewEllipseRubberBand is elliptical rubber band for use within QgsLayoutView widgets.
QgsLayoutViewRectangularRubberBand is rectangular rubber band for use within QgsLayoutView widgets.
QgsLayoutViewRubberBand is an abstract base class for temporary rubber band items in various shapes,...
QgsLayoutViewTriangleRubberBand is triangular rubber band for use within QgsLayoutView widgets.
A graphical widget to display and interact with QgsLayouts.
Definition: qgslayoutview.h:50
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:49
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Definition: qgslayout.h:120
void addMultiFrame(QgsLayoutMultiFrame *multiFrame)
Adds a multiFrame to the layout.
Definition: qgslayout.cpp:589
QgsLayoutItemMap * referenceMap() const
Returns the map item which will be used to generate corresponding world files when the layout is expo...
Definition: qgslayout.cpp:447
@ ZViewTool
Z-value for temporary view tool items.
Definition: qgslayout.h:63
QgsProject * project() const
The project associated with the layout.
Definition: qgslayout.cpp:141
void setAlignment(Qt::Alignment alignment)
Sets the alignment for the legend component.
QgsTextFormat & textFormat()
Returns the text format used for rendering this legend component.
@ Group
Legend group title.
@ Subgroup
Legend subgroup title.
@ Title
Legend title.
@ SymbolLabel
Symbol label (excluding icon)
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for rendering this legend component.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:93
double rotation() const
Gets the current map canvas rotation in clockwise degrees.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:481
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Encapsulates the contents and formatting of a single table cell.
Definition: qgstablecell.h:36
Container for all settings relating to text rendering.
Definition: qgstextformat.h:41
void setFont(const QFont &font)
Sets the font used for rendering text.
QFont font() const
Returns the font used for rendering text.
Represents a vector layer which manages a vector based data sets.
QgsLayoutItemMap * findSensibleDefaultLinkedMapItem(QgsLayoutItem *referenceItem)
Attempts to find the best guess at a map item to link referenceItem to, by:
QVector< QgsTableRow > QgsTableContents
A set of table rows.
Definition: qgstablecell.h:220
QVector< QgsTableCell > QgsTableRow
A row of table cells.
Definition: qgstablecell.h:211