QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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
60{
61 // start by trying to find a selected map
62 QList<QgsLayoutItemMap *> mapItems;
63 referenceItem->layout()->layoutItems( mapItems );
64
65 QgsLayoutItemMap *targetMap = nullptr;
66 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
67 {
68 if ( map->isSelected() )
69 {
70 return map;
71 }
72 }
73
74 // nope, no selection... hm, was the item drawn over a map? If so, use the topmost intersecting one
75 double largestZValue = std::numeric_limits< double >::lowest();
76 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
77 {
78 if ( map->collidesWithItem( referenceItem ) && map->zValue() > largestZValue )
79 {
80 targetMap = map;
81 largestZValue = map->zValue();
82 }
83 }
84 if ( targetMap )
85 return targetMap;
86
87 // ah frick it, just use the reference (or biggest!) map
88 return referenceItem->layout()->referenceMap();
89}
90
92{
94
95 registry->addItemGroup( QgsLayoutItemGuiGroup( QStringLiteral( "shapes" ), QObject::tr( "Shape" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicShape.svg" ) ) ) );
96 registry->addItemGroup( QgsLayoutItemGuiGroup( QStringLiteral( "nodes" ), QObject::tr( "Node Item" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddNodesItem.svg" ) ) ) );
97
98 auto createRubberBand = ( []( QgsLayoutView * view )->QgsLayoutViewRubberBand *
99 {
100 return new QgsLayoutViewRectangularRubberBand( view );
101 } );
102 auto createEllipseBand = ( []( QgsLayoutView * view )->QgsLayoutViewRubberBand *
103 {
104 return new QgsLayoutViewEllipticalRubberBand( view );
105 } );
106 auto createTriangleBand = ( []( QgsLayoutView * view )->QgsLayoutViewRubberBand *
107 {
108 return new QgsLayoutViewTriangleRubberBand( view );
109 } );
110
111#if 0
112 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutItem + 1002, QStringLiteral( "test" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLabel.svg" ) ), nullptr, createRubberBand ) );
113#endif
114
115 // map item
116
117 auto mapItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutMap, QObject::tr( "Map" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddMap.svg" ) ),
118 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
119 {
120 return new QgsLayoutMapWidget( qobject_cast< QgsLayoutItemMap * >( item ), mapCanvas );
121 }, createRubberBand );
122 mapItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & )
123 {
124 QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( item );
125 Q_ASSERT( map );
126
127 //get the color for map canvas background and set map background color accordingly
128 map->setBackgroundColor( QgsProject::instance()->backgroundColor() );
129
130 if ( mapCanvas )
131 {
132 map->setMapRotation( mapCanvas->rotation() );
133 map->zoomToExtent( mapCanvas->mapSettings().visibleExtent() );
134 }
135
136 // auto assign a unique id to map items
137 QList<QgsLayoutItemMap *> mapsList;
138 if ( map->layout() )
139 map->layout()->layoutItems( mapsList );
140
141 int counter = mapsList.size() + 1;
142 bool existing = false;
143 while ( true )
144 {
145 existing = false;
146 for ( QgsLayoutItemMap *otherMap : std::as_const( mapsList ) )
147 {
148 if ( map == otherMap )
149 continue;
150
151 if ( otherMap->id() == QObject::tr( "Map %1" ).arg( counter ) )
152 {
153 existing = true;
154 break;
155 }
156 }
157 if ( existing )
158 counter++;
159 else
160 break;
161 }
162 map->setId( QObject::tr( "Map %1" ).arg( counter ) );
163 } );
164 registry->addLayoutItemGuiMetadata( mapItemMetadata.release() );
165
166 // picture item
167
168 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutPicture, QObject::tr( "Picture" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddImage.svg" ) ),
169 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
170 {
171 return new QgsLayoutPictureWidget( qobject_cast< QgsLayoutItemPicture * >( item ) );
172 }, createRubberBand ) );
173
174
175 // label item
176
177 auto labelItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutLabel, QObject::tr( "Label" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionLabel.svg" ) ),
178 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
179 {
180 return new QgsLayoutLabelWidget( qobject_cast< QgsLayoutItemLabel * >( item ) );
181 }, createRubberBand );
182 labelItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & properties )
183 {
184 QgsLayoutItemLabel *label = qobject_cast< QgsLayoutItemLabel * >( item );
185 Q_ASSERT( label );
186
187 label->setText( properties.value( QStringLiteral( "expression" ) ).toString().isEmpty() ? QObject::tr( "Lorem ipsum" ) : QStringLiteral( "[% %1 %]" ).arg( properties.value( QStringLiteral( "expression" ) ).toString() ) );
188 if ( QApplication::isRightToLeft() )
189 {
190 label->setHAlign( Qt::AlignRight );
191 }
192 QSizeF minSize = label->sizeForText();
193 QSizeF currentSize = label->rect().size();
194
195 //make sure label size is sufficient to fit text
196 double labelWidth = std::max( minSize.width(), currentSize.width() );
197 double labelHeight = std::max( minSize.height(), currentSize.height() );
198 label->attemptSetSceneRect( QRectF( label->pos().x(), label->pos().y(), labelWidth, labelHeight ) );
199 } );
200
201 registry->addLayoutItemGuiMetadata( labelItemMetadata.release() );
202
203
204 // legend item
205
206 auto legendItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutLegend, QObject::tr( "Legend" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLegend.svg" ) ),
207 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
208 {
209 return new QgsLayoutLegendWidget( qobject_cast< QgsLayoutItemLegend * >( item ), mapCanvas );
210 }, createRubberBand );
211 legendItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & )
212 {
213 QgsLayoutItemLegend *legend = qobject_cast< QgsLayoutItemLegend * >( item );
214 Q_ASSERT( legend );
215
216 // try to find a good map to link the legend with by default
218
219 if ( QApplication::isRightToLeft() )
220 {
221 // for right-to-left locales, use an appropriate default layout
222 legend->setSymbolAlignment( Qt::AlignRight );
223 legend->rstyle( QgsLegendStyle::Group ).setAlignment( Qt::AlignRight );
224 legend->rstyle( QgsLegendStyle::Subgroup ).setAlignment( Qt::AlignRight );
225 legend->rstyle( QgsLegendStyle::SymbolLabel ).setAlignment( Qt::AlignRight );
226 legend->setTitleAlignment( Qt::AlignRight );
227 }
228
229 //set default legend font from settings
230 QgsSettings settings;
231 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
232 if ( !defaultFontString.isEmpty() )
233 {
234 QFont font;
235 font.setFamily( defaultFontString );
236
238 f.setFont( font );
240
241 f = legend->rstyle( QgsLegendStyle::Group ).textFormat();
242 f.setFont( font );
244
246 f.setFont( font );
248
250 f.setFont( font );
252 }
253
254 legend->updateLegend();
255 } );
256
257 registry->addLayoutItemGuiMetadata( legendItemMetadata.release() );
258
259 // scalebar item
260
261 auto scalebarItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutScaleBar, QObject::tr( "Scale Bar" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionScaleBar.svg" ) ),
262 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
263 {
264 return new QgsLayoutScaleBarWidget( qobject_cast< QgsLayoutItemScaleBar * >( item ) );
265 }, createRubberBand );
266 scalebarItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & )
267 {
268 QgsLayoutItemScaleBar *scalebar = qobject_cast< QgsLayoutItemScaleBar * >( item );
269 Q_ASSERT( scalebar );
270
271 // try to find a good map to link the scalebar with by default
272 if ( QgsLayoutItemMap *targetMap = findSensibleDefaultLinkedMapItem( scalebar ) )
273 {
274 scalebar->setLinkedMap( targetMap );
275 scalebar->applyDefaultSize( scalebar->guessUnits() );
276 }
277 } );
278
279 registry->addLayoutItemGuiMetadata( scalebarItemMetadata.release() );
280
281
282 // north arrow
283 std::unique_ptr< QgsLayoutItemGuiMetadata > northArrowMetadata = std::make_unique< QgsLayoutItemGuiMetadata>(
284 QgsLayoutItemRegistry::LayoutPicture, QObject::tr( "North Arrow" ), QgsApplication::getThemeIcon( QStringLiteral( "/north_arrow.svg" ) ),
285 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
286 {
287 return new QgsLayoutPictureWidget( qobject_cast< QgsLayoutItemPicture * >( item ) );
288 }, createRubberBand );
289 northArrowMetadata->setItemCreationFunction( []( QgsLayout * layout )->QgsLayoutItem *
290 {
291
292 // count how many existing north arrows are already in layout
293 QList< QgsLayoutItemPicture * > pictureItems;
294 layout->layoutItems( pictureItems );
295 int northArrowCount = 0;
296
297 QgsSettings settings;
298 const QString defaultPath = settings.value( QStringLiteral( "LayoutDesigner/defaultNorthArrow" ), QStringLiteral( ":/images/north_arrows/layout_default_north_arrow.svg" ), QgsSettings::Gui ).toString();
299
300 for ( QgsLayoutItemPicture *p : std::as_const( pictureItems ) )
301 {
302 // look for pictures which use the default north arrow svg
303 if ( p->picturePath() == defaultPath )
304 northArrowCount++;
305 }
306
307 std::unique_ptr< QgsLayoutItemPicture > picture = std::make_unique< QgsLayoutItemPicture >( layout );
308 picture->setNorthMode( QgsLayoutItemPicture::GridNorth );
309 picture->setPicturePath( defaultPath );
310 // set an id by default, so that north arrows are discernible in layout item lists
311 picture->setId( northArrowCount > 0 ? QObject::tr( "North Arrow %1" ).arg( northArrowCount + 1 ) : QObject::tr( "North Arrow" ) );
312 return picture.release();
313 } );
314 northArrowMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item, const QVariantMap & )
315 {
316 QgsLayoutItemPicture *picture = qobject_cast< QgsLayoutItemPicture * >( item );
317 Q_ASSERT( picture );
318
319 QList<QgsLayoutItemMap *> mapItems;
320 picture->layout()->layoutItems( mapItems );
321
322 // try to find a good map to link the north arrow with by default
323 picture->setLinkedMap( findSensibleDefaultLinkedMapItem( picture ) );
324 } );
325 registry->addLayoutItemGuiMetadata( northArrowMetadata.release() );
326
327 // shape items
328
329 auto createShapeWidget =
331 {
332 return new QgsLayoutShapeWidget( qobject_cast< QgsLayoutItemShape * >( item ) );
333 };
334
335 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Rectangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), createShapeWidget, createRubberBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout * layout )->QgsLayoutItem*
336 {
337 std::unique_ptr< QgsLayoutItemShape > shape = std::make_unique< QgsLayoutItemShape >( layout );
338 shape->setShapeType( QgsLayoutItemShape::Rectangle );
339 return shape.release();
340 } ) );
341 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Ellipse" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicCircle.svg" ) ), createShapeWidget, createEllipseBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout * layout )->QgsLayoutItem*
342 {
343 std::unique_ptr< QgsLayoutItemShape > shape = std::make_unique< QgsLayoutItemShape >( layout );
344 shape->setShapeType( QgsLayoutItemShape::Ellipse );
345 return shape.release();
346 } ) );
347 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Triangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicTriangle.svg" ) ), createShapeWidget, createTriangleBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout * layout )->QgsLayoutItem*
348 {
349 std::unique_ptr< QgsLayoutItemShape > shape = std::make_unique< QgsLayoutItemShape >( layout );
350 shape->setShapeType( QgsLayoutItemShape::Triangle );
351 return shape.release();
352 } ) );
353
354 // marker
355 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutMarker, QObject::tr( "Marker" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddMarker.svg" ) ),
356 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
357 {
358 return new QgsLayoutMarkerWidget( qobject_cast< QgsLayoutItemMarker * >( item ) );
359 }, nullptr ) );
360
361 // arrow
362 std::unique_ptr< QgsLayoutItemGuiMetadata > arrowMetadata = std::make_unique< QgsLayoutItemGuiMetadata>(
363 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Arrow" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddArrow.svg" ) ),
364 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
365 {
366 return new QgsLayoutPolylineWidget( qobject_cast< QgsLayoutItemPolyline * >( item ) );
367 }, createRubberBand, QString(), true );
368 arrowMetadata->setItemCreationFunction( []( QgsLayout * layout )->QgsLayoutItem *
369 {
370 std::unique_ptr< QgsLayoutItemPolyline > arrow = std::make_unique< QgsLayoutItemPolyline >( layout );
371 arrow->setEndMarker( QgsLayoutItemPolyline::ArrowHead );
372 return arrow.release();
373 } );
374 arrowMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPathItem*
375 {
376 std::unique_ptr< QGraphicsPathItem > band = std::make_unique< QGraphicsPathItem >();
377 band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
378 band->setZValue( QgsLayout::ZViewTool );
379 return band.release();
380 } );
381 registry->addLayoutItemGuiMetadata( arrowMetadata.release() );
382
383 // node items
384
385 std::unique_ptr< QgsLayoutItemGuiMetadata > polygonMetadata = std::make_unique< QgsLayoutItemGuiMetadata >(
386 QgsLayoutItemRegistry::LayoutPolygon, QObject::tr( "Polygon" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolygon.svg" ) ),
387 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
388 {
389 return new QgsLayoutPolygonWidget( qobject_cast< QgsLayoutItemPolygon * >( item ) );
390 }, createRubberBand, QStringLiteral( "nodes" ), true );
391 polygonMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPolygonItem*
392 {
393 std::unique_ptr< QGraphicsPolygonItem > band = std::make_unique< QGraphicsPolygonItem >();
394 band->setBrush( Qt::NoBrush );
395 band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
396 band->setZValue( QgsLayout::ZViewTool );
397 return band.release();
398 } );
399 registry->addLayoutItemGuiMetadata( polygonMetadata.release() );
400
401 std::unique_ptr< QgsLayoutItemGuiMetadata > polylineMetadata = std::make_unique< QgsLayoutItemGuiMetadata>(
402 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Polyline" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolyline.svg" ) ),
403 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
404 {
405 return new QgsLayoutPolylineWidget( qobject_cast< QgsLayoutItemPolyline * >( item ) );
406 }, createRubberBand, QStringLiteral( "nodes" ), true );
407 polylineMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPathItem*
408 {
409 std::unique_ptr< QGraphicsPathItem > band = std::make_unique< QGraphicsPathItem >();
410 band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
411 band->setZValue( QgsLayout::ZViewTool );
412 return band.release();
413 } );
414 registry->addLayoutItemGuiMetadata( polylineMetadata.release() );
415
416
417 // html item
418
419 auto htmlItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutHtml, QObject::tr( "HTML" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddHtml.svg" ) ),
420 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
421 {
422 return new QgsLayoutHtmlWidget( qobject_cast< QgsLayoutFrame * >( item ) );
423 }, createRubberBand );
424 htmlItemMetadata->setItemCreationFunction( [ = ]( QgsLayout * layout )->QgsLayoutItem *
425 {
426 std::unique_ptr< QgsLayoutItemHtml > htmlMultiFrame = std::make_unique< QgsLayoutItemHtml >( layout );
427 QgsLayoutItemHtml *html = htmlMultiFrame.get();
428 layout->addMultiFrame( htmlMultiFrame.release() );
429 std::unique_ptr< QgsLayoutFrame > frame = std::make_unique< QgsLayoutFrame >( layout, html );
430 QgsLayoutFrame *f = frame.get();
431 html->addFrame( frame.release() );
432 return f;
433 } );
434 registry->addLayoutItemGuiMetadata( htmlItemMetadata.release() );
435
436 // attribute table item
437
438 auto attributeTableItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutAttributeTable, QObject::tr( "Attribute Table" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddTable.svg" ) ),
439 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
440 {
441 return new QgsLayoutAttributeTableWidget( qobject_cast< QgsLayoutFrame * >( item ) );
442 }, createRubberBand );
443 attributeTableItemMetadata->setItemCreationFunction( [ = ]( QgsLayout * layout )->QgsLayoutItem *
444 {
445 std::unique_ptr< QgsLayoutItemAttributeTable > tableMultiFrame = std::make_unique< QgsLayoutItemAttributeTable >( layout );
446 QgsLayoutItemAttributeTable *table = tableMultiFrame.get();
447
448 //set first vector layer from layer registry as table source
449 QMap<QString, QgsMapLayer *> layerMap = layout->project()->mapLayers();
450 for ( auto it = layerMap.constBegin() ; it != layerMap.constEnd(); ++it )
451 {
452 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ) )
453 {
454 table->setVectorLayer( vl );
455 break;
456 }
457 }
458
459 //set default table fonts from settings
460 QgsSettings settings;
461 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
462 if ( !defaultFontString.isEmpty() )
463 {
464 QgsTextFormat format;
465 QFont f = format.font();
466 f.setFamily( defaultFontString );
467 format.setFont( f );
468 tableMultiFrame->setContentTextFormat( format );
469 f.setBold( true );
470 format.setFont( f );
471 tableMultiFrame->setHeaderTextFormat( format );
472 }
473
474 layout->addMultiFrame( tableMultiFrame.release() );
475 std::unique_ptr< QgsLayoutFrame > frame = std::make_unique< QgsLayoutFrame >( layout, table );
476 QgsLayoutFrame *f = frame.get();
477 table->addFrame( frame.release() );
478 return f;
479 } );
480 registry->addLayoutItemGuiMetadata( attributeTableItemMetadata.release() );
481
482 // manual table item
483
484 auto manualTableItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutManualTable, QObject::tr( "Fixed Table" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddManualTable.svg" ) ),
485 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
486 {
487 return new QgsLayoutManualTableWidget( qobject_cast< QgsLayoutFrame * >( item ) );
488 }, createRubberBand );
489 manualTableItemMetadata->setItemCreationFunction( [ = ]( QgsLayout * layout )->QgsLayoutItem *
490 {
491 std::unique_ptr< QgsLayoutItemManualTable > tableMultiFrame = std::make_unique< QgsLayoutItemManualTable >( layout );
492 QgsLayoutItemManualTable *table = tableMultiFrame.get();
493
494 // initially start with a 2x2 empty table
495 QgsTableContents contents;
496 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
497 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
498 table->setTableContents( contents );
499
500 //set default table fonts from settings
501 QgsSettings settings;
502 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
503 if ( !defaultFontString.isEmpty() )
504 {
505 QgsTextFormat format;
506 QFont f = format.font();
507 f.setFamily( defaultFontString );
508 format.setFont( f );
509 tableMultiFrame->setContentTextFormat( format );
510 f.setBold( true );
511 format.setFont( f );
512 tableMultiFrame->setHeaderTextFormat( format );
513 }
514
515 layout->addMultiFrame( tableMultiFrame.release() );
516
517 std::unique_ptr< QgsLayoutFrame > frame = std::make_unique< QgsLayoutFrame >( layout, table );
518 QgsLayoutFrame *f = frame.get();
519 table->addFrame( frame.release() );
520 return f;
521 } );
522 registry->addLayoutItemGuiMetadata( manualTableItemMetadata.release() );
523
524
525 // elevation profile item
526
527 auto elevationProfileItemMetadata = std::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutElevationProfile, QObject::tr( "Elevation Profile" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionElevationProfile.svg" ) ),
528 [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
529 {
530 return new QgsLayoutElevationProfileWidget( qobject_cast< QgsLayoutItemElevationProfile * >( item ) );
531 }, createRubberBand );
532 elevationProfileItemMetadata->setItemCreationFunction( [ = ]( QgsLayout * layout )->QgsLayoutItem *
533 {
534 std::unique_ptr< QgsLayoutItemElevationProfile > profileItem = std::make_unique< QgsLayoutItemElevationProfile >( layout );
535
536 //set default fonts from settings
537 QgsSettings settings;
538 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
539 if ( !defaultFontString.isEmpty() )
540 {
541 QgsTextFormat format = profileItem->plot()->xAxis().textFormat();
542 QFont f = format.font();
543 f.setFamily( defaultFontString );
544 format.setFont( f );
545 profileItem->plot()->xAxis().setTextFormat( format );
546
547 format = profileItem->plot()->yAxis().textFormat();
548 f = format.font();
549 f.setFamily( defaultFontString );
550 format.setFont( f );
551 profileItem->plot()->yAxis().setTextFormat( format );
552 }
553 return profileItem.release();
554 } );
555 registry->addLayoutItemGuiMetadata( elevationProfileItemMetadata.release() );
556
557}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsLayoutItemGuiRegistry * layoutItemGuiRegistry()
Returns the global layout item GUI registry, used for registering the GUI behavior of layout items.
Definition: qgsgui.cpp:128
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:51
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:50
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Definition: qgslayout.h:121
void addMultiFrame(QgsLayoutMultiFrame *multiFrame)
Adds a multiFrame to the layout.
Definition: qgslayout.cpp:578
QgsLayoutItemMap * referenceMap() const
Returns the map item which will be used to generate corresponding world files when the layout is expo...
Definition: qgslayout.cpp:436
@ ZViewTool
Z-value for temporary view tool items.
Definition: qgslayout.h:64
QgsProject * project() const
The project associated with the layout.
Definition: qgslayout.cpp:138
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:90
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:477
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:63
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