QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
64{
65 // start by trying to find a selected map
66 QList<QgsLayoutItemMap *> mapItems;
67 referenceItem->layout()->layoutItems( mapItems );
68
69 QgsLayoutItemMap *targetMap = nullptr;
70 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
71 {
72 if ( map->isSelected() )
73 {
74 return map;
75 }
76 }
77
78 // nope, no selection... hm, was the item drawn over a map? If so, use the topmost intersecting one
79 double largestZValue = std::numeric_limits<double>::lowest();
80 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
81 {
82 if ( map->collidesWithItem( referenceItem ) && map->zValue() > largestZValue )
83 {
84 targetMap = map;
85 largestZValue = map->zValue();
86 }
87 }
88 if ( targetMap )
89 return targetMap;
90
91 // ah frick it, just use the reference (or biggest!) map
92 return referenceItem->layout()->referenceMap();
93}
94
96{
98
99 registry->addItemGroup( QgsLayoutItemGuiGroup( QStringLiteral( "shapes" ), QObject::tr( "Shape" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicShape.svg" ) ) ) );
100 registry->addItemGroup( QgsLayoutItemGuiGroup( QStringLiteral( "nodes" ), QObject::tr( "Node Item" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddNodesItem.svg" ) ) ) );
101
102 auto createRubberBand = ( []( QgsLayoutView *view ) -> QgsLayoutViewRubberBand * {
103 return new QgsLayoutViewRectangularRubberBand( view );
104 } );
105 auto createEllipseBand = ( []( QgsLayoutView *view ) -> QgsLayoutViewRubberBand * {
106 return new QgsLayoutViewEllipticalRubberBand( view );
107 } );
108 auto createTriangleBand = ( []( QgsLayoutView *view ) -> QgsLayoutViewRubberBand * {
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" ) ), [mapCanvas]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutMapWidget( qobject_cast<QgsLayoutItemMap *>( item ), mapCanvas ); }, createRubberBand );
119 mapItemMetadata->setItemAddedToLayoutFunction( [mapCanvas]( QgsLayoutItem *item, const QVariantMap & ) {
120 QgsLayoutItemMap *map = qobject_cast<QgsLayoutItemMap *>( item );
121 Q_ASSERT( map );
122
123 //get the color for map canvas background and set map background color accordingly
124 map->setBackgroundColor( QgsProject::instance()->backgroundColor() );
125
126 if ( mapCanvas )
127 {
128 map->setMapRotation( mapCanvas->rotation() );
129 map->zoomToExtent( mapCanvas->mapSettings().visibleExtent() );
130 }
131
132 // auto assign a unique id to map items
133 QList<QgsLayoutItemMap *> mapsList;
134 if ( map->layout() )
135 map->layout()->layoutItems( mapsList );
136
137 int counter = mapsList.size() + 1;
138 bool existing = false;
139 while ( true )
140 {
141 existing = false;
142 for ( QgsLayoutItemMap *otherMap : std::as_const( mapsList ) )
143 {
144 if ( map == otherMap )
145 continue;
146
147 if ( otherMap->id() == QObject::tr( "Map %1" ).arg( counter ) )
148 {
149 existing = true;
150 break;
151 }
152 }
153 if ( existing )
154 counter++;
155 else
156 break;
157 }
158 map->setId( QObject::tr( "Map %1" ).arg( counter ) );
159 } );
160 registry->addLayoutItemGuiMetadata( mapItemMetadata.release() );
161
162 // picture item
163
164 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutPicture, QObject::tr( "Picture" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddImage.svg" ) ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutPictureWidget( qobject_cast<QgsLayoutItemPicture *>( item ) ); }, createRubberBand ) );
165
166 // label item
167
168 auto labelItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutLabel, QObject::tr( "Label" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionLabel.svg" ) ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutLabelWidget( qobject_cast<QgsLayoutItemLabel *>( item ) ); }, createRubberBand );
169 labelItemMetadata->setItemAddedToLayoutFunction( []( QgsLayoutItem *item, const QVariantMap &properties ) {
170 QgsLayoutItemLabel *label = qobject_cast<QgsLayoutItemLabel *>( item );
171 Q_ASSERT( label );
172
173 label->setText( properties.value( QStringLiteral( "expression" ) ).toString().isEmpty() ? QObject::tr( "Lorem ipsum" ) : QStringLiteral( "[% %1 %]" ).arg( properties.value( QStringLiteral( "expression" ) ).toString() ) );
174 if ( QApplication::isRightToLeft() )
175 {
176 label->setHAlign( Qt::AlignRight );
177 }
178 QSizeF minSize = label->sizeForText();
179 QSizeF currentSize = label->rect().size();
180
181 //make sure label size is sufficient to fit text
182 double labelWidth = std::max( minSize.width(), currentSize.width() );
183 double labelHeight = std::max( minSize.height(), currentSize.height() );
184 label->attemptSetSceneRect( QRectF( label->pos().x(), label->pos().y(), labelWidth, labelHeight ) );
185 } );
186
187 labelItemMetadata->setItemDoubleClickedFunction( []( QgsLayoutItem *item, Qgis::MouseHandlesAction action ) {
188 QgsLayoutItemLabel *label = qobject_cast<QgsLayoutItemLabel *>( item );
189
190 // size to text doesn't have any real meaning for HTML content, skip it
191 if ( label->mode() == QgsLayoutItemLabel::ModeHtml )
192 return;
193
194 Q_ASSERT( label );
196 switch ( action )
197 {
205 return;
206
209 break;
210
213 break;
214
217 break;
218
221 break;
222
225 break;
226
229 break;
230
233 break;
234
237 break;
238 }
239
240 label->beginCommand( QObject::tr( "Resize to Text" ) );
241 label->adjustSizeToText( reference );
242 label->endCommand();
243 } );
244
245 registry->addLayoutItemGuiMetadata( labelItemMetadata.release() );
246
247
248 // legend item
249
250 auto legendItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutLegend, QObject::tr( "Legend" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLegend.svg" ) ), [mapCanvas]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutLegendWidget( qobject_cast<QgsLayoutItemLegend *>( item ), mapCanvas ); }, createRubberBand );
251 legendItemMetadata->setItemAddedToLayoutFunction( []( QgsLayoutItem *item, const QVariantMap & ) {
252 QgsLayoutItemLegend *legend = qobject_cast<QgsLayoutItemLegend *>( item );
253 Q_ASSERT( legend );
254
255 // try to find a good map to link the legend with by default
257
258 if ( QApplication::isRightToLeft() )
259 {
260 // for right-to-left locales, use an appropriate default layout
261 legend->setSymbolAlignment( Qt::AlignRight );
262 legend->rstyle( Qgis::LegendComponent::Group ).setAlignment( Qt::AlignRight );
263 legend->rstyle( Qgis::LegendComponent::Subgroup ).setAlignment( Qt::AlignRight );
264 legend->rstyle( Qgis::LegendComponent::SymbolLabel ).setAlignment( Qt::AlignRight );
265 legend->setTitleAlignment( Qt::AlignRight );
266 }
267
268 //set default legend font from settings
269 QgsSettings settings;
270 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
271 if ( !defaultFontString.isEmpty() )
272 {
273 QFont font;
274 QgsFontUtils::setFontFamily( font, defaultFontString );
275
277 f.setFont( font );
279
281 f.setFont( font );
283
285 f.setFont( font );
287
289 f.setFont( font );
291 }
292
293 legend->updateLegend();
294 } );
295
296 registry->addLayoutItemGuiMetadata( legendItemMetadata.release() );
297
298 // scalebar item
299
300 auto scalebarItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutScaleBar, QObject::tr( "Scale Bar" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionScaleBar.svg" ) ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutScaleBarWidget( qobject_cast<QgsLayoutItemScaleBar *>( item ) ); }, createRubberBand );
301 scalebarItemMetadata->setItemAddedToLayoutFunction( []( QgsLayoutItem *item, const QVariantMap & ) {
302 QgsLayoutItemScaleBar *scalebar = qobject_cast<QgsLayoutItemScaleBar *>( item );
303 Q_ASSERT( scalebar );
304
305 // default to project's scale calculation method
306 scalebar->setMethod( scalebar->layout()->project()->scaleMethod() );
307
308 // try to find a good map to link the scalebar with by default
309 if ( QgsLayoutItemMap *targetMap = findSensibleDefaultLinkedMapItem( scalebar ) )
310 {
311 scalebar->setLinkedMap( targetMap );
312 scalebar->applyDefaultSize( scalebar->guessUnits() );
313 }
314 } );
315
316 registry->addLayoutItemGuiMetadata( scalebarItemMetadata.release() );
317
318
319 // north arrow
320 auto northArrowMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
321 QgsLayoutItemRegistry::LayoutPicture, QObject::tr( "North Arrow" ), QgsApplication::getThemeIcon( QStringLiteral( "/north_arrow.svg" ) ),
322 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
323 return new QgsLayoutPictureWidget( qobject_cast<QgsLayoutItemPicture *>( item ) );
324 },
325 createRubberBand
326 );
327 northArrowMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
328 // count how many existing north arrows are already in layout
329 QList<QgsLayoutItemPicture *> pictureItems;
330 layout->layoutItems( pictureItems );
331 int northArrowCount = 0;
332
333 QgsSettings settings;
334 const QString defaultPath = settings.value( QStringLiteral( "LayoutDesigner/defaultNorthArrow" ), QStringLiteral( ":/images/north_arrows/layout_default_north_arrow.svg" ), QgsSettings::Gui ).toString();
335
336 for ( QgsLayoutItemPicture *p : std::as_const( pictureItems ) )
337 {
338 // look for pictures which use the default north arrow svg
339 if ( p->picturePath() == defaultPath )
340 northArrowCount++;
341 }
342
343 auto picture = std::make_unique<QgsLayoutItemPicture>( layout );
344 picture->setNorthMode( QgsLayoutItemPicture::GridNorth );
345 picture->setPicturePath( defaultPath );
346 // set an id by default, so that north arrows are discernible in layout item lists
347 picture->setId( northArrowCount > 0 ? QObject::tr( "North Arrow %1" ).arg( northArrowCount + 1 ) : QObject::tr( "North Arrow" ) );
348 return picture.release();
349 } );
350 northArrowMetadata->setItemAddedToLayoutFunction( []( QgsLayoutItem *item, const QVariantMap & ) {
351 QgsLayoutItemPicture *picture = qobject_cast<QgsLayoutItemPicture *>( item );
352 Q_ASSERT( picture );
353
354 QList<QgsLayoutItemMap *> mapItems;
355 picture->layout()->layoutItems( mapItems );
356
357 // try to find a good map to link the north arrow with by default
358 picture->setLinkedMap( findSensibleDefaultLinkedMapItem( picture ) );
359 } );
360 registry->addLayoutItemGuiMetadata( northArrowMetadata.release() );
361
362 // shape items
363
364 auto createShapeWidget =
365 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
366 return new QgsLayoutShapeWidget( qobject_cast<QgsLayoutItemShape *>( item ) );
367 };
368
369 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Rectangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), createShapeWidget, createRubberBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout *layout ) -> QgsLayoutItem * {
370 auto shape = std::make_unique<QgsLayoutItemShape>( layout );
371 shape->setShapeType( QgsLayoutItemShape::Rectangle );
372 return shape.release();
373 } ) );
374 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Ellipse" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicCircle.svg" ) ), createShapeWidget, createEllipseBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout *layout ) -> QgsLayoutItem * {
375 auto shape = std::make_unique<QgsLayoutItemShape>( layout );
376 shape->setShapeType( QgsLayoutItemShape::Ellipse );
377 return shape.release();
378 } ) );
379 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Triangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicTriangle.svg" ) ), createShapeWidget, createTriangleBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout *layout ) -> QgsLayoutItem * {
380 auto shape = std::make_unique<QgsLayoutItemShape>( layout );
381 shape->setShapeType( QgsLayoutItemShape::Triangle );
382 return shape.release();
383 } ) );
384
385 // marker
386 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutMarker, QObject::tr( "Marker" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddMarker.svg" ) ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutMarkerWidget( qobject_cast<QgsLayoutItemMarker *>( item ) ); }, nullptr ) );
387
388 // arrow
389 auto arrowMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
390 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Arrow" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddArrow.svg" ) ),
391 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
392 return new QgsLayoutPolylineWidget( qobject_cast<QgsLayoutItemPolyline *>( item ) );
393 },
394 createRubberBand, QString(), true
395 );
396 arrowMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
397 auto arrow = std::make_unique<QgsLayoutItemPolyline>( layout );
398 arrow->setEndMarker( QgsLayoutItemPolyline::ArrowHead );
399 return arrow.release();
400 } );
401 arrowMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * ) -> QGraphicsItemGroup * {
402 auto band = std::make_unique<QGraphicsItemGroup>();
403 QGraphicsPathItem *poly = new QGraphicsPathItem( band.get() );
404 poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
405
406 QGraphicsPathItem *tempPoly = new QGraphicsPathItem( band.get() );
407 tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );
408
409 band->setZValue( QgsLayout::ZViewTool );
410 return band.release();
411 } );
412 registry->addLayoutItemGuiMetadata( arrowMetadata.release() );
413
414 // node items
415
416 auto polygonMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
417 QgsLayoutItemRegistry::LayoutPolygon, QObject::tr( "Polygon" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolygon.svg" ) ),
418 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
419 return new QgsLayoutPolygonWidget( qobject_cast<QgsLayoutItemPolygon *>( item ) );
420 },
421 createRubberBand, QStringLiteral( "nodes" ), true
422 );
423 polygonMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * ) -> QGraphicsItemGroup * {
424 auto band = std::make_unique<QGraphicsItemGroup>();
425 QGraphicsPolygonItem *poly = new QGraphicsPolygonItem( band.get() );
426 poly->setBrush( QBrush( QColor( 227, 22, 22, 20 ) ) );
427 poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
428
429 QGraphicsPolygonItem *tempPoly = new QGraphicsPolygonItem( band.get() );
430 tempPoly->setBrush( Qt::NoBrush );
431 tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );
432
433 band->setZValue( QgsLayout::ZViewTool );
434 return band.release();
435 } );
436 registry->addLayoutItemGuiMetadata( polygonMetadata.release() );
437
438 auto polylineMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
439 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Polyline" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolyline.svg" ) ),
440 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
441 return new QgsLayoutPolylineWidget( qobject_cast<QgsLayoutItemPolyline *>( item ) );
442 },
443 createRubberBand, QStringLiteral( "nodes" ), true
444 );
445 polylineMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * ) -> QGraphicsItemGroup * {
446 auto band = std::make_unique<QGraphicsItemGroup>();
447 QGraphicsPathItem *poly = new QGraphicsPathItem( band.get() );
448 poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
449
450 QGraphicsPathItem *tempPoly = new QGraphicsPathItem( band.get() );
451 tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );
452
453 band->setZValue( QgsLayout::ZViewTool );
454 return band.release();
455 } );
456 registry->addLayoutItemGuiMetadata( polylineMetadata.release() );
457
458
459 // html item
460
461 auto htmlItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutHtml, QObject::tr( "HTML" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddHtml.svg" ) ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutHtmlWidget( qobject_cast<QgsLayoutFrame *>( item ) ); }, createRubberBand );
462 htmlItemMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
463 auto htmlMultiFrame = std::make_unique<QgsLayoutItemHtml>( layout );
464 QgsLayoutItemHtml *html = htmlMultiFrame.get();
465 layout->addMultiFrame( htmlMultiFrame.release() );
466 auto frame = std::make_unique<QgsLayoutFrame>( layout, html );
467 QgsLayoutFrame *f = frame.get();
468 html->addFrame( frame.release() );
469 // cppcheck-suppress returnDanglingLifetime
470 return f;
471 } );
472 registry->addLayoutItemGuiMetadata( htmlItemMetadata.release() );
473
474 // attribute table item
475
476 auto attributeTableItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutAttributeTable, QObject::tr( "Attribute Table" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddTable.svg" ) ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutAttributeTableWidget( qobject_cast<QgsLayoutFrame *>( item ) ); }, createRubberBand );
477 attributeTableItemMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
478 auto tableMultiFrame = std::make_unique<QgsLayoutItemAttributeTable>( layout );
479 QgsLayoutItemAttributeTable *table = tableMultiFrame.get();
480
481 //set first vector layer from layer registry as table source
482 QMap<QString, QgsMapLayer *> layerMap = layout->project()->mapLayers();
483 for ( auto it = layerMap.constBegin(); it != layerMap.constEnd(); ++it )
484 {
485 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ) )
486 {
487 table->setVectorLayer( vl );
488 break;
489 }
490 }
491
492 //set default table fonts from settings
493 QgsSettings settings;
494 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
495 if ( !defaultFontString.isEmpty() )
496 {
497 QgsTextFormat format;
498 QFont f = format.font();
499 QgsFontUtils::setFontFamily( f, defaultFontString );
500 format.setFont( f );
501 tableMultiFrame->setContentTextFormat( format );
502 f.setBold( true );
503 format.setFont( f );
504 tableMultiFrame->setHeaderTextFormat( format );
505 }
506
507 layout->addMultiFrame( tableMultiFrame.release() );
508 auto frame = std::make_unique<QgsLayoutFrame>( layout, table );
509 QgsLayoutFrame *f = frame.get();
510 table->addFrame( frame.release() );
511 // cppcheck-suppress returnDanglingLifetime
512 return f;
513 } );
514 registry->addLayoutItemGuiMetadata( attributeTableItemMetadata.release() );
515
516 // manual table item
517
518 auto manualTableItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutManualTable, QObject::tr( "Fixed Table" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddManualTable.svg" ) ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutManualTableWidget( qobject_cast<QgsLayoutFrame *>( item ) ); }, createRubberBand );
519 manualTableItemMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
520 auto tableMultiFrame = std::make_unique<QgsLayoutItemManualTable>( layout );
521 QgsLayoutItemManualTable *table = tableMultiFrame.get();
522
523 // initially start with a 2x2 empty table
524 QgsTableContents contents;
525 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
526 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
527 table->setTableContents( contents );
528
529 //set default table fonts from settings
530 QgsSettings settings;
531 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
532 if ( !defaultFontString.isEmpty() )
533 {
534 QgsTextFormat format;
535 QFont f = format.font();
536 QgsFontUtils::setFontFamily( f, defaultFontString );
537 format.setFont( f );
538 tableMultiFrame->setContentTextFormat( format );
539 f.setBold( true );
540 format.setFont( f );
541 tableMultiFrame->setHeaderTextFormat( format );
542 }
543
544 layout->addMultiFrame( tableMultiFrame.release() );
545
546 auto frame = std::make_unique<QgsLayoutFrame>( layout, table );
547 QgsLayoutFrame *f = frame.get();
548 table->addFrame( frame.release() );
549 // cppcheck-suppress returnDanglingLifetime
550 return f;
551 } );
552 manualTableItemMetadata->setItemDoubleClickedFunction( []( QgsLayoutItem *item, Qgis::MouseHandlesAction ) {
553 QgsLayoutManualTableWidget::openTableDesigner( qobject_cast<QgsLayoutFrame *>( item ) );
554 } );
555 registry->addLayoutItemGuiMetadata( manualTableItemMetadata.release() );
556
557
558 // elevation profile item
559
560 auto elevationProfileItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutElevationProfile, QObject::tr( "Elevation Profile" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionElevationProfile.svg" ) ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutElevationProfileWidget( qobject_cast<QgsLayoutItemElevationProfile *>( item ) ); }, createRubberBand );
561 elevationProfileItemMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
562 auto profileItem = std::make_unique<QgsLayoutItemElevationProfile>( layout );
563
564 //set default fonts from settings
565 QgsSettings settings;
566 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
567 if ( !defaultFontString.isEmpty() )
568 {
569 QgsTextFormat format = profileItem->plot()->xAxis().textFormat();
570 QFont f = format.font();
571 QgsFontUtils::setFontFamily( f, defaultFontString );
572 format.setFont( f );
573 profileItem->plot()->xAxis().setTextFormat( format );
574
575 format = profileItem->plot()->yAxis().textFormat();
576 f = format.font();
577 QgsFontUtils::setFontFamily( f, defaultFontString );
578 format.setFont( f );
579 profileItem->plot()->yAxis().setTextFormat( format );
580 }
581 return profileItem.release();
582 } );
583 registry->addLayoutItemGuiMetadata( elevationProfileItemMetadata.release() );
584
585 // chart item
586
587 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutChart, QObject::tr( "Chart" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddChart.svg" ) ), []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutChartWidget( qobject_cast<QgsLayoutItemChart *>( item ) ); }, createRubberBand ) );
588}
@ Group
Legend group title.
Definition qgis.h:4579
@ Subgroup
Legend subgroup title.
Definition qgis.h:4580
@ Title
Legend title.
Definition qgis.h:4578
@ SymbolLabel
Symbol label (excluding icon).
Definition qgis.h:4582
MouseHandlesAction
Action to be performed by the mouse handles.
Definition qgis.h:6024
@ ResizeRightDown
Resize right down (Bottom right handle).
Definition qgis.h:6033
@ NoAction
No action.
Definition qgis.h:6039
@ SelectItem
Select item.
Definition qgis.h:6038
@ ResizeLeftUp
Resize left up (Top left handle).
Definition qgis.h:6030
@ ResizeLeftDown
Resize left down (Bottom left handle).
Definition qgis.h:6032
@ ResizeRight
Resize right (Right handle).
Definition qgis.h:6029
@ MoveItem
Move item.
Definition qgis.h:6025
@ ResizeDown
Resize down (Bottom handle).
Definition qgis.h:6027
@ RotateTopRight
Rotate from top right handle.
Definition qgis.h:6035
@ RotateTopLeft
Rotate from top left handle.
Definition qgis.h:6034
@ RotateBottomRight
Rotate right bottom right handle.
Definition qgis.h:6037
@ ResizeRightUp
Resize right up (Top right handle).
Definition qgis.h:6031
@ ResizeLeft
Resize left (Left handle).
Definition qgis.h:6028
@ RotateBottomLeft
Rotate from bottom left handle.
Definition qgis.h:6036
@ ResizeUp
Resize up (Top handle).
Definition qgis.h:6026
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:151
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.
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 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:131
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:65
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.