QGIS API Documentation 3.41.0-Master (af5edcb665c)
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#include "qgsgui.h"
21#include "qgslayoutitemshape.h"
22#include "qgslayoutmapwidget.h"
25#include "qgslayoutitemmap.h"
28#include "qgslayoutitemmarker.h"
33#include "qgslayoutitemlabel.h"
36#include "qgslayoutitemlegend.h"
39#include "qgslayoutframe.h"
40#include "qgslayoutitemhtml.h"
41#include "qgslayouthtmlwidget.h"
48#include "qgsmapcanvas.h"
49#include "qgsplot.h"
50#include "qgsfontutils.h"
51
61{
62 // start by trying to find a selected map
63 QList<QgsLayoutItemMap *> mapItems;
64 referenceItem->layout()->layoutItems( mapItems );
65
66 QgsLayoutItemMap *targetMap = nullptr;
67 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
68 {
69 if ( map->isSelected() )
70 {
71 return map;
72 }
73 }
74
75 // nope, no selection... hm, was the item drawn over a map? If so, use the topmost intersecting one
76 double largestZValue = std::numeric_limits<double>::lowest();
77 for ( QgsLayoutItemMap *map : std::as_const( mapItems ) )
78 {
79 if ( map->collidesWithItem( referenceItem ) && map->zValue() > largestZValue )
80 {
81 targetMap = map;
82 largestZValue = map->zValue();
83 }
84 }
85 if ( targetMap )
86 return targetMap;
87
88 // ah frick it, just use the reference (or biggest!) map
89 return referenceItem->layout()->referenceMap();
90}
91
93{
95
96 registry->addItemGroup( QgsLayoutItemGuiGroup( QStringLiteral( "shapes" ), QObject::tr( "Shape" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicShape.svg" ) ) ) );
97 registry->addItemGroup( QgsLayoutItemGuiGroup( QStringLiteral( "nodes" ), QObject::tr( "Node Item" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddNodesItem.svg" ) ) ) );
98
99 auto createRubberBand = ( []( QgsLayoutView *view ) -> QgsLayoutViewRubberBand * {
100 return new QgsLayoutViewRectangularRubberBand( view );
101 } );
102 auto createEllipseBand = ( []( QgsLayoutView *view ) -> QgsLayoutViewRubberBand * {
103 return new QgsLayoutViewEllipticalRubberBand( view );
104 } );
105 auto createTriangleBand = ( []( QgsLayoutView *view ) -> QgsLayoutViewRubberBand * {
106 return new QgsLayoutViewTriangleRubberBand( view );
107 } );
108
109#if 0
110 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutItem + 1002, QStringLiteral( "test" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLabel.svg" ) ), nullptr, createRubberBand ) );
111#endif
112
113 // map item
114
115 auto mapItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutMap, QObject::tr( "Map" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddMap.svg" ) ), [=]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutMapWidget( qobject_cast<QgsLayoutItemMap *>( item ), mapCanvas ); }, createRubberBand );
116 mapItemMetadata->setItemAddedToLayoutFunction( [=]( QgsLayoutItem *item, const QVariantMap & ) {
117 QgsLayoutItemMap *map = qobject_cast<QgsLayoutItemMap *>( item );
118 Q_ASSERT( map );
119
120 //get the color for map canvas background and set map background color accordingly
121 map->setBackgroundColor( QgsProject::instance()->backgroundColor() );
122
123 if ( mapCanvas )
124 {
125 map->setMapRotation( mapCanvas->rotation() );
126 map->zoomToExtent( mapCanvas->mapSettings().visibleExtent() );
127 }
128
129 // auto assign a unique id to map items
130 QList<QgsLayoutItemMap *> mapsList;
131 if ( map->layout() )
132 map->layout()->layoutItems( mapsList );
133
134 int counter = mapsList.size() + 1;
135 bool existing = false;
136 while ( true )
137 {
138 existing = false;
139 for ( QgsLayoutItemMap *otherMap : std::as_const( mapsList ) )
140 {
141 if ( map == otherMap )
142 continue;
143
144 if ( otherMap->id() == QObject::tr( "Map %1" ).arg( counter ) )
145 {
146 existing = true;
147 break;
148 }
149 }
150 if ( existing )
151 counter++;
152 else
153 break;
154 }
155 map->setId( QObject::tr( "Map %1" ).arg( counter ) );
156 } );
157 registry->addLayoutItemGuiMetadata( mapItemMetadata.release() );
158
159 // picture item
160
161 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 ) );
162
163
164 // label item
165
166 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 );
167 labelItemMetadata->setItemAddedToLayoutFunction( [=]( QgsLayoutItem *item, const QVariantMap &properties ) {
168 QgsLayoutItemLabel *label = qobject_cast<QgsLayoutItemLabel *>( item );
169 Q_ASSERT( label );
170
171 label->setText( properties.value( QStringLiteral( "expression" ) ).toString().isEmpty() ? QObject::tr( "Lorem ipsum" ) : QStringLiteral( "[% %1 %]" ).arg( properties.value( QStringLiteral( "expression" ) ).toString() ) );
172 if ( QApplication::isRightToLeft() )
173 {
174 label->setHAlign( Qt::AlignRight );
175 }
176 QSizeF minSize = label->sizeForText();
177 QSizeF currentSize = label->rect().size();
178
179 //make sure label size is sufficient to fit text
180 double labelWidth = std::max( minSize.width(), currentSize.width() );
181 double labelHeight = std::max( minSize.height(), currentSize.height() );
182 label->attemptSetSceneRect( QRectF( label->pos().x(), label->pos().y(), labelWidth, labelHeight ) );
183 } );
184
185 labelItemMetadata->setItemDoubleClickedFunction( [=]( QgsLayoutItem *item, Qgis::MouseHandlesAction action ) {
186 QgsLayoutItemLabel *label = qobject_cast<QgsLayoutItemLabel *>( item );
187
188 // size to text doesn't have any real meaning for HTML content, skip it
189 if ( label->mode() == QgsLayoutItemLabel::ModeHtml )
190 return;
191
192 Q_ASSERT( label );
194 switch ( action )
195 {
199 return;
200
203 break;
204
207 break;
208
211 break;
212
215 break;
216
219 break;
220
223 break;
224
227 break;
228
231 break;
232 }
233
234 label->adjustSizeToText( reference );
235 } );
236
237 registry->addLayoutItemGuiMetadata( labelItemMetadata.release() );
238
239
240 // legend item
241
242 auto legendItemMetadata = std::make_unique<QgsLayoutItemGuiMetadata>( QgsLayoutItemRegistry::LayoutLegend, QObject::tr( "Legend" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLegend.svg" ) ), [=]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * { return new QgsLayoutLegendWidget( qobject_cast<QgsLayoutItemLegend *>( item ), mapCanvas ); }, createRubberBand );
243 legendItemMetadata->setItemAddedToLayoutFunction( [=]( QgsLayoutItem *item, const QVariantMap & ) {
244 QgsLayoutItemLegend *legend = qobject_cast<QgsLayoutItemLegend *>( item );
245 Q_ASSERT( legend );
246
247 // try to find a good map to link the legend with by default
249
250 if ( QApplication::isRightToLeft() )
251 {
252 // for right-to-left locales, use an appropriate default layout
253 legend->setSymbolAlignment( Qt::AlignRight );
254 legend->rstyle( QgsLegendStyle::Group ).setAlignment( Qt::AlignRight );
255 legend->rstyle( QgsLegendStyle::Subgroup ).setAlignment( Qt::AlignRight );
256 legend->rstyle( QgsLegendStyle::SymbolLabel ).setAlignment( Qt::AlignRight );
257 legend->setTitleAlignment( Qt::AlignRight );
258 }
259
260 //set default legend font from settings
261 QgsSettings settings;
262 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
263 if ( !defaultFontString.isEmpty() )
264 {
265 QFont font;
266 QgsFontUtils::setFontFamily( font, defaultFontString );
267
269 f.setFont( font );
271
272 f = legend->rstyle( QgsLegendStyle::Group ).textFormat();
273 f.setFont( font );
275
277 f.setFont( font );
279
281 f.setFont( font );
283 }
284
285 legend->updateLegend();
286 } );
287
288 registry->addLayoutItemGuiMetadata( legendItemMetadata.release() );
289
290 // scalebar item
291
292 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 );
293 scalebarItemMetadata->setItemAddedToLayoutFunction( [=]( QgsLayoutItem *item, const QVariantMap & ) {
294 QgsLayoutItemScaleBar *scalebar = qobject_cast<QgsLayoutItemScaleBar *>( item );
295 Q_ASSERT( scalebar );
296
297 // try to find a good map to link the scalebar with by default
298 if ( QgsLayoutItemMap *targetMap = findSensibleDefaultLinkedMapItem( scalebar ) )
299 {
300 scalebar->setLinkedMap( targetMap );
301 scalebar->applyDefaultSize( scalebar->guessUnits() );
302 }
303 } );
304
305 registry->addLayoutItemGuiMetadata( scalebarItemMetadata.release() );
306
307
308 // north arrow
309 std::unique_ptr<QgsLayoutItemGuiMetadata> northArrowMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
310 QgsLayoutItemRegistry::LayoutPicture, QObject::tr( "North Arrow" ), QgsApplication::getThemeIcon( QStringLiteral( "/north_arrow.svg" ) ),
311 [=]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
312 return new QgsLayoutPictureWidget( qobject_cast<QgsLayoutItemPicture *>( item ) );
313 },
314 createRubberBand
315 );
316 northArrowMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
317 // count how many existing north arrows are already in layout
318 QList<QgsLayoutItemPicture *> pictureItems;
319 layout->layoutItems( pictureItems );
320 int northArrowCount = 0;
321
322 QgsSettings settings;
323 const QString defaultPath = settings.value( QStringLiteral( "LayoutDesigner/defaultNorthArrow" ), QStringLiteral( ":/images/north_arrows/layout_default_north_arrow.svg" ), QgsSettings::Gui ).toString();
324
325 for ( QgsLayoutItemPicture *p : std::as_const( pictureItems ) )
326 {
327 // look for pictures which use the default north arrow svg
328 if ( p->picturePath() == defaultPath )
329 northArrowCount++;
330 }
331
332 std::unique_ptr<QgsLayoutItemPicture> picture = std::make_unique<QgsLayoutItemPicture>( layout );
333 picture->setNorthMode( QgsLayoutItemPicture::GridNorth );
334 picture->setPicturePath( defaultPath );
335 // set an id by default, so that north arrows are discernible in layout item lists
336 picture->setId( northArrowCount > 0 ? QObject::tr( "North Arrow %1" ).arg( northArrowCount + 1 ) : QObject::tr( "North Arrow" ) );
337 return picture.release();
338 } );
339 northArrowMetadata->setItemAddedToLayoutFunction( [=]( QgsLayoutItem *item, const QVariantMap & ) {
340 QgsLayoutItemPicture *picture = qobject_cast<QgsLayoutItemPicture *>( item );
341 Q_ASSERT( picture );
342
343 QList<QgsLayoutItemMap *> mapItems;
344 picture->layout()->layoutItems( mapItems );
345
346 // try to find a good map to link the north arrow with by default
347 picture->setLinkedMap( findSensibleDefaultLinkedMapItem( picture ) );
348 } );
349 registry->addLayoutItemGuiMetadata( northArrowMetadata.release() );
350
351 // shape items
352
353 auto createShapeWidget =
354 []( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
355 return new QgsLayoutShapeWidget( qobject_cast<QgsLayoutItemShape *>( item ) );
356 };
357
358 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Rectangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), createShapeWidget, createRubberBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout *layout ) -> QgsLayoutItem * {
359 std::unique_ptr<QgsLayoutItemShape> shape = std::make_unique<QgsLayoutItemShape>( layout );
360 shape->setShapeType( QgsLayoutItemShape::Rectangle );
361 return shape.release();
362 } ) );
363 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Ellipse" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicCircle.svg" ) ), createShapeWidget, createEllipseBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout *layout ) -> QgsLayoutItem * {
364 std::unique_ptr<QgsLayoutItemShape> shape = std::make_unique<QgsLayoutItemShape>( layout );
365 shape->setShapeType( QgsLayoutItemShape::Ellipse );
366 return shape.release();
367 } ) );
368 registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Triangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicTriangle.svg" ) ), createShapeWidget, createTriangleBand, QStringLiteral( "shapes" ), false, QgsLayoutItemAbstractGuiMetadata::Flags(), []( QgsLayout *layout ) -> QgsLayoutItem * {
369 std::unique_ptr<QgsLayoutItemShape> shape = std::make_unique<QgsLayoutItemShape>( layout );
370 shape->setShapeType( QgsLayoutItemShape::Triangle );
371 return shape.release();
372 } ) );
373
374 // marker
375 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 ) );
376
377 // arrow
378 std::unique_ptr<QgsLayoutItemGuiMetadata> arrowMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
379 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Arrow" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddArrow.svg" ) ),
380 [=]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
381 return new QgsLayoutPolylineWidget( qobject_cast<QgsLayoutItemPolyline *>( item ) );
382 },
383 createRubberBand, QString(), true
384 );
385 arrowMetadata->setItemCreationFunction( []( QgsLayout *layout ) -> QgsLayoutItem * {
386 std::unique_ptr<QgsLayoutItemPolyline> arrow = std::make_unique<QgsLayoutItemPolyline>( layout );
387 arrow->setEndMarker( QgsLayoutItemPolyline::ArrowHead );
388 return arrow.release();
389 } );
390 arrowMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * ) -> QGraphicsItemGroup * {
391 std::unique_ptr<QGraphicsItemGroup> band = std::make_unique<QGraphicsItemGroup>();
392 QGraphicsPathItem *poly = new QGraphicsPathItem( band.get() );
393 poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
394
395 QGraphicsPathItem *tempPoly = new QGraphicsPathItem( band.get() );
396 tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );
397
398 band->setZValue( QgsLayout::ZViewTool );
399 return band.release();
400 } );
401 registry->addLayoutItemGuiMetadata( arrowMetadata.release() );
402
403 // node items
404
405 std::unique_ptr<QgsLayoutItemGuiMetadata> polygonMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
406 QgsLayoutItemRegistry::LayoutPolygon, QObject::tr( "Polygon" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolygon.svg" ) ),
407 [=]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
408 return new QgsLayoutPolygonWidget( qobject_cast<QgsLayoutItemPolygon *>( item ) );
409 },
410 createRubberBand, QStringLiteral( "nodes" ), true
411 );
412 polygonMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * ) -> QGraphicsItemGroup * {
413 std::unique_ptr<QGraphicsItemGroup> band = std::make_unique<QGraphicsItemGroup>();
414 QGraphicsPolygonItem *poly = new QGraphicsPolygonItem( band.get() );
415 poly->setBrush( QBrush( QColor( 227, 22, 22, 20 ) ) );
416 poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
417
418 QGraphicsPolygonItem *tempPoly = new QGraphicsPolygonItem( band.get() );
419 tempPoly->setBrush( Qt::NoBrush );
420 tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );
421
422 band->setZValue( QgsLayout::ZViewTool );
423 return band.release();
424 } );
425 registry->addLayoutItemGuiMetadata( polygonMetadata.release() );
426
427 std::unique_ptr<QgsLayoutItemGuiMetadata> polylineMetadata = std::make_unique<QgsLayoutItemGuiMetadata>(
428 QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Polyline" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolyline.svg" ) ),
429 [=]( QgsLayoutItem *item ) -> QgsLayoutItemBaseWidget * {
430 return new QgsLayoutPolylineWidget( qobject_cast<QgsLayoutItemPolyline *>( item ) );
431 },
432 createRubberBand, QStringLiteral( "nodes" ), true
433 );
434 polylineMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * ) -> QGraphicsItemGroup * {
435 std::unique_ptr<QGraphicsItemGroup> band = std::make_unique<QGraphicsItemGroup>();
436 QGraphicsPathItem *poly = new QGraphicsPathItem( band.get() );
437 poly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
438
439 QGraphicsPathItem *tempPoly = new QGraphicsPathItem( band.get() );
440 tempPoly->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0, Qt::DotLine ) );
441
442 band->setZValue( QgsLayout::ZViewTool );
443 return band.release();
444 } );
445 registry->addLayoutItemGuiMetadata( polylineMetadata.release() );
446
447
448 // html item
449
450 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 );
451 htmlItemMetadata->setItemCreationFunction( [=]( QgsLayout *layout ) -> QgsLayoutItem * {
452 std::unique_ptr<QgsLayoutItemHtml> htmlMultiFrame = std::make_unique<QgsLayoutItemHtml>( layout );
453 QgsLayoutItemHtml *html = htmlMultiFrame.get();
454 layout->addMultiFrame( htmlMultiFrame.release() );
455 std::unique_ptr<QgsLayoutFrame> frame = std::make_unique<QgsLayoutFrame>( layout, html );
456 QgsLayoutFrame *f = frame.get();
457 html->addFrame( frame.release() );
458 // cppcheck-suppress returnDanglingLifetime
459 return f;
460 } );
461 registry->addLayoutItemGuiMetadata( htmlItemMetadata.release() );
462
463 // attribute table item
464
465 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 );
466 attributeTableItemMetadata->setItemCreationFunction( [=]( QgsLayout *layout ) -> QgsLayoutItem * {
467 std::unique_ptr<QgsLayoutItemAttributeTable> tableMultiFrame = std::make_unique<QgsLayoutItemAttributeTable>( layout );
468 QgsLayoutItemAttributeTable *table = tableMultiFrame.get();
469
470 //set first vector layer from layer registry as table source
471 QMap<QString, QgsMapLayer *> layerMap = layout->project()->mapLayers();
472 for ( auto it = layerMap.constBegin(); it != layerMap.constEnd(); ++it )
473 {
474 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ) )
475 {
476 table->setVectorLayer( vl );
477 break;
478 }
479 }
480
481 //set default table fonts from settings
482 QgsSettings settings;
483 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
484 if ( !defaultFontString.isEmpty() )
485 {
486 QgsTextFormat format;
487 QFont f = format.font();
488 QgsFontUtils::setFontFamily( f, defaultFontString );
489 format.setFont( f );
490 tableMultiFrame->setContentTextFormat( format );
491 f.setBold( true );
492 format.setFont( f );
493 tableMultiFrame->setHeaderTextFormat( format );
494 }
495
496 layout->addMultiFrame( tableMultiFrame.release() );
497 std::unique_ptr<QgsLayoutFrame> frame = std::make_unique<QgsLayoutFrame>( layout, table );
498 QgsLayoutFrame *f = frame.get();
499 table->addFrame( frame.release() );
500 // cppcheck-suppress returnDanglingLifetime
501 return f;
502 } );
503 registry->addLayoutItemGuiMetadata( attributeTableItemMetadata.release() );
504
505 // manual table item
506
507 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 );
508 manualTableItemMetadata->setItemCreationFunction( [=]( QgsLayout *layout ) -> QgsLayoutItem * {
509 std::unique_ptr<QgsLayoutItemManualTable> tableMultiFrame = std::make_unique<QgsLayoutItemManualTable>( layout );
510 QgsLayoutItemManualTable *table = tableMultiFrame.get();
511
512 // initially start with a 2x2 empty table
513 QgsTableContents contents;
514 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
515 contents << ( QgsTableRow() << QgsTableCell() << QgsTableCell() );
516 table->setTableContents( contents );
517
518 //set default table fonts from settings
519 QgsSettings settings;
520 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
521 if ( !defaultFontString.isEmpty() )
522 {
523 QgsTextFormat format;
524 QFont f = format.font();
525 QgsFontUtils::setFontFamily( f, defaultFontString );
526 format.setFont( f );
527 tableMultiFrame->setContentTextFormat( format );
528 f.setBold( true );
529 format.setFont( f );
530 tableMultiFrame->setHeaderTextFormat( format );
531 }
532
533 layout->addMultiFrame( tableMultiFrame.release() );
534
535 std::unique_ptr<QgsLayoutFrame> frame = std::make_unique<QgsLayoutFrame>( layout, table );
536 QgsLayoutFrame *f = frame.get();
537 table->addFrame( frame.release() );
538 // cppcheck-suppress returnDanglingLifetime
539 return f;
540 } );
541 manualTableItemMetadata->setItemDoubleClickedFunction( [=]( QgsLayoutItem *item, Qgis::MouseHandlesAction ) {
542 QgsLayoutManualTableWidget::openTableDesigner( qobject_cast<QgsLayoutFrame *>( item ) );
543 } );
544 registry->addLayoutItemGuiMetadata( manualTableItemMetadata.release() );
545
546
547 // elevation profile item
548
549 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 );
550 elevationProfileItemMetadata->setItemCreationFunction( [=]( QgsLayout *layout ) -> QgsLayoutItem * {
551 std::unique_ptr<QgsLayoutItemElevationProfile> profileItem = std::make_unique<QgsLayoutItemElevationProfile>( layout );
552
553 //set default fonts from settings
554 QgsSettings settings;
555 const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
556 if ( !defaultFontString.isEmpty() )
557 {
558 QgsTextFormat format = profileItem->plot()->xAxis().textFormat();
559 QFont f = format.font();
560 QgsFontUtils::setFontFamily( f, defaultFontString );
561 format.setFont( f );
562 profileItem->plot()->xAxis().setTextFormat( format );
563
564 format = profileItem->plot()->yAxis().textFormat();
565 f = format.font();
566 QgsFontUtils::setFontFamily( f, defaultFontString );
567 format.setFont( f );
568 profileItem->plot()->yAxis().setTextFormat( format );
569 }
570 return profileItem.release();
571 } );
572 registry->addLayoutItemGuiMetadata( elevationProfileItemMetadata.release() );
573}
MouseHandlesAction
Action to be performed by the mouse handles.
Definition qgis.h:5685
@ ResizeRightDown
Resize right down (Bottom right handle)
@ SelectItem
Select item.
@ ResizeLeftUp
Resize left up (Top left handle)
@ ResizeLeftDown
Resize left down (Bottom left handle)
@ ResizeRight
Resize right (Right handle)
@ ResizeDown
Resize down (Bottom handle)
@ ResizeRightUp
Resize right up (Top right handle)
@ ResizeLeft
Resize left (Left handle)
@ ResizeUp
Resize up (Top handle)
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:140
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.
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.
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.
@ 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.
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.
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.
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.
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.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition qgslayout.h:49
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Definition qgslayout.h:120
void addMultiFrame(QgsLayoutMultiFrame *multiFrame)
Adds a multiFrame to the layout.
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:63
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.
@ 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.
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.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Encapsulates the contents and formatting of a single table cell.
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 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.
QVector< QgsTableCell > QgsTableRow
A row of table cells.