QGIS API Documentation 3.99.0-Master (e9821da5c6b)
Loading...
Searching...
No Matches
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
18#include "qgsfontutils.h"
19#include "qgsgui.h"
23#include "qgslayoutframe.h"
24#include "qgslayouthtmlwidget.h"
26#include "qgslayoutitemchart.h"
29#include "qgslayoutitemhtml.h"
30#include "qgslayoutitemlabel.h"
31#include "qgslayoutitemlegend.h"
33#include "qgslayoutitemmap.h"
34#include "qgslayoutitemmarker.h"
40#include "qgslayoutitemshape.h"
44#include "qgslayoutmapwidget.h"
52#include "qgsmapcanvas.h"
53#include "qgsplot.h"
54
55#include <QString>
56
57using namespace Qt::StringLiterals;
58
68{
69 // start by trying to find a selected map
70 QList<QgsLayoutItemMap *> mapItems;
71 referenceItem->layout()->layoutItems( mapItems );
72
73 QgsLayoutItemMap *targetMap = nullptr;
74 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
75 {
76 if ( map->isSelected() )
77 {
78 return map;
79 }
80 }
81
82 // nope, no selection... hm, was the item drawn over a map? If so, use the topmost intersecting one
83 double largestZValue = std::numeric_limits<double>::lowest();
84 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
85 {
86 if ( map->collidesWithItem( referenceItem ) && map->zValue() > largestZValue )
87 {
88 targetMap = map;
89 largestZValue = map->zValue();
90 }
91 }
92 if ( targetMap )
93 return targetMap;
94
95 // ah frick it, just use the reference (or biggest!) map
96 return referenceItem->layout()->referenceMap();
97}
98
100{
102
103 registry->addItemGroup( QgsLayoutItemGuiGroup( u"shapes"_s, QObject::tr( "Shape" ), QgsApplication::getThemeIcon( u"/mActionAddBasicShape.svg"_s ) ) );
104 registry->addItemGroup( QgsLayoutItemGuiGroup( u"nodes"_s, QObject::tr( "Node Item" ), QgsApplication::getThemeIcon( u"/mActionAddNodesItem.svg"_s ) ) );
105
106 auto createRubberBand = ( []( QgsLayoutView *view ) -> QgsLayoutViewRubberBand * {
107 return new QgsLayoutViewRectangularRubberBand( view );
108 } );
109 auto createEllipseBand = ( []( QgsLayoutView *view ) -> QgsLayoutViewRubberBand * {
110 return new QgsLayoutViewEllipticalRubberBand( view );
111 } );
112 auto createTriangleBand = ( []( QgsLayoutView *view ) -> QgsLayoutViewRubberBand * {
113 return new QgsLayoutViewTriangleRubberBand( view );
114 } );
115
116#if 0
117 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutItem + 1002, u"test"_s, QgsApplication::getThemeIcon( u"/mActionAddLabel.svg"_s ), nullptr, createRubberBand ) );
118#endif
119
120 // map item
121
122 auto mapItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutMap, QObject::tr( "Map" ), QgsApplication::getThemeIcon( u"/mActionAddMap.svg"_s ), [mapCanvas]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutMapWidget( qobject_cast<QgsLayoutItemMap *>( item ), mapCanvas ); }, createRubberBand );
123 mapItemMetadata->setItemAddedToLayoutFunction( [mapCanvas]( QgsLayoutItem *item, const QVariantMap & ) {
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( u"/mActionAddImage.svg"_s ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutPictureWidget( qobject_cast<QgsLayoutItemPicture *>( item ) ); }, createRubberBand ) );
169
170 // label item
171
172 auto labelItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutLabel, QObject::tr( "Label" ), QgsApplication::getThemeIcon( u"/mActionLabel.svg"_s ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutLabelWidget( qobject_cast<QgsLayoutItemLabel *>( item ) ); }, createRubberBand );
173 labelItemMetadata->setItemAddedToLayoutFunction( []( QgsLayoutItem *item, const QVariantMap &properties ) {
174 QgsLayoutItemLabel *label = qobject_cast<QgsLayoutItemLabel *>( item );
175 Q_ASSERT( label );
176
177 label->setText( properties.value( u"expression"_s ).toString().isEmpty() ? QObject::tr( "Lorem ipsum" ) : u"[% %1 %]"_s.arg( properties.value( u"expression"_s ).toString() ) );
178 if ( QApplication::isRightToLeft() )
179 {
180 label->setHAlign( Qt::AlignRight );
181 }
182 QSizeF minSize = label->sizeForText();
183 QSizeF currentSize = label->rect().size();
184
185 //make sure label size is sufficient to fit text
186 double labelWidth = std::max( minSize.width(), currentSize.width() );
187 double labelHeight = std::max( minSize.height(), currentSize.height() );
188 label->attemptSetSceneRect( QRectF( label->pos().x(), label->pos().y(), labelWidth, labelHeight ) );
189 } );
190
191 labelItemMetadata->setItemDoubleClickedFunction( []( QgsLayoutItem *item, Qgis::MouseHandlesAction action ) {
192 QgsLayoutItemLabel *label = qobject_cast<QgsLayoutItemLabel *>( item );
193
194 // size to text doesn't have any real meaning for HTML content, skip it
195 if ( label->mode() == QgsLayoutItemLabel::ModeHtml )
196 return;
197
198 Q_ASSERT( label );
200 switch ( action )
201 {
209 return;
210
213 break;
214
217 break;
218
221 break;
222
225 break;
226
229 break;
230
233 break;
234
237 break;
238
241 break;
242 }
243
244 label->beginCommand( QObject::tr( "Resize to Text" ) );
245 label->adjustSizeToText( reference );
246 label->endCommand();
247 } );
248
249 registry->addLayoutItemGuiMetadata( labelItemMetadata.release() );
250
251
252 // legend item
253
254 auto legendItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutLegend, QObject::tr( "Legend" ), QgsApplication::getThemeIcon( u"/mActionAddLegend.svg"_s ), [mapCanvas]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutLegendWidget( qobject_cast<QgsLayoutItemLegend *>( item ), mapCanvas ); }, createRubberBand );
255 legendItemMetadata->setItemAddedToLayoutFunction( []( QgsLayoutItem *item, const QVariantMap & ) {
256 QgsLayoutItemLegend *legend = qobject_cast<QgsLayoutItemLegend *>( item );
257 Q_ASSERT( legend );
258
259 // set to default sync mode
261
262 // try to find a good map to link the legend with by default
264
265 if ( QApplication::isRightToLeft() )
266 {
267 // for right-to-left locales, use an appropriate default layout
268 legend->setSymbolAlignment( Qt::AlignRight );
269 legend->rstyle( Qgis::LegendComponent::Group ).setAlignment( Qt::AlignRight );
270 legend->rstyle( Qgis::LegendComponent::Subgroup ).setAlignment( Qt::AlignRight );
271 legend->rstyle( Qgis::LegendComponent::SymbolLabel ).setAlignment( Qt::AlignRight );
272 legend->setTitleAlignment( Qt::AlignRight );
273 }
274
275 //set default legend font from settings
276 QgsSettings settings;
277 const QString defaultFontString = settings.value( u"LayoutDesigner/defaultFont"_s, QVariant(), QgsSettings::Gui ).toString();
278 if ( !defaultFontString.isEmpty() )
279 {
280 QFont font;
281 QgsFontUtils::setFontFamily( font, defaultFontString );
282
284 f.setFont( font );
286
288 f.setFont( font );
290
292 f.setFont( font );
294
296 f.setFont( font );
298 }
299
300 legend->updateLegend();
301 } );
302
303 registry->addLayoutItemGuiMetadata( legendItemMetadata.release() );
304
305 // scalebar item
306
307 auto scalebarItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutScaleBar, QObject::tr( "Scale Bar" ), QgsApplication::getThemeIcon( u"/mActionScaleBar.svg"_s ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutScaleBarWidget( qobject_cast<QgsLayoutItemScaleBar *>( item ) ); }, createRubberBand );
308 scalebarItemMetadata->setItemAddedToLayoutFunction( []( QgsLayoutItem *item, const QVariantMap & ) {
309 QgsLayoutItemScaleBar *scalebar = qobject_cast<QgsLayoutItemScaleBar *>( item );
310 Q_ASSERT( scalebar );
311
312 // default to project's scale calculation method
313 scalebar->setMethod( scalebar->layout()->project()->scaleMethod() );
314
315 // try to find a good map to link the scalebar with by default
316 if ( QgsLayoutItemMap *targetMap = findSensibleDefaultLinkedMapItem( scalebar ) )
317 {
318 scalebar->setLinkedMap( targetMap );
319 scalebar->applyDefaultSize( scalebar->guessUnits() );
320 }
321 } );
322
323 registry->addLayoutItemGuiMetadata( scalebarItemMetadata.release() );
324
325
326 // north arrow
327 auto northArrowMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
328 QgsLayoutItemRegistry::LayoutPicture, QObject::tr( "North Arrow" ), QgsApplication::getThemeIcon( u"/north_arrow.svg"_s ),
329 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
330 return new QgsLayoutPictureWidget( qobject_cast<QgsLayoutItemPicture *>( item ) );
331 },
332 createRubberBand
333 );
334 northArrowMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
335 // count how many existing north arrows are already in layout
336 QList<QgsLayoutItemPicture *> pictureItems;
337 layout->layoutItems( pictureItems );
338 int northArrowCount = 0;
339
340 QgsSettings settings;
341 const QString defaultPath = settings.value( u"LayoutDesigner/defaultNorthArrow"_s, u":/images/north_arrows/layout_default_north_arrow.svg"_s, QgsSettings::Gui ).toString();
342
343 for ( QgsLayoutItemPicture *p : std::as_const( pictureItems ) )
344 {
345 // look for pictures which use the default north arrow svg
346 if ( p->picturePath() == defaultPath )
347 northArrowCount++;
348 }
349
350 auto picture = std::make_unique<QgsLayoutItemPicture>( layout );
351 picture->setNorthMode( QgsLayoutItemPicture::GridNorth );
352 picture->setPicturePath( defaultPath );
353 // set an id by default, so that north arrows are discernible in layout item lists
354 picture->setId( northArrowCount > 0 ? QObject::tr( "North Arrow %1" ).arg( northArrowCount + 1 ) : QObject::tr( "North Arrow" ) );
355 return picture.release();
356 } );
357 northArrowMetadata->setItemAddedToLayoutFunction( []( QgsLayoutItem *item, const QVariantMap & ) {
358 QgsLayoutItemPicture *picture = qobject_cast<QgsLayoutItemPicture *>( item );
359 Q_ASSERT( picture );
360
361 QList<QgsLayoutItemMap *> mapItems;
362 picture->layout()->layoutItems( mapItems );
363
364 // try to find a good map to link the north arrow with by default
365 picture->setLinkedMap( findSensibleDefaultLinkedMapItem( picture ) );
366 } );
367 registry->addLayoutItemGuiMetadata( northArrowMetadata.release() );
368
369 // shape items
370
371 auto createShapeWidget =
372 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
373 return new QgsLayoutShapeWidget( qobject_cast<QgsLayoutItemShape *>( item ) );
374 };
375
376 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Rectangle" ), QgsApplication::getThemeIcon( u"/mActionAddBasicRectangle.svg"_s ), createShapeWidget, createRubberBand, u"shapes"_s, false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout *layout ) -> QgsLayoutItem * {
377 auto shape = std::make_unique<QgsLayoutItemShape>( layout );
378 shape->setShapeType( QgsLayoutItemShape::Rectangle );
379 return shape.release();
380 } ) );
381 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Ellipse" ), QgsApplication::getThemeIcon( u"/mActionAddBasicCircle.svg"_s ), createShapeWidget, createEllipseBand, u"shapes"_s, false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout *layout ) -> QgsLayoutItem * {
382 auto shape = std::make_unique<QgsLayoutItemShape>( layout );
383 shape->setShapeType( QgsLayoutItemShape::Ellipse );
384 return shape.release();
385 } ) );
386 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Triangle" ), QgsApplication::getThemeIcon( u"/mActionAddBasicTriangle.svg"_s ), createShapeWidget, createTriangleBand, u"shapes"_s, false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout *layout ) -> QgsLayoutItem * {
387 auto shape = std::make_unique<QgsLayoutItemShape>( layout );
388 shape->setShapeType( QgsLayoutItemShape::Triangle );
389 return shape.release();
390 } ) );
391
392 // marker
393 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutMarker, QObject::tr( "Marker" ), QgsApplication::getThemeIcon( u"/mActionAddMarker.svg"_s ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutMarkerWidget( qobject_cast<QgsLayoutItemMarker *>( item ) ); }, nullptr ) );
394
395 // arrow
396 auto arrowMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
397 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Arrow" ), QgsApplication::getThemeIcon( u"/mActionAddArrow.svg"_s ),
398 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
399 return new QgsLayoutPolylineWidget( qobject_cast<QgsLayoutItemPolyline *>( item ) );
400 },
401 createRubberBand, QString(), true
402 );
403 arrowMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
404 auto arrow = std::make_unique<QgsLayoutItemPolyline>( layout );
405 arrow->setEndMarker( QgsLayoutItemPolyline::ArrowHead );
406 return arrow.release();
407 } );
408 arrowMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * ) -> QGraphicsItemGroup * {
409 auto band = std::make_unique<QGraphicsItemGroup>();
410 QGraphicsPathItem *poly = new QGraphicsPathItem( band.get() );
411 poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
412
413 QGraphicsPathItem *tempPoly = new QGraphicsPathItem( band.get() );
414 tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );
415
416 band->setZValue( QgsLayout::ZViewTool );
417 return band.release();
418 } );
419 registry->addLayoutItemGuiMetadata( arrowMetadata.release() );
420
421 // node items
422
423 auto polygonMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
424 QgsLayoutItemRegistry::LayoutPolygon, QObject::tr( "Polygon" ), QgsApplication::getThemeIcon( u"/mActionAddPolygon.svg"_s ),
425 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
426 return new QgsLayoutPolygonWidget( qobject_cast<QgsLayoutItemPolygon *>( item ) );
427 },
428 createRubberBand, u"nodes"_s, true
429 );
430 polygonMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * ) -> QGraphicsItemGroup * {
431 auto band = std::make_unique<QGraphicsItemGroup>();
432 QGraphicsPolygonItem *poly = new QGraphicsPolygonItem( band.get() );
433 poly->setBrush( QBrush( QColor( 227, 22, 22, 20 ) ) );
434 poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
435
436 QGraphicsPolygonItem *tempPoly = new QGraphicsPolygonItem( band.get() );
437 tempPoly->setBrush( Qt::NoBrush );
438 tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );
439
440 band->setZValue( QgsLayout::ZViewTool );
441 return band.release();
442 } );
443 registry->addLayoutItemGuiMetadata( polygonMetadata.release() );
444
445 auto polylineMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
446 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Polyline" ), QgsApplication::getThemeIcon( u"/mActionAddPolyline.svg"_s ),
447 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
448 return new QgsLayoutPolylineWidget( qobject_cast<QgsLayoutItemPolyline *>( item ) );
449 },
450 createRubberBand, u"nodes"_s, true
451 );
452 polylineMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * ) -> QGraphicsItemGroup * {
453 auto band = std::make_unique<QGraphicsItemGroup>();
454 QGraphicsPathItem *poly = new QGraphicsPathItem( band.get() );
455 poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
456
457 QGraphicsPathItem *tempPoly = new QGraphicsPathItem( band.get() );
458 tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );
459
460 band->setZValue( QgsLayout::ZViewTool );
461 return band.release();
462 } );
463 registry->addLayoutItemGuiMetadata( polylineMetadata.release() );
464
465
466 // html item
467
468 auto htmlItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutHtml, QObject::tr( "HTML" ), QgsApplication::getThemeIcon( u"/mActionAddHtml.svg"_s ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutHtmlWidget( qobject_cast<QgsLayoutFrame *>( item ) ); }, createRubberBand );
469 htmlItemMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
470 auto htmlMultiFrame = std::make_unique<QgsLayoutItemHtml>( layout );
471 QgsLayoutItemHtml *html = htmlMultiFrame.get();
472 layout->addMultiFrame( htmlMultiFrame.release() );
473 auto frame = std::make_unique<QgsLayoutFrame>( layout, html );
474 QgsLayoutFrame *f = frame.get();
475 html->addFrame( frame.release() );
476 // cppcheck-suppress returnDanglingLifetime
477 return f;
478 } );
479 registry->addLayoutItemGuiMetadata( htmlItemMetadata.release() );
480
481 // attribute table item
482
483 auto attributeTableItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutAttributeTable, QObject::tr( "Attribute Table" ), QgsApplication::getThemeIcon( u"/mActionAddTable.svg"_s ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutAttributeTableWidget( qobject_cast<QgsLayoutFrame *>( item ) ); }, createRubberBand );
484 attributeTableItemMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
485 auto tableMultiFrame = std::make_unique<QgsLayoutItemAttributeTable>( layout );
486 QgsLayoutItemAttributeTable *table = tableMultiFrame.get();
487
488 //set first vector layer from layer registry as table source
489 QMap<QString, QgsMapLayer *> layerMap = layout->project()->mapLayers();
490 for ( auto it = layerMap.constBegin(); it != layerMap.constEnd(); ++it )
491 {
492 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ) )
493 {
494 table->setVectorLayer( vl );
495 break;
496 }
497 }
498
499 //set default table fonts from settings
500 QgsSettings settings;
501 const QString defaultFontString = settings.value( u"LayoutDesigner/defaultFont"_s, QVariant(), QgsSettings::Gui ).toString();
502 if ( !defaultFontString.isEmpty() )
503 {
504 QgsTextFormat format;
505 QFont f = format.font();
506 QgsFontUtils::setFontFamily( f, defaultFontString );
507 format.setFont( f );
508 tableMultiFrame->setContentTextFormat( format );
509 f.setBold( true );
510 format.setFont( f );
511 tableMultiFrame->setHeaderTextFormat( format );
512 }
513
514 layout->addMultiFrame( tableMultiFrame.release() );
515 auto frame = std::make_unique<QgsLayoutFrame>( layout, table );
516 QgsLayoutFrame *f = frame.get();
517 table->addFrame( frame.release() );
518 // cppcheck-suppress returnDanglingLifetime
519 return f;
520 } );
521 registry->addLayoutItemGuiMetadata( attributeTableItemMetadata.release() );
522
523 // manual table item
524
525 auto manualTableItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutManualTable, QObject::tr( "Fixed Table" ), QgsApplication::getThemeIcon( u"/mActionAddManualTable.svg"_s ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutManualTableWidget( qobject_cast<QgsLayoutFrame *>( item ) ); }, createRubberBand );
526 manualTableItemMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
527 auto tableMultiFrame = std::make_unique<QgsLayoutItemManualTable>( layout );
528 QgsLayoutItemManualTable *table = tableMultiFrame.get();
529
530 // initially start with a 2x2 empty table
531 QgsTableContents contents;
532 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
533 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
534 table->setTableContents( contents );
535
536 //set default table fonts from settings
537 QgsSettings settings;
538 const QString defaultFontString = settings.value( u"LayoutDesigner/defaultFont"_s, QVariant(), QgsSettings::Gui ).toString();
539 if ( !defaultFontString.isEmpty() )
540 {
541 QgsTextFormat format;
542 QFont f = format.font();
543 QgsFontUtils::setFontFamily( f, defaultFontString );
544 format.setFont( f );
545 tableMultiFrame->setContentTextFormat( format );
546 f.setBold( true );
547 format.setFont( f );
548 tableMultiFrame->setHeaderTextFormat( format );
549 }
550
551 layout->addMultiFrame( tableMultiFrame.release() );
552
553 auto frame = std::make_unique<QgsLayoutFrame>( layout, table );
554 QgsLayoutFrame *f = frame.get();
555 table->addFrame( frame.release() );
556 // cppcheck-suppress returnDanglingLifetime
557 return f;
558 } );
559 manualTableItemMetadata->setItemDoubleClickedFunction( []( QgsLayoutItem *item, Qgis::MouseHandlesAction ) {
560 QgsLayoutManualTableWidget::openTableDesigner( qobject_cast<QgsLayoutFrame *>( item ) );
561 } );
562 registry->addLayoutItemGuiMetadata( manualTableItemMetadata.release() );
563
564
565 // elevation profile item
566
567 auto elevationProfileItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutElevationProfile, QObject::tr( "Elevation Profile" ), QgsApplication::getThemeIcon( u"/mActionElevationProfile.svg"_s ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutElevationProfileWidget( qobject_cast<QgsLayoutItemElevationProfile *>( item ) ); }, createRubberBand );
568 elevationProfileItemMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
569 auto profileItem = std::make_unique<QgsLayoutItemElevationProfile>( layout );
570
571 //set default fonts from settings
572 QgsSettings settings;
573 const QString defaultFontString = settings.value( u"LayoutDesigner/defaultFont"_s, QVariant(), QgsSettings::Gui ).toString();
574 if ( !defaultFontString.isEmpty() )
575 {
576 QgsTextFormat format = profileItem->plot()->xAxis().textFormat();
577 QFont f = format.font();
578 QgsFontUtils::setFontFamily( f, defaultFontString );
579 format.setFont( f );
580 profileItem->plot()->xAxis().setTextFormat( format );
581
582 format = profileItem->plot()->yAxis().textFormat();
583 f = format.font();
584 QgsFontUtils::setFontFamily( f, defaultFontString );
585 format.setFont( f );
586 profileItem->plot()->yAxis().setTextFormat( format );
587 }
588 return profileItem.release();
589 } );
590 registry->addLayoutItemGuiMetadata( elevationProfileItemMetadata.release() );
591
592 // chart item
593
594 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutChart, QObject::tr( "Chart" ), QgsApplication::getThemeIcon( u"/mActionAddChart.svg"_s ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutChartWidget( qobject_cast<QgsLayoutItemChart *>( item ) ); }, createRubberBand ) );
595}
@ Group
Legend group title.
Definition qgis.h:4662
@ Subgroup
Legend subgroup title.
Definition qgis.h:4663
@ Title
Legend title.
Definition qgis.h:4661
@ SymbolLabel
Symbol label (excluding icon).
Definition qgis.h:4665
MouseHandlesAction
Action to be performed by the mouse handles.
Definition qgis.h:6314
@ ResizeRightDown
Resize right down (Bottom right handle).
Definition qgis.h:6323
@ NoAction
No action.
Definition qgis.h:6329
@ SelectItem
Select item.
Definition qgis.h:6328
@ ResizeLeftUp
Resize left up (Top left handle).
Definition qgis.h:6320
@ ResizeLeftDown
Resize left down (Bottom left handle).
Definition qgis.h:6322
@ ResizeRight
Resize right (Right handle).
Definition qgis.h:6319
@ MoveItem
Move item.
Definition qgis.h:6315
@ ResizeDown
Resize down (Bottom handle).
Definition qgis.h:6317
@ RotateTopRight
Rotate from top right handle.
Definition qgis.h:6325
@ RotateTopLeft
Rotate from top left handle.
Definition qgis.h:6324
@ RotateBottomRight
Rotate right bottom right handle.
Definition qgis.h:6327
@ ResizeRightUp
Resize right up (Top right handle).
Definition qgis.h:6321
@ ResizeLeft
Resize left (Left handle).
Definition qgis.h:6318
@ RotateBottomLeft
Rotate from bottom left handle.
Definition qgis.h:6326
@ ResizeUp
Resize up (Top handle).
Definition qgis.h:6316
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:154
A widget for configuring layout attribute table items.
A widget for configuring layout chart 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.
Mode mode() const
Returns the label's current mode.
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.
void adjustSizeToText()
Resizes the item so that the label's text fits to the item.
@ ModeHtml
Label displays rendered HTML content.
A layout item subclass for map legends.
QgsLegendStyle & rstyle(Qgis::LegendComponent s)
Returns reference to modifiable legend style.
static const QgsSettingsEntryEnumFlag< Qgis::LegendSyncMode > * settingDefaultLegendSyncMode
Settings entry - Layout legend synchronization mode.
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.
void setSyncMode(Qgis::LegendSyncMode mode)
Sets the legend's synchronization mode.
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.
@ LayoutAttributeTable
Attribute table.
@ LayoutPolyline
Polyline shape 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.
void setMethod(Qgis::ScaleCalculationMethod method)
Sets the scale calculation method, which determines how the bar's scale will be calculated.
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.
void beginCommand(const QString &commandText, UndoCommand command=UndoNone)
Starts new undo command for this item.
ReferencePoint
Fixed position reference point.
@ LowerMiddle
Lower center of item.
@ MiddleLeft
Middle left of item.
@ UpperRight
Upper right corner of item.
@ LowerLeft
Lower left corner of item.
@ UpperLeft
Upper left corner of item.
@ UpperMiddle
Upper center of item.
@ MiddleRight
Middle right of item.
@ LowerRight
Lower right corner of item.
void endCommand()
Completes the current item command and push it onto the layout's undo stack.
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.
static void openTableDesigner(QgsLayoutFrame *frame, QWidget *parent=nullptr)
Creates and open the table editor dialog.
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.
An elliptical rubber band for use within QgsLayoutView widgets.
A rectangular rubber band for use within QgsLayoutView widgets.
An abstract base class for temporary rubber band items in various shapes, for use within QgsLayoutVie...
A triangular rubber band for use within QgsLayoutView widgets.
A graphical widget to display and interact with QgsLayouts.
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.
QgsLayoutItemMap * referenceMap() const
Returns the map item which will be used to generate corresponding world files when the layout is expo...
@ ZViewTool
Z-value for temporary view tool items.
Definition qgslayout.h:64
QgsProject * project() const
The project associated with the layout.
void setAlignment(Qt::Alignment alignment)
Sets the alignment for the legend component.
QgsTextFormat & textFormat()
Returns the text format used for rendering this legend component.
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.
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.
Qgis::ScaleCalculationMethod scaleMethod
Definition qgsproject.h:135
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
Stores settings for use within QGIS.
Definition qgssettings.h:68
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.
Container for all settings relating to text rendering.
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 dataset.
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.
QVector< QgsTableCell > QgsTableRow
A row of table cells.