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