QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgscompositionconverter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscompositionconverter.cpp - QgsCompositionConverter
3 
4  ---------------------
5  begin : 13.12.2017
6  copyright : (C) 2017 by Alessandro Pasotti
7  email : elpaso at itopen dot it
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include <QObject>
18 
20 #include "qgsreadwritecontext.h"
21 #include "qgslayertree.h"
22 #include "qgslayoutmodel.h"
23 #include "qgslayoutitemgroup.h"
24 #include "qgslayoutobject.h"
25 #include "qgsfontutils.h"
26 #include "qgspainting.h"
27 #include "qgsproperty.h"
28 #include "qgssymbollayerutils.h"
29 #include "qgssymbollayer.h"
30 #include "qgsproject.h"
32 #include "qgsvectorlayer.h"
33 #include "qgslinesymbollayer.h"
34 
35 #include "qgsprintlayout.h"
36 #include "qgslayoutatlas.h"
37 
38 #include "qgslayoutundostack.h"
40 #include "qgslayoutitemregistry.h"
41 #include "qgslayoutitemlabel.h"
42 #include "qgslayoutitemshape.h"
43 #include "qgslayoutitempicture.h"
44 #include "qgslayoutitempolygon.h"
45 #include "qgslayoutitempolyline.h"
46 #include "qgslayoutitemmap.h"
47 #include "qgslayoutitemmapgrid.h"
48 #include "qgslayoutitemscalebar.h"
49 #include "qgslayoutitemlegend.h"
50 #include "qgslayoutitemhtml.h"
51 #include "qgslayouttable.h"
53 #include "qgslayouttablecolumn.h"
54 #include "qgslayoutmultiframe.h"
55 #include "qgslayoutframe.h"
58 
59 QgsPropertiesDefinition QgsCompositionConverter::sPropertyDefinitions;
60 
61 void QgsCompositionConverter::initPropertyDefinitions()
62 {
63  if ( !sPropertyDefinitions.isEmpty() )
64  return;
65 
66  sPropertyDefinitions = QgsPropertiesDefinition
67  {
68  { QgsCompositionConverter::TestProperty, QgsPropertyDefinition( "dataDefinedProperty", QgsPropertyDefinition::DataTypeString, "invalid property", QString() ) },
69  {
70  QgsCompositionConverter::PresetPaperSize, QgsPropertyDefinition( "dataDefinedPaperSize", QgsPropertyDefinition::DataTypeString, QObject::tr( "Paper size" ), QObject::tr( "string " ) + QStringLiteral( "[<b>A5</b>|<b>A4</b>|<b>A3</b>|<b>A2</b>|<b>A1</b>|<b>A0</b>"
71  "|<b>B5</b>|<b>B4</b>|<b>B3</b>|<b>B2</b>|<b>B1</b>|<b>B0</b>"
72  "|<b>Legal</b>|<b>Ansi A</b>|<b>Ansi B</b>|<b>Ansi C</b>|<b>Ansi D</b>|<b>Ansi E</b>"
73  "|<b>Arch A</b>|<b>Arch B</b>|<b>Arch C</b>|<b>Arch D</b>|<b>Arch E</b>|<b>Arch E1</b>]"
74  ) )
75  },
76  { QgsCompositionConverter::PaperWidth, QgsPropertyDefinition( "dataDefinedPaperWidth", QObject::tr( "Page width" ), QgsPropertyDefinition::DoublePositive ) },
77  { QgsCompositionConverter::PaperHeight, QgsPropertyDefinition( "dataDefinedPaperHeight", QObject::tr( "Page height" ), QgsPropertyDefinition::DoublePositive ) },
78  { QgsCompositionConverter::NumPages, QgsPropertyDefinition( "dataDefinedNumPages", QObject::tr( "Number of pages" ), QgsPropertyDefinition::IntegerPositive ) },
79  { QgsCompositionConverter::PaperOrientation, QgsPropertyDefinition( "dataDefinedPaperOrientation", QgsPropertyDefinition::DataTypeString, QObject::tr( "Symbol size" ), QObject::tr( "string " ) + QStringLiteral( "[<b>portrait</b>|<b>landscape</b>]" ) ) },
80  { QgsCompositionConverter::PageNumber, QgsPropertyDefinition( "dataDefinedPageNumber", QObject::tr( "Page number" ), QgsPropertyDefinition::IntegerPositive ) },
81  { QgsCompositionConverter::PositionX, QgsPropertyDefinition( "dataDefinedPositionX", QObject::tr( "Position (X)" ), QgsPropertyDefinition::Double ) },
82  { QgsCompositionConverter::PositionY, QgsPropertyDefinition( "dataDefinedPositionY", QObject::tr( "Position (Y)" ), QgsPropertyDefinition::Double ) },
84  { QgsCompositionConverter::ItemHeight, QgsPropertyDefinition( "dataDefinedHeight", QObject::tr( "Height" ), QgsPropertyDefinition::DoublePositive ) },
85  { QgsCompositionConverter::ItemRotation, QgsPropertyDefinition( "dataDefinedRotation", QObject::tr( "Rotation angle" ), QgsPropertyDefinition::Rotation ) },
86  { QgsCompositionConverter::Transparency, QgsPropertyDefinition( "dataDefinedTransparency", QObject::tr( "Transparency" ), QgsPropertyDefinition::Opacity ) },
87  { QgsCompositionConverter::Opacity, QgsPropertyDefinition( "dataDefinedOpacity", QObject::tr( "Opacity" ), QgsPropertyDefinition::Opacity ) },
88  { QgsCompositionConverter::BlendMode, QgsPropertyDefinition( "dataDefinedBlendMode", QObject::tr( "Blend mode" ), QgsPropertyDefinition::BlendMode ) },
89  { QgsCompositionConverter::ExcludeFromExports, QgsPropertyDefinition( "dataDefinedExcludeExports", QObject::tr( "Exclude item from exports" ), QgsPropertyDefinition::Boolean ) },
90  { QgsCompositionConverter::FrameColor, QgsPropertyDefinition( "dataDefinedFrameColor", QObject::tr( "Frame color" ), QgsPropertyDefinition::ColorWithAlpha ) },
91  { QgsCompositionConverter::BackgroundColor, QgsPropertyDefinition( "dataDefinedBackgroundColor", QObject::tr( "Background color" ), QgsPropertyDefinition::ColorWithAlpha ) },
92  { QgsCompositionConverter::MapRotation, QgsPropertyDefinition( "dataDefinedMapRotation", QObject::tr( "Map rotation" ), QgsPropertyDefinition::Rotation ) },
93  { QgsCompositionConverter::MapScale, QgsPropertyDefinition( "dataDefinedMapScale", QObject::tr( "Map scale" ), QgsPropertyDefinition::DoublePositive ) },
94  { QgsCompositionConverter::MapXMin, QgsPropertyDefinition( "dataDefinedMapXMin", QObject::tr( "Extent minimum X" ), QgsPropertyDefinition::Double ) },
95  { QgsCompositionConverter::MapYMin, QgsPropertyDefinition( "dataDefinedMapYMin", QObject::tr( "Extent minimum Y" ), QgsPropertyDefinition::Double ) },
96  { QgsCompositionConverter::MapXMax, QgsPropertyDefinition( "dataDefinedMapXMax", QObject::tr( "Extent maximum X" ), QgsPropertyDefinition::Double ) },
97  { QgsCompositionConverter::MapYMax, QgsPropertyDefinition( "dataDefinedMapYMax", QObject::tr( "Extent maximum Y" ), QgsPropertyDefinition::Double ) },
98  { QgsCompositionConverter::MapAtlasMargin, QgsPropertyDefinition( "dataDefinedMapAtlasMargin", QObject::tr( "Atlas margin" ), QgsPropertyDefinition::DoublePositive ) },
99  { QgsCompositionConverter::MapLayers, QgsPropertyDefinition( "dataDefinedMapLayers", QgsPropertyDefinition::DataTypeString, QObject::tr( "Symbol size" ), QObject::tr( "list of map layer names separated by | characters" ) ) },
100  { QgsCompositionConverter::MapStylePreset, QgsPropertyDefinition( "dataDefinedMapStylePreset", QgsPropertyDefinition::DataTypeString, QObject::tr( "Symbol size" ), QObject::tr( "list of map layer names separated by | characters" ) ) },
101  { QgsCompositionConverter::PictureSource, QgsPropertyDefinition( "dataDefinedSource", QObject::tr( "Picture source (URL)" ), QgsPropertyDefinition::String ) },
102  { QgsCompositionConverter::SourceUrl, QgsPropertyDefinition( "dataDefinedSourceUrl", QObject::tr( "Source URL" ), QgsPropertyDefinition::String ) },
103  { QgsCompositionConverter::PictureSvgBackgroundColor, QgsPropertyDefinition( "dataDefinedSvgBackgroundColor", QObject::tr( "SVG background color" ), QgsPropertyDefinition::ColorWithAlpha ) },
104  { QgsCompositionConverter::PictureSvgStrokeColor, QgsPropertyDefinition( "dataDefinedSvgStrokeColor", QObject::tr( "SVG stroke color" ), QgsPropertyDefinition::ColorWithAlpha ) },
105  { QgsCompositionConverter::PictureSvgStrokeWidth, QgsPropertyDefinition( "dataDefinedSvgStrokeWidth", QObject::tr( "SVG stroke width" ), QgsPropertyDefinition::StrokeWidth ) },
106  { QgsCompositionConverter::LegendTitle, QgsPropertyDefinition( "dataDefinedLegendTitle", QObject::tr( "Legend title" ), QgsPropertyDefinition::String ) },
107  { QgsCompositionConverter::LegendColumnCount, QgsPropertyDefinition( "dataDefinedLegendColumns", QObject::tr( "Number of columns" ), QgsPropertyDefinition::IntegerPositiveGreaterZero ) },
108  { QgsCompositionConverter::ScalebarFillColor, QgsPropertyDefinition( "dataDefinedScalebarFill", QObject::tr( "Fill color" ), QgsPropertyDefinition::ColorWithAlpha ) },
109  { QgsCompositionConverter::ScalebarFillColor2, QgsPropertyDefinition( "dataDefinedScalebarFill2", QObject::tr( "Secondary fill color" ), QgsPropertyDefinition::ColorWithAlpha ) },
110  { QgsCompositionConverter::ScalebarLineColor, QgsPropertyDefinition( "dataDefinedScalebarLineColor", QObject::tr( "Line color" ), QgsPropertyDefinition::ColorWithAlpha ) },
111  { QgsCompositionConverter::ScalebarLineWidth, QgsPropertyDefinition( "dataDefinedScalebarLineWidth", QObject::tr( "Line width" ), QgsPropertyDefinition::StrokeWidth ) },
112  };
113 }
114 
115 QgsPropertiesDefinition QgsCompositionConverter::propertyDefinitions()
116 {
117  QgsCompositionConverter::initPropertyDefinitions();
118  return sPropertyDefinitions;
119 }
120 
121 
122 std::unique_ptr< QgsPrintLayout > QgsCompositionConverter::createLayoutFromCompositionXml( const QDomElement &composerElement, QgsProject *project )
123 {
124  initPropertyDefinitions();
125 
126  QDomElement parentElement = composerElement.parentNode().toElement();
127 
128  std::unique_ptr< QgsPrintLayout > layout = qgis::make_unique< QgsPrintLayout >( project );
129  layout->undoStack()->blockCommands( true );
130 
131  layout->mCustomProperties.readXml( composerElement );
132 
133  // Guides
134  layout->guides().setVisible( composerElement.attribute( QStringLiteral( "guidesVisible" ), QStringLiteral( "1" ) ).toInt() != 0 );
135 
136  int printResolution = composerElement.attribute( QStringLiteral( "printResolution" ), QStringLiteral( "300" ) ).toInt();
137  layout->renderContext().setDpi( printResolution );
138 
139  // Create pages
140  int pages = composerElement.attribute( QStringLiteral( "numPages" ) ).toInt( );
141  float paperHeight = composerElement.attribute( QStringLiteral( "paperHeight" ) ).toDouble( );
142  float paperWidth = composerElement.attribute( QStringLiteral( "paperWidth" ) ).toDouble( );
143 
144  QString name = composerElement.attribute( QStringLiteral( "name" ) );
145  // Try title
146  if ( name.isEmpty() )
147  name = composerElement.attribute( QStringLiteral( "title" ) );
148  // Try title on parent element
149  if ( name.isEmpty() )
150  name = parentElement.attribute( QStringLiteral( "title" ) );
151  layout->setName( name );
152  QgsLayoutSize pageSize( paperWidth, paperHeight );
153  for ( int j = 0; j < pages; j++ )
154  {
155  QgsLayoutItemPage *page = QgsLayoutItemPage::create( layout.get() );
156  page->setPageSize( pageSize );
157  layout->pageCollection()->addPage( page );
158  //custom snap lines
159  QDomNodeList snapLineNodes = composerElement.elementsByTagName( QStringLiteral( "SnapLine" ) );
160  for ( int i = 0; i < snapLineNodes.size(); ++i )
161  {
162  QDomElement snapLineElem = snapLineNodes.at( i ).toElement();
163  double x1 = snapLineElem.attribute( QStringLiteral( "x1" ) ).toDouble();
164  double y1 = snapLineElem.attribute( QStringLiteral( "y1" ) ).toDouble();
165  double x2 = snapLineElem.attribute( QStringLiteral( "x2" ) ).toDouble();
166  // Not necessary: double y2 = snapLineElem.attribute( QStringLiteral( "y2" ) ).toDouble();
167  Qt::Orientation orientation( x1 == x2 ? Qt::Orientation::Vertical : Qt::Orientation::Horizontal );
168  QgsLayoutMeasurement position( x1 == x2 ? x1 : y1 );
169  std::unique_ptr< QgsLayoutGuide > guide = qgis::make_unique< QgsLayoutGuide >( orientation, position, page );
170  layout->guides().addGuide( guide.release() );
171  }
172  }
173 
174 
175  if ( composerElement.elementsByTagName( QStringLiteral( "symbol" ) ).size() )
176  {
177  QDomElement symbolElement = composerElement.elementsByTagName( QStringLiteral( "symbol" ) ).at( 0 ).toElement();
178  QgsReadWriteContext context;
179  if ( project )
180  context.setPathResolver( project->pathResolver() );
181  std::unique_ptr< QgsFillSymbol > symbol( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElement, context ) );
182  if ( symbol )
183  layout->pageCollection()->setPageStyleSymbol( symbol.get() );
184  }
185 
186  addItemsFromCompositionXml( layout.get(), composerElement );
187 
188  // Read atlas from the parent element (Composer)
189  if ( parentElement.elementsByTagName( QStringLiteral( "Atlas" ) ).size() )
190  {
191  QDomElement atlasElement = parentElement.elementsByTagName( QStringLiteral( "Atlas" ) ).at( 0 ).toElement();
192  readAtlasXml( layout->atlas(), atlasElement, layout->project() );
193  }
194 
195  layout->undoStack()->blockCommands( false );
196  return layout;
197 }
198 
199 
200 void QgsCompositionConverter::adjustPos( QgsPrintLayout *layout, QgsLayoutItem *layoutItem, QPointF *position, bool &pasteInPlace, int zOrderOffset, QPointF &pasteShiftPos, int &pageNumber )
201 {
202  if ( position )
203  {
204  if ( pasteInPlace )
205  {
206  layoutItem->attemptMove( QgsLayoutPoint( *position ), true, false, pageNumber );
207  }
208  else
209  {
210  layoutItem->attemptMoveBy( pasteShiftPos.x(), pasteShiftPos.y() );
211  }
212  }
213 
214  if ( !layoutItem->scene() )
215  layout->addLayoutItem( layoutItem );
216  layoutItem->setZValue( layoutItem->zValue() + zOrderOffset );
217 }
218 
219 void QgsCompositionConverter::restoreGeneralComposeItemProperties( QgsLayoutItem *layoutItem, const QDomElement &itemElem )
220 {
221  //restore general composer item properties
222  QDomNodeList composerItemList = itemElem.elementsByTagName( QStringLiteral( "ComposerItem" ) );
223  if ( !composerItemList.isEmpty() )
224  {
225  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
226 
227  //rotation
228  if ( !qgsDoubleNear( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) )
229  {
230  //check for old (pre 2.1) rotation attribute
231  layoutItem->setItemRotation( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(), false );
232  }
233  QgsCompositionConverter::readXml( layoutItem, composerItemElem );
234  }
235 }
236 
237 QRectF QgsCompositionConverter::itemPosition( QgsLayoutItem *layoutItem, const QDomElement &itemElem )
238 {
239  int page;
240  double x, y, pagex, pagey, width, height;
241  bool xOk, yOk, pageOk, pagexOk, pageyOk, widthOk, heightOk, positionModeOk;
242 
243  x = itemElem.attribute( QStringLiteral( "x" ) ).toDouble( &xOk );
244  y = itemElem.attribute( QStringLiteral( "y" ) ).toDouble( &yOk );
245  page = itemElem.attribute( QStringLiteral( "page" ) ).toInt( &pageOk );
246  pagex = itemElem.attribute( QStringLiteral( "pagex" ) ).toDouble( &pagexOk );
247  pagey = itemElem.attribute( QStringLiteral( "pagey" ) ).toDouble( &pageyOk );
248  width = itemElem.attribute( QStringLiteral( "width" ) ).toDouble( &widthOk );
249  height = itemElem.attribute( QStringLiteral( "height" ) ).toDouble( &heightOk );
250 
251 
252  layoutItem->mReferencePoint = static_cast< QgsLayoutItem::ReferencePoint >( itemElem.attribute( QStringLiteral( "positionMode" ) ).toInt( &positionModeOk ) );
253  if ( !positionModeOk )
254  {
255  layoutItem->setReferencePoint( QgsLayoutItem::ReferencePoint::UpperLeft );
256  }
257 
258  if ( pageOk && pagexOk && pageyOk )
259  {
260  xOk = true;
261  yOk = true;
262  x = pagex;
263  // position in the page (1-based)
264  if ( page <= layoutItem->layout()->pageCollection()->pageCount() )
265  {
266  QgsLayoutItemPage *pageObject = layoutItem->layout()->pageCollection()->pages().at( page - 1 );
267  y = ( page - 1 )
268  * ( pageObject->sizeWithUnits().height()
269  + layoutItem->layout()->pageCollection()->spaceBetweenPages() )
270  + pagey;
271  }
272  else
273  {
274  y = pagey;
275  }
276  }
277  return QRectF( x, y, width, height );
278 }
279 
280 QPointF QgsCompositionConverter::minPointFromXml( const QDomElement &elem )
281 {
282  double minX = std::numeric_limits<double>::max();
283  double minY = std::numeric_limits<double>::max();
284  QDomNodeList composerItemList = elem.elementsByTagName( QStringLiteral( "ComposerItem" ) );
285  for ( int i = 0; i < composerItemList.size(); ++i )
286  {
287  QDomElement currentComposerItemElem = composerItemList.at( i ).toElement();
288  double x, y;
289  bool xOk, yOk;
290  x = currentComposerItemElem.attribute( QStringLiteral( "x" ) ).toDouble( &xOk );
291  y = currentComposerItemElem.attribute( QStringLiteral( "y" ) ).toDouble( &yOk );
292  if ( !xOk || !yOk )
293  {
294  continue;
295  }
296  minX = std::min( minX, x );
297  minY = std::min( minY, y );
298  }
299  if ( minX < std::numeric_limits<double>::max() )
300  {
301  return QPointF( minX, minY );
302  }
303  else
304  {
305  return QPointF( 0, 0 );
306  }
307 }
308 
309 QList<QgsLayoutObject *> QgsCompositionConverter::addItemsFromCompositionXml( QgsPrintLayout *layout, const QDomElement &parentElement, QPointF *position, bool pasteInPlace )
310 {
311 
312  initPropertyDefinitions();
313 
314  QList< QgsLayoutObject * > newItems;
315 
316  //if we are adding items to a layout which already contains items, we need to make sure
317  //these items are placed at the top of the layout and that zValues are not duplicated
318  //so, calculate an offset which needs to be added to the zValue of created items
319  int zOrderOffset = layout->mItemsModel->zOrderListSize();
320 
321  QPointF pasteShiftPos;
322  int pageNumber = -1;
323  if ( position )
324  {
325  //If we are placing items relative to a certain point, then calculate how much we need
326  //to shift the items by so that they are placed at this point
327  //First, calculate the minimum position from the xml
328  QPointF minItemPos = minPointFromXml( parentElement );
329  //next, calculate how much each item needs to be shifted from its original position
330  //so that it's placed at the correct relative position
331  pasteShiftPos = *position - minItemPos;
332  if ( pasteInPlace )
333  {
334  pageNumber = layout->mPageCollection->pageNumberForPoint( *position );
335  }
336  }
337 
338  QgsStringMap mapIdUiidMap;
339 
340  // Map (this needs to come first to build the uuid <-> ID map for map composer items
341  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerMap" ) ).size(); i++ )
342  {
343  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerMap" ) ).at( i ) );
344  QgsLayoutItemMap *layoutItem = new QgsLayoutItemMap( layout );
345  readMapXml( layoutItem, itemNode.toElement(), layout->project(), mapIdUiidMap );
346  adjustPos( layout, layoutItem, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
347  newItems << layoutItem ;
348  }
349 
350  // Label
351  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerLabel" ) ).size(); i++ )
352  {
353  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerLabel" ) ).at( i ) );
354  QgsLayoutItemLabel *layoutItem = new QgsLayoutItemLabel( layout );
355  readLabelXml( layoutItem, itemNode.toElement(), layout->project() );
356  adjustPos( layout, layoutItem, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
357  newItems << layoutItem ;
358  }
359 
360  // Shape
361  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerShape" ) ).size(); i++ )
362  {
363  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerShape" ) ).at( i ) );
364  QgsLayoutItemShape *layoutItem = new QgsLayoutItemShape( layout );
365  readShapeXml( layoutItem, itemNode.toElement(), layout->project() );
366  adjustPos( layout, layoutItem, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
367  newItems << layoutItem ;
368  }
369 
370  // Picture
371  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerPicture" ) ).size(); i++ )
372  {
373  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerPicture" ) ).at( i ) );
374  QgsLayoutItemPicture *layoutItem = new QgsLayoutItemPicture( layout );
375  readPictureXml( layoutItem, itemNode.toElement(), layout->project(), mapIdUiidMap );
376  adjustPos( layout, layoutItem, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
377  newItems << layoutItem ;
378  }
379 
380  // Polygon
381  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerPolygon" ) ).size(); i++ )
382  {
383  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerPolygon" ) ).at( i ) );
384  QgsLayoutItemPolygon *layoutItem = new QgsLayoutItemPolygon( layout );
385  readPolyXml<QgsLayoutItemPolygon, QgsFillSymbol>( layoutItem, itemNode.toElement(), layout->project() );
386  adjustPos( layout, layoutItem, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
387  newItems << layoutItem ;
388  }
389 
390  // Polyline
391  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerPolyline" ) ).size(); i++ )
392  {
393  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerPolyline" ) ).at( i ) );
394  QgsLayoutItemPolyline *layoutItem = new QgsLayoutItemPolyline( layout );
395  readPolyXml<QgsLayoutItemPolyline, QgsLineSymbol>( layoutItem, itemNode.toElement(), layout->project() );
396  adjustPos( layout, layoutItem, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
397  newItems << layoutItem ;
398  }
399 
400  // Arrow
401  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerArrow" ) ).size(); i++ )
402  {
403  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerArrow" ) ).at( i ) );
404  QgsLayoutItemPolyline *layoutItem = new QgsLayoutItemPolyline( layout );
405  readArrowXml( layoutItem, itemNode.toElement(), layout->project() );
406  adjustPos( layout, layoutItem, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
407  newItems << layoutItem ;
408  }
409 
410  // Scalebar
411  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerScaleBar" ) ).size(); i++ )
412  {
413  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerScaleBar" ) ).at( i ) );
414  QgsLayoutItemScaleBar *layoutItem = new QgsLayoutItemScaleBar( layout );
415  readScaleBarXml( layoutItem, itemNode.toElement(), layout->project(), mapIdUiidMap );
416  adjustPos( layout, layoutItem, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
417  newItems << layoutItem ;
418  }
419 
420  // Legend
421  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerLegend" ) ).size(); i++ )
422  {
423  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerLegend" ) ).at( i ) );
424  QgsLayoutItemLegend *layoutItem = new QgsLayoutItemLegend( layout );
425  readLegendXml( layoutItem, itemNode.toElement(), layout->project(), mapIdUiidMap );
426  adjustPos( layout, layoutItem, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
427  newItems << layoutItem ;
428  }
429 
430  // Html
431  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerHtml" ) ).size(); i++ )
432  {
433  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerHtml" ) ).at( i ) );
434  QgsLayoutItemHtml *layoutItem = new QgsLayoutItemHtml( layout );
435  readHtmlXml( layoutItem, itemNode.toElement(), layout->project() );
436  // Adjust position for frames
437  const QList<QgsLayoutFrame *> framesList( layoutItem->frames() );
438  for ( const auto &frame : framesList )
439  {
440  adjustPos( layout, frame, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
441  }
442  newItems << layoutItem ;
443  }
444 
445  // Attribute Table
446  for ( int i = 0; i < parentElement.elementsByTagName( QStringLiteral( "ComposerAttributeTableV2" ) ).size(); i++ )
447  {
448  QDomNode itemNode( parentElement.elementsByTagName( QStringLiteral( "ComposerAttributeTableV2" ) ).at( i ) );
449  QgsLayoutItemAttributeTable *layoutItem = new QgsLayoutItemAttributeTable( layout );
450  readTableXml( layoutItem, itemNode.toElement(), layout->project() );
451  // Adjust position for frames
452  const QList<QgsLayoutFrame *> framesList( layoutItem->frames() );
453  for ( const auto &frame : framesList )
454  {
455  adjustPos( layout, frame, position, pasteInPlace, zOrderOffset, pasteShiftPos, pageNumber );
456  }
457  newItems << layoutItem ;
458  }
459 
460  return newItems;
461 }
462 
463 bool QgsCompositionConverter::isCompositionTemplate( const QDomDocument &document )
464 {
465  return document.elementsByTagName( QStringLiteral( "Composition" ) ).count() > 0;
466 }
467 
468 QDomDocument QgsCompositionConverter::convertCompositionTemplate( const QDomDocument &document, QgsProject *project )
469 {
470  QDomDocument doc;
471  QgsReadWriteContext context;
472  if ( project )
473  context.setPathResolver( project->pathResolver() );
474  if ( document.elementsByTagName( QStringLiteral( "Composition" ) ).count( ) > 0 )
475  {
476  QDomElement composerElem = document.elementsByTagName( QStringLiteral( "Composition" ) ).at( 0 ).toElement( );
477 
478  std::unique_ptr<QgsLayout> layout = createLayoutFromCompositionXml( composerElem,
479  project );
480  QDomElement elem = layout->writeXml( doc, context );
481  doc.appendChild( elem );
482  }
483  return doc;
484 }
485 
486 bool QgsCompositionConverter::readLabelXml( QgsLayoutItemLabel *layoutItem, const QDomElement &itemElem, const QgsProject *project )
487 {
488  Q_UNUSED( project )
489  if ( itemElem.isNull() )
490  {
491  return false;
492  }
493 
494  restoreGeneralComposeItemProperties( layoutItem, itemElem );
495 
496  //text
497  layoutItem->setText( itemElem.attribute( QStringLiteral( "labelText" ) ) );
498 
499  //html state
500  layoutItem->setMode( itemElem.attribute( QStringLiteral( "htmlState" ) ).toInt() == Qt::Checked ? QgsLayoutItemLabel::Mode::ModeHtml : QgsLayoutItemLabel::Mode::ModeFont );
501 
502  //margin
503  bool marginXOk = false;
504  bool marginYOk = false;
505  double marginX = itemElem.attribute( QStringLiteral( "marginX" ) ).toDouble( &marginXOk );
506  double marginY = itemElem.attribute( QStringLiteral( "marginY" ) ).toDouble( &marginYOk );
507  if ( !marginXOk || !marginYOk )
508  {
509  //upgrade old projects where margins where stored in a single attribute
510  double margin = itemElem.attribute( QStringLiteral( "margin" ), QStringLiteral( "1.0" ) ).toDouble();
511  marginX = margin;
512  marginY = margin;
513  }
514  layoutItem->setMarginX( marginX );
515  layoutItem->setMarginY( marginY );
516 
517  //Horizontal alignment
518  layoutItem->setHAlign( static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "halign" ) ).toInt() ) );
519 
520  //Vertical alignment
521  layoutItem->setVAlign( static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "valign" ) ).toInt() ) );
522 
523 
524  QFont font;
525  //font
526  QgsFontUtils::setFromXmlChildNode( font, itemElem, QStringLiteral( "LabelFont" ) );
527  layoutItem->setFont( font );
528 
529  //font color
530  QDomNodeList fontColorList = itemElem.elementsByTagName( QStringLiteral( "FontColor" ) );
531  if ( !fontColorList.isEmpty() )
532  {
533  QDomElement fontColorElem = fontColorList.at( 0 ).toElement();
534  int red = fontColorElem.attribute( QStringLiteral( "red" ), QStringLiteral( "0" ) ).toInt();
535  int green = fontColorElem.attribute( QStringLiteral( "green" ), QStringLiteral( "0" ) ).toInt();
536  int blue = fontColorElem.attribute( QStringLiteral( "blue" ), QStringLiteral( "0" ) ).toInt();
537  layoutItem->setFontColor( QColor( red, green, blue ) );
538  }
539  else
540  {
541  layoutItem->setFontColor( QColor( 0, 0, 0 ) );
542  }
543 
544  return true;
545 }
546 
547 bool QgsCompositionConverter::readShapeXml( QgsLayoutItemShape *layoutItem, const QDomElement &itemElem, const QgsProject *project )
548 {
549  Q_UNUSED( project )
550  layoutItem->setShapeType( static_cast<QgsLayoutItemShape::Shape>( itemElem.attribute( QStringLiteral( "shapeType" ), QStringLiteral( "0" ) ).toInt() ) );
551  layoutItem->setCornerRadius( QgsLayoutMeasurement( itemElem.attribute( QStringLiteral( "cornerRadius" ), QStringLiteral( "0" ) ).toDouble() ) );
552 
553  restoreGeneralComposeItemProperties( layoutItem, itemElem );
554 
555  QgsReadWriteContext context;
556  if ( project )
557  context.setPathResolver( project->pathResolver() );
558 
559  if ( itemElem.elementsByTagName( QStringLiteral( "symbol" ) ).size() )
560  {
561  QDomElement symbolElement = itemElem.elementsByTagName( QStringLiteral( "symbol" ) ).at( 0 ).toElement();
562  std::unique_ptr< QgsFillSymbol > shapeStyleSymbol( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElement, context ) );
563  if ( shapeStyleSymbol )
564  layoutItem->setSymbol( shapeStyleSymbol.get() );
565  }
566  else
567  {
568  //upgrade project file from 2.0 to use symbol styling
569  QgsStringMap properties;
570  properties.insert( QStringLiteral( "color" ), QgsSymbolLayerUtils::encodeColor( layoutItem->brush().color() ) );
571  if ( layoutItem->hasBackground() )
572  {
573  properties.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
574  }
575  else
576  {
577  properties.insert( QStringLiteral( "style" ), QStringLiteral( "no" ) );
578  }
579  if ( layoutItem->frameEnabled() )
580  {
581  properties.insert( QStringLiteral( "style_border" ), QStringLiteral( "solid" ) );
582  }
583  else
584  {
585  properties.insert( QStringLiteral( "style_border" ), QStringLiteral( "no" ) );
586  }
587  properties.insert( QStringLiteral( "color_border" ), QgsSymbolLayerUtils::encodeColor( layoutItem->pen().color() ) );
588  properties.insert( QStringLiteral( "width_border" ), QString::number( layoutItem->pen().widthF() ) );
589 
590  //for pre 2.0 projects, shape color and outline were specified in a different element...
591  QDomNodeList outlineColorList = itemElem.elementsByTagName( QStringLiteral( "OutlineColor" ) );
592  if ( !outlineColorList.isEmpty() )
593  {
594  QDomElement frameColorElem = outlineColorList.at( 0 ).toElement();
595  bool redOk, greenOk, blueOk, alphaOk, widthOk;
596  int penRed, penGreen, penBlue, penAlpha;
597  double penWidth;
598 
599  penWidth = itemElem.attribute( QStringLiteral( "outlineWidth" ) ).toDouble( &widthOk );
600  penRed = frameColorElem.attribute( QStringLiteral( "red" ) ).toInt( &redOk );
601  penGreen = frameColorElem.attribute( QStringLiteral( "green" ) ).toInt( &greenOk );
602  penBlue = frameColorElem.attribute( QStringLiteral( "blue" ) ).toInt( &blueOk );
603  penAlpha = frameColorElem.attribute( QStringLiteral( "alpha" ) ).toInt( &alphaOk );
604 
605  if ( redOk && greenOk && blueOk && alphaOk && widthOk )
606  {
607  properties.insert( QStringLiteral( "color_border" ), QgsSymbolLayerUtils::encodeColor( QColor( penRed, penGreen, penBlue, penAlpha ) ) );
608  properties.insert( QStringLiteral( "width_border" ), QString::number( penWidth ) );
609  }
610  }
611  QDomNodeList fillColorList = itemElem.elementsByTagName( QStringLiteral( "FillColor" ) );
612  if ( !fillColorList.isEmpty() )
613  {
614  QDomElement fillColorElem = fillColorList.at( 0 ).toElement();
615  bool redOk, greenOk, blueOk, alphaOk;
616  int fillRed, fillGreen, fillBlue, fillAlpha;
617 
618  fillRed = fillColorElem.attribute( QStringLiteral( "red" ) ).toInt( &redOk );
619  fillGreen = fillColorElem.attribute( QStringLiteral( "green" ) ).toInt( &greenOk );
620  fillBlue = fillColorElem.attribute( QStringLiteral( "blue" ) ).toInt( &blueOk );
621  fillAlpha = fillColorElem.attribute( QStringLiteral( "alpha" ) ).toInt( &alphaOk );
622 
623  if ( redOk && greenOk && blueOk && alphaOk )
624  {
625  properties.insert( QStringLiteral( "color" ), QgsSymbolLayerUtils::encodeColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) ) );
626  properties.insert( QStringLiteral( "style" ), QStringLiteral( "solid" ) );
627  }
628  }
629  if ( itemElem.hasAttribute( QStringLiteral( "transparentFill" ) ) )
630  {
631  //old style (pre 2.0) of specifying that shapes had no fill
632  bool hasOldTransparentFill = itemElem.attribute( QStringLiteral( "transparentFill" ), QStringLiteral( "0" ) ).toInt();
633  if ( hasOldTransparentFill )
634  {
635  properties.insert( QStringLiteral( "style" ), QStringLiteral( "no" ) );
636  }
637  }
638 
639  std::unique_ptr< QgsFillSymbol > shapeStyleSymbol( QgsFillSymbol::createSimple( properties ) );
640  layoutItem->setSymbol( shapeStyleSymbol.get() );
641  }
642  // Disable frame for shapes
643  layoutItem->setFrameEnabled( false );
644  layoutItem->setBackgroundEnabled( false );
645 
646  return true;
647 }
648 
649 bool QgsCompositionConverter::readPictureXml( QgsLayoutItemPicture *layoutItem, const QDomElement &itemElem, const QgsProject *project, const QgsStringMap &mapId2Uuid )
650 {
651  restoreGeneralComposeItemProperties( layoutItem, itemElem );
652 
653  layoutItem->mResizeMode = QgsLayoutItemPicture::ResizeMode( itemElem.attribute( QStringLiteral( "resizeMode" ), QStringLiteral( "0" ) ).toInt() );
654  //when loading from xml, default to anchor point of middle to match pre 2.4 behavior
655  bool positionModeOk = false;
656  layoutItem->mReferencePoint = static_cast< QgsLayoutItem::ReferencePoint >( itemElem.attribute( QStringLiteral( "positionMode" ) ).toInt( &positionModeOk ) );
657  if ( !positionModeOk )
658  {
659  layoutItem->mReferencePoint = QgsLayoutItem::ReferencePoint::UpperLeft;
660  }
661  bool anchorPointOk = false;
662 
663  layoutItem->setPictureAnchor( static_cast< QgsLayoutItem::ReferencePoint >( itemElem.attribute( QStringLiteral( "anchorPoint" ), QString::number( QgsLayoutItem::ReferencePoint::Middle ) ).toInt( &anchorPointOk ) ) );
664  if ( !anchorPointOk )
665  {
666  layoutItem->mPictureAnchor = QgsLayoutItem::ReferencePoint::UpperLeft;
667  }
668  layoutItem->mSvgFillColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "svgFillColor" ), QgsSymbolLayerUtils::encodeColor( QColor( 255, 255, 255 ) ) ) );
669  layoutItem->mSvgStrokeColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "svgBorderColor" ), QgsSymbolLayerUtils::encodeColor( QColor( 0, 0, 0 ) ) ) );
670  layoutItem->mSvgStrokeWidth = itemElem.attribute( QStringLiteral( "svgBorderWidth" ), QStringLiteral( "0.2" ) ).toDouble();
671 
672  QString imagePath = itemElem.attribute( QStringLiteral( "file" ) );
673  if ( project )
674  {
675  // convert from relative path to absolute. For SVG we also need to consider system SVG paths
676  QgsPathResolver pathResolver = project->pathResolver();
677  if ( imagePath.endsWith( QLatin1String( ".svg" ), Qt::CaseInsensitive ) )
678  imagePath = QgsSymbolLayerUtils::svgSymbolNameToPath( imagePath, pathResolver );
679  else
680  imagePath = pathResolver.readPath( imagePath );
681  }
682  layoutItem->setPicturePath( imagePath );
683  layoutItem->mPictureHeight = itemElem.attribute( QStringLiteral( "pictureHeight" ), QStringLiteral( "10" ) ).toDouble();
684  layoutItem->mPictureWidth = itemElem.attribute( QStringLiteral( "pictureWidth" ), QStringLiteral( "10" ) ).toDouble();
685 
686  //picture rotation
687  if ( !qgsDoubleNear( itemElem.attribute( QStringLiteral( "pictureRotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) )
688  {
689  layoutItem->mPictureRotation = itemElem.attribute( QStringLiteral( "pictureRotation" ), QStringLiteral( "0" ) ).toDouble();
690  }
691 
692  //rotation map
693  layoutItem->mNorthArrowHandler->setNorthMode( static_cast< QgsLayoutNorthArrowHandler::NorthMode >( itemElem.attribute( QStringLiteral( "northMode" ), QStringLiteral( "0" ) ).toInt() ) );
694  layoutItem->mNorthArrowHandler->setNorthOffset( itemElem.attribute( QStringLiteral( "northOffset" ), QStringLiteral( "0" ) ).toDouble() );
695 
696  QString rotationMapId = itemElem.attribute( QStringLiteral( "mapId" ), QStringLiteral( "-1" ) );
697  if ( rotationMapId != QStringLiteral( "-1" ) )
698  {
699  // Find uuid for map with given id
700  QgsLayoutItemMap *mapInstance = qobject_cast<QgsLayoutItemMap *>( layoutItem->layout()->itemByUuid( mapId2Uuid[ rotationMapId ] ) );
701  if ( mapInstance )
702  {
703  layoutItem->setLinkedMap( mapInstance );
704  }
705  }
706  return true;
707 }
708 
709 bool QgsCompositionConverter::readArrowXml( QgsLayoutItemPolyline *layoutItem, const QDomElement &itemElem, const QgsProject *project )
710 {
711  readPolyXml<QgsLayoutItemPolyline, QgsLineSymbol>( layoutItem, itemElem, project );
712  QPolygonF polygon;
713  QDomNodeList startPointList = itemElem.elementsByTagName( QStringLiteral( "StartPoint" ) );
714  if ( ! startPointList.isEmpty() )
715  {
716  QDomElement node = startPointList.at( 0 ).toElement();
717  polygon.append( QPointF( node.attribute( QStringLiteral( "x" ) ).toDouble( ), node.attribute( QStringLiteral( "y" ) ).toDouble() ) );
718  }
719  QDomNodeList stopPointList = itemElem.elementsByTagName( QStringLiteral( "StopPoint" ) );
720  if ( ! stopPointList.isEmpty() )
721  {
722  QDomElement node = stopPointList.at( 0 ).toElement();
723  polygon.append( QPointF( node.attribute( QStringLiteral( "x" ) ).toDouble( ), node.attribute( QStringLiteral( "y" ) ).toDouble() ) );
724  }
725 
726  QgsCompositionConverter::MarkerMode markerMode = static_cast< QgsCompositionConverter::MarkerMode>( itemElem.attribute( QStringLiteral( "markerMode" ), QStringLiteral( "0" ) ).toInt( ) );
727 
728  if ( markerMode == QgsCompositionConverter::MarkerMode::DefaultMarker )
729  {
730  layoutItem->setEndMarker( QgsLayoutItemPolyline::MarkerMode::ArrowHead );
731  layoutItem->setStartMarker( QgsLayoutItemPolyline::MarkerMode::NoMarker );
732  layoutItem->setArrowHeadFillColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "arrowHeadFillColor" ), QgsSymbolLayerUtils::encodeColor( QColor( 255, 255, 255 ) ) ) ) );
733  layoutItem->setArrowHeadStrokeColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "arrowHeadOutlineColor" ), QgsSymbolLayerUtils::encodeColor( QColor( 255, 255, 255 ) ) ) ) );
734  layoutItem->setArrowHeadStrokeWidth( itemElem.attribute( QStringLiteral( "outlineWidth" ), QStringLiteral( "1.0" ) ).toDouble( ) );
735  layoutItem->setArrowHeadWidth( itemElem.attribute( QStringLiteral( "arrowHeadWidth" ), QStringLiteral( "1.0" ) ).toDouble( ) );
736  }
737  else if ( markerMode == QgsCompositionConverter::MarkerMode::SVGMarker )
738  {
739  QString endMarkerFile = itemElem.attribute( QStringLiteral( "endMarkerFile" ) );
740  QString startMarkerFile = itemElem.attribute( QStringLiteral( "endMarkerFile" ) );
741 
742  // Fix the paths
743  if ( project )
744  {
745  // convert from relative path to absolute. For SVG we also need to consider system SVG paths
746  QgsPathResolver pathResolver = project->pathResolver();
747  if ( !endMarkerFile.isEmpty() )
748  {
749  if ( endMarkerFile.endsWith( QLatin1String( ".svg" ), Qt::CaseInsensitive ) )
750  endMarkerFile = QgsSymbolLayerUtils::svgSymbolNameToPath( endMarkerFile, pathResolver );
751  else
752  endMarkerFile = pathResolver.readPath( endMarkerFile );
753  }
754  if ( !startMarkerFile.isEmpty() )
755  {
756  if ( startMarkerFile.endsWith( QLatin1String( ".svg" ), Qt::CaseInsensitive ) )
757  startMarkerFile = QgsSymbolLayerUtils::svgSymbolNameToPath( startMarkerFile, pathResolver );
758  else
759  startMarkerFile = pathResolver.readPath( startMarkerFile );
760  }
761  }
762  if ( !endMarkerFile.isEmpty() )
763  {
764  layoutItem->setEndMarker( QgsLayoutItemPolyline::MarkerMode::SvgMarker );
765  layoutItem->setEndSvgMarkerPath( endMarkerFile );
766  }
767  if ( !startMarkerFile.isEmpty() )
768  {
769  layoutItem->setStartMarker( QgsLayoutItemPolyline::MarkerMode::SvgMarker );
770  layoutItem->setStartSvgMarkerPath( startMarkerFile );
771  }
772  }
773  else // NoMarker
774  {
775  layoutItem->setEndMarker( QgsLayoutItemPolyline::MarkerMode::NoMarker );
776  layoutItem->setStartMarker( QgsLayoutItemPolyline::MarkerMode::NoMarker );
777  }
778  // Calculate the margin
779  double margin = polygon.boundingRect().left() - layoutItem->pos().x();
780  polygon.translate( - polygon.boundingRect().left() + margin, - polygon.boundingRect().top() + margin );
781  layoutItem->setNodes( polygon );
782 
783  return true;
784 }
785 
786 bool QgsCompositionConverter::readMapXml( QgsLayoutItemMap *layoutItem, const QDomElement &itemElem, const QgsProject *project, QgsStringMap &mapId2Uuid )
787 {
788  restoreGeneralComposeItemProperties( layoutItem, itemElem );
789 
790  mapId2Uuid[ itemElem.attribute( QStringLiteral( "id" ) ) ] = layoutItem->uuid();
791 
792  // TODO: Unused but all the layouts readXML require it (I'd suggest to remove it from the API)
793  QDomDocument doc;
794 
795  QgsReadWriteContext context;
796 
797  if ( project )
798  context.setPathResolver( project->pathResolver() );
799 
800  //extent
801  QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral( "Extent" ) );
802  if ( !extentNodeList.isEmpty() )
803  {
804  QDomElement extentElem = extentNodeList.at( 0 ).toElement();
805  double xmin, xmax, ymin, ymax;
806  xmin = extentElem.attribute( QStringLiteral( "xmin" ) ).toDouble();
807  xmax = extentElem.attribute( QStringLiteral( "xmax" ) ).toDouble();
808  ymin = extentElem.attribute( QStringLiteral( "ymin" ) ).toDouble();
809  ymax = extentElem.attribute( QStringLiteral( "ymax" ) ).toDouble();
810  layoutItem->setExtent( QgsRectangle( xmin, ymin, xmax, ymax ) );
811  }
812 
813  QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral( "crs" ) );
814  if ( !crsNodeList.isEmpty() )
815  {
816  QDomElement crsElem = crsNodeList.at( 0 ).toElement();
817  layoutItem->crs().readXml( crsElem );
818  }
819  else
820  {
821  layoutItem->setCrs( QgsCoordinateReferenceSystem() );
822  }
823 
824  //map rotation
825  if ( !qgsDoubleNear( itemElem.attribute( QStringLiteral( "mapRotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) )
826  {
827  layoutItem->setMapRotation( itemElem.attribute( QStringLiteral( "mapRotation" ), QStringLiteral( "0" ) ).toDouble() );
828  }
829 
830  // follow map theme
831  layoutItem->setFollowVisibilityPreset( itemElem.attribute( QStringLiteral( "followPreset" ) ).compare( QLatin1String( "true" ) ) == 0 );
832  layoutItem->setFollowVisibilityPresetName( itemElem.attribute( QStringLiteral( "followPresetName" ) ) );
833 
834  //mKeepLayerSet flag
835  QString keepLayerSetFlag = itemElem.attribute( QStringLiteral( "keepLayerSet" ) );
836  if ( keepLayerSetFlag.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
837  {
838  layoutItem->setKeepLayerSet( true );
839  }
840  else
841  {
842  layoutItem->setKeepLayerSet( false );
843  }
844 
845  QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral( "drawCanvasItems" ), QStringLiteral( "true" ) );
846  if ( drawCanvasItemsFlag.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
847  {
848  layoutItem->setDrawAnnotations( true );
849  }
850  else
851  {
852  layoutItem->setDrawAnnotations( false );
853  }
854 
855  layoutItem->mLayerStyleOverrides.clear();
856 
857  //mLayers
858  layoutItem->mLayers.clear();
859 
860  QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral( "LayerSet" ) );
861  if ( !layerSetNodeList.isEmpty() )
862  {
863  QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
864  QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral( "Layer" ) );
865  layoutItem->mLayers.reserve( layerIdNodeList.size() );
866  for ( int i = 0; i < layerIdNodeList.size(); ++i )
867  {
868  QDomElement layerElem = layerIdNodeList.at( i ).toElement();
869  QString layerId = layerElem.text();
870  QString layerName = layerElem.attribute( QStringLiteral( "name" ) );
871  QString layerSource = layerElem.attribute( QStringLiteral( "source" ) );
872  QString layerProvider = layerElem.attribute( QStringLiteral( "provider" ) );
873 
874  QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
875  ref.resolveWeakly( project );
876  layoutItem->mLayers << ref;
877  }
878  }
879 
880  // override styles
881  QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral( "LayerStyles" ) );
882  layoutItem->mKeepLayerStyles = !layerStylesNodeList.isEmpty();
883  if ( layoutItem->mKeepLayerStyles )
884  {
885  QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
886  QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral( "LayerStyle" ) );
887  for ( int i = 0; i < layerStyleNodeList.size(); ++i )
888  {
889  const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
890  QString layerId = layerStyleElement.attribute( QStringLiteral( "layerid" ) );
891  QString layerName = layerStyleElement.attribute( QStringLiteral( "name" ) );
892  QString layerSource = layerStyleElement.attribute( QStringLiteral( "source" ) );
893  QString layerProvider = layerStyleElement.attribute( QStringLiteral( "provider" ) );
894  QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
895  ref.resolveWeakly( project );
896 
897  QgsMapLayerStyle style;
898  style.readXml( layerStyleElement );
899  layoutItem->mLayerStyleOverrides.insert( ref.layerId, style.xmlData() );
900  }
901  }
902 
903  layoutItem->mDrawing = false;
904  layoutItem->mNumCachedLayers = 0;
905  layoutItem->mCacheInvalidated = true;
906 
907  //overviews
908  //read overview stack
909  QDomNodeList mapOverviewNodeList = itemElem.elementsByTagName( QStringLiteral( "ComposerMapOverview" ) );
910  for ( int i = 0; i < mapOverviewNodeList.size(); ++i )
911  {
912  QDomElement mapOverviewElem = mapOverviewNodeList.at( i ).toElement();
913  std::unique_ptr<QgsLayoutItemMapOverview> mapOverview( new QgsLayoutItemMapOverview( mapOverviewElem.attribute( QStringLiteral( "name" ) ), layoutItem ) );
914  mapOverview->readXml( mapOverviewElem, doc, context );
915  QString frameMapId = mapOverviewElem.attribute( QStringLiteral( "frameMap" ), QStringLiteral( "-1" ) );
916  if ( frameMapId != QStringLiteral( "-1" ) && mapId2Uuid.contains( frameMapId ) )
917  {
918  QgsLayoutItemMap *mapInstance = qobject_cast<QgsLayoutItemMap *>( layoutItem->layout()->itemByUuid( mapId2Uuid[ frameMapId ] ) );
919  if ( mapInstance )
920  {
921  mapOverview->setLinkedMap( mapInstance );
922  }
923  layoutItem->mOverviewStack->addOverview( mapOverview.release() );
924  }
925  }
926 
927  //grids
928  layoutItem->mGridStack->readXml( itemElem, doc, context );
929 
930  //load grid / grid annotation in old xml format
931  //only do this if the grid stack didn't load any grids, otherwise this will
932  //be the dummy element created by QGIS >= 2.5 (refs #10905)
933  QDomNodeList gridNodeList = itemElem.elementsByTagName( QStringLiteral( "Grid" ) );
934  if ( layoutItem->mGridStack->size() == 0 && !gridNodeList.isEmpty() )
935  {
936  QDomElement gridElem = gridNodeList.at( 0 ).toElement();
937  QgsLayoutItemMapGrid *mapGrid = new QgsLayoutItemMapGrid( QObject::tr( "Grid %1" ).arg( 1 ), layoutItem );
938  mapGrid->setEnabled( gridElem.attribute( QStringLiteral( "show" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) );
939  mapGrid->setStyle( QgsLayoutItemMapGrid::GridStyle( gridElem.attribute( QStringLiteral( "gridStyle" ), QStringLiteral( "0" ) ).toInt() ) );
940  mapGrid->setIntervalX( gridElem.attribute( QStringLiteral( "intervalX" ), QStringLiteral( "0" ) ).toDouble() );
941  mapGrid->setIntervalY( gridElem.attribute( QStringLiteral( "intervalY" ), QStringLiteral( "0" ) ).toDouble() );
942  mapGrid->setOffsetX( gridElem.attribute( QStringLiteral( "offsetX" ), QStringLiteral( "0" ) ).toDouble() );
943  mapGrid->setOffsetY( gridElem.attribute( QStringLiteral( "offsetY" ), QStringLiteral( "0" ) ).toDouble() );
944  mapGrid->setCrossLength( gridElem.attribute( QStringLiteral( "crossLength" ), QStringLiteral( "3" ) ).toDouble() );
945  mapGrid->setFrameStyle( static_cast< QgsLayoutItemMapGrid::FrameStyle >( gridElem.attribute( QStringLiteral( "gridFrameStyle" ), QStringLiteral( "0" ) ).toInt() ) );
946  mapGrid->setFrameWidth( gridElem.attribute( QStringLiteral( "gridFrameWidth" ), QStringLiteral( "2.0" ) ).toDouble() );
947  mapGrid->setFramePenSize( gridElem.attribute( QStringLiteral( "gridFramePenThickness" ), QStringLiteral( "0.5" ) ).toDouble() );
948  mapGrid->setFramePenColor( QgsSymbolLayerUtils::decodeColor( gridElem.attribute( QStringLiteral( "framePenColor" ), QStringLiteral( "0,0,0" ) ) ) );
949  mapGrid->setFrameFillColor1( QgsSymbolLayerUtils::decodeColor( gridElem.attribute( QStringLiteral( "frameFillColor1" ), QStringLiteral( "255,255,255,255" ) ) ) );
950  mapGrid->setFrameFillColor2( QgsSymbolLayerUtils::decodeColor( gridElem.attribute( QStringLiteral( "frameFillColor2" ), QStringLiteral( "0,0,0,255" ) ) ) );
951  mapGrid->setBlendMode( QgsPainting::getCompositionMode( static_cast< QgsPainting::BlendMode >( itemElem.attribute( QStringLiteral( "gridBlendMode" ), QStringLiteral( "0" ) ).toUInt() ) ) );
952  QDomElement gridSymbolElem = gridElem.firstChildElement( QStringLiteral( "symbol" ) );
953  QgsLineSymbol *lineSymbol = nullptr;
954  if ( gridSymbolElem.isNull() )
955  {
956  //old project file, read penWidth /penColorRed, penColorGreen, penColorBlue
957  lineSymbol = QgsLineSymbol::createSimple( QgsStringMap() );
958  lineSymbol->setWidth( gridElem.attribute( QStringLiteral( "penWidth" ), QStringLiteral( "0" ) ).toDouble() );
959  lineSymbol->setColor( QColor( gridElem.attribute( QStringLiteral( "penColorRed" ), QStringLiteral( "0" ) ).toInt(),
960  gridElem.attribute( QStringLiteral( "penColorGreen" ), QStringLiteral( "0" ) ).toInt(),
961  gridElem.attribute( QStringLiteral( "penColorBlue" ), QStringLiteral( "0" ) ).toInt() ) );
962  }
963  else
964  {
965  lineSymbol = QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( gridSymbolElem, context );
966  }
967  mapGrid->setLineSymbol( lineSymbol );
968 
969  //annotation
970  QDomNodeList annotationNodeList = gridElem.elementsByTagName( QStringLiteral( "Annotation" ) );
971  if ( !annotationNodeList.isEmpty() )
972  {
973  QDomElement annotationElem = annotationNodeList.at( 0 ).toElement();
974  mapGrid->setAnnotationEnabled( annotationElem.attribute( QStringLiteral( "show" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) );
975  mapGrid->setAnnotationFormat( QgsLayoutItemMapGrid::AnnotationFormat( annotationElem.attribute( QStringLiteral( "format" ), QStringLiteral( "0" ) ).toInt() ) );
976  mapGrid->setAnnotationPosition( QgsLayoutItemMapGrid::AnnotationPosition( annotationElem.attribute( QStringLiteral( "leftPosition" ), QStringLiteral( "0" ) ).toInt() ), QgsLayoutItemMapGrid::Left );
977  mapGrid->setAnnotationPosition( QgsLayoutItemMapGrid::AnnotationPosition( annotationElem.attribute( QStringLiteral( "rightPosition" ), QStringLiteral( "0" ) ).toInt() ), QgsLayoutItemMapGrid::Right );
978  mapGrid->setAnnotationPosition( QgsLayoutItemMapGrid::AnnotationPosition( annotationElem.attribute( QStringLiteral( "topPosition" ), QStringLiteral( "0" ) ).toInt() ), QgsLayoutItemMapGrid::Top );
979  mapGrid->setAnnotationPosition( QgsLayoutItemMapGrid::AnnotationPosition( annotationElem.attribute( QStringLiteral( "bottomPosition" ), QStringLiteral( "0" ) ).toInt() ), QgsLayoutItemMapGrid::Bottom );
980  mapGrid->setAnnotationDirection( QgsLayoutItemMapGrid::AnnotationDirection( annotationElem.attribute( QStringLiteral( "leftDirection" ), QStringLiteral( "0" ) ).toInt() ), QgsLayoutItemMapGrid::Left );
981  mapGrid->setAnnotationDirection( QgsLayoutItemMapGrid::AnnotationDirection( annotationElem.attribute( QStringLiteral( "rightDirection" ), QStringLiteral( "0" ) ).toInt() ), QgsLayoutItemMapGrid::Right );
982  mapGrid->setAnnotationDirection( QgsLayoutItemMapGrid::AnnotationDirection( annotationElem.attribute( QStringLiteral( "topDirection" ), QStringLiteral( "0" ) ).toInt() ), QgsLayoutItemMapGrid::Top );
983  mapGrid->setAnnotationDirection( QgsLayoutItemMapGrid::AnnotationDirection( annotationElem.attribute( QStringLiteral( "bottomDirection" ), QStringLiteral( "0" ) ).toInt() ), QgsLayoutItemMapGrid::Bottom );
984  mapGrid->setAnnotationFrameDistance( annotationElem.attribute( QStringLiteral( "frameDistance" ), QStringLiteral( "0" ) ).toDouble() );
985  QFont annotationFont;
986  annotationFont.fromString( annotationElem.attribute( QStringLiteral( "font" ), QString() ) );
987  mapGrid->setAnnotationFont( annotationFont );
988  mapGrid->setAnnotationFontColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "0,0,0,255" ) ) ) );
989 
990  mapGrid->setAnnotationPrecision( annotationElem.attribute( QStringLiteral( "precision" ), QStringLiteral( "3" ) ).toInt() );
991  }
992  layoutItem->mGridStack->addGrid( mapGrid );
993  }
994 
995  //atlas
996  QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral( "AtlasMap" ) );
997  if ( !atlasNodeList.isEmpty() )
998  {
999  QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
1000  layoutItem->mAtlasDriven = ( atlasElem.attribute( QStringLiteral( "atlasDriven" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) );
1001  if ( atlasElem.hasAttribute( QStringLiteral( "fixedScale" ) ) ) // deprecated XML
1002  {
1003  layoutItem->setAtlasScalingMode( atlasElem.attribute( QStringLiteral( "fixedScale" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) ? QgsLayoutItemMap::AtlasScalingMode::Fixed : QgsLayoutItemMap::AtlasScalingMode::Auto );
1004  }
1005  else if ( atlasElem.hasAttribute( QStringLiteral( "scalingMode" ) ) )
1006  {
1007  layoutItem->setAtlasScalingMode( static_cast<QgsLayoutItemMap::AtlasScalingMode>( atlasElem.attribute( QStringLiteral( "scalingMode" ) ).toInt() ) );
1008  }
1009  layoutItem->setAtlasMargin( atlasElem.attribute( QStringLiteral( "margin" ), QStringLiteral( "0.1" ) ).toDouble() );
1010  }
1011 
1012  layoutItem->updateBoundingRect();
1013 
1014  return true;
1015 }
1016 
1017 bool QgsCompositionConverter::readScaleBarXml( QgsLayoutItemScaleBar *layoutItem, const QDomElement &itemElem, const QgsProject *project, const QgsStringMap &mapId2Uuid )
1018 {
1019  Q_UNUSED( project )
1020  restoreGeneralComposeItemProperties( layoutItem, itemElem );
1021 
1022  layoutItem->setHeight( itemElem.attribute( QStringLiteral( "height" ), QStringLiteral( "5.0" ) ).toDouble() );
1023  layoutItem->setHeight( itemElem.attribute( QStringLiteral( "height" ), QStringLiteral( "5.0" ) ).toDouble() );
1024  layoutItem->setLabelBarSpace( itemElem.attribute( QStringLiteral( "labelBarSpace" ), QStringLiteral( "3.0" ) ).toDouble() );
1025  layoutItem->setBoxContentSpace( itemElem.attribute( QStringLiteral( "boxContentSpace" ), QStringLiteral( "1.0" ) ).toDouble() );
1026  layoutItem->setNumberOfSegments( itemElem.attribute( QStringLiteral( "numSegments" ), QStringLiteral( "2" ) ).toInt() );
1027  layoutItem->setNumberOfSegmentsLeft( itemElem.attribute( QStringLiteral( "numSegmentsLeft" ), QStringLiteral( "0" ) ).toInt() );
1028  layoutItem->setUnitsPerSegment( itemElem.attribute( QStringLiteral( "numUnitsPerSegment" ), QStringLiteral( "1.0" ) ).toDouble() );
1029  layoutItem->setSegmentSizeMode( static_cast<QgsScaleBarSettings::SegmentSizeMode>( itemElem.attribute( QStringLiteral( "segmentSizeMode" ), QStringLiteral( "0" ) ).toInt() ) );
1030  layoutItem->setMinimumBarWidth( itemElem.attribute( QStringLiteral( "minBarWidth" ), QStringLiteral( "50" ) ).toDouble() );
1031  layoutItem->setMaximumBarWidth( itemElem.attribute( QStringLiteral( "maxBarWidth" ), QStringLiteral( "150" ) ).toDouble() );
1032  layoutItem->mSegmentMillimeters = itemElem.attribute( QStringLiteral( "segmentMillimeters" ), QStringLiteral( "0.0" ) ).toDouble();
1033  layoutItem->setMapUnitsPerScaleBarUnit( itemElem.attribute( QStringLiteral( "numMapUnitsPerScaleBarUnit" ), QStringLiteral( "1.0" ) ).toDouble() );
1034  layoutItem->setUnitLabel( itemElem.attribute( QStringLiteral( "unitLabel" ) ) );
1035 
1036  QFont f;
1037  if ( !QgsFontUtils::setFromXmlChildNode( f, itemElem, QStringLiteral( "scaleBarFont" ) ) )
1038  {
1039  f.fromString( itemElem.attribute( QStringLiteral( "font" ), QString() ) );
1040  }
1042  layoutItem->setFont( f );
1044 
1045  //colors
1046  //fill color
1047  QDomNodeList fillColorList = itemElem.elementsByTagName( QStringLiteral( "fillColor" ) );
1048  if ( !fillColorList.isEmpty() )
1049  {
1050  QDomElement fillColorElem = fillColorList.at( 0 ).toElement();
1051  bool redOk, greenOk, blueOk, alphaOk;
1052  int fillRed, fillGreen, fillBlue, fillAlpha;
1053 
1054  fillRed = fillColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1055  fillGreen = fillColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1056  fillBlue = fillColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1057  fillAlpha = fillColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1058 
1059  if ( redOk && greenOk && blueOk && alphaOk )
1060  {
1061  layoutItem->fillSymbol()->setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
1062  }
1063  }
1064  else
1065  {
1066  layoutItem->fillSymbol()->setColor( QColor( itemElem.attribute( QStringLiteral( "brushColor" ), QStringLiteral( "#000000" ) ) ) );
1067  }
1068 
1069  //fill color 2
1070  QDomNodeList fillColor2List = itemElem.elementsByTagName( QStringLiteral( "fillColor2" ) );
1071  if ( !fillColor2List.isEmpty() )
1072  {
1073  QDomElement fillColor2Elem = fillColor2List.at( 0 ).toElement();
1074  bool redOk, greenOk, blueOk, alphaOk;
1075  int fillRed, fillGreen, fillBlue, fillAlpha;
1076 
1077  fillRed = fillColor2Elem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1078  fillGreen = fillColor2Elem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1079  fillBlue = fillColor2Elem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1080  fillAlpha = fillColor2Elem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1081 
1082  if ( redOk && greenOk && blueOk && alphaOk )
1083  {
1084  layoutItem->alternateFillSymbol()->setColor( QColor( fillRed, fillGreen, fillBlue, fillAlpha ) );
1085  }
1086  }
1087  else
1088  {
1089  layoutItem->alternateFillSymbol()->setColor( QColor( itemElem.attribute( QStringLiteral( "brush2Color" ), QStringLiteral( "#ffffff" ) ) ) );
1090  }
1091 
1092  std::unique_ptr< QgsLineSymbol > lineSymbol = qgis::make_unique< QgsLineSymbol >();
1093  std::unique_ptr< QgsSimpleLineSymbolLayer > lineSymbolLayer = qgis::make_unique< QgsSimpleLineSymbolLayer >();
1094  lineSymbolLayer->setWidth( itemElem.attribute( QStringLiteral( "outlineWidth" ), QStringLiteral( "0.3" ) ).toDouble() );
1095  lineSymbolLayer->setWidthUnit( QgsUnitTypes::RenderMillimeters );
1096  lineSymbolLayer->setPenJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( itemElem.attribute( QStringLiteral( "lineJoinStyle" ), QStringLiteral( "miter" ) ) ) );
1097  lineSymbolLayer->setPenCapStyle( QgsSymbolLayerUtils::decodePenCapStyle( itemElem.attribute( QStringLiteral( "lineCapStyle" ), QStringLiteral( "square" ) ) ) );
1098  //stroke color
1099  QDomNodeList strokeColorList = itemElem.elementsByTagName( QStringLiteral( "strokeColor" ) );
1100  if ( !strokeColorList.isEmpty() )
1101  {
1102  QDomElement strokeColorElem = strokeColorList.at( 0 ).toElement();
1103  bool redOk, greenOk, blueOk, alphaOk;
1104  int strokeRed, strokeGreen, strokeBlue, strokeAlpha;
1105 
1106  strokeRed = strokeColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1107  strokeGreen = strokeColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1108  strokeBlue = strokeColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1109  strokeAlpha = strokeColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1110 
1111  if ( redOk && greenOk && blueOk && alphaOk )
1112  {
1113  lineSymbolLayer->setColor( QColor( strokeRed, strokeGreen, strokeBlue, strokeAlpha ) );
1114  }
1115  }
1116  else
1117  {
1118  lineSymbolLayer->setColor( QColor( itemElem.attribute( QStringLiteral( "penColor" ), QStringLiteral( "#000000" ) ) ) );
1119  }
1120  lineSymbol->changeSymbolLayer( 0, lineSymbolLayer.release() );
1121  layoutItem->setDivisionLineSymbol( lineSymbol->clone() );
1122  layoutItem->setSubdivisionLineSymbol( lineSymbol->clone() );
1123  layoutItem->setLineSymbol( lineSymbol.release() );
1124 
1125  //font color
1126  QDomNodeList textColorList = itemElem.elementsByTagName( QStringLiteral( "textColor" ) );
1127  if ( !textColorList.isEmpty() )
1128  {
1129  QDomElement textColorElem = textColorList.at( 0 ).toElement();
1130  bool redOk, greenOk, blueOk, alphaOk;
1131  int textRed, textGreen, textBlue, textAlpha;
1132 
1133  textRed = textColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1134  textGreen = textColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1135  textBlue = textColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1136  textAlpha = textColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1137 
1138  if ( redOk && greenOk && blueOk && alphaOk )
1139  {
1141  layoutItem->setFontColor( QColor( textRed, textGreen, textBlue, textAlpha ) );
1143  }
1144  }
1145  else
1146  {
1147  QColor c;
1148  c.setNamedColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "#000000" ) ) );
1150  layoutItem->setFontColor( c );
1152  }
1153 
1154  //style
1155  QString styleString = itemElem.attribute( QStringLiteral( "style" ), QString() );
1156  layoutItem->setStyle( QObject::tr( styleString.toLocal8Bit().data() ) );
1157 
1158  if ( itemElem.attribute( QStringLiteral( "unitType" ) ).isEmpty() )
1159  {
1161  switch ( itemElem.attribute( QStringLiteral( "units" ) ).toInt() )
1162  {
1163  case 0:
1165  break;
1166  case 1:
1168  break;
1169  case 2:
1171  break;
1172  case 3:
1174  break;
1175  }
1176  layoutItem->setUnits( u );
1177  }
1178  else
1179  {
1180  layoutItem->setUnits( QgsUnitTypes::decodeDistanceUnit( itemElem.attribute( QStringLiteral( "unitType" ) ) ) );
1181  }
1182  layoutItem->setAlignment( static_cast< QgsScaleBarSettings::Alignment >( itemElem.attribute( QStringLiteral( "alignment" ), QStringLiteral( "0" ) ).toInt() ) );
1183 
1184  //composer map: use uuid
1185  QString mapId = itemElem.attribute( QStringLiteral( "mapId" ), QStringLiteral( "-1" ) );
1186  if ( mapId != QStringLiteral( "-1" ) && mapId2Uuid.contains( mapId ) )
1187  {
1188  QgsLayoutItemMap *mapInstance = qobject_cast<QgsLayoutItemMap *>( layoutItem->layout()->itemByUuid( mapId2Uuid[ mapId ] ) );
1189  if ( mapInstance )
1190  {
1191  layoutItem->setLinkedMap( mapInstance );
1192  }
1193  }
1194 
1195  return true;
1196 }
1197 
1198 bool QgsCompositionConverter::readLegendXml( QgsLayoutItemLegend *layoutItem, const QDomElement &itemElem, const QgsProject *project, const QgsStringMap &mapId2Uuid )
1199 {
1200  restoreGeneralComposeItemProperties( layoutItem, itemElem );
1201 
1202  QgsPathResolver pathResolver;
1203  if ( project )
1204  pathResolver = project->pathResolver();
1205  QgsReadWriteContext context;
1206  context.setPathResolver( pathResolver );
1207  context.setProjectTranslator( const_cast<QgsProject *>( project ) );
1208 
1209  //composer map: use uuid
1210  QString mapId = itemElem.attribute( QStringLiteral( "map" ), QStringLiteral( "-1" ) );
1211  if ( mapId != QStringLiteral( "-1" ) && mapId2Uuid.contains( mapId ) )
1212  {
1213  QgsLayoutItemMap *mapInstance = qobject_cast<QgsLayoutItemMap *>( layoutItem->layout()->itemByUuid( mapId2Uuid[ mapId ] ) );
1214  if ( mapInstance )
1215  {
1216  layoutItem->setLinkedMap( mapInstance );
1217  }
1218  }
1219 
1220  //read general properties
1221  layoutItem->setTitle( itemElem.attribute( QStringLiteral( "title" ) ) );
1222  if ( !itemElem.attribute( QStringLiteral( "titleAlignment" ) ).isEmpty() )
1223  {
1224  layoutItem->setTitleAlignment( static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "titleAlignment" ) ).toInt() ) );
1225  }
1226  int colCount = itemElem.attribute( QStringLiteral( "columnCount" ), QStringLiteral( "1" ) ).toInt();
1227  if ( colCount < 1 ) colCount = 1;
1228  layoutItem->setColumnCount( colCount );
1229  layoutItem->setSplitLayer( itemElem.attribute( QStringLiteral( "splitLayer" ), QStringLiteral( "0" ) ).toInt() == 1 );
1230  layoutItem->setEqualColumnWidth( itemElem.attribute( QStringLiteral( "equalColumnWidth" ), QStringLiteral( "0" ) ).toInt() == 1 );
1231 
1232  QDomNodeList stylesNodeList = itemElem.elementsByTagName( QStringLiteral( "styles" ) );
1233  if ( !stylesNodeList.isEmpty() )
1234  {
1235  QDomNode stylesNode = stylesNodeList.at( 0 );
1236  for ( int i = 0; i < stylesNode.childNodes().size(); i++ )
1237  {
1238  QDomElement styleElem = stylesNode.childNodes().at( i ).toElement();
1239  QgsLegendStyle style;
1240  style.readXml( styleElem, QDomDocument() );
1241  QString name = styleElem.attribute( QStringLiteral( "name" ) );
1243  if ( name == QLatin1String( "title" ) ) s = QgsLegendStyle::Title;
1244  else if ( name == QLatin1String( "group" ) ) s = QgsLegendStyle::Group;
1245  else if ( name == QLatin1String( "subgroup" ) ) s = QgsLegendStyle::Subgroup;
1246  else if ( name == QLatin1String( "symbol" ) ) s = QgsLegendStyle::Symbol;
1247  else if ( name == QLatin1String( "symbolLabel" ) ) s = QgsLegendStyle::SymbolLabel;
1248  else continue;
1249  layoutItem->setStyle( s, style );
1250  }
1251  }
1252 
1253  //font color
1254  QColor fontClr;
1255  fontClr.setNamedColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "#000000" ) ) );
1256  layoutItem->setFontColor( fontClr );
1257 
1258  //spaces
1259  layoutItem->setBoxSpace( itemElem.attribute( QStringLiteral( "boxSpace" ), QStringLiteral( "2.0" ) ).toDouble() );
1260  layoutItem->setColumnSpace( itemElem.attribute( QStringLiteral( "columnSpace" ), QStringLiteral( "2.0" ) ).toDouble() );
1261 
1262  layoutItem->setSymbolWidth( itemElem.attribute( QStringLiteral( "symbolWidth" ), QStringLiteral( "7.0" ) ).toDouble() );
1263  layoutItem->setSymbolHeight( itemElem.attribute( QStringLiteral( "symbolHeight" ), QStringLiteral( "14.0" ) ).toDouble() );
1264  layoutItem->setWmsLegendWidth( itemElem.attribute( QStringLiteral( "wmsLegendWidth" ), QStringLiteral( "50" ) ).toDouble() );
1265  layoutItem->setWmsLegendHeight( itemElem.attribute( QStringLiteral( "wmsLegendHeight" ), QStringLiteral( "25" ) ).toDouble() );
1266  layoutItem->setLineSpacing( itemElem.attribute( QStringLiteral( "lineSpacing" ), QStringLiteral( "1.0" ) ).toDouble() );
1267 
1268  layoutItem->setDrawRasterStroke( itemElem.attribute( QStringLiteral( "rasterBorder" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
1269  layoutItem->setRasterStrokeColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "rasterBorderColor" ), QStringLiteral( "0,0,0" ) ) ) );
1270  layoutItem->setRasterStrokeWidth( itemElem.attribute( QStringLiteral( "rasterBorderWidth" ), QStringLiteral( "0" ) ).toDouble() );
1271 
1272  layoutItem->setWrapString( itemElem.attribute( QStringLiteral( "wrapChar" ) ) );
1273 
1274  layoutItem->mSizeToContents = itemElem.attribute( QStringLiteral( "resizeToContents" ), QStringLiteral( "1" ) ) != QLatin1String( "0" );
1275  layoutItem->mLegendFilterByMap = itemElem.attribute( QStringLiteral( "legendFilterByMap" ), QStringLiteral( "0" ) ).toInt();
1276  layoutItem->mFilterOutAtlas = itemElem.attribute( QStringLiteral( "legendFilterByAtlas" ), QStringLiteral( "0" ) ).toInt();
1277 
1278  // QGIS >= 2.6
1279  QDomElement layerTreeElem = itemElem.firstChildElement( QStringLiteral( "layer-tree" ) );
1280  if ( layerTreeElem.isNull() )
1281  layerTreeElem = itemElem.firstChildElement( QStringLiteral( "layer-tree-group" ) );
1282 
1283  if ( !layerTreeElem.isNull() )
1284  {
1285  QgsLayerTree *tree( QgsLayerTree::readXml( layerTreeElem, context ) );
1286  if ( project )
1287  tree->resolveReferences( project, true );
1288  layoutItem->setCustomLayerTree( tree );
1289  }
1290  else
1291  {
1292  layoutItem->setCustomLayerTree( nullptr );
1293  }
1294 
1295  return true;
1296 }
1297 
1298 bool QgsCompositionConverter::readAtlasXml( QgsLayoutAtlas *atlasItem, const QDomElement &itemElem, const QgsProject *project )
1299 {
1300  atlasItem->setEnabled( itemElem.attribute( QStringLiteral( "enabled" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) );
1301 
1302  // look for stored layer name
1303  QString layerId = itemElem.attribute( QStringLiteral( "coverageLayer" ) );
1304  QString layerName = itemElem.attribute( QStringLiteral( "coverageLayerName" ) );
1305  QString layerSource = itemElem.attribute( QStringLiteral( "coverageLayerSource" ) );
1306  QString layerProvider = itemElem.attribute( QStringLiteral( "coverageLayerProvider" ) );
1307 
1308  QgsVectorLayerRef layerRef( layerId, layerName, layerSource, layerProvider );
1309  atlasItem->setCoverageLayer( layerRef.resolveWeakly( project ) );
1310 
1311  atlasItem->setPageNameExpression( itemElem.attribute( QStringLiteral( "pageNameExpression" ), QString() ) );
1312  QString errorString;
1313  atlasItem->setFilenameExpression( itemElem.attribute( QStringLiteral( "filenamePattern" ), QString() ), errorString );
1314  // note: no error reporting for errorString
1315  atlasItem->setSortFeatures( itemElem.attribute( QStringLiteral( "sortFeatures" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) );
1316  if ( atlasItem->sortFeatures() )
1317  {
1318  atlasItem->setSortExpression( itemElem.attribute( QStringLiteral( "sortKey" ), QString() ) );
1319  atlasItem->setSortAscending( itemElem.attribute( QStringLiteral( "sortAscending" ), QStringLiteral( "true" ) ) == QLatin1String( "true" ) );
1320  }
1321  atlasItem->setFilterFeatures( itemElem.attribute( QStringLiteral( "filterFeatures" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) );
1322  if ( atlasItem->filterFeatures( ) )
1323  {
1324  QString expErrorString;
1325  atlasItem->setFilterExpression( itemElem.attribute( QStringLiteral( "featureFilter" ), QString() ), expErrorString );
1326  // note: no error reporting for errorString
1327  }
1328 
1329  atlasItem->setHideCoverage( itemElem.attribute( QStringLiteral( "hideCoverage" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) );
1330 
1331  return true;
1332 
1333 }
1334 
1335 bool QgsCompositionConverter::readHtmlXml( QgsLayoutItemHtml *layoutItem, const QDomElement &itemElem, const QgsProject *project )
1336 {
1337  Q_UNUSED( project )
1338  readOldComposerObjectXml( layoutItem, itemElem );
1339 
1340  //first create the frames
1341  layoutItem->setResizeMode( static_cast< QgsLayoutMultiFrame::ResizeMode >( itemElem.attribute( QStringLiteral( "resizeMode" ), QStringLiteral( "0" ) ).toInt() ) );
1342  QDomNodeList frameList = itemElem.elementsByTagName( QStringLiteral( "ComposerFrame" ) );
1343  for ( int i = 0; i < frameList.size(); ++i )
1344  {
1345  QDomElement frameElem = frameList.at( i ).toElement();
1346  QgsLayoutFrame *newFrame = new QgsLayoutFrame( layoutItem->layout(), layoutItem );
1347  restoreGeneralComposeItemProperties( newFrame, frameElem );
1348  // Read frame XML
1349  double x = itemElem.attribute( QStringLiteral( "sectionX" ) ).toDouble();
1350  double y = itemElem.attribute( QStringLiteral( "sectionY" ) ).toDouble();
1351  double width = itemElem.attribute( QStringLiteral( "sectionWidth" ) ).toDouble();
1352  double height = itemElem.attribute( QStringLiteral( "sectionHeight" ) ).toDouble();
1353  newFrame->setContentSection( QRectF( x, y, width, height ) );
1354  newFrame->setHidePageIfEmpty( itemElem.attribute( QStringLiteral( "hidePageIfEmpty" ), QStringLiteral( "0" ) ).toInt() );
1355  newFrame->setHideBackgroundIfEmpty( itemElem.attribute( QStringLiteral( "hideBackgroundIfEmpty" ), QStringLiteral( "0" ) ).toInt() );
1356  layoutItem->addFrame( newFrame, false );
1357  }
1358 
1359  bool contentModeOK;
1360  layoutItem->setContentMode( static_cast< QgsLayoutItemHtml::ContentMode >( itemElem.attribute( QStringLiteral( "contentMode" ) ).toInt( &contentModeOK ) ) );
1361  if ( !contentModeOK )
1362  {
1363  layoutItem->setContentMode( QgsLayoutItemHtml::ContentMode::Url );
1364  }
1365  layoutItem->setEvaluateExpressions( itemElem.attribute( QStringLiteral( "evaluateExpressions" ), QStringLiteral( "true" ) ) == QLatin1String( "true" ) );
1366  layoutItem->setUseSmartBreaks( itemElem.attribute( QStringLiteral( "useSmartBreaks" ), QStringLiteral( "true" ) ) == QLatin1String( "true" ) );
1367  layoutItem->setMaxBreakDistance( itemElem.attribute( QStringLiteral( "maxBreakDistance" ), QStringLiteral( "10" ) ).toDouble() );
1368  layoutItem->setHtml( itemElem.attribute( QStringLiteral( "html" ) ) );
1369  layoutItem->setUserStylesheet( itemElem.attribute( QStringLiteral( "stylesheet" ) ) );
1370  layoutItem->setUserStylesheetEnabled( itemElem.attribute( QStringLiteral( "stylesheetEnabled" ), QStringLiteral( "false" ) ) == QLatin1String( "true" ) );
1371 
1372  //finally load the set url
1373  QString urlString = itemElem.attribute( QStringLiteral( "url" ) );
1374  if ( !urlString.isEmpty() )
1375  {
1376  layoutItem->setUrl( urlString );
1377  }
1378  layoutItem->loadHtml( true );
1379 
1380  return true;
1381 }
1382 
1383 bool QgsCompositionConverter::readTableXml( QgsLayoutItemAttributeTable *layoutItem, const QDomElement &itemElem, const QgsProject *project )
1384 {
1385 
1386  Q_UNUSED( project )
1387  readOldComposerObjectXml( layoutItem, itemElem );
1388 
1389  //first create the frames
1390  layoutItem->setResizeMode( static_cast< QgsLayoutMultiFrame::ResizeMode >( itemElem.attribute( QStringLiteral( "resizeMode" ), QStringLiteral( "0" ) ).toInt() ) );
1391  QDomNodeList frameList = itemElem.elementsByTagName( QStringLiteral( "ComposerFrame" ) );
1392  for ( int i = 0; i < frameList.size(); ++i )
1393  {
1394  QDomElement frameElem = frameList.at( i ).toElement();
1395  QgsLayoutFrame *newFrame = new QgsLayoutFrame( layoutItem->layout(), layoutItem );
1396  restoreGeneralComposeItemProperties( newFrame, frameElem );
1397  // Read frame XML
1398  double x = itemElem.attribute( QStringLiteral( "sectionX" ) ).toDouble();
1399  double y = itemElem.attribute( QStringLiteral( "sectionY" ) ).toDouble();
1400  double width = itemElem.attribute( QStringLiteral( "sectionWidth" ) ).toDouble();
1401  double height = itemElem.attribute( QStringLiteral( "sectionHeight" ) ).toDouble();
1402  newFrame->setContentSection( QRectF( x, y, width, height ) );
1403  newFrame->setHidePageIfEmpty( itemElem.attribute( QStringLiteral( "hidePageIfEmpty" ), QStringLiteral( "0" ) ).toInt() );
1404  newFrame->setHideBackgroundIfEmpty( itemElem.attribute( QStringLiteral( "hideBackgroundIfEmpty" ), QStringLiteral( "0" ) ).toInt() );
1405  layoutItem->addFrame( newFrame, false );
1406  }
1407 
1408  layoutItem->setEmptyTableBehavior( static_cast<QgsLayoutTable::EmptyTableMode>( itemElem.attribute( QStringLiteral( "emptyTableMode" ), QStringLiteral( "0" ) ).toInt() ) );
1409  layoutItem->setEmptyTableMessage( itemElem.attribute( QStringLiteral( "emptyTableMessage" ), QObject::tr( "No matching records" ) ) );
1410  layoutItem->setShowEmptyRows( itemElem.attribute( QStringLiteral( "showEmptyRows" ), QStringLiteral( "0" ) ).toInt() );
1411  if ( !QgsFontUtils::setFromXmlChildNode( layoutItem->mHeaderFont, itemElem, QStringLiteral( "headerFontProperties" ) ) )
1412  {
1413  layoutItem->mHeaderFont.fromString( itemElem.attribute( QStringLiteral( "headerFont" ), QString() ) );
1414  }
1415  layoutItem->setHeaderFontColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "headerFontColor" ), QStringLiteral( "0,0,0,255" ) ) ) );
1416  layoutItem->setHeaderHAlignment( static_cast<QgsLayoutTable::HeaderHAlignment>( itemElem.attribute( QStringLiteral( "headerHAlignment" ), QStringLiteral( "0" ) ).toInt() ) ) ;
1417  layoutItem->setHeaderMode( static_cast<QgsLayoutTable::HeaderMode>( itemElem.attribute( QStringLiteral( "headerMode" ), QStringLiteral( "0" ) ).toInt() ) );
1418  if ( !QgsFontUtils::setFromXmlChildNode( layoutItem->mContentFont, itemElem, QStringLiteral( "contentFontProperties" ) ) )
1419  {
1420  layoutItem->mContentFont.fromString( itemElem.attribute( QStringLiteral( "contentFont" ), QString() ) );
1421  }
1422  layoutItem->setContentFontColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "contentFontColor" ), QStringLiteral( "0,0,0,255" ) ) ) );
1423  layoutItem->setCellMargin( itemElem.attribute( QStringLiteral( "cellMargin" ), QStringLiteral( "1.0" ) ).toDouble() );
1424  layoutItem->setGridStrokeWidth( itemElem.attribute( QStringLiteral( "gridStrokeWidth" ), QStringLiteral( "0.5" ) ).toDouble() );
1425  layoutItem->setHorizontalGrid( itemElem.attribute( QStringLiteral( "horizontalGrid" ), QStringLiteral( "1" ) ).toInt() );
1426  layoutItem->setVerticalGrid( itemElem.attribute( QStringLiteral( "verticalGrid" ), QStringLiteral( "1" ) ).toInt() );
1427  layoutItem->setShowGrid( itemElem.attribute( QStringLiteral( "showGrid" ), QStringLiteral( "1" ) ).toInt() );
1428  layoutItem->setGridColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "gridColor" ), QStringLiteral( "0,0,0,255" ) ) ) );
1429  layoutItem->setBackgroundColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "backgroundColor" ), QStringLiteral( "255,255,255,0" ) ) ) );
1430  layoutItem->setWrapBehavior( static_cast<QgsLayoutTable::WrapBehavior>( itemElem.attribute( QStringLiteral( "wrapBehavior" ), QStringLiteral( "0" ) ).toInt() ) );
1431 
1432  //restore column specifications
1433  layoutItem->mColumns.clear();
1434  layoutItem->mSortColumns.clear();
1435 
1436  QDomNodeList columnsList = itemElem.elementsByTagName( QStringLiteral( "displayColumns" ) );
1437  if ( !columnsList.isEmpty() )
1438  {
1439  QDomElement columnsElem = columnsList.at( 0 ).toElement();
1440  QDomNodeList columnEntryList = columnsElem.elementsByTagName( QStringLiteral( "column" ) );
1441  for ( int i = 0; i < columnEntryList.size(); ++i )
1442  {
1443  QDomElement columnElem = columnEntryList.at( i ).toElement();
1444  QgsLayoutTableColumn column;
1445  column.mHAlignment = static_cast< Qt::AlignmentFlag >( columnElem.attribute( QStringLiteral( "hAlignment" ), QString::number( Qt::AlignLeft ) ).toInt() );
1446  column.mVAlignment = static_cast< Qt::AlignmentFlag >( columnElem.attribute( QStringLiteral( "vAlignment" ), QString::number( Qt::AlignVCenter ) ).toInt() );
1447  column.mHeading = columnElem.attribute( QStringLiteral( "heading" ), QString() );
1448  column.mAttribute = columnElem.attribute( QStringLiteral( "attribute" ), QString() );
1449  column.mSortByRank = columnElem.attribute( QStringLiteral( "sortByRank" ), QStringLiteral( "0" ) ).toInt();
1450  column.mSortOrder = static_cast< Qt::SortOrder >( columnElem.attribute( QStringLiteral( "sortOrder" ), QString::number( Qt::AscendingOrder ) ).toInt() );
1451  column.mWidth = columnElem.attribute( QStringLiteral( "width" ), QStringLiteral( "0.0" ) ).toDouble();
1452 
1453  QDomNodeList bgColorList = columnElem.elementsByTagName( QStringLiteral( "backgroundColor" ) );
1454  if ( !bgColorList.isEmpty() )
1455  {
1456  QDomElement bgColorElem = bgColorList.at( 0 ).toElement();
1457  bool redOk, greenOk, blueOk, alphaOk;
1458  int bgRed, bgGreen, bgBlue, bgAlpha;
1459  bgRed = bgColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1460  bgGreen = bgColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1461  bgBlue = bgColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1462  bgAlpha = bgColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1463  if ( redOk && greenOk && blueOk && alphaOk )
1464  {
1465  column.mBackgroundColor = QColor( bgRed, bgGreen, bgBlue, bgAlpha );
1466  }
1467  }
1468  layoutItem->mColumns.append( column );
1469 
1470  // sorting columns are now (QGIS 3.14+) handled in a dedicated list
1471  // copy the display columns if sortByRank > 0 and then, sort them by rank
1473  std::copy_if( layoutItem->mColumns.begin(), layoutItem->mColumns.end(), std::back_inserter( layoutItem->mSortColumns ), []( const QgsLayoutTableColumn & col ) {return col.sortByRank() > 0;} );
1474  std::sort( layoutItem->mSortColumns.begin(), layoutItem->mSortColumns.end(), []( const QgsLayoutTableColumn & a, const QgsLayoutTableColumn & b ) {return a.sortByRank() < b.sortByRank();} );
1476  }
1477  }
1478 
1479  //restore cell styles
1480  QDomNodeList stylesList = itemElem.elementsByTagName( QStringLiteral( "cellStyles" ) );
1481  if ( !stylesList.isEmpty() )
1482  {
1483  QDomElement stylesElem = stylesList.at( 0 ).toElement();
1484 
1485  QMap< QgsLayoutTable::CellStyleGroup, QString >::const_iterator it = layoutItem->mCellStyleNames.constBegin();
1486  for ( ; it != layoutItem->mCellStyleNames.constEnd(); ++it )
1487  {
1488  QString styleName = it.value();
1489  QDomNodeList styleList = stylesElem.elementsByTagName( styleName );
1490  if ( !styleList.isEmpty() )
1491  {
1492  QDomElement styleElem = styleList.at( 0 ).toElement();
1493  QgsLayoutTableStyle *style = layoutItem->mCellStyles.value( it.key() );
1494  if ( style )
1495  style->readXml( styleElem );
1496  }
1497  }
1498  }
1499 
1500  // look for stored layer name
1501  QString layerId = itemElem.attribute( QStringLiteral( "vectorLayer" ) );
1502  QString layerName = itemElem.attribute( QStringLiteral( "vectorLayerName" ) );
1503  QString layerSource = itemElem.attribute( QStringLiteral( "vectorLayerSource" ) );
1504  QString layerProvider = itemElem.attribute( QStringLiteral( "vectorLayerProvider" ) );
1505 
1506  QgsVectorLayerRef layerRef( layerId, layerName, layerSource, layerProvider );
1507  layoutItem->setVectorLayer( layerRef.resolveWeakly( project ) );
1508 
1509  return true;
1510 }
1511 
1512 
1513 template <class T, class T2>
1514 bool QgsCompositionConverter::readPolyXml( T *layoutItem, const QDomElement &itemElem, const QgsProject *project )
1515 {
1516  restoreGeneralComposeItemProperties( layoutItem, itemElem );
1517  QDomNodeList nodeList = itemElem.elementsByTagName( QStringLiteral( "node" ) );
1518  if ( !nodeList.isEmpty() )
1519  {
1520  QPolygonF polygon;
1521  for ( int i = 0; i < nodeList.length(); i++ )
1522  {
1523  QDomElement node = nodeList.at( i ).toElement();
1524  polygon.append( QPointF( node.attribute( QStringLiteral( "x" ) ).toDouble( ), node.attribute( QStringLiteral( "y" ) ).toDouble() ) );
1525  }
1526  layoutItem->setNodes( polygon );
1527  }
1528  if ( itemElem.elementsByTagName( QStringLiteral( "symbol" ) ).size() )
1529  {
1530  QDomElement symbolElement = itemElem.elementsByTagName( QStringLiteral( "symbol" ) ).at( 0 ).toElement();
1531  QgsReadWriteContext context;
1532  if ( project )
1533  context.setPathResolver( project->pathResolver( ) );
1534  T2 *styleSymbol = QgsSymbolLayerUtils::loadSymbol<T2>( symbolElement, context );
1535  if ( styleSymbol )
1536  layoutItem->setSymbol( styleSymbol );
1537  }
1538  // Disable frame for shapes
1539  layoutItem->setFrameEnabled( false );
1540  layoutItem->setBackgroundEnabled( false );
1541  return true;
1542 }
1543 
1544 
1545 bool QgsCompositionConverter::readXml( QgsLayoutItem *layoutItem, const QDomElement &itemElem )
1546 {
1547  if ( itemElem.isNull() )
1548  {
1549  return false;
1550  }
1551 
1552  readOldComposerObjectXml( layoutItem, itemElem );
1553 
1554  //uuid
1555  layoutItem->mUuid = itemElem.attribute( QStringLiteral( "uuid" ), QUuid::createUuid().toString() );
1556 
1557  // temporary for groups imported from templates
1558  layoutItem->mTemplateUuid = itemElem.attribute( QStringLiteral( "templateUuid" ) );
1559 
1560  //id
1561  QString id = itemElem.attribute( QStringLiteral( "id" ), QString() );
1562  layoutItem->setId( id );
1563 
1564  //frame
1565  QString frame = itemElem.attribute( QStringLiteral( "frame" ) );
1566  layoutItem->setFrameEnabled( frame.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 ) ;
1567 
1568  //frame
1569  QString background = itemElem.attribute( QStringLiteral( "background" ) );
1570  layoutItem->setBackgroundEnabled( background.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 );
1571 
1572  //position lock for mouse moves/resizes
1573  QString positionLock = itemElem.attribute( QStringLiteral( "positionLock" ) );
1574  layoutItem->setLocked( positionLock.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 );
1575 
1576  //visibility
1577  layoutItem->setVisibility( itemElem.attribute( QStringLiteral( "visibility" ), QStringLiteral( "1" ) ) != QStringLiteral( "0" ) );
1578 
1579  layoutItem->mParentGroupUuid = itemElem.attribute( QStringLiteral( "groupUuid" ) );
1580  if ( !layoutItem->mParentGroupUuid.isEmpty() )
1581  {
1582  if ( QgsLayoutItemGroup *group = layoutItem->parentGroup() )
1583  {
1584  group->addItem( layoutItem );
1585  }
1586  }
1587  layoutItem->mTemplateUuid = itemElem.attribute( QStringLiteral( "templateUuid" ) );
1588 
1589 
1590  QRectF position = itemPosition( layoutItem, itemElem );
1591 
1592  // TODO: missing?
1593  // mLastValidViewScaleFactor = itemElem.attribute( QStringLiteral( "lastValidViewScaleFactor" ), QStringLiteral( "-1" ) ).toDouble();
1594 
1595  layoutItem->setZValue( itemElem.attribute( QStringLiteral( "zValue" ) ).toDouble() );
1596 
1597  //pen
1598  QDomNodeList frameColorList = itemElem.elementsByTagName( QStringLiteral( "FrameColor" ) );
1599  if ( !frameColorList.isEmpty() )
1600  {
1601  QDomElement frameColorElem = frameColorList.at( 0 ).toElement();
1602  bool redOk, greenOk, blueOk, alphaOk, widthOk;
1603  int penRed, penGreen, penBlue, penAlpha;
1604  double penWidth;
1605 
1606  penWidth = itemElem.attribute( QStringLiteral( "outlineWidth" ) ).toDouble( &widthOk );
1607  penRed = frameColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1608  penGreen = frameColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1609  penBlue = frameColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1610  penAlpha = frameColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1611  layoutItem->setFrameJoinStyle( QgsSymbolLayerUtils::decodePenJoinStyle( itemElem.attribute( QStringLiteral( "frameJoinStyle" ), QStringLiteral( "miter" ) ) ) );
1612 
1613  if ( redOk && greenOk && blueOk && alphaOk && widthOk )
1614  {
1615  layoutItem->setFrameStrokeColor( QColor( penRed, penGreen, penBlue, penAlpha ) );
1616  layoutItem->setFrameStrokeWidth( QgsLayoutMeasurement( penWidth ) );
1617  QPen framePen( layoutItem->frameStrokeColor() );
1618  framePen.setWidthF( layoutItem->frameStrokeWidth( ).length() );
1619  framePen.setJoinStyle( layoutItem->frameJoinStyle( ) );
1620  layoutItem->setPen( framePen );
1621  //apply any data defined settings
1622  layoutItem->refreshFrame( false );
1623  }
1624  }
1625 
1626  //brush
1627  QDomNodeList bgColorList = itemElem.elementsByTagName( QStringLiteral( "BackgroundColor" ) );
1628  if ( !bgColorList.isEmpty() )
1629  {
1630  QDomElement bgColorElem = bgColorList.at( 0 ).toElement();
1631  bool redOk, greenOk, blueOk, alphaOk;
1632  int bgRed, bgGreen, bgBlue, bgAlpha;
1633  bgRed = bgColorElem.attribute( QStringLiteral( "red" ) ).toDouble( &redOk );
1634  bgGreen = bgColorElem.attribute( QStringLiteral( "green" ) ).toDouble( &greenOk );
1635  bgBlue = bgColorElem.attribute( QStringLiteral( "blue" ) ).toDouble( &blueOk );
1636  bgAlpha = bgColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
1637  if ( redOk && greenOk && blueOk && alphaOk )
1638  {
1639  layoutItem->mBackgroundColor = QColor( bgRed, bgGreen, bgBlue, bgAlpha );
1640  layoutItem->setBrush( QBrush( layoutItem->mBackgroundColor, Qt::SolidPattern ) );
1641  }
1642  //apply any data defined settings
1643  layoutItem->refreshBackgroundColor( false );
1644  }
1645 
1646  //blend mode
1647  layoutItem->setBlendMode( QgsPainting::getCompositionMode( static_cast< QgsPainting::BlendMode >( itemElem.attribute( QStringLiteral( "blendMode" ), QStringLiteral( "0" ) ).toUInt() ) ) );
1648 
1649  //opacity
1650  if ( itemElem.hasAttribute( QStringLiteral( "opacity" ) ) )
1651  {
1652  layoutItem->setItemOpacity( itemElem.attribute( QStringLiteral( "opacity" ), QStringLiteral( "1" ) ).toDouble() );
1653  }
1654  else
1655  {
1656  layoutItem->setItemOpacity( 1.0 - itemElem.attribute( QStringLiteral( "transparency" ), QStringLiteral( "0" ) ).toInt() / 100.0 );
1657  }
1658 
1659  layoutItem->mExcludeFromExports = itemElem.attribute( QStringLiteral( "excludeFromExports" ), QStringLiteral( "0" ) ).toInt();
1660  layoutItem->mEvaluatedExcludeFromExports = layoutItem->mExcludeFromExports;
1661 
1662  // positioning
1663  layoutItem->attemptSetSceneRect( position );
1664  //rotation
1665  layoutItem->setItemRotation( itemElem.attribute( QStringLiteral( "itemRotation" ), QStringLiteral( "0" ) ).toDouble(), false );
1666 
1667  layoutItem->mBlockUndoCommands = false;
1668 
1669  return true;
1670 }
1671 
1672 
1673 
1674 bool QgsCompositionConverter::readOldComposerObjectXml( QgsLayoutObject *layoutItem,
1675  const QDomElement &itemElem )
1676 {
1677  if ( itemElem.isNull() )
1678  {
1679  return false;
1680  }
1681 
1682  //old (pre 3.0) data defined properties
1683  QgsCompositionConverter::readOldDataDefinedPropertyMap( itemElem, layoutItem->mDataDefinedProperties );
1684 
1685  QDomNode propsNode = itemElem.namedItem( QStringLiteral( "dataDefinedProperties" ) );
1686  if ( !propsNode.isNull() )
1687  {
1688  layoutItem->mDataDefinedProperties.readXml( propsNode.toElement(), sPropertyDefinitions );
1689  }
1691  {
1692  // upgrade transparency -> opacity
1694  exp = QStringLiteral( "100.0 - (%1)" ).arg( exp );
1697  }
1698 
1699  //custom properties
1700  layoutItem->mCustomProperties.readXml( itemElem );
1701 
1702  return true;
1703 }
1704 
1705 
1706 void QgsCompositionConverter::readOldDataDefinedPropertyMap( const QDomElement &itemElem, QgsPropertyCollection &dataDefinedProperties )
1707 {
1708  const QgsPropertiesDefinition defs = QgsCompositionConverter::propertyDefinitions();
1709  QgsPropertiesDefinition::const_iterator i = defs.constBegin();
1710  for ( ; i != defs.constEnd(); ++i )
1711  {
1712  QString elemName = i.value().name();
1713  QDomNodeList ddNodeList = itemElem.elementsByTagName( elemName );
1714  if ( !ddNodeList.isEmpty() )
1715  {
1716  QDomElement ddElem = ddNodeList.at( 0 ).toElement();
1717  QgsProperty prop = readOldDataDefinedProperty( static_cast< QgsCompositionConverter::DataDefinedProperty >( i.key() ), ddElem );
1718  if ( prop )
1719  dataDefinedProperties.setProperty( i.key(), prop );
1720  }
1721  }
1722 }
1723 
1724 QgsProperty QgsCompositionConverter::readOldDataDefinedProperty( const QgsCompositionConverter::DataDefinedProperty property, const QDomElement &ddElem )
1725 {
1727  {
1728  //invalid property
1729  return QgsProperty();
1730  }
1731 
1732  QString active = ddElem.attribute( QStringLiteral( "active" ) );
1733  bool isActive = false;
1734  if ( active.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
1735  {
1736  isActive = true;
1737  }
1738  QString field = ddElem.attribute( QStringLiteral( "field" ) );
1739  QString expr = ddElem.attribute( QStringLiteral( "expr" ) );
1740 
1741  QString useExpr = ddElem.attribute( QStringLiteral( "useExpr" ) );
1742  bool isExpression = false;
1743  if ( useExpr.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
1744  {
1745  isExpression = true;
1746  }
1747 
1748  if ( isExpression )
1749  return QgsProperty::fromExpression( expr, isActive );
1750  else
1751  return QgsProperty::fromField( field, isActive );
1752 }
QgsCompositionConverter::ItemHeight
@ ItemHeight
Height of item.
Definition: qgscompositionconverter.h:77
QgsScaleBarSettings::SegmentSizeMode
SegmentSizeMode
Modes for setting size for scale bar segments.
Definition: qgsscalebarsettings.h:57
QgsLayoutItem::parentGroup
QgsLayoutItemGroup * parentGroup() const
Returns the item's parent group, if the item is part of a QgsLayoutItemGroup group.
Definition: qgslayoutitem.cpp:230
QgsLayoutTable::setHeaderMode
void setHeaderMode(HeaderMode mode)
Sets the display mode for headers in the table.
Definition: qgslayouttable.cpp:656
QgsLayoutItemScaleBar::setFontColor
Q_DECL_DEPRECATED void setFontColor(const QColor &color)
Sets the color used for drawing text in the scalebar.
Definition: qgslayoutitemscalebar.cpp:664
qgslayoutitemgroup.h
QgsLayoutItemPicture::setLinkedMap
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map object for rotation.
Definition: qgslayoutitempicture.cpp:667
QgsLayoutObject::layout
const QgsLayout * layout() const
Returns the layout the object is attached to.
Definition: qgslayoutobject.cpp:118
QgsLayoutItemScaleBar::setFont
Q_DECL_DEPRECATED void setFont(const QFont &font)
Sets the font used for drawing text in the scalebar.
Definition: qgslayoutitemscalebar.cpp:648
QgsLayoutAtlas::setPageNameExpression
void setPageNameExpression(const QString &expression)
Sets the expression (or field name) used for calculating the page name.
Definition: qgslayoutatlas.cpp:165
QgsReadWriteContext::setPathResolver
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
Definition: qgsreadwritecontext.cpp:52
QgsLayoutItemPolyline::setArrowHeadStrokeWidth
void setArrowHeadStrokeWidth(double width)
Sets the pen width in millimeters for the stroke of the arrow head.
Definition: qgslayoutitempolyline.cpp:385
QgsLayoutItemMapGrid
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
Definition: qgslayoutitemmapgrid.h:138
QgsLegendStyle::Symbol
@ Symbol
Symbol icon (excluding label)
Definition: qgslegendstyle.h:73
qgslayoutitemmapgrid.h
qgslayoutitempolygon.h
QgsProperty::fromField
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
Definition: qgsproperty.cpp:220
QgsLayout::addLayoutItem
void addLayoutItem(QgsLayoutItem *item)
Adds an item to the layout.
Definition: qgslayout.cpp:539
QgsLegendStyle::Style
Style
Component of legends which can be styled.
Definition: qgslegendstyle.h:53
QgsSymbolLayerUtils::encodeColor
static QString encodeColor(const QColor &color)
Definition: qgssymbollayerutils.cpp:52
QgsLayoutItemShape
Layout item for basic filled shapes (e.g. rectangles, ellipses).
Definition: qgslayoutitemshape.h:32
QgsLayoutNodesItem::setNodes
void setNodes(const QPolygonF &nodes)
Sets the nodes the shape consists of.
Definition: qgslayoutitemnodeitem.cpp:27
QgsLayoutItemMapGrid::setFrameWidth
void setFrameWidth(const double width)
Sets the grid frame width (in layout units).
Definition: qgslayoutitemmapgrid.cpp:2415
QgsCompositionConverter::MapXMin
@ MapXMin
Map extent x minimum.
Definition: qgscompositionconverter.h:88
qgsmaplayerstylemanager.h
QgsLayoutItemHtml::setUserStylesheetEnabled
void setUserStylesheetEnabled(bool enabled)
Sets whether user stylesheets are enabled for the HTML content.
Definition: qgslayoutitemhtml.cpp:444
QgsCompositionConverter::MapScale
@ MapScale
Map scale.
Definition: qgscompositionconverter.h:87
qgslayoutitemattributetable.h
qgslayoutundostack.h
QgsLayoutTable::setHeaderHAlignment
void setHeaderHAlignment(HeaderHAlignment alignment)
Sets the horizontal alignment for table headers.
Definition: qgslayouttable.cpp:643
QgsLayoutTable::HeaderHAlignment
HeaderHAlignment
Controls how headers are horizontally aligned in a table.
Definition: qgslayouttable.h:120
QgsProperty
A store for object properties.
Definition: qgsproperty.h:231
QgsLayoutItemPage
Item representing the paper in a layout.
Definition: qgslayoutitempage.h:54
QgsLayoutItemMapGrid::setOffsetX
void setOffsetX(double offset)
Sets the offset for grid lines in the x-direction.
Definition: qgslayoutitemmapgrid.cpp:2271
QgsLayoutItem::setFrameEnabled
virtual void setFrameEnabled(bool drawFrame)
Sets whether this item has a frame drawn around it or not.
Definition: qgslayoutitem.cpp:834
QgsLayoutItem::frameEnabled
bool frameEnabled() const
Returns true if the item includes a frame.
Definition: qgslayoutitem.h:727
QgsPainting::BlendMode
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer.
Definition: qgspainting.h:49
QgsLayoutItemScaleBar::setAlignment
void setAlignment(QgsScaleBarSettings::Alignment alignment)
Sets the scalebar alignment.
Definition: qgslayoutitemscalebar.cpp:407
QgsLayoutItemHtml::setUseSmartBreaks
void setUseSmartBreaks(bool useSmartBreaks)
Sets whether the html item should use smart breaks.
Definition: qgslayoutitemhtml.cpp:421
QgsLayoutItemMap::updateBoundingRect
void updateBoundingRect()
Updates the bounding rect of this item. Call this function before doing any changes related to annota...
Definition: qgslayoutitemmap.cpp:1704
QgsReadWriteContext
Definition: qgsreadwritecontext.h:34
QgsCompositionConverter::PositionY
@ PositionY
Y position on page.
Definition: qgscompositionconverter.h:75
QgsLayoutFrame::setHideBackgroundIfEmpty
void setHideBackgroundIfEmpty(bool hideBackgroundIfEmpty)
Sets whether the background and frame stroke should be hidden if this frame is empty.
Definition: qgslayoutframe.cpp:94
QgsLayoutItemMapGrid::setOffsetY
void setOffsetY(double offset)
Sets the offset for grid lines in the y-direction.
Definition: qgslayoutitemmapgrid.cpp:2282
QgsPropertyDefinition::BlendMode
@ BlendMode
Blend mode.
Definition: qgsproperty.h:68
QgsCompositionConverter::BlendMode
@ BlendMode
Item blend mode.
Definition: qgscompositionconverter.h:81
QgsLayoutItemPolyline::setArrowHeadFillColor
void setArrowHeadFillColor(const QColor &color)
Sets the color used to fill the arrow head.
Definition: qgslayoutitempolyline.cpp:379
QgsLayout::itemByUuid
QgsLayoutItem * itemByUuid(const QString &uuid, bool includeTemplateUuids=false) const
Returns the layout item with matching uuid unique identifier, or nullptr if a matching item could not...
Definition: qgslayout.cpp:237
QgsUnitTypes::DistanceUnknownUnit
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
QgsLayoutItemPolyline::setEndSvgMarkerPath
void setEndSvgMarkerPath(const QString &path)
Sets the path to a SVG marker to draw at the end of the line.
Definition: qgslayoutitempolyline.cpp:356
QgsLayoutItem::setFrameStrokeWidth
virtual void setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
Definition: qgslayoutitem.cpp:860
QgsLayoutItemScaleBar::setSegmentSizeMode
void setSegmentSizeMode(QgsScaleBarSettings::SegmentSizeMode mode)
Sets the size mode for scale bar segments.
Definition: qgslayoutitemscalebar.cpp:139
QgsLayoutItemLegend::setTitle
void setTitle(const QString &title)
Sets the legend title.
Definition: qgslayoutitemlegend.cpp:286
QgsLayoutMeasurement::length
double length() const
Returns the length of the measurement.
Definition: qgslayoutmeasurement.h:48
QgsLayoutItemMapGrid::setFramePenSize
void setFramePenSize(const double width)
Sets the width of the stroke drawn in the grid frame.
Definition: qgslayoutitemmapgrid.cpp:2427
QgsCompositionConverter::PaperWidth
@ PaperWidth
Paper width.
Definition: qgscompositionconverter.h:68
QgsPropertyDefinition::DataTypeString
@ DataTypeString
Property requires a string value.
Definition: qgsproperty.h:93
QgsLayoutItemLabel::setMarginY
void setMarginY(double margin)
Sets the vertical margin between the edge of the frame and the label contents, in layout units.
Definition: qgslayoutitemlabel.cpp:334
qgsreadwritecontext.h
QgsCompositionConverter::convertCompositionTemplate
static QDomDocument convertCompositionTemplate(const QDomDocument &document, QgsProject *project)
Convert a composition template document to a layout template.
Definition: qgscompositionconverter.cpp:468
QgsCompositionConverter::BackgroundColor
@ BackgroundColor
Item background color.
Definition: qgscompositionconverter.h:84
QgsLayoutItem::attemptMoveBy
void attemptMoveBy(double deltaX, double deltaY)
Attempts to shift the item's position by a specified deltaX and deltaY, in layout units.
Definition: qgslayoutitem.cpp:530
QgsCompositionConverter::MapXMax
@ MapXMax
Map extent x maximum.
Definition: qgscompositionconverter.h:90
QgsLayoutItemHtml::setHtml
void setHtml(const QString &html)
Sets the html to display in the item when the item is using the QgsLayoutItemHtml::ManualHtml mode.
Definition: qgslayoutitemhtml.cpp:110
QgsLayoutItemPolyline
Definition: qgslayoutitempolyline.h:32
QgsCompositionConverter::MapStylePreset
@ MapStylePreset
Layer and style map theme.
Definition: qgscompositionconverter.h:94
QgsLayoutObject::mCustomProperties
QgsObjectCustomProperties mCustomProperties
Custom properties for object.
Definition: qgslayoutobject.h:340
QgsLayoutItemMap::setFollowVisibilityPresetName
void setFollowVisibilityPresetName(const QString &name)
Sets preset name for map rendering.
Definition: qgslayoutitemmap.cpp:322
qgslayoutnortharrowhandler.h
QgsProject::pathResolver
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
Definition: qgsproject.cpp:2590
qgssymbollayerutils.h
QgsLayoutItemScaleBar::setBoxContentSpace
void setBoxContentSpace(double space)
Sets the space (margin) between the scalebar box and content in millimeters.
Definition: qgslayoutitemscalebar.cpp:248
QgsAbstractPropertyCollection::readXml
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
Definition: qgspropertycollection.cpp:108
QgsLayoutItemLabel::setFontColor
void setFontColor(const QColor &color)
Sets the label font color.
Definition: qgslayoutitemlabel.h:198
QgsLayoutItemMapGrid::setBlendMode
void setBlendMode(const QPainter::CompositionMode mode)
Sets the blending mode used for drawing the grid.
Definition: qgslayoutitemmapgrid.h:288
QgsCompositionConverter::createLayoutFromCompositionXml
static std::unique_ptr< QgsPrintLayout > createLayoutFromCompositionXml(const QDomElement &composerElement, QgsProject *project)
createLayoutFromCompositionXml is a factory that creates layout instances from a QGIS 2....
Definition: qgscompositionconverter.cpp:122
QgsCompositionConverter::TestProperty
@ TestProperty
Dummy property with no effect on item.
Definition: qgscompositionconverter.h:65
QgsLayoutItemScaleBar::setLinkedMap
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map item linked to the scalebar.
Definition: qgslayoutitemscalebar.cpp:259
QgsLayoutPageCollection::spaceBetweenPages
double spaceBetweenPages() const
Returns the space between pages, in layout units.
Definition: qgslayoutpagecollection.cpp:273
QgsLayoutItem::attemptSetSceneRect
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.
Definition: qgslayoutitem.cpp:514
QgsLayoutItem::refreshBackgroundColor
void refreshBackgroundColor(bool updateItem=true)
Refresh item's background color, considering data defined colors.
Definition: qgslayoutitem.cpp:1482
qgslayoutmultiframe.h
QgsProperty::asExpression
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
Definition: qgsproperty.cpp:332
QgsCompositionConverter::MapRotation
@ MapRotation
Map rotation.
Definition: qgscompositionconverter.h:86
QgsPropertyDefinition::IntegerPositiveGreaterZero
@ IntegerPositiveGreaterZero
Non-zero positive integer values.
Definition: qgsproperty.h:57
QgsLayoutTable::setGridColor
void setGridColor(const QColor &color)
Sets the color used for grid lines in the table.
Definition: qgslayouttable.cpp:724
QgsLayoutItemHtml
Definition: qgslayoutitemhtml.h:36
QgsLayoutItemScaleBar::setLineSymbol
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar (only used for some scalebar types).
Definition: qgslayoutitemscalebar.cpp:192
QgsLayoutObject::mDataDefinedProperties
QgsPropertyCollection mDataDefinedProperties
Definition: qgslayoutobject.h:337
QgsLayoutItemMapGrid::setStyle
void setStyle(GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
Definition: qgslayoutitemmapgrid.cpp:2315
QgsLayoutItemMapGrid::GridStyle
GridStyle
Grid drawing style.
Definition: qgslayoutitemmapgrid.h:159
QgsLayoutTable::setBackgroundColor
void setBackgroundColor(const QColor &color)
Sets the color used for background of table.
Definition: qgslayouttable.cpp:765
QgsLayoutItemShape::setCornerRadius
void setCornerRadius(QgsLayoutMeasurement radius)
Sets the corner radius for rounded rectangle corners.
Definition: qgslayoutitemshape.h:95
QgsLayoutItemPage::setPageSize
void setPageSize(const QgsLayoutSize &size)
Sets the size of the page.
Definition: qgslayoutitempage.cpp:70
QgsLayoutTable::mContentFont
QFont mContentFont
Table contents font.
Definition: qgslayouttable.h:551
QgsLayoutItemMap::AtlasScalingMode
AtlasScalingMode
Scaling modes used for the serial rendering (atlas)
Definition: qgslayoutitemmap.h:49
QgsPropertyDefinition::Double
@ Double
Double value (including negative values)
Definition: qgsproperty.h:58
QgsUnitTypes::RenderMillimeters
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:168
QgsLayoutTable::setGridStrokeWidth
void setGridStrokeWidth(double width)
Sets the width in mm for grid lines in the table.
Definition: qgslayouttable.cpp:710
QgsObjectCustomProperties::readXml
void readXml(const QDomNode &parentNode, const QString &keyStartsWith=QString())
Read store contents from an XML node.
Definition: qgsobjectcustomproperties.cpp:50
QgsLayoutItemLegend::setFontColor
void setFontColor(const QColor &color)
Sets the legend font color.
Definition: qgslayoutitemlegend.cpp:382
QgsLayoutItemScaleBar::setMaximumBarWidth
void setMaximumBarWidth(double maxWidth)
Sets the maximum width (in millimeters) for scale bar segments.
Definition: qgslayoutitemscalebar.cpp:163
QgsLayoutAtlas::setEnabled
void setEnabled(bool enabled)
Sets whether the atlas is enabled.
Definition: qgslayoutatlas.cpp:123
QgsLayoutItemMapGrid::setFramePenColor
void setFramePenColor(const QColor &color)
Sets the color of the stroke drawn in the grid frame.
Definition: qgslayoutitemmapgrid.h:812
qgslayoutitemlabel.h
QgsLayoutItemHtml::setUserStylesheet
void setUserStylesheet(const QString &stylesheet)
Sets the user stylesheet CSS rules to use while rendering the HTML content.
Definition: qgslayoutitemhtml.cpp:435
QgsLayoutItemLabel::setHAlign
void setHAlign(Qt::AlignmentFlag alignment)
Sets the horizontal alignment of the label.
Definition: qgslayoutitemlabel.h:140
QgsLayoutItemMap::setCrs
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the map's preset crs (coordinate reference system).
Definition: qgslayoutitemmap.cpp:273
QgsProperty::fromExpression
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
Definition: qgsproperty.cpp:212
qgsfontutils.h
QgsUnitTypes::DistanceUnit
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:67
QgsLayoutItemHtml::setUrl
void setUrl(const QUrl &url)
Sets the url for content to display in the item when the item is using the QgsLayoutItemHtml::Url mod...
Definition: qgslayoutitemhtml.cpp:98
QgsLayoutItemLabel::setVAlign
void setVAlign(Qt::AlignmentFlag alignment)
Sets for the vertical alignment of the label.
Definition: qgslayoutitemlabel.h:147
QgsLayoutItemPolyline::setStartSvgMarkerPath
void setStartSvgMarkerPath(const QString &path)
Sets the path to a SVG marker to draw at the start of the line.
Definition: qgslayoutitempolyline.cpp:339
QgsReadWriteContext::setProjectTranslator
void setProjectTranslator(QgsProjectTranslator *projectTranslator)
Sets the project translator.
Definition: qgsreadwritecontext.cpp:87
QgsCoordinateReferenceSystem::readXml
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
Definition: qgscoordinatereferencesystem.cpp:1995
QgsLegendStyle::SymbolLabel
@ SymbolLabel
Symbol label (excluding icon)
Definition: qgslegendstyle.h:74
QgsLayoutTable::setEmptyTableBehavior
void setEmptyTableBehavior(EmptyTableMode mode)
Sets the behavior mode for empty tables with no content rows.
Definition: qgslayouttable.cpp:574
QgsSymbolLayerUtils::decodeColor
static QColor decodeColor(const QString &str)
Definition: qgssymbollayerutils.cpp:57
QgsLayoutItemScaleBar::setHeight
void setHeight(double height)
Sets the scalebar height (in millimeters).
Definition: qgslayoutitemscalebar.h:464
QgsLayoutTable::setShowGrid
void setShowGrid(bool showGrid)
Sets whether grid lines should be drawn in the table.
Definition: qgslayouttable.cpp:696
QgsLayout::pageCollection
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
Definition: qgslayout.cpp:458
QgsLayoutItem::ReferencePoint
ReferencePoint
Fixed position reference point.
Definition: qgslayoutitem.h:201
QgsLineSymbol::setWidth
void setWidth(double width)
Sets the width for the whole line symbol.
Definition: qgssymbol.cpp:1919
QgsCompositionConverter::ItemRotation
@ ItemRotation
Rotation of item.
Definition: qgscompositionconverter.h:78
QgsLayoutItem::sizeWithUnits
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
Definition: qgslayoutitem.h:668
QgsRectangle
Definition: qgsrectangle.h:41
QgsLayoutItem::refreshFrame
void refreshFrame(bool updateItem=true)
Refresh item's frame, considering data defined colors and frame size.
Definition: qgslayoutitem.cpp:1447
QgsCompositionConverter::PageNumber
@ PageNumber
Page number for item placement.
Definition: qgscompositionconverter.h:73
QgsCompositionConverter::Transparency
@ Transparency
Item transparency (deprecated)
Definition: qgscompositionconverter.h:79
QgsProject
Definition: qgsproject.h:92
QgsPropertyCollection::property
QgsProperty property(int key) const override
Returns a matching property from the collection, if one exists.
Definition: qgspropertycollection.cpp:204
QgsPropertyDefinition::String
@ String
Any string value.
Definition: qgsproperty.h:62
QgsLayoutItemScaleBar::setLabelBarSpace
void setLabelBarSpace(double space)
Sets the spacing (in millimeters) between labels and the scalebar.
Definition: qgslayoutitemscalebar.h:488
QgsLayoutAtlas::filterFeatures
bool filterFeatures() const
Returns true if features should be filtered in the coverage layer.
Definition: qgslayoutatlas.h:208
qgslayoutframe.h
QgsLayoutItemLegend
Definition: qgslayoutitemlegend.h:113
QgsLegendStyle::Title
@ Title
Legend title.
Definition: qgslegendstyle.h:70
QgsLayoutItemPolyline::setArrowHeadStrokeColor
void setArrowHeadStrokeColor(const QColor &color)
Sets the color used to draw the stroke around the arrow head.
Definition: qgslayoutitempolyline.cpp:373
QgsPropertyDefinition::Rotation
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:61
QgsLayoutTable::mSortColumns
QgsLayoutTableSortColumns mSortColumns
Columns to sort the table.
Definition: qgslayouttable.h:578
QgsCompositionConverter::MapYMax
@ MapYMax
Map extent y maximum.
Definition: qgscompositionconverter.h:91
QgsUnitTypes::decodeDistanceUnit
static Q_INVOKABLE QgsUnitTypes::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
Definition: qgsunittypes.cpp:165
QgsLayoutItemScaleBar::setNumberOfSegments
void setNumberOfSegments(int segments)
Sets the number of segments included in the scalebar.
Definition: qgslayoutitemscalebar.cpp:116
QgsLayoutItemPolyline::setStartMarker
void setStartMarker(MarkerMode mode)
Sets the start marker mode, which controls what marker is drawn at the start of the line.
Definition: qgslayoutitempolyline.cpp:307
Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:752
QgsLayoutItem::hasBackground
bool hasBackground() const
Returns true if the item has a background.
Definition: qgslayoutitem.h:797
QgsLayoutItemHtml::loadHtml
void loadHtml(bool useCache=false, const QgsExpressionContext *context=nullptr)
Reloads the html source from the url and redraws the item.
Definition: qgslayoutitemhtml.cpp:126
QgsLayoutItemHtml::ContentMode
ContentMode
Source modes for the HTML content to render in the item.
Definition: qgslayoutitemhtml.h:43
QgsPropertiesDefinition
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
Definition: qgspropertycollection.h:29
QgsCompositionConverter::MapAtlasMargin
@ MapAtlasMargin
Map atlas margin.
Definition: qgscompositionconverter.h:92
QgsLayoutItem::setBlendMode
void setBlendMode(QPainter::CompositionMode mode)
Sets the item's composition blending mode.
Definition: qgslayoutitem.cpp:900
QgsLayerTree
Definition: qgslayertree.h:32
QgsPrintLayout
Print layout, a QgsLayout subclass for static or atlas-based layouts.
Definition: qgsprintlayout.h:30
QgsLayoutItem::frameStrokeWidth
QgsLayoutMeasurement frameStrokeWidth() const
Returns the frame's stroke width.
Definition: qgslayoutitem.h:772
qgslayouttable.h
QgsCompositionConverter::LegendColumnCount
@ LegendColumnCount
Legend column count.
Definition: qgscompositionconverter.h:104
QgsLayoutTable::setVerticalGrid
void setVerticalGrid(bool verticalGrid)
Sets whether the grid's vertical lines should be drawn in the table.
Definition: qgslayouttable.cpp:751
QgsLayoutItemLegend::setLineSpacing
void setLineSpacing(double spacing)
Sets the spacing in-between multiple lines.
Definition: qgslayoutitemlegend.cpp:352
QgsScaleBarSettings::Alignment
Alignment
Scalebar alignment.
Definition: qgsscalebarsettings.h:47
QgsLayoutFrame
Definition: qgslayoutframe.h:31
QgsLayoutItemLegend::setStyle
void setStyle(QgsLegendStyle::Style component, const QgsLegendStyle &style)
Sets the style of component to style for the legend.
Definition: qgslayoutitemlegend.cpp:322
QgsLayoutItemScaleBar::setSubdivisionLineSymbol
void setSubdivisionLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar subdivisions (only used for some scalebar types).
Definition: qgslayoutitemscalebar.cpp:212
QgsLayoutItemLegend::setSplitLayer
void setSplitLayer(bool enabled)
Sets whether the legend items from a single layer can be split over multiple columns.
Definition: qgslayoutitemlegend.cpp:462
QgsLayoutFrame::setHidePageIfEmpty
void setHidePageIfEmpty(bool hidePageIfEmpty)
Sets whether the page should be hidden (ie, not included in layout exports) if this frame is empty.
Definition: qgslayoutframe.cpp:89
QgsLayoutItemScaleBar::setUnits
void setUnits(QgsUnitTypes::DistanceUnit units)
Sets the distance units used by the scalebar.
Definition: qgslayoutitemscalebar.cpp:414
QgsLayoutItemScaleBar::fillSymbol
QgsFillSymbol * fillSymbol() const
Returns the primary fill symbol used to render the scalebar (only used for some scalebar types).
Definition: qgslayoutitemscalebar.cpp:217
QgsLayoutItemMapGrid::AnnotationDirection
AnnotationDirection
Direction of grid annotations.
Definition: qgslayoutitemmapgrid.h:190
QgsLayoutItemMap::setAtlasScalingMode
void setAtlasScalingMode(AtlasScalingMode mode)
Sets the current atlas scaling mode.
Definition: qgslayoutitemmap.h:387
QgsLayoutItem::frameJoinStyle
Qt::PenJoinStyle frameJoinStyle() const
Returns the join style used for drawing the item's frame.
Definition: qgslayoutitem.h:781
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsPropertyDefinition::ColorWithAlpha
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:65
QgsLayoutFrame::setContentSection
void setContentSection(const QRectF &section)
Sets the visible part of the multiframe's content which is visible within this frame (relative to the...
Definition: qgslayoutframe.h:61
QgsCompositionConverter::isCompositionTemplate
static bool isCompositionTemplate(const QDomDocument &document)
Check if the given document is a composition template.
Definition: qgscompositionconverter.cpp:463
QgsLayoutTable::setCellMargin
void setCellMargin(double margin)
Sets the margin distance in mm between cell borders and their contents.
Definition: qgslayouttable.cpp:559
QgsLayoutItemLegend::setEqualColumnWidth
void setEqualColumnWidth(bool equalize)
Sets whether column widths should be equalized.
Definition: qgslayoutitemlegend.cpp:472
QgsLayoutItemLabel::setText
void setText(const QString &text)
Sets the label's preset text.
Definition: qgslayoutitemlabel.cpp:226
QgsLayoutNorthArrowHandler::setNorthOffset
void setNorthOffset(double offset)
Sets the offset added to the arrows's rotation from a map's North.
Definition: qgslayoutnortharrowhandler.cpp:118
QgsLayoutItemLegend::setRasterStrokeColor
void setRasterStrokeColor(const QColor &color)
Sets the stroke color for the stroke drawn around raster symbol items.
Definition: qgslayoutitemlegend.cpp:492
QgsLayoutTable::setHorizontalGrid
void setHorizontalGrid(bool horizontalGrid)
Sets whether the grid's horizontal lines should be drawn in the table.
Definition: qgslayouttable.cpp:737
QgsPainting::getCompositionMode
static QPainter::CompositionMode getCompositionMode(QgsPainting::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
Definition: qgspainting.cpp:20
QgsLayoutItem::setLocked
void setLocked(bool locked)
Sets whether the item is locked, preventing mouse interactions with the item.
Definition: qgslayoutitem.cpp:200
QgsLayoutItem::setVisibility
virtual void setVisibility(bool visible)
Sets whether the item is visible.
Definition: qgslayoutitem.cpp:170
QgsLayoutItemMapGrid::setIntervalY
void setIntervalY(double interval)
Sets the interval between grid lines in the y-direction.
Definition: qgslayoutitemmapgrid.cpp:2260
QgsCompositionConverter::PictureSvgStrokeWidth
@ PictureSvgStrokeWidth
SVG stroke width.
Definition: qgscompositionconverter.h:99
QgsLayoutPageCollection::pages
QList< QgsLayoutItemPage * > pages()
Returns a list of pages in the collection.
Definition: qgslayoutpagecollection.cpp:450
QgsLayoutItem::setBackgroundEnabled
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
Definition: qgslayoutitem.cpp:887
QgsLayoutItemMapGrid::setFrameFillColor1
void setFrameFillColor1(const QColor &color)
Sets the first fill color used for the grid frame.
Definition: qgslayoutitemmapgrid.h:829
QgsCompositionConverter::PaperOrientation
@ PaperOrientation
Paper orientation.
Definition: qgscompositionconverter.h:71
QgsLayoutMultiFrame::ResizeMode
ResizeMode
Specifies the behavior for creating new frames to fit the multiframe's content.
Definition: qgslayoutmultiframe.h:101
qgslayoutguidecollection.h
QgsLineSymbol
Definition: qgssymbol.h:1117
QgsLayoutItemLegend::setBoxSpace
void setBoxSpace(double space)
Sets the legend box space.
Definition: qgslayoutitemlegend.cpp:362
QgsLayoutItemLabel::setFont
void setFont(const QFont &font)
Sets the label's current font.
Definition: qgslayoutitemlabel.cpp:316
qgspainting.h
QgsCompositionConverter::ScalebarLineColor
@ ScalebarLineColor
Scalebar line color.
Definition: qgscompositionconverter.h:108
QgsLayoutItemHtml::setEvaluateExpressions
void setEvaluateExpressions(bool evaluateExpressions)
Sets whether the html item will evaluate QGIS expressions prior to rendering the HTML content.
Definition: qgslayoutitemhtml.cpp:119
QgsCompositionConverter::ExcludeFromExports
@ ExcludeFromExports
Exclude item from exports.
Definition: qgscompositionconverter.h:82
QgsUnitTypes::DistanceFeet
@ DistanceFeet
Imperial feet.
Definition: qgsunittypes.h:71
QgsLayoutItemMapGrid::Right
@ Right
Right border.
Definition: qgslayoutitemmapgrid.h:220
QgsLayoutItemMapGrid::setLineSymbol
void setLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used for drawing grid lines.
Definition: qgslayoutitemmapgrid.cpp:2096
QgsLayoutItem::setFrameStrokeColor
void setFrameStrokeColor(const QColor &color)
Sets the frame stroke color.
Definition: qgslayoutitem.cpp:847
QgsUnitTypes::DistanceMeters
@ DistanceMeters
Meters.
Definition: qgsunittypes.h:69
QgsPropertyDefinition
Definition for a property.
Definition: qgsproperty.h:47
QgsCompositionConverter::PictureSvgBackgroundColor
@ PictureSvgBackgroundColor
SVG background color.
Definition: qgscompositionconverter.h:97
QgsLayoutItem::setFrameJoinStyle
void setFrameJoinStyle(Qt::PenJoinStyle style)
Sets the join style used when drawing the item's frame.
Definition: qgslayoutitem.cpp:872
qgssymbollayer.h
QgsCompositionConverter::AllProperties
@ AllProperties
All properties for item.
Definition: qgscompositionconverter.h:64
QgsLayoutItemLabel::setMarginX
void setMarginX(double margin)
Sets the horizontal margin between the edge of the frame and the label contents, in layout units.
Definition: qgslayoutitemlabel.cpp:328
QgsLayoutItemPicture::setPicturePath
void setPicturePath(const QString &path, Format format=FormatUnknown)
Sets the source path of the image (may be svg or a raster format).
Definition: qgslayoutitempicture.cpp:704
QgsLayoutItemScaleBar::setMinimumBarWidth
void setMinimumBarWidth(double minWidth)
Sets the minimum width (in millimeters) for scale bar segments.
Definition: qgslayoutitemscalebar.cpp:151
QgsLayoutItemMapGrid::AnnotationPosition
AnnotationPosition
Position for grid annotations.
Definition: qgslayoutitemmapgrid.h:181
QgsLayoutItemAttributeTable
Definition: qgslayoutitemattributetable.h:34
QgsLayoutItemPicture::ResizeMode
ResizeMode
Controls how pictures are scaled within the item's frame.
Definition: qgslayoutitempicture.h:43
QgsLayoutItemMapGrid::setAnnotationFormat
void setAnnotationFormat(const AnnotationFormat format)
Sets the format for drawing grid annotations.
Definition: qgslayoutitemmapgrid.h:670
QgsLayoutTable::HeaderMode
HeaderMode
Controls where headers are shown in the table.
Definition: qgslayouttable.h:131
QgsCompositionConverter::PictureSvgStrokeColor
@ PictureSvgStrokeColor
SVG stroke color.
Definition: qgscompositionconverter.h:98
QgsLayoutItem
Base class for graphical items within a QgsLayout.
Definition: qgslayoutitem.h:112
QgsLayoutNorthArrowHandler::setNorthMode
void setNorthMode(NorthMode mode)
Sets the mode used to calculate the arrow rotation.
Definition: qgslayoutnortharrowhandler.cpp:112
QgsLayoutItemScaleBar::setMapUnitsPerScaleBarUnit
void setMapUnitsPerScaleBarUnit(double units)
Sets the number of map units per scale bar unit used by the scalebar.
Definition: qgslayoutitemscalebar.h:199
QgsLayoutItemMapGrid::setAnnotationFont
void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
Definition: qgslayoutitemmapgrid.h:568
QgsLayoutTable::WrapBehavior
WrapBehavior
Controls how long strings in the table are handled.
Definition: qgslayouttable.h:151
QgsCompositionConverter::ScalebarLineWidth
@ ScalebarLineWidth
Scalebar line width.
Definition: qgscompositionconverter.h:109
QgsCompositionConverter::PaperHeight
@ PaperHeight
Paper height.
Definition: qgscompositionconverter.h:69
qgslayertree.h
QgsLayoutItemMap::crs
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
Definition: qgslayoutitemmap.cpp:264
QgsLayoutItemScaleBar::setStyle
void setStyle(const QString &name)
Sets the scale bar style by name.
Definition: qgslayoutitemscalebar.cpp:609
QgsLayoutTable::EmptyTableMode
EmptyTableMode
Controls how empty tables are displayed.
Definition: qgslayouttable.h:141
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:206
QgsLayoutAtlas::setSortAscending
void setSortAscending(bool ascending)
Sets whether features should be sorted in an ascending order.
Definition: qgslayoutatlas.cpp:191
QgsLayoutItemLegend::setLinkedMap
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map to associate with the legend.
Definition: qgslayoutitemlegend.cpp:716
QgsLayoutItemGroup
Definition: qgslayoutitemgroup.h:28
QgsCompositionConverter::Opacity
@ Opacity
Item opacity.
Definition: qgscompositionconverter.h:80
QgsLayoutItemMapGrid::Bottom
@ Bottom
Bottom border.
Definition: qgslayoutitemmapgrid.h:221
QgsLayoutMultiFrame::frames
QList< QgsLayoutFrame * > frames() const
Returns a list of all child frames for this multiframe.
Definition: qgslayoutmultiframe.cpp:91
QgsLayoutItemPage::create
static QgsLayoutItemPage * create(QgsLayout *layout)
Returns a new page item for the specified layout.
Definition: qgslayoutitempage.cpp:55
QgsLayoutAtlas::setHideCoverage
void setHideCoverage(bool hide)
Sets whether the coverage layer should be hidden in map items in the layouts.
Definition: qgslayoutatlas.cpp:471
QgsLayoutItemLegend::setSymbolWidth
void setSymbolWidth(double width)
Sets the legend symbol width.
Definition: qgslayoutitemlegend.cpp:392
QgsLayoutItemMapGrid::setEnabled
void setEnabled(bool enabled) override
Controls whether the item will be drawn.
Definition: qgslayoutitemmapgrid.cpp:2233
QgsLayoutSize::height
double height() const
Returns the height of the size.
Definition: qgslayoutsize.h:90
QgsLayoutItemPicture
Definition: qgslayoutitempicture.h:35
qgsvectorlayer.h
QgsCompositionConverter::MapLayers
@ MapLayers
Map layer set.
Definition: qgscompositionconverter.h:93
QgsLayoutItemPolyline::setArrowHeadWidth
void setArrowHeadWidth(double width)
Sets the width of line arrow heads in mm.
Definition: qgslayoutitempolyline.cpp:319
QgsLayoutItemMapOverview
An individual overview which is drawn above the map content in a QgsLayoutItemMap,...
Definition: qgslayoutitemmapoverview.h:126
QgsLayoutNorthArrowHandler::NorthMode
NorthMode
Method for syncing rotation to a map's North direction.
Definition: qgslayoutnortharrowhandler.h:38
QgsCompositionConverter::MarkerMode
MarkerMode
The MarkerMode enum is the old QGIS 2.x arrow marker mode.
Definition: qgscompositionconverter.h:115
QgsPropertyDefinition::IntegerPositive
@ IntegerPositive
Positive integer values (including 0)
Definition: qgsproperty.h:56
QgsCompositionConverter::ScalebarFillColor
@ ScalebarFillColor
Scalebar fill color.
Definition: qgscompositionconverter.h:106
QgsSymbolLayerUtils::decodePenCapStyle
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
Definition: qgssymbollayerutils.cpp:238
qgslayoutitemlegend.h
QgsLayoutItemMap
Layout graphical items for displaying a map.
Definition: qgslayoutitemmap.h:39
QgsLayoutItemLabel::setMode
void setMode(Mode mode)
Sets the label's current mode, allowing the label to switch between font based and HTML based renderi...
Definition: qgslayoutitemlabel.cpp:240
QgsLayoutItem::setId
virtual void setId(const QString &id)
Set the item's id name.
Definition: qgslayoutitem.cpp:134
QgsLayoutItemMapGrid::setFrameStyle
void setFrameStyle(const FrameStyle style)
Sets the grid frame style.
Definition: qgslayoutitemmapgrid.h:700
QgsLayoutTable::setShowEmptyRows
void setShowEmptyRows(bool showEmpty)
Sets whether empty rows should be drawn.
Definition: qgslayouttable.cpp:604
QgsPropertyCollection
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
Definition: qgspropertycollection.h:318
QgsLayoutItem::attemptMove
virtual void attemptMove(const QgsLayoutPoint &point, bool useReferencePoint=true, bool includesFrame=false, int page=-1)
Attempts to move the item to a specified point.
Definition: qgslayoutitem.cpp:470
QgsLayoutTable::setHeaderFontColor
void setHeaderFontColor(const QColor &color)
Sets the color used to draw header text in the table.
Definition: qgslayouttable.cpp:630
QgsCompositionConverter::DataDefinedProperty
DataDefinedProperty
Composition data defined properties for different item types.
Definition: qgscompositionconverter.h:61
QgsPathResolver::readPath
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Definition: qgspathresolver.cpp:35
QgsLayoutItem::setReferencePoint
void setReferencePoint(ReferencePoint point)
Sets the reference point for positioning of the layout item.
Definition: qgslayoutitem.cpp:418
QgsFontUtils::setFromXmlChildNode
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
Definition: qgsfontutils.cpp:348
QgsLayoutItem::uuid
virtual QString uuid() const
Returns the item identification string.
Definition: qgslayoutitem.h:340
QgsStringMap
QMap< QString, QString > QgsStringMap
Definition: qgis.h:714
QgsLayoutTableStyle
Styling option for a layout table cell.
Definition: qgslayouttable.h:75
QgsLayoutItemLegend::setColumnCount
void setColumnCount(int count)
Sets the legend column count.
Definition: qgslayoutitemlegend.cpp:451
QgsLayoutItemLegend::setDrawRasterStroke
void setDrawRasterStroke(bool enabled)
Sets whether a stroke will be drawn around raster symbol items.
Definition: qgslayoutitemlegend.cpp:482
qgslinesymbollayer.h
QgsLayoutItemLegend::setWmsLegendHeight
void setWmsLegendHeight(double height)
Sets the WMS legend height.
Definition: qgslayoutitemlegend.cpp:431
QgsLayoutTable::mCellStyles
QMap< CellStyleGroup, QgsLayoutTableStyle * > mCellStyles
Definition: qgslayouttable.h:593
QgsPropertyDefinition::Boolean
@ Boolean
Boolean value.
Definition: qgsproperty.h:54
QgsLayoutAtlas::setSortExpression
void setSortExpression(const QString &expression)
Sets the expression (or field name) to use for sorting features.
Definition: qgslayoutatlas.cpp:200
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsSymbol::setColor
void setColor(const QColor &color)
Sets the color for the symbol.
Definition: qgssymbol.cpp:485
QgsCompositionConverter::SourceUrl
@ SourceUrl
Html source url.
Definition: qgscompositionconverter.h:101
QgsCompositionConverter::addItemsFromCompositionXml
static QList< QgsLayoutObject * > addItemsFromCompositionXml(QgsPrintLayout *layout, const QDomElement &parentElement, QPointF *position=nullptr, bool pasteInPlace=false)
addItemsFromCompositionXml parse a QGIS 2.x composition XML in the parentElement, converts the 2....
Definition: qgscompositionconverter.cpp:309
qgscompositionconverter.h
QgsLayoutItemLegend::setTitleAlignment
void setTitleAlignment(Qt::AlignmentFlag alignment)
Sets the alignment of the legend title.
Definition: qgslayoutitemlegend.cpp:307
QgsLineSymbol::createSimple
static QgsLineSymbol * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
Definition: qgssymbol.cpp:1429
QgsSymbolLayerUtils::svgSymbolNameToPath
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
Definition: qgssymbollayerutils.cpp:3879
QgsLayoutTable::setWrapBehavior
void setWrapBehavior(WrapBehavior behavior)
Sets the wrap behavior for the table, which controls how text within cells is automatically wrapped.
Definition: qgslayouttable.cpp:778
QgsLayoutItemMap::setMapRotation
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...
Definition: qgslayoutitemmap.cpp:465
QgsLayoutItemHtml::setMaxBreakDistance
void setMaxBreakDistance(double distance)
Sets the maximum distance allowed when calculating where to place page breaks in the html.
Definition: qgslayoutitemhtml.cpp:428
QgsLayoutItemPicture::setPictureAnchor
void setPictureAnchor(QgsLayoutItem::ReferencePoint anchor)
Sets the picture's anchor point, which controls how it is placed within the picture item's frame.
Definition: qgslayoutitempicture.cpp:842
qgslayouttablecolumn.h
QgsLayoutItem::setItemRotation
virtual void setItemRotation(double rotation, bool adjustPosition=true)
Sets the layout item's rotation, in degrees clockwise.
Definition: qgslayoutitem.cpp:1127
qgsprintlayout.h
QgsLayoutItemShape::setShapeType
void setShapeType(QgsLayoutItemShape::Shape type)
Sets the type of shape (e.g.
Definition: qgslayoutitemshape.cpp:94
qgslayoutitempicture.h
qgsproperty.h
QgsLayoutItemMap::setFollowVisibilityPreset
void setFollowVisibilityPreset(bool follow)
Sets whether the map should follow a map theme.
Definition: qgslayoutitemmap.cpp:312
QgsLayoutItemMap::setAtlasMargin
void setAtlasMargin(double margin)
Sets the margin size (percentage) used when the map is in atlas mode.
Definition: qgslayoutitemmap.h:408
QgsMapLayerStyle::xmlData
QString xmlData() const
Returns XML content of the style.
Definition: qgsmaplayerstyle.cpp:43
QgsLayoutItemMapGrid::setCrossLength
void setCrossLength(const double length)
Sets the length (in layout units) of the cross segments drawn for the grid.
Definition: qgslayoutitemmapgrid.cpp:2325
QgsLayoutItemScaleBar::setUnitsPerSegment
void setUnitsPerSegment(double units)
Sets the number of scalebar units per segment.
Definition: qgslayoutitemscalebar.cpp:127
QgsLayoutItemMapGrid::Top
@ Top
Top border.
Definition: qgslayoutitemmapgrid.h:222
QgsLayoutAtlas::setCoverageLayer
void setCoverageLayer(QgsVectorLayer *layer)
Sets the coverage layer to use for the atlas features.
Definition: qgslayoutatlas.cpp:154
QgsLayoutItemMapGrid::AnnotationFormat
AnnotationFormat
Format for displaying grid annotations.
Definition: qgslayoutitemmapgrid.h:201
qgslayoutitempolyline.h
QgsLayoutItemLegend::setColumnSpace
void setColumnSpace(double spacing)
Sets the legend column spacing.
Definition: qgslayoutitemlegend.cpp:372
QgsSymbolLayerUtils::decodePenJoinStyle
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
Definition: qgssymbollayerutils.cpp:188
qgslayoutpagecollection.h
qgslayoutitemshape.h
QgsLayoutItemPolygon
Definition: qgslayoutitempolygon.h:30
QgsLayoutSize
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
Definition: qgslayoutsize.h:40
QgsLayoutItemAttributeTable::setVectorLayer
void setVectorLayer(QgsVectorLayer *layer)
Sets the vector layer from which to display feature attributes.
Definition: qgslayoutitemattributetable.cpp:72
QgsLayoutItemScaleBar::alternateFillSymbol
QgsFillSymbol * alternateFillSymbol() const
Returns the secondary fill symbol used to render the scalebar (only used for some scalebar types).
Definition: qgslayoutitemscalebar.cpp:227
QgsLayoutItemLegend::setRasterStrokeWidth
void setRasterStrokeWidth(double width)
Sets the stroke width for the stroke drawn around raster symbol items.
Definition: qgslayoutitemlegend.cpp:502
QgsCompositionConverter::LegendTitle
@ LegendTitle
Legend title.
Definition: qgscompositionconverter.h:103
QgsLayoutItemScaleBar::setDivisionLineSymbol
void setDivisionLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol used to render the scalebar divisions (only used for some scalebar types).
Definition: qgslayoutitemscalebar.cpp:202
QgsLayoutItemLegend::setWmsLegendWidth
void setWmsLegendWidth(double width)
Sets the WMS legend width.
Definition: qgslayoutitemlegend.cpp:422
QgsLayoutItemShape::Shape
Shape
Shape type.
Definition: qgslayoutitemshape.h:39
QgsLayoutItemMapGrid::setAnnotationDirection
void setAnnotationDirection(AnnotationDirection direction, BorderSide side)
Sets the direction for drawing frame annotations for the specified map side.
Definition: qgslayoutitemmapgrid.cpp:2331
QgsLayoutTableStyle::readXml
bool readXml(const QDomElement &styleElem)
Reads the style's properties from XML.
Definition: qgslayouttable.cpp:40
QgsLayoutItemMapGrid::setAnnotationFontColor
void setAnnotationFontColor(const QColor &color)
Sets the font color used for drawing grid annotations.
Definition: qgslayoutitemmapgrid.h:580
QgsUnitTypes::DistanceNauticalMiles
@ DistanceNauticalMiles
Nautical miles.
Definition: qgsunittypes.h:72
QgsFillSymbol::createSimple
static QgsFillSymbol * createSimple(const QgsStringMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Definition: qgssymbol.cpp:1440
QgsLayoutItem::frameStrokeColor
QColor frameStrokeColor() const
Returns the frame's stroke color.
Definition: qgslayoutitem.h:754
QgsPropertyCollection::setProperty
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
Definition: qgspropertycollection.cpp:177
_LayerRef< QgsMapLayer >
QgsPropertyDefinition::Opacity
@ Opacity
Opacity (0-100)
Definition: qgsproperty.h:63
QgsCompositionConverter::FrameColor
@ FrameColor
Item frame color.
Definition: qgscompositionconverter.h:83
qgslayoutobject.h
QgsLayoutAtlas::setFilterExpression
bool setFilterExpression(const QString &expression, QString &errorString)
Sets the expression used for filtering features in the coverage layer.
Definition: qgslayoutatlas.cpp:218
QgsMapLayerStyle
Definition: qgsmaplayerstyle.h:42
QgsLayoutTable::mColumns
QgsLayoutTableColumns mColumns
Columns to show in table.
Definition: qgslayouttable.h:575
QgsLayoutTableColumn
Definition: qgslayouttablecolumn.h:36
QgsLayoutItemMapGrid::setAnnotationPosition
void setAnnotationPosition(AnnotationPosition position, BorderSide side)
Sets the position for the grid annotations on a specified side of the map frame.
Definition: qgslayoutitemmapgrid.cpp:2441
QgsLayoutMultiFrame::setResizeMode
void setResizeMode(ResizeMode mode)
Sets the resize mode for the multiframe, and recalculates frame sizes to match.
Definition: qgslayoutmultiframe.cpp:79
QgsCompositionConverter::ItemWidth
@ ItemWidth
Width of item.
Definition: qgscompositionconverter.h:76
QgsLayoutItemLabel
Definition: qgslayoutitemlabel.h:34
QgsLayoutItemScaleBar
Definition: qgslayoutitemscalebar.h:35
QgsLayoutItemMapGrid::setIntervalX
void setIntervalX(double interval)
Sets the interval between grid lines in the x-direction.
Definition: qgslayoutitemmapgrid.cpp:2249
QgsLayout::project
QgsProject * project() const
The project associated with the layout.
Definition: qgslayout.cpp:131
QgsLayoutItem::setItemOpacity
void setItemOpacity(double opacity)
Sets the item's opacity.
Definition: qgslayoutitem.cpp:907
QgsLayoutMultiFrame::addFrame
virtual void addFrame(QgsLayoutFrame *frame, bool recalcFrameSizes=true)
Adds a frame to the multiframe.
Definition: qgslayoutmultiframe.cpp:56
QgsLayoutTable::setContentFontColor
void setContentFontColor(const QColor &color)
Sets the color used to draw text in table body cells.
Definition: qgslayouttable.cpp:683
QgsLayoutItemLegend::setSymbolHeight
void setSymbolHeight(double height)
Sets the legend symbol height.
Definition: qgslayoutitemlegend.cpp:412
QgsLayoutItemMapGrid::setFrameFillColor2
void setFrameFillColor2(const QColor &color)
Sets the second fill color used for the grid frame.
Definition: qgslayoutitemmapgrid.h:845
QgsLayoutItemMapGrid::setAnnotationFrameDistance
void setAnnotationFrameDistance(const double distance)
Sets the distance between the map frame and annotations.
Definition: qgslayoutitemmapgrid.cpp:2482
QgsLayoutPageCollection::pageCount
int pageCount() const
Returns the number of pages in the collection.
Definition: qgslayoutpagecollection.cpp:455
QgsCompositionConverter::PictureSource
@ PictureSource
Picture source url.
Definition: qgscompositionconverter.h:96
QgsPropertyCollection::isActive
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
Definition: qgspropertycollection.cpp:258
QgsLayerTree::readXml
static QgsLayerTree * readXml(QDomElement &element, const QgsReadWriteContext &context)
Load the layer tree from an XML element.
Definition: qgslayertree.cpp:114
QgsLayoutAtlas::setFilterFeatures
void setFilterFeatures(bool filtered)
Sets whether features should be filtered in the coverage layer.
Definition: qgslayoutatlas.cpp:209
QgsLayoutPoint
This class provides a method of storing points, consisting of an x and y coordinate,...
Definition: qgslayoutpoint.h:39
qgslayoutitemregistry.h
Q_NOWARN_DEPRECATED_PUSH
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:751
QgsLayoutTable::setEmptyTableMessage
void setEmptyTableMessage(const QString &message)
Sets the message for empty tables with no content rows.
Definition: qgslayouttable.cpp:589
QgsLegendStyle::readXml
void readXml(const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context=QgsReadWriteContext())
Reads the component's style definition from an XML element.
Definition: qgslegendstyle.cpp:67
QgsLayoutItemMap::setExtent
void setExtent(const QgsRectangle &extent)
Sets a new extent for the map.
Definition: qgslayoutitemmap.cpp:188
QgsLayoutItemMap::setKeepLayerSet
void setKeepLayerSet(bool enabled)
Sets whether the stored layer set should be used or the current layer set of the associated project.
Definition: qgslayoutitemmap.h:227
QgsPropertyDefinition::StrokeWidth
@ StrokeWidth
Line stroke width.
Definition: qgsproperty.h:73
QgsLayoutAtlas
Definition: qgslayoutatlas.h:41
qgslayoutitemscalebar.h
QgsLayoutItemPolyline::setEndMarker
void setEndMarker(MarkerMode mode)
Sets the end marker mode, which controls what marker is drawn at the end of the line.
Definition: qgslayoutitempolyline.cpp:313
QgsLegendStyle::Group
@ Group
Legend group title.
Definition: qgslegendstyle.h:71
QgsLegendStyle::Subgroup
@ Subgroup
Legend subgroup title.
Definition: qgslegendstyle.h:72
qgslayoutmodel.h
QgsPathResolver
Definition: qgspathresolver.h:31
QgsCompositionConverter::NoProperty
@ NoProperty
No property.
Definition: qgscompositionconverter.h:63
QgsLayoutTable::mHeaderFont
QFont mHeaderFont
Header font.
Definition: qgslayouttable.h:539
QgsLayoutItemMapGrid::setAnnotationEnabled
void setAnnotationEnabled(const bool enabled)
Sets whether annotations should be shown for the grid.
Definition: qgslayoutitemmapgrid.h:556
QgsCompositionConverter::NumPages
@ NumPages
Number of pages in composition.
Definition: qgscompositionconverter.h:70
QgsLayoutItemMapGrid::setAnnotationPrecision
void setAnnotationPrecision(const int precision)
Sets the coordinate precision for grid annotations.
Definition: qgslayoutitemmapgrid.h:593
qgsproject.h
QgsCompositionConverter::MapYMin
@ MapYMin
Map extent y minimum.
Definition: qgscompositionconverter.h:89
QgsCompositionConverter::PresetPaperSize
@ PresetPaperSize
Preset paper size for composition.
Definition: qgscompositionconverter.h:67
QgsLayoutItemHtml::setContentMode
void setContentMode(ContentMode mode)
Sets the source mode for item's HTML content.
Definition: qgslayoutitemhtml.h:72
QgsLayoutMeasurement
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
Definition: qgslayoutmeasurement.h:33
QgsLayoutItemShape::setSymbol
void setSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used to draw the shape.
Definition: qgslayoutitemshape.cpp:135
QgsLayoutItemScaleBar::setNumberOfSegmentsLeft
void setNumberOfSegmentsLeft(int segments)
Sets the number of segments included in the left part of the scalebar.
Definition: qgslayoutitemscalebar.cpp:237
QgsLayoutAtlas::setSortFeatures
void setSortFeatures(bool enabled)
Sets whether features should be sorted in the atlas.
Definition: qgslayoutatlas.cpp:182
QgsLayoutItemMapGrid::FrameStyle
FrameStyle
Style for grid frame.
Definition: qgslayoutitemmapgrid.h:228
QgsLayoutAtlas::setFilenameExpression
bool setFilenameExpression(const QString &expression, QString &errorString)
Sets the filename expression used for generating output filenames for each atlas page.
Definition: qgslayoutatlas.cpp:482
qgslayoutitemhtml.h
QgsLayoutItemLegend::setWrapString
void setWrapString(const QString &string)
Sets the legend text wrapping string.
Definition: qgslayoutitemlegend.cpp:436
QgsLayoutObject
Definition: qgslayoutobject.h:39
QgsLayoutItemMap::setDrawAnnotations
void setDrawAnnotations(bool draw)
Sets whether annotations are drawn within the map.
Definition: qgslayoutitemmap.h:342
QgsMapLayerStyle::readXml
void readXml(const QDomElement &styleElement)
Read style configuration (for project file reading)
Definition: qgsmaplayerstyle.cpp:86
QgsLegendStyle
Definition: qgslegendstyle.h:35
qgslayoutitemmap.h
QgsCompositionConverter::ScalebarFillColor2
@ ScalebarFillColor2
Scalebar secondary fill color.
Definition: qgscompositionconverter.h:107
QgsLayoutItemScaleBar::setUnitLabel
void setUnitLabel(const QString &label)
Sets the label for units.
Definition: qgslayoutitemscalebar.h:211
QgsLayoutItemMapGrid::Left
@ Left
Left border.
Definition: qgslayoutitemmapgrid.h:219
QgsPropertyDefinition::DoublePositive
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:59
QgsLayoutAtlas::sortFeatures
bool sortFeatures() const
Returns true if features should be sorted in the atlas.
Definition: qgslayoutatlas.h:149
qgslayoutatlas.h
QgsCompositionConverter::PositionX
@ PositionX
X position on page.
Definition: qgscompositionconverter.h:74