QGIS API Documentation  2.99.0-Master (9ed189e)
qgscomposerlegend.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposerlegend.cpp - description
3  ---------------------
4  begin : June 2008
5  copyright : (C) 2008 by Marco Hugentobler
6  email : marco dot hugentobler at karto dot baug dot ethz dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 #include <limits>
18 
19 #include "qgscomposerlegend.h"
20 #include "qgscomposermap.h"
21 #include "qgscomposition.h"
22 #include "qgscomposermodel.h"
23 #include "qgslayertree.h"
24 #include "qgslayertreemodel.h"
25 #include "qgslegendrenderer.h"
26 #include "qgslegendstyle.h"
27 #include "qgslogger.h"
28 #include "qgsmapsettings.h"
29 #include "qgsproject.h"
30 #include "qgssymbollayerutils.h"
31 #include "qgslayertreeutils.h"
32 #include <QDomDocument>
33 #include <QDomElement>
34 #include <QPainter>
35 
37  : QgsComposerItem( composition )
38  , mCustomLayerTree( nullptr )
39  , mComposerMap( nullptr )
40  , mLegendFilterByMap( false )
41  , mLegendFilterByExpression( false )
42  , mFilterOutAtlas( false )
43  , mFilterAskedForUpdate( false )
44  , mInAtlas( false )
45  , mInitialMapScaleCalculated( false )
46  , mForceResize( false )
47  , mSizeToContents( true )
48 {
49  mLegendModel = new QgsLegendModel( mComposition->project()->layerTreeRoot() );
50 
51  connect( &composition->atlasComposition(), SIGNAL( renderEnded() ), this, SLOT( onAtlasEnded() ) );
52  connect( &composition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( onAtlasFeature( QgsFeature* ) ) );
53 
54  // Connect to the main layertreeroot.
55  // It serves in "auto update mode" as a medium between the main app legend and this one
56  connect( mComposition->project()->layerTreeRoot(), SIGNAL( customPropertyChanged( QgsLayerTreeNode*, QString ) ), this, SLOT( nodeCustomPropertyChanged( QgsLayerTreeNode*, QString ) ) );
57 }
58 
60  : QgsComposerItem( nullptr )
61  , mLegendModel( nullptr )
62  , mCustomLayerTree( nullptr )
63  , mComposerMap( nullptr )
64  , mLegendFilterByMap( false )
65  , mLegendFilterByExpression( false )
66  , mFilterOutAtlas( false )
67  , mFilterAskedForUpdate( false )
68  , mInAtlas( false )
69  , mInitialMapScaleCalculated( false )
70  , mForceResize( false )
71  , mSizeToContents( true )
72 {
73 
74 }
75 
77 {
78  delete mLegendModel;
79  delete mCustomLayerTree;
80 }
81 
82 void QgsComposerLegend::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
83 {
84  Q_UNUSED( itemStyle );
85  Q_UNUSED( pWidget );
86 
87  if ( !painter )
88  return;
89 
90  if ( !shouldDrawItem() )
91  {
92  return;
93  }
94 
95  if ( mFilterAskedForUpdate )
96  {
97  mFilterAskedForUpdate = false;
98  doUpdateFilterByMap();
99  }
100 
101  int dpi = painter->device()->logicalDpiX();
102  double dotsPerMM = dpi / 25.4;
103 
104  if ( mComposition )
105  {
107  mSettings.setDpi( dpi );
108  }
109  if ( mComposerMap )
110  {
111  mSettings.setMmPerMapUnit( mComposerMap->mapUnitsToMM() );
112 
113  // use a temporary QgsMapSettings to find out real map scale
114  QSizeF mapSizePixels = QSizeF( mComposerMap->rect().width() * dotsPerMM, mComposerMap->rect().height() * dotsPerMM );
115  QgsRectangle mapExtent = *mComposerMap->currentMapExtent();
116 
117  QgsMapSettings ms = mComposerMap->mapSettings( mapExtent, mapSizePixels, dpi );
118  mSettings.setMapScale( ms.scale() );
119  }
120  mInitialMapScaleCalculated = true;
121 
122  QgsLegendRenderer legendRenderer( mLegendModel, mSettings );
123  legendRenderer.setLegendSize( mForceResize && mSizeToContents ? QSize() : rect().size() );
124 
125  //adjust box if width or height is too small
126  if ( mSizeToContents )
127  {
128  QSizeF size = legendRenderer.minimumSize();
129  if ( mForceResize )
130  {
131  mForceResize = false;
132  //set new rect, respecting position mode and data defined size/position
133  QRectF targetRect = QRectF( pos().x(), pos().y(), size.width(), size.height() );
134  setSceneRect( evalItemRect( targetRect, true ) );
135  }
136  else if ( size.height() > rect().height() || size.width() > rect().width() )
137  {
138  //need to resize box
139  QRectF targetRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() );
140  if ( size.height() > targetRect.height() )
141  targetRect.setHeight( size.height() );
142  if ( size.width() > rect().width() )
143  targetRect.setWidth( size.width() );
144 
145  //set new rect, respecting position mode and data defined size/position
146  setSceneRect( evalItemRect( targetRect, true ) );
147  }
148  }
149 
150  drawBackground( painter );
151  painter->save();
152  //antialiasing on
153  painter->setRenderHint( QPainter::Antialiasing, true );
154  painter->setPen( QPen( QColor( 0, 0, 0 ) ) );
155 
156  if ( !mSizeToContents )
157  {
158  // set a clip region to crop out parts of legend which don't fit
159  QRectF thisPaintRect = QRectF( 0, 0, rect().width(), rect().height() );
160  painter->setClipRect( thisPaintRect );
161  }
162 
163  legendRenderer.drawLegend( painter );
164 
165  painter->restore();
166 
167  //draw frame and selection boxes if necessary
168  drawFrame( painter );
169  if ( isSelected() )
170  {
171  drawSelectionBoxes( painter );
172  }
173 }
174 
175 QSizeF QgsComposerLegend::paintAndDetermineSize( QPainter* painter )
176 {
177  if ( mFilterAskedForUpdate )
178  {
179  mFilterAskedForUpdate = false;
180  doUpdateFilterByMap();
181  }
182 
183  QgsLegendRenderer legendRenderer( mLegendModel, mSettings );
184  QSizeF size = legendRenderer.minimumSize();
185  if ( painter )
186  legendRenderer.drawLegend( painter );
187  return size;
188 }
189 
190 
192 {
193  if ( !mSizeToContents )
194  return;
195 
196  if ( !mInitialMapScaleCalculated )
197  {
198  // this is messy - but until we have painted the item we have no knowledge of the current DPI
199  // and so cannot correctly calculate the map scale. This results in incorrect size calculations
200  // for marker symbols with size in map units, causing the legends to initially expand to huge
201  // sizes if we attempt to calculate the box size first.
202  return;
203  }
204 
205  QgsLegendRenderer legendRenderer( mLegendModel, mSettings );
206  QSizeF size = legendRenderer.minimumSize();
207  QgsDebugMsg( QString( "width = %1 height = %2" ).arg( size.width() ).arg( size.height() ) );
208  if ( size.isValid() )
209  {
210  QRectF targetRect = QRectF( pos().x(), pos().y(), size.width(), size.height() );
211  //set new rect, respecting position mode and data defined size/position
212  setSceneRect( evalItemRect( targetRect, true ) );
213  }
214 }
215 
217 {
218  mSizeToContents = enabled;
219 }
220 
222 {
223  return mSizeToContents;
224 }
225 
226 void QgsComposerLegend::setCustomLayerTree( QgsLayerTreeGroup* rootGroup )
227 {
228  mLegendModel->setRootGroup( rootGroup ? rootGroup : mComposition->project()->layerTreeRoot() );
229 
230  delete mCustomLayerTree;
231  mCustomLayerTree = rootGroup;
232 }
233 
234 
236 {
237  if ( autoUpdate == autoUpdateModel() )
238  return;
239 
240  setCustomLayerTree( autoUpdate ? nullptr : QgsLayerTree::toGroup( mComposition->project()->layerTreeRoot()->clone() ) );
241  adjustBoxSize();
242  updateItem();
243 }
244 
245 void QgsComposerLegend::nodeCustomPropertyChanged( QgsLayerTreeNode*, const QString& )
246 {
247  if ( autoUpdateModel() )
248  {
249  // in "auto update" mode, some parameters on the main app legend may have been changed (expression filtering)
250  // we must then call updateItem to reflect the changes
251  updateItem();
252  }
253 }
254 
256 {
257  return !mCustomLayerTree;
258 }
259 
261 {
262  mLegendFilterByMap = enabled;
263  updateItem();
264 }
265 
266 void QgsComposerLegend::setTitle( const QString& t )
267 {
268  mTitle = t;
269  mSettings.setTitle( t );
270 
271  if ( mComposition && id().isEmpty() )
272  {
273  //notify the model that the display name has changed
275  }
276 }
277 QString QgsComposerLegend::title() const { return mTitle; }
278 
279 Qt::AlignmentFlag QgsComposerLegend::titleAlignment() const { return mSettings.titleAlignment(); }
280 void QgsComposerLegend::setTitleAlignment( Qt::AlignmentFlag alignment ) { mSettings.setTitleAlignment( alignment ); }
281 
285 
286 QFont QgsComposerLegend::styleFont( QgsLegendStyle::Style s ) const { return mSettings.style( s ).font(); }
288 
289 void QgsComposerLegend::setStyleMargin( QgsLegendStyle::Style s, double margin ) { rstyle( s ).setMargin( margin ); }
290 void QgsComposerLegend::setStyleMargin( QgsLegendStyle::Style s, QgsLegendStyle::Side side, double margin ) { rstyle( s ).setMargin( side, margin ); }
291 
292 double QgsComposerLegend::lineSpacing() const { return mSettings.lineSpacing(); }
293 void QgsComposerLegend::setLineSpacing( double spacing ) { mSettings.setLineSpacing( spacing ); }
294 
295 double QgsComposerLegend::boxSpace() const { return mSettings.boxSpace(); }
296 void QgsComposerLegend::setBoxSpace( double s ) { mSettings.setBoxSpace( s ); }
297 
298 double QgsComposerLegend::columnSpace() const { return mSettings.columnSpace(); }
299 void QgsComposerLegend::setColumnSpace( double s ) { mSettings.setColumnSpace( s ); }
300 
301 QColor QgsComposerLegend::fontColor() const { return mSettings.fontColor(); }
302 void QgsComposerLegend::setFontColor( const QColor& c ) { mSettings.setFontColor( c ); }
303 
304 double QgsComposerLegend::symbolWidth() const { return mSettings.symbolSize().width(); }
305 void QgsComposerLegend::setSymbolWidth( double w ) { mSettings.setSymbolSize( QSizeF( w, mSettings.symbolSize().height() ) ); }
306 
307 double QgsComposerLegend::symbolHeight() const { return mSettings.symbolSize().height(); }
308 void QgsComposerLegend::setSymbolHeight( double h ) { mSettings.setSymbolSize( QSizeF( mSettings.symbolSize().width(), h ) ); }
309 
310 double QgsComposerLegend::wmsLegendWidth() const { return mSettings.wmsLegendSize().width(); }
311 void QgsComposerLegend::setWmsLegendWidth( double w ) { mSettings.setWmsLegendSize( QSizeF( w, mSettings.wmsLegendSize().height() ) ); }
312 
313 double QgsComposerLegend::wmsLegendHeight() const {return mSettings.wmsLegendSize().height(); }
314 void QgsComposerLegend::setWmsLegendHeight( double h ) { mSettings.setWmsLegendSize( QSizeF( mSettings.wmsLegendSize().width(), h ) ); }
315 
316 void QgsComposerLegend::setWrapChar( const QString& t ) { mSettings.setWrapChar( t ); }
317 QString QgsComposerLegend::wrapChar() const {return mSettings.wrapChar(); }
318 
319 int QgsComposerLegend::columnCount() const { return mColumnCount; }
320 void QgsComposerLegend::setColumnCount( int c ) { mColumnCount = c; mSettings.setColumnCount( c ); }
321 
322 bool QgsComposerLegend::splitLayer() const { return mSettings.splitLayer(); }
323 void QgsComposerLegend::setSplitLayer( bool s ) { mSettings.setSplitLayer( s ); }
324 
325 bool QgsComposerLegend::equalColumnWidth() const { return mSettings.equalColumnWidth(); }
327 
328 bool QgsComposerLegend::drawRasterBorder() const { return mSettings.drawRasterBorder(); }
329 void QgsComposerLegend::setDrawRasterBorder( bool enabled ) { mSettings.setDrawRasterBorder( enabled ); }
330 
331 QColor QgsComposerLegend::rasterBorderColor() const { return mSettings.rasterBorderColor(); }
332 void QgsComposerLegend::setRasterBorderColor( const QColor& color ) { mSettings.setRasterBorderColor( color ); }
333 
334 double QgsComposerLegend::rasterBorderWidth() const { return mSettings.rasterBorderWidth(); }
335 void QgsComposerLegend::setRasterBorderWidth( double width ) { mSettings.setRasterBorderWidth( width ); }
336 
338 {
339  adjustBoxSize();
340  updateItem();
341 }
342 
344 {
345  adjustBoxSize();
346  updateItem();
347 }
348 
350 {
351  updateFilterByMap( false );
353 }
354 
355 bool QgsComposerLegend::writeXml( QDomElement& elem, QDomDocument & doc ) const
356 {
357  if ( elem.isNull() )
358  {
359  return false;
360  }
361 
362  QDomElement composerLegendElem = doc.createElement( QStringLiteral( "ComposerLegend" ) );
363  elem.appendChild( composerLegendElem );
364 
365  //write general properties
366  composerLegendElem.setAttribute( QStringLiteral( "title" ), mTitle );
367  composerLegendElem.setAttribute( QStringLiteral( "titleAlignment" ), QString::number( static_cast< int >( mSettings.titleAlignment() ) ) );
368  composerLegendElem.setAttribute( QStringLiteral( "columnCount" ), QString::number( mColumnCount ) );
369  composerLegendElem.setAttribute( QStringLiteral( "splitLayer" ), QString::number( mSettings.splitLayer() ) );
370  composerLegendElem.setAttribute( QStringLiteral( "equalColumnWidth" ), QString::number( mSettings.equalColumnWidth() ) );
371 
372  composerLegendElem.setAttribute( QStringLiteral( "boxSpace" ), QString::number( mSettings.boxSpace() ) );
373  composerLegendElem.setAttribute( QStringLiteral( "columnSpace" ), QString::number( mSettings.columnSpace() ) );
374 
375  composerLegendElem.setAttribute( QStringLiteral( "symbolWidth" ), QString::number( mSettings.symbolSize().width() ) );
376  composerLegendElem.setAttribute( QStringLiteral( "symbolHeight" ), QString::number( mSettings.symbolSize().height() ) );
377  composerLegendElem.setAttribute( QStringLiteral( "lineSpacing" ), QString::number( mSettings.lineSpacing() ) );
378 
379  composerLegendElem.setAttribute( QStringLiteral( "rasterBorder" ), mSettings.drawRasterBorder() );
380  composerLegendElem.setAttribute( QStringLiteral( "rasterBorderColor" ), QgsSymbolLayerUtils::encodeColor( mSettings.rasterBorderColor() ) );
381  composerLegendElem.setAttribute( QStringLiteral( "rasterBorderWidth" ), QString::number( mSettings.rasterBorderWidth() ) );
382 
383  composerLegendElem.setAttribute( QStringLiteral( "wmsLegendWidth" ), QString::number( mSettings.wmsLegendSize().width() ) );
384  composerLegendElem.setAttribute( QStringLiteral( "wmsLegendHeight" ), QString::number( mSettings.wmsLegendSize().height() ) );
385  composerLegendElem.setAttribute( QStringLiteral( "wrapChar" ), mSettings.wrapChar() );
386  composerLegendElem.setAttribute( QStringLiteral( "fontColor" ), mSettings.fontColor().name() );
387 
388  composerLegendElem.setAttribute( QStringLiteral( "resizeToContents" ), mSizeToContents );
389 
390  if ( mComposerMap )
391  {
392  composerLegendElem.setAttribute( QStringLiteral( "map" ), mComposerMap->id() );
393  }
394 
395  QDomElement composerLegendStyles = doc.createElement( QStringLiteral( "styles" ) );
396  composerLegendElem.appendChild( composerLegendStyles );
397 
398  style( QgsLegendStyle::Title ).writeXml( QStringLiteral( "title" ), composerLegendStyles, doc );
399  style( QgsLegendStyle::Group ).writeXml( QStringLiteral( "group" ), composerLegendStyles, doc );
400  style( QgsLegendStyle::Subgroup ).writeXml( QStringLiteral( "subgroup" ), composerLegendStyles, doc );
401  style( QgsLegendStyle::Symbol ).writeXml( QStringLiteral( "symbol" ), composerLegendStyles, doc );
402  style( QgsLegendStyle::SymbolLabel ).writeXml( QStringLiteral( "symbolLabel" ), composerLegendStyles, doc );
403 
404  if ( mCustomLayerTree )
405  {
406  // if not using auto-update - store the custom layer tree
407  mCustomLayerTree->writeXml( composerLegendElem );
408  }
409 
410  if ( mLegendFilterByMap )
411  {
412  composerLegendElem.setAttribute( QStringLiteral( "legendFilterByMap" ), QStringLiteral( "1" ) );
413  }
414 
415  return _writeXml( composerLegendElem, doc );
416 }
417 
418 static void _readOldLegendGroup( QDomElement& elem, QgsLayerTreeGroup* parentGroup, QgsProject* project )
419 {
420  QDomElement itemElem = elem.firstChildElement();
421 
422  while ( !itemElem.isNull() )
423  {
424 
425  if ( itemElem.tagName() == QLatin1String( "LayerItem" ) )
426  {
427  QString layerId = itemElem.attribute( QStringLiteral( "layerId" ) );
428  if ( QgsMapLayer* layer = project->mapLayer( layerId ) )
429  {
430  QgsLayerTreeLayer* nodeLayer = parentGroup->addLayer( layer );
431  QString userText = itemElem.attribute( QStringLiteral( "userText" ) );
432  if ( !userText.isEmpty() )
433  nodeLayer->setCustomProperty( QStringLiteral( "legend/title-label" ), userText );
434  QString style = itemElem.attribute( QStringLiteral( "style" ) );
435  if ( !style.isEmpty() )
436  nodeLayer->setCustomProperty( QStringLiteral( "legend/title-style" ), style );
437  QString showFeatureCount = itemElem.attribute( QStringLiteral( "showFeatureCount" ) );
438  if ( showFeatureCount.toInt() )
439  nodeLayer->setCustomProperty( QStringLiteral( "showFeatureCount" ), 1 );
440 
441  // support for individual legend items (user text, order) not implemented yet
442  }
443  }
444  else if ( itemElem.tagName() == QLatin1String( "GroupItem" ) )
445  {
446  QgsLayerTreeGroup* nodeGroup = parentGroup->addGroup( itemElem.attribute( QStringLiteral( "userText" ) ) );
447  QString style = itemElem.attribute( QStringLiteral( "style" ) );
448  if ( !style.isEmpty() )
449  nodeGroup->setCustomProperty( QStringLiteral( "legend/title-style" ), style );
450 
451  _readOldLegendGroup( itemElem, nodeGroup, project );
452  }
453 
454  itemElem = itemElem.nextSiblingElement();
455  }
456 }
457 
458 bool QgsComposerLegend::readXml( const QDomElement& itemElem, const QDomDocument& doc )
459 {
460  if ( itemElem.isNull() )
461  {
462  return false;
463  }
464 
465  //read general properties
466  mTitle = itemElem.attribute( QStringLiteral( "title" ) );
467  mSettings.setTitle( mTitle );
468  if ( !itemElem.attribute( QStringLiteral( "titleAlignment" ) ).isEmpty() )
469  {
470  mSettings.setTitleAlignment( static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "titleAlignment" ) ).toInt() ) );
471  }
472  int colCount = itemElem.attribute( QStringLiteral( "columnCount" ), QStringLiteral( "1" ) ).toInt();
473  if ( colCount < 1 ) colCount = 1;
474  mColumnCount = colCount;
475  mSettings.setColumnCount( mColumnCount );
476  mSettings.setSplitLayer( itemElem.attribute( QStringLiteral( "splitLayer" ), QStringLiteral( "0" ) ).toInt() == 1 );
477  mSettings.setEqualColumnWidth( itemElem.attribute( QStringLiteral( "equalColumnWidth" ), QStringLiteral( "0" ) ).toInt() == 1 );
478 
479  QDomNodeList stylesNodeList = itemElem.elementsByTagName( QStringLiteral( "styles" ) );
480  if ( !stylesNodeList.isEmpty() )
481  {
482  QDomNode stylesNode = stylesNodeList.at( 0 );
483  for ( int i = 0; i < stylesNode.childNodes().size(); i++ )
484  {
485  QDomElement styleElem = stylesNode.childNodes().at( i ).toElement();
487  style.readXml( styleElem, doc );
488  QString name = styleElem.attribute( QStringLiteral( "name" ) );
490  if ( name == QLatin1String( "title" ) ) s = QgsLegendStyle::Title;
491  else if ( name == QLatin1String( "group" ) ) s = QgsLegendStyle::Group;
492  else if ( name == QLatin1String( "subgroup" ) ) s = QgsLegendStyle::Subgroup;
493  else if ( name == QLatin1String( "symbol" ) ) s = QgsLegendStyle::Symbol;
494  else if ( name == QLatin1String( "symbolLabel" ) ) s = QgsLegendStyle::SymbolLabel;
495  else continue;
496  setStyle( s, style );
497  }
498  }
499 
500  //font color
501  QColor fontClr;
502  fontClr.setNamedColor( itemElem.attribute( QStringLiteral( "fontColor" ), QStringLiteral( "#000000" ) ) );
503  mSettings.setFontColor( fontClr );
504 
505  //spaces
506  mSettings.setBoxSpace( itemElem.attribute( QStringLiteral( "boxSpace" ), QStringLiteral( "2.0" ) ).toDouble() );
507  mSettings.setColumnSpace( itemElem.attribute( QStringLiteral( "columnSpace" ), QStringLiteral( "2.0" ) ).toDouble() );
508 
509  mSettings.setSymbolSize( QSizeF( itemElem.attribute( QStringLiteral( "symbolWidth" ), QStringLiteral( "7.0" ) ).toDouble(), itemElem.attribute( QStringLiteral( "symbolHeight" ), QStringLiteral( "14.0" ) ).toDouble() ) );
510  mSettings.setWmsLegendSize( QSizeF( itemElem.attribute( QStringLiteral( "wmsLegendWidth" ), QStringLiteral( "50" ) ).toDouble(), itemElem.attribute( QStringLiteral( "wmsLegendHeight" ), QStringLiteral( "25" ) ).toDouble() ) );
511  mSettings.setLineSpacing( itemElem.attribute( QStringLiteral( "lineSpacing" ), "1.0" ).toDouble() );
512 
513  mSettings.setDrawRasterBorder( itemElem.attribute( QStringLiteral( "rasterBorder" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
514  mSettings.setRasterBorderColor( QgsSymbolLayerUtils::decodeColor( itemElem.attribute( QStringLiteral( "rasterBorderColor" ), QStringLiteral( "0,0,0" ) ) ) );
515  mSettings.setRasterBorderWidth( itemElem.attribute( QStringLiteral( "rasterBorderWidth" ), QStringLiteral( "0" ) ).toDouble() );
516 
517  mSettings.setWrapChar( itemElem.attribute( QStringLiteral( "wrapChar" ) ) );
518 
519  mSizeToContents = itemElem.attribute( QStringLiteral( "resizeToContents" ), QStringLiteral( "1" ) ) != QLatin1String( "0" );
520 
521  //composer map
522  mLegendFilterByMap = itemElem.attribute( QStringLiteral( "legendFilterByMap" ), QStringLiteral( "0" ) ).toInt();
523  if ( !itemElem.attribute( QStringLiteral( "map" ) ).isEmpty() )
524  {
525  setComposerMap( mComposition->getComposerMapById( itemElem.attribute( QStringLiteral( "map" ) ).toInt() ) );
526  }
527 
528  QDomElement oldLegendModelElem = itemElem.firstChildElement( QStringLiteral( "Model" ) );
529  if ( !oldLegendModelElem.isNull() )
530  {
531  // QGIS <= 2.4
532  QgsLayerTreeGroup* nodeRoot = new QgsLayerTreeGroup();
533  _readOldLegendGroup( oldLegendModelElem, nodeRoot, mComposition->project() );
534  setCustomLayerTree( nodeRoot );
535  }
536  else
537  {
538  // QGIS >= 2.6
539  QDomElement layerTreeElem = itemElem.firstChildElement( QStringLiteral( "layer-tree-group" ) );
540  setCustomLayerTree( QgsLayerTreeGroup::readXml( layerTreeElem, mComposition->project() ) );
541  }
542 
543  //restore general composer item properties
544  QDomNodeList composerItemList = itemElem.elementsByTagName( QStringLiteral( "ComposerItem" ) );
545  if ( !composerItemList.isEmpty() )
546  {
547  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
548  _readXml( composerItemElem, doc );
549  }
550 
551  // < 2.0 projects backward compatibility >>>>>
552  //title font
553  QString titleFontString = itemElem.attribute( QStringLiteral( "titleFont" ) );
554  if ( !titleFontString.isEmpty() )
555  {
556  rstyle( QgsLegendStyle::Title ).rfont().fromString( titleFontString );
557  }
558  //group font
559  QString groupFontString = itemElem.attribute( QStringLiteral( "groupFont" ) );
560  if ( !groupFontString.isEmpty() )
561  {
562  rstyle( QgsLegendStyle::Group ).rfont().fromString( groupFontString );
563  }
564 
565  //layer font
566  QString layerFontString = itemElem.attribute( QStringLiteral( "layerFont" ) );
567  if ( !layerFontString.isEmpty() )
568  {
569  rstyle( QgsLegendStyle::Subgroup ).rfont().fromString( layerFontString );
570  }
571  //item font
572  QString itemFontString = itemElem.attribute( QStringLiteral( "itemFont" ) );
573  if ( !itemFontString.isEmpty() )
574  {
575  rstyle( QgsLegendStyle::SymbolLabel ).rfont().fromString( itemFontString );
576  }
577 
578  if ( !itemElem.attribute( QStringLiteral( "groupSpace" ) ).isEmpty() )
579  {
580  rstyle( QgsLegendStyle::Group ).setMargin( QgsLegendStyle::Top, itemElem.attribute( QStringLiteral( "groupSpace" ), QStringLiteral( "3.0" ) ).toDouble() );
581  }
582  if ( !itemElem.attribute( QStringLiteral( "layerSpace" ) ).isEmpty() )
583  {
584  rstyle( QgsLegendStyle::Subgroup ).setMargin( QgsLegendStyle::Top, itemElem.attribute( QStringLiteral( "layerSpace" ), QStringLiteral( "3.0" ) ).toDouble() );
585  }
586  if ( !itemElem.attribute( QStringLiteral( "symbolSpace" ) ).isEmpty() )
587  {
588  rstyle( QgsLegendStyle::Symbol ).setMargin( QgsLegendStyle::Top, itemElem.attribute( QStringLiteral( "symbolSpace" ), QStringLiteral( "2.0" ) ).toDouble() );
589  rstyle( QgsLegendStyle::SymbolLabel ).setMargin( QgsLegendStyle::Top, itemElem.attribute( QStringLiteral( "symbolSpace" ), QStringLiteral( "2.0" ) ).toDouble() );
590  }
591  // <<<<<<< < 2.0 projects backward compatibility
592 
593  emit itemChanged();
594  return true;
595 }
596 
598 {
599  if ( !id().isEmpty() )
600  {
601  return id();
602  }
603 
604  //if no id, default to portion of title text
605  QString text = mSettings.title();
606  if ( text.isEmpty() )
607  {
608  return tr( "<legend>" );
609  }
610  if ( text.length() > 25 )
611  {
612  return QString( tr( "%1..." ) ).arg( text.left( 25 ) );
613  }
614  else
615  {
616  return text;
617  }
618 }
619 
621 {
622  if ( mComposerMap )
623  {
624  disconnect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
625  disconnect( mComposerMap, SIGNAL( itemChanged() ), this, SLOT( updateFilterByMap() ) );
626  disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateFilterByMap() ) );
627  disconnect( mComposerMap, SIGNAL( layerStyleOverridesChanged() ), this, SLOT( mapLayerStyleOverridesChanged() ) );
628  }
629 
630  mComposerMap = map;
631 
632  if ( map )
633  {
634  QObject::connect( map, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
635  QObject::connect( map, SIGNAL( itemChanged() ), this, SLOT( updateFilterByMap() ) );
636  QObject::connect( map, SIGNAL( extentChanged() ), this, SLOT( updateFilterByMap() ) );
637  QObject::connect( map, SIGNAL( layerStyleOverridesChanged() ), this, SLOT( mapLayerStyleOverridesChanged() ) );
638  }
639 
640  updateItem();
641 }
642 
644 {
645  setComposerMap( nullptr );
646 }
647 
649 {
651  const QgsExpressionContext* evalContext = context ? context : &scopedContext;
652 
653  bool forceUpdate = false;
654  //updates data defined properties and redraws item to match
655  if ( property == QgsComposerObject::LegendTitle || property == QgsComposerObject::AllProperties )
656  {
657  bool ok = false;
658  QString t = mDataDefinedProperties.valueAsString( QgsComposerObject::LegendTitle, *evalContext, mTitle, &ok );
659  if ( ok )
660  {
661  mSettings.setTitle( t );
662  forceUpdate = true;
663  }
664  }
666  {
667  bool ok = false;
668  int cols = mDataDefinedProperties.valueAsInt( QgsComposerObject::LegendColumnCount, *evalContext, mColumnCount, &ok );
669  if ( ok && cols >= 0 )
670  {
671  mSettings.setColumnCount( cols );
672  forceUpdate = true;
673  }
674  }
675  if ( forceUpdate )
676  {
677  adjustBoxSize();
678  update();
679  }
680 
682 }
683 
684 void QgsComposerLegend::mapLayerStyleOverridesChanged()
685 {
686  if ( !mComposerMap )
687  return;
688 
689  // map's style has been changed, so make sure to update the legend here
690  if ( mLegendFilterByMap )
691  {
692  // legend is being filtered by map, so we need to re run the hit test too
693  // as the style overrides may also have affected the visible symbols
694  updateFilterByMap( false );
695  }
696  else
697  {
698  mLegendModel->setLayerStyleOverrides( mComposerMap->layerStyleOverrides() );
699 
700  Q_FOREACH ( QgsLayerTreeLayer* nodeLayer, mLegendModel->rootGroup()->findLayers() )
701  mLegendModel->refreshLayerLegend( nodeLayer );
702  }
703 
704  adjustBoxSize();
705  updateItem();
706 }
707 
708 void QgsComposerLegend::updateFilterByMap( bool redraw )
709 {
710  if ( isRemoved() )
711  return;
712  // ask for update
713  // the actual update will take place before the redraw.
714  // This is to avoid multiple calls to the filter
715  mFilterAskedForUpdate = true;
716 
717  if ( redraw )
719 }
720 
721 void QgsComposerLegend::doUpdateFilterByMap()
722 {
723  if ( mComposerMap )
724  mLegendModel->setLayerStyleOverrides( mComposerMap->layerStyleOverrides() );
725  else
726  mLegendModel->setLayerStyleOverrides( QMap<QString, QString>() );
727 
728 
729  bool filterByExpression = QgsLayerTreeUtils::hasLegendFilterExpression( *( mCustomLayerTree ? mCustomLayerTree : mComposition->project()->layerTreeRoot() ) );
730 
731  if ( mComposerMap && ( mLegendFilterByMap || filterByExpression || mInAtlas ) )
732  {
733  int dpi = mComposition->printResolution();
734 
735  QgsRectangle requestRectangle;
736  mComposerMap->requestedExtent( requestRectangle );
737 
738  QSizeF theSize( requestRectangle.width(), requestRectangle.height() );
739  theSize *= mComposerMap->mapUnitsToMM() * dpi / 25.4;
740 
741  QgsMapSettings ms = mComposerMap->mapSettings( requestRectangle, theSize, dpi );
742 
743  QgsGeometry filterPolygon;
744  if ( mInAtlas )
745  {
746  filterPolygon = composition()->atlasComposition().currentGeometry( mComposerMap->crs() );
747  }
748  mLegendModel->setLegendFilter( &ms, /* useExtent */ mInAtlas || mLegendFilterByMap, filterPolygon, /* useExpressions */ true );
749  }
750  else
751  mLegendModel->setLegendFilterByMap( nullptr );
752 
753  mForceResize = true;
754 }
755 
757 {
758  mFilterOutAtlas = doFilter;
759 }
760 
762 {
763  return mFilterOutAtlas;
764 }
765 
766 void QgsComposerLegend::onAtlasFeature( QgsFeature* feat )
767 {
768  if ( !feat )
769  return;
770  mInAtlas = mFilterOutAtlas;
771  updateFilterByMap();
772 }
773 
774 void QgsComposerLegend::onAtlasEnded()
775 {
776  mInAtlas = false;
777  updateFilterByMap();
778 }
779 
780 // -------------------------------------------------------------------------
782 #include "qgsvectorlayer.h"
783 
785  : QgsLayerTreeModel( rootNode, parent )
786 {
789 }
790 
791 QVariant QgsLegendModel::data( const QModelIndex& index, int role ) const
792 {
793  // handle custom layer node labels
794  if ( QgsLayerTreeNode* node = index2node( index ) )
795  {
796  if ( QgsLayerTree::isLayer( node ) && ( role == Qt::DisplayRole || role == Qt::EditRole ) && !node->customProperty( QStringLiteral( "legend/title-label" ) ).isNull() )
797  {
798  QgsLayerTreeLayer* nodeLayer = QgsLayerTree::toLayer( node );
799  QString name = node->customProperty( QStringLiteral( "legend/title-label" ) ).toString();
800  if ( nodeLayer->customProperty( QStringLiteral( "showFeatureCount" ), 0 ).toInt() && role == Qt::DisplayRole )
801  {
802  QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( nodeLayer->layer() );
803  if ( vlayer && vlayer->featureCount() >= 0 )
804  name += QStringLiteral( " [%1]" ).arg( vlayer->featureCount() );
805  }
806  return name;
807  }
808  }
809 
810  return QgsLayerTreeModel::data( index, role );
811 }
812 
813 Qt::ItemFlags QgsLegendModel::flags( const QModelIndex& index ) const
814 {
815  // make the legend nodes selectable even if they are not by default
816  if ( index2legendNode( index ) )
817  return QgsLayerTreeModel::flags( index ) | Qt::ItemIsSelectable;
818 
819  return QgsLayerTreeModel::flags( index );
820 }
void setTitleAlignment(Qt::AlignmentFlag alignment)
Sets the alignment of the legend title.
void setWrapChar(const QString &t)
Layer tree group node serves as a container for layers and further groups.
void setLegendSize(QSizeF s)
Set the preferred resulting legend size.
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, int dpi) const
Return map settings that would be used for drawing of the map.
QgsComposerLegend(QgsComposition *composition)
A rectangle specified with double values.
Definition: qgsrectangle.h:36
Base class for all map layer types.
Definition: qgsmaplayer.h:52
QgsLayerTreeGroup * rootGroup() const
Return pointer to the root node of the layer tree. Always a non-null pointer.
double mapUnitsToMM() const
Returns the conversion factor map units -> mm.
bool readXml(const QDomElement &itemElem, const QDomDocument &doc) override
Sets state from Dom document.
void setEqualColumnWidth(bool s)
Item model implementation based on layer tree model for composer legend.
QgsLayerTreeGroup * addGroup(const QString &name)
Append a new group node with given name. Newly created node is owned by this group.
const QgsComposerMap * getComposerMapById(const int id) const
Returns the composer map with specified id.
void setBoxSpace(double s)
void setMmPerMapUnit(double mmPerMapUnit)
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
QgsMapLayer * mapLayer(const QString &theLayerId) const
Retrieve a pointer to a registered layer by layer ID.
void setDrawRasterBorder(bool enabled)
Sets whether a border will be drawn around raster symbol items.
QString wrapChar() const
void setSplitLayer(bool s)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget) override
Reimplementation of QCanvasItem::paint.
QgsComposerModel * itemsModel()
Returns the items model attached to the composition.
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
void itemChanged()
Emitted when the item changes.
void setSymbolSize(QSizeF s)
void drawLegend(QPainter *painter)
Draw the legend with given painter.
int printResolution() const
void setColumnSpace(double s)
A item that forms part of a map composition.
virtual void writeXml(QDomElement &parentElement) override
Write group (tree) as XML element <layer-tree-group> and add it to the given parent element...
double rasterBorderWidth() const
Returns the border width (in millimeters) for the border drawn around raster symbol items...
QFont font() const
virtual void refreshDataDefinedProperty(const DataDefinedProperty property=AllProperties, const QgsExpressionContext *context=nullptr)
Refreshes a data defined property for the item by reevaluating the property&#39;s value and redrawing the...
QRectF evalItemRect(const QRectF &newRect, const bool resizeOnly=false, const QgsExpressionContext *context=nullptr)
Evaluates an item&#39;s bounding rect to consider data defined position and size of item and reference po...
int id() const
Get identification number.
QgsLegendStyle style(QgsLegendStyle::Style s) const
Returns style.
Composer legend components style.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:79
QColor rasterBorderColor() const
Returns the border color for the border drawn around raster symbol items.
bool writeXml(QDomElement &elem, QDomDocument &doc) const override
Stores state in Dom node.
void setLineSpacing(double spacing)
Sets the spacing in-between multiple lines.
static QgsLayerTreeGroup * readXml(QDomElement &element)
Read group (tree) from XML element <layer-tree-group> and return the newly created group (or null on ...
virtual void drawFrame(QPainter *p)
Draw black frame around item.
QgsLayerTreeGroup * layerTreeRoot() const
Return pointer to the root (invisible) node of the project&#39;s layer tree.
void setTitle(const QString &t)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:136
void updateLegend()
Updates the model and all legend entries.
void updateItemDisplayName(QgsComposerItem *item)
Must be called when an item&#39;s display name is modified.
DataDefinedProperty
Data defined properties for different item types.
QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is ...
Definition: qgslayertree.h:46
void setWmsLegendHeight(double h)
Allow check boxes for legend nodes (if supported by layer&#39;s legend)
void setResizeToContents(bool enabled)
Sets whether the legend should automatically resize to fit its contents.
void setStyle(QgsLegendStyle::Style s, const QgsLegendStyle &style)
QgsLayerTreeLayer * addLayer(QgsMapLayer *layer)
Append a new layer node for given map layer. Newly created node is owned by this group.
void adjustBoxSize()
Sets item box to the whole content.
The QgsMapSettings class contains configuration for rendering of the map.
static QString encodeColor(const QColor &color)
static void _readOldLegendGroup(QDomElement &elem, QgsLayerTreeGroup *parentGroup, QgsProject *project)
void setStyleMargin(QgsLegendStyle::Style s, double margin)
Set style margin.
The QgsLayerTreeModel class is model implementation for Qt item views framework.
QSizeF wmsLegendSize() const
QgsLegendStyle style(QgsLegendStyle::Style s) const
Returns style.
bool _writeXml(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document. Usually called from writeXml methods of ...
void setFont(const QFont &font)
void setRasterBorderWidth(double width)
Sets the border width for the border drawn around raster symbol items.
void setRasterBorderWidth(double width)
Sets the border width for the border drawn around raster symbol items.
virtual void updateItem()
Updates item, with the possibility to do custom update for subclasses.
bool equalColumnWidth() const
void setSymbolHeight(double h)
double rasterBorderWidth() const
Returns the border width (in millimeters) for the border drawn around raster symbol items...
void setLegendFilterOutAtlas(bool doFilter)
When set to true, during an atlas rendering, it will filter out legend elements where features are ou...
virtual void drawSelectionBoxes(QPainter *p)
Draws additional graphics on selected items.
double scale() const
Return the calculated scale of the map.
void setLegendFilterByMap(const QgsMapSettings *settings)
Force only display of legend nodes which are valid for given map settings.
long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
virtual void refreshDataDefinedProperty(const QgsComposerObject::DataDefinedProperty property=QgsComposerObject::AllProperties, const QgsExpressionContext *context=nullptr) override
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:212
static QgsLayerTreeModelLegendNode * index2legendNode(const QModelIndex &index)
Return legend node for given index.
bool useAdvancedEffects() const
Returns true if a composition should use advanced effects such as blend modes.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setMapScale(double scale)
QVariant data(const QModelIndex &index, int role) const override
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file...
QColor fontColor() const
void setComposerMap(const QgsComposerMap *map)
void synchronizeWithModel()
Data changed.
void setTitle(const QString &t)
QFont styleFont(QgsLegendStyle::Style s) const
QgsPropertyCollection mDataDefinedProperties
This class is a base class for nodes in a layer tree.
Reads and writes project states.
Definition: qgsproject.h:74
void setMargin(Side side, double margin)
QMap< QString, QString > layerStyleOverrides() const
Getter for stored overrides of styles for layers.
double symbolWidth() const
Qt::AlignmentFlag titleAlignment() const
Returns the alignment of the legend title.
double wmsLegendHeight() const
void setDrawRasterBorder(bool enabled)
Sets whether a border will be drawn around raster symbol items.
void setDpi(int dpi)
double boxSpace() const
QString wrapChar() const
void setFontColor(const QColor &c)
static bool hasLegendFilterExpression(const QgsLayerTreeGroup &group)
Test if one of the layers in a group has an expression filter.
bool isLayer(QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:40
bool _readXml(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document. Usually called from readXml methods of su...
void setColumnSpace(double s)
void setFlag(Flag f, bool on=true)
Enable or disable a model flag.
Graphics scene for map printing.
virtual void updateItem() override
Update() overloading.
QSizeF minimumSize()
Run the layout algorithm and determine the size required for legend.
void setLegendFilterByMapEnabled(bool enabled)
Set whether legend items should be filtered to show just the ones visible in the associated map...
Object representing map window.
void setSymbolWidth(double w)
QSizeF paintAndDetermineSize(QPainter *painter)
Paints the legend and calculates its size. If painter is 0, only size is calculated.
void setRasterBorderColor(const QColor &color)
Sets the border color for the border drawn around raster symbol items.
void setRootGroup(QgsLayerTreeGroup *newRootGroup)
Reset the model and use a new root group node.
void invalidateCurrentMap()
Sets mCompositionMap to 0 if the map is deleted.
virtual QString displayName() const override
Get item display name.
bool autoUpdateModel() const
void refreshLayerLegend(QgsLayerTreeLayer *nodeLayer)
Force a refresh of legend nodes of a layer node.
virtual bool isRemoved() const
Returns whether this item has been removed from the composition.
void setWmsLegendWidth(double w)
QSizeF symbolSize() const
void setLineSpacing(double s)
virtual QgsExpressionContext createExpressionContext() const override
Creates an expression context relating to the item&#39;s current state.
bool resizeToContents() const
Returns whether the legend should automatically resize to fit its contents.
QgsMapLayer * layer() const
void readXml(const QDomElement &elem, const QDomDocument &doc)
double symbolHeight() const
QgsComposition * mComposition
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string...
void setWmsLegendSize(QSizeF s)
QgsLegendStyle & rstyle(QgsLegendStyle::Style s)
Returns reference to modifiable style.
QgsGeometry currentGeometry(const QgsCoordinateReferenceSystem &projectedTo=QgsCoordinateReferenceSystem()) const
Returns the current atlas geometry in the given projection system (default to the coverage layer&#39;s CR...
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
void setUseAdvancedEffects(bool use)
void setAutoUpdateModel(bool autoUpdate)
QgsLayerTreeNode * index2node(const QModelIndex &index) const
Return layer tree node for given index.
const QgsComposition * composition() const
Returns the composition the item is attached to.
virtual QgsLayerTreeGroup * clone() const override
Return a clone of the group. The children are cloned too.
QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is ...
Definition: qgslayertree.h:52
void setWrapChar(const QString &t)
void setStyle(QgsLegendStyle::Style s, const QgsLegendStyle &style)
QgsProject * project() const
The project associated with the composition.
bool equalColumnWidth() const
virtual void drawBackground(QPainter *p)
Draw background.
QgsLegendModel(QgsLayerTreeGroup *rootNode, QObject *parent=nullptr)
Construct the model based on the given layer tree.
void setColumnCount(int c)
double columnSpace() const
void requestedExtent(QgsRectangle &extent) const
Calculates the extent to request and the yShift of the top-left point in case of rotation.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
virtual void setSceneRect(const QRectF &rectangle)
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
void setEqualColumnWidth(bool s)
QString title() const
void setTitleAlignment(Qt::AlignmentFlag alignment)
Sets the alignment of the legend title.
QFont & rfont()
void writeXml(const QString &name, QDomElement &elem, QDomDocument &doc) const
void setStyleFont(QgsLegendStyle::Style s, const QFont &f)
Set style font.
QgsAtlasComposition & atlasComposition()
double wmsLegendWidth() const
Flags flags() const
Return OR-ed combination of model flags.
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Set map of map layer style overrides (key: layer ID, value: style name) where a different style shoul...
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes. Searches recursively the whole sub-tree.
QgsComposerItem(QgsComposition *composition, bool manageZValue=true)
Constructor.
QColor rasterBorderColor() const
Returns the border color for the border drawn around raster symbol items.
void setFontColor(const QColor &c)
double lineSpacing() const
bool legendFilterOutAtlas() const
Whether to filter out legend elements outside of the current atlas feature.
QColor fontColor() const
void setLegendFilter(const QgsMapSettings *settings, bool useExtent=true, const QgsGeometry &polygon=QgsGeometry(), bool useExpressions=true)
Filter display of legend nodes for given map settings.
Represents a vector layer which manages a vector based data sets.
QgsLegendStyle & rstyle(QgsLegendStyle::Style s)
Returns reference to modifiable style.
bool drawRasterBorder() const
Returns whether a border will be drawn around raster symbol items.
bool splitLayer() const
int valueAsInt(int key, const QgsExpressionContext &context, int defaultValue=0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as an integer...
QString id() const
Get item&#39;s id (which is not necessarly unique)
const QgsRectangle * currentMapExtent() const
Returns a pointer to the current map extent, which is either the original user specified extent or th...
void setBoxSpace(double s)
Allow reordering with drag&#39;n&#39;drop.
double lineSpacing() const
Returns the spacing in-between lines in mm.
double columnSpace() const
void setSplitLayer(bool s)
bool drawRasterBorder() const
Returns whether a border will be drawn around raster symbol items.
static QColor decodeColor(const QString &str)
void setRasterBorderColor(const QColor &color)
Sets the border color for the border drawn around raster symbol items.
All properties for item.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:217
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the node. Properties are stored in a map and saved in project file...
Layer tree node points to a map layer.
The QgsLegendRenderer class handles automatic layout and rendering of legend.
QString title() const
Qt::AlignmentFlag titleAlignment() const
Returns the alignment of the legend title.
double boxSpace() const