QGIS API Documentation  3.23.0-Master (eb871beae0)
qgslayoutitemlabel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutitemlabel.cpp
3  -------------------
4  begin : October 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
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 
18 #include "qgslayoutitemlabel.h"
19 #include "qgslayoutitemregistry.h"
20 #include "qgslayout.h"
21 #include "qgslayoututils.h"
22 #include "qgslayoutmodel.h"
23 #include "qgsexpression.h"
25 #include "qgsvectorlayer.h"
26 #include "qgsproject.h"
27 #include "qgsdistancearea.h"
28 #include "qgsfontutils.h"
29 #include "qgsexpressioncontext.h"
30 #include "qgsmapsettings.h"
31 #include "qgslayoutitemmap.h"
32 #include "qgssettings.h"
33 
34 #include "qgswebview.h"
35 #include "qgswebframe.h"
36 #include "qgswebpage.h"
37 
38 #include <QCoreApplication>
39 #include <QDate>
40 #include <QDomElement>
41 #include <QPainter>
42 #include <QTimer>
43 #include <QEventLoop>
44 #include <QThread>
45 
47  : QgsLayoutItem( layout )
48 {
49  mDistanceArea.reset( new QgsDistanceArea() );
50  mHtmlUnitsToLayoutUnits = htmlUnitsToLayoutUnits();
51 
52  //get default layout font from settings
53  const QgsSettings settings;
54  const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
55  if ( !defaultFontString.isEmpty() )
56  {
57  mFont.setFamily( defaultFontString );
58  }
59 
60  //default to a 10 point font size
61  mFont.setPointSizeF( 10 );
62 
63  //default to no background
64  setBackgroundEnabled( false );
65 
66  //a label added while atlas preview is enabled needs to have the expression context set,
67  //otherwise fields in the label aren't correctly evaluated until atlas preview feature changes (#9457)
68  refreshExpressionContext();
69 
70  // only possible on the main thread!
71  if ( QThread::currentThread() == QApplication::instance()->thread() )
72  {
73  mWebPage.reset( new QgsWebPage( this ) );
74  }
75  else
76  {
77  QgsMessageLog::logMessage( QObject::tr( "Cannot load HTML based item label in background threads" ) );
78  }
79  if ( mWebPage )
80  {
81  mWebPage->setIdentifier( tr( "Layout label item" ) );
82  mWebPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
83 
84  //This makes the background transparent. Found on http://blog.qt.digia.com/blog/2009/06/30/transparent-qwebview-or-qwebpage/
85  QPalette palette = mWebPage->palette();
86  palette.setBrush( QPalette::Base, Qt::transparent );
87  mWebPage->setPalette( palette );
88 
89  mWebPage->mainFrame()->setZoomFactor( 10.0 );
90  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
91  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
92 
93  connect( mWebPage.get(), &QWebPage::loadFinished, this, &QgsLayoutItemLabel::loadingHtmlFinished );
94  }
95 }
96 
98 {
99  return new QgsLayoutItemLabel( layout );
100 }
101 
103 {
105 }
106 
108 {
109  return QgsApplication::getThemeIcon( QStringLiteral( "/mLayoutItemLabel.svg" ) );
110 }
111 
113 {
114  QPainter *painter = context.renderContext().painter();
115  const QgsScopedQPainterState painterState( painter );
116 
117  // painter is scaled to dots, so scale back to layout units
118  painter->scale( context.renderContext().scaleFactor(), context.renderContext().scaleFactor() );
119 
120  const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
121  const double xPenAdjust = mMarginX < 0 ? -penWidth : penWidth;
122  const double yPenAdjust = mMarginY < 0 ? -penWidth : penWidth;
123  const QRectF painterRect( xPenAdjust + mMarginX, yPenAdjust + mMarginY, rect().width() - 2 * xPenAdjust - 2 * mMarginX, rect().height() - 2 * yPenAdjust - 2 * mMarginY );
124 
125  switch ( mMode )
126  {
127  case ModeHtml:
128  {
129  if ( mFirstRender )
130  {
131  contentChanged();
132  mFirstRender = false;
133  }
134 
135  if ( mWebPage )
136  {
137  painter->scale( 1.0 / mHtmlUnitsToLayoutUnits / 10.0, 1.0 / mHtmlUnitsToLayoutUnits / 10.0 );
138  mWebPage->setViewportSize( QSize( painterRect.width() * mHtmlUnitsToLayoutUnits * 10.0, painterRect.height() * mHtmlUnitsToLayoutUnits * 10.0 ) );
139  mWebPage->settings()->setUserStyleSheetUrl( createStylesheetUrl() );
140  mWebPage->mainFrame()->render( painter );
141  }
142  break;
143  }
144 
145  case ModeFont:
146  {
147  const QString textToDraw = currentText();
148  painter->setFont( mFont );
149  QgsLayoutUtils::drawText( painter, painterRect, textToDraw, mFont, mFontColor, mHAlignment, mVAlignment, Qt::TextWordWrap );
150  break;
151  }
152  }
153 }
154 
155 void QgsLayoutItemLabel::contentChanged()
156 {
157  switch ( mMode )
158  {
159  case ModeHtml:
160  {
161  const QString textToDraw = currentText();
162  if ( !mWebPage )
163  {
164  mHtmlLoaded = true;
165  return;
166  }
167 
168  //mHtmlLoaded tracks whether the QWebPage has completed loading
169  //its html contents, set it initially to false. The loadingHtmlFinished slot will
170  //set this to true after html is loaded.
171  mHtmlLoaded = false;
172 
173  const QUrl baseUrl = QUrl::fromLocalFile( mLayout->project()->absoluteFilePath() );
174  mWebPage->mainFrame()->setHtml( textToDraw, baseUrl );
175 
176  //For very basic html labels with no external assets, the html load will already be
177  //complete before we even get a chance to start the QEventLoop. Make sure we check
178  //this before starting the loop
179 
180  // important -- we CAN'T do this when it's a render inside the designer, otherwise the
181  // event loop will mess with the paint event and cause it to be deleted, and BOOM!
182  if ( !mHtmlLoaded && ( !mLayout || !mLayout->renderContext().isPreviewRender() ) )
183  {
184  //Setup event loop and timeout for rendering html
185  QEventLoop loop;
186 
187  //Connect timeout and webpage loadFinished signals to loop
188  connect( mWebPage.get(), &QWebPage::loadFinished, &loop, &QEventLoop::quit );
189 
190  // Start a 20 second timeout in case html loading will never complete
191  QTimer timeoutTimer;
192  timeoutTimer.setSingleShot( true );
193  connect( &timeoutTimer, &QTimer::timeout, &loop, &QEventLoop::quit );
194  timeoutTimer.start( 20000 );
195 
196  // Pause until html is loaded
197  loop.exec( QEventLoop::ExcludeUserInputEvents );
198  }
199  break;
200  }
201  case ModeFont:
202  invalidateCache();
203  break;
204  }
205 }
206 
207 void QgsLayoutItemLabel::loadingHtmlFinished( bool result )
208 {
209  Q_UNUSED( result )
210  mHtmlLoaded = true;
211  invalidateCache();
212  update();
213 }
214 
215 double QgsLayoutItemLabel::htmlUnitsToLayoutUnits()
216 {
217  if ( !mLayout )
218  {
219  return 1.0;
220  }
221 
222  //TODO : fix this more precisely so that the label's default text size is the same with or without "display as html"
223  return mLayout->convertToLayoutUnits( QgsLayoutMeasurement( mLayout->renderContext().dpi() / 72.0, QgsUnitTypes::LayoutMillimeters ) ); //webkit seems to assume a standard dpi of 72
224 }
225 
226 void QgsLayoutItemLabel::setText( const QString &text )
227 {
228  mText = text;
229  emit changed();
230 
231  contentChanged();
232 
233  if ( mLayout && id().isEmpty() && mMode != ModeHtml )
234  {
235  //notify the model that the display name has changed
236  mLayout->itemsModel()->updateItemDisplayName( this );
237  }
238 }
239 
241 {
242  if ( mode == mMode )
243  {
244  return;
245  }
246 
247  mMode = mode;
248  contentChanged();
249 
250  if ( mLayout && id().isEmpty() )
251  {
252  //notify the model that the display name has changed
253  mLayout->itemsModel()->updateItemDisplayName( this );
254  }
255 }
256 
257 void QgsLayoutItemLabel::refreshExpressionContext()
258 {
259  if ( !mLayout )
260  return;
261 
262  QgsVectorLayer *layer = mLayout->reportContext().layer();
263  //setup distance area conversion
264  if ( layer )
265  {
266  mDistanceArea->setSourceCrs( layer->crs(), mLayout->project()->transformContext() );
267  }
268  else
269  {
270  //set to composition's reference map's crs
271  QgsLayoutItemMap *referenceMap = mLayout->referenceMap();
272  if ( referenceMap )
273  mDistanceArea->setSourceCrs( referenceMap->crs(), mLayout->project()->transformContext() );
274  }
275  mDistanceArea->setEllipsoid( mLayout->project()->ellipsoid() );
276  contentChanged();
277 
278  update();
279 }
280 
282 {
283  QString displayText = mText;
284  replaceDateText( displayText );
285 
287 
288  return QgsExpression::replaceExpressionText( displayText, &context, mDistanceArea.get() );
289 }
290 
291 void QgsLayoutItemLabel::replaceDateText( QString &text ) const
292 {
293  const QString constant = QStringLiteral( "$CURRENT_DATE" );
294  const int currentDatePos = text.indexOf( constant );
295  if ( currentDatePos != -1 )
296  {
297  //check if there is a bracket just after $CURRENT_DATE
298  QString formatText;
299  const int openingBracketPos = text.indexOf( '(', currentDatePos );
300  const int closingBracketPos = text.indexOf( ')', openingBracketPos + 1 );
301  if ( openingBracketPos != -1 &&
302  closingBracketPos != -1 &&
303  ( closingBracketPos - openingBracketPos ) > 1 &&
304  openingBracketPos == currentDatePos + constant.size() )
305  {
306  formatText = text.mid( openingBracketPos + 1, closingBracketPos - openingBracketPos - 1 );
307  text.replace( currentDatePos, closingBracketPos - currentDatePos + 1, QDate::currentDate().toString( formatText ) );
308  }
309  else //no bracket
310  {
311  text.replace( QLatin1String( "$CURRENT_DATE" ), QDate::currentDate().toString() );
312  }
313  }
314 }
315 
316 void QgsLayoutItemLabel::setFont( const QFont &f )
317 {
318  mFont = f;
319 }
320 
321 void QgsLayoutItemLabel::setMargin( const double m )
322 {
323  mMarginX = m;
324  mMarginY = m;
325  prepareGeometryChange();
326 }
327 
328 void QgsLayoutItemLabel::setMarginX( const double margin )
329 {
330  mMarginX = margin;
331  prepareGeometryChange();
332 }
333 
334 void QgsLayoutItemLabel::setMarginY( const double margin )
335 {
336  mMarginY = margin;
337  prepareGeometryChange();
338 }
339 
341 {
342  const QSizeF newSize = sizeForText();
343 
344  //keep alignment point constant
345  double xShift = 0;
346  double yShift = 0;
347 
348  itemShiftAdjustSize( newSize.width(), newSize.height(), xShift, yShift );
349 
350  //update rect for data defined size and position
351  attemptSetSceneRect( QRectF( pos().x() + xShift, pos().y() + yShift, newSize.width(), newSize.height() ) );
352 }
353 
355 {
356  const double textWidth = QgsLayoutUtils::textWidthMM( mFont, currentText() );
357  const double fontHeight = QgsLayoutUtils::fontHeightMM( mFont );
358 
359  const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
360 
361  const double width = textWidth + 2 * mMarginX + 2 * penWidth;
362  const double height = fontHeight + 2 * mMarginY + 2 * penWidth;
363 
364  return mLayout->convertToLayoutUnits( QgsLayoutSize( width, height, QgsUnitTypes::LayoutMillimeters ) );
365 }
366 
368 {
369  return mFont;
370 }
371 
372 bool QgsLayoutItemLabel::writePropertiesToElement( QDomElement &layoutLabelElem, QDomDocument &doc, const QgsReadWriteContext & ) const
373 {
374  layoutLabelElem.setAttribute( QStringLiteral( "htmlState" ), static_cast< int >( mMode ) );
375 
376  layoutLabelElem.setAttribute( QStringLiteral( "labelText" ), mText );
377  layoutLabelElem.setAttribute( QStringLiteral( "marginX" ), QString::number( mMarginX ) );
378  layoutLabelElem.setAttribute( QStringLiteral( "marginY" ), QString::number( mMarginY ) );
379  layoutLabelElem.setAttribute( QStringLiteral( "halign" ), mHAlignment );
380  layoutLabelElem.setAttribute( QStringLiteral( "valign" ), mVAlignment );
381 
382  //font
383  const QDomElement labelFontElem = QgsFontUtils::toXmlElement( mFont, doc, QStringLiteral( "LabelFont" ) );
384  layoutLabelElem.appendChild( labelFontElem );
385 
386  //font color
387  QDomElement fontColorElem = doc.createElement( QStringLiteral( "FontColor" ) );
388  fontColorElem.setAttribute( QStringLiteral( "red" ), mFontColor.red() );
389  fontColorElem.setAttribute( QStringLiteral( "green" ), mFontColor.green() );
390  fontColorElem.setAttribute( QStringLiteral( "blue" ), mFontColor.blue() );
391  fontColorElem.setAttribute( QStringLiteral( "alpha" ), mFontColor.alpha() );
392  layoutLabelElem.appendChild( fontColorElem );
393 
394  return true;
395 }
396 
397 bool QgsLayoutItemLabel::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext & )
398 {
399  //restore label specific properties
400 
401  //text
402  mText = itemElem.attribute( QStringLiteral( "labelText" ) );
403 
404  //html state
405  mMode = static_cast< Mode >( itemElem.attribute( QStringLiteral( "htmlState" ) ).toInt() );
406 
407  //margin
408  bool marginXOk = false;
409  bool marginYOk = false;
410  mMarginX = itemElem.attribute( QStringLiteral( "marginX" ) ).toDouble( &marginXOk );
411  mMarginY = itemElem.attribute( QStringLiteral( "marginY" ) ).toDouble( &marginYOk );
412  if ( !marginXOk || !marginYOk )
413  {
414  //upgrade old projects where margins where stored in a single attribute
415  const double margin = itemElem.attribute( QStringLiteral( "margin" ), QStringLiteral( "1.0" ) ).toDouble();
416  mMarginX = margin;
417  mMarginY = margin;
418  }
419 
420  //Horizontal alignment
421  mHAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "halign" ) ).toInt() );
422 
423  //Vertical alignment
424  mVAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "valign" ) ).toInt() );
425 
426  //font
427  QgsFontUtils::setFromXmlChildNode( mFont, itemElem, QStringLiteral( "LabelFont" ) );
428 
429  //font color
430  const QDomNodeList fontColorList = itemElem.elementsByTagName( QStringLiteral( "FontColor" ) );
431  if ( !fontColorList.isEmpty() )
432  {
433  const QDomElement fontColorElem = fontColorList.at( 0 ).toElement();
434  const int red = fontColorElem.attribute( QStringLiteral( "red" ), QStringLiteral( "0" ) ).toInt();
435  const int green = fontColorElem.attribute( QStringLiteral( "green" ), QStringLiteral( "0" ) ).toInt();
436  const int blue = fontColorElem.attribute( QStringLiteral( "blue" ), QStringLiteral( "0" ) ).toInt();
437  const int alpha = fontColorElem.attribute( QStringLiteral( "alpha" ), QStringLiteral( "255" ) ).toInt();
438  mFontColor = QColor( red, green, blue, alpha );
439  }
440  else
441  {
442  mFontColor = QColor( 0, 0, 0 );
443  }
444 
445  return true;
446 }
447 
449 {
450  if ( !id().isEmpty() )
451  {
452  return id();
453  }
454 
455  switch ( mMode )
456  {
457  case ModeHtml:
458  return tr( "<HTML Label>" );
459 
460  case ModeFont:
461  {
462 
463  //if no id, default to portion of label text
464  const QString text = mText;
465  if ( text.isEmpty() )
466  {
467  return tr( "<Label>" );
468  }
469  if ( text.length() > 25 )
470  {
471  return QString( tr( "%1…" ) ).arg( text.left( 25 ).simplified() );
472  }
473  else
474  {
475  return text.simplified();
476  }
477  }
478  }
479  return QString(); // no warnings
480 }
481 
483 {
484  QRectF rectangle = rect();
485  const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
486  rectangle.adjust( -penWidth, -penWidth, penWidth, penWidth );
487 
488  if ( mMarginX < 0 )
489  {
490  rectangle.adjust( mMarginX, 0, -mMarginX, 0 );
491  }
492  if ( mMarginY < 0 )
493  {
494  rectangle.adjust( 0, mMarginY, 0, -mMarginY );
495  }
496 
497  return rectangle;
498 }
499 
500 void QgsLayoutItemLabel::setFrameEnabled( const bool drawFrame )
501 {
503  prepareGeometryChange();
504 }
505 
507 {
508  QgsLayoutItem::setFrameStrokeWidth( strokeWidth );
509  prepareGeometryChange();
510 }
511 
513 {
514  invalidateCache();
516  refreshExpressionContext();
517 }
518 
520 {
521  const QString evaluated = currentText();
522  if ( evaluated == mText )
523  return; // no changes
524 
525  setText( evaluated );
526 }
527 
528 void QgsLayoutItemLabel::itemShiftAdjustSize( double newWidth, double newHeight, double &xShift, double &yShift ) const
529 {
530  //keep alignment point constant
531  const double currentWidth = rect().width();
532  const double currentHeight = rect().height();
533  xShift = 0;
534  yShift = 0;
535 
536  const double r = rotation();
537  if ( r >= 0 && r < 90 )
538  {
539  if ( mHAlignment == Qt::AlignHCenter )
540  {
541  xShift = - ( newWidth - currentWidth ) / 2.0;
542  }
543  else if ( mHAlignment == Qt::AlignRight )
544  {
545  xShift = - ( newWidth - currentWidth );
546  }
547  if ( mVAlignment == Qt::AlignVCenter )
548  {
549  yShift = -( newHeight - currentHeight ) / 2.0;
550  }
551  else if ( mVAlignment == Qt::AlignBottom )
552  {
553  yShift = - ( newHeight - currentHeight );
554  }
555  }
556  if ( r >= 90 && r < 180 )
557  {
558  if ( mHAlignment == Qt::AlignHCenter )
559  {
560  yShift = -( newHeight - currentHeight ) / 2.0;
561  }
562  else if ( mHAlignment == Qt::AlignRight )
563  {
564  yShift = -( newHeight - currentHeight );
565  }
566  if ( mVAlignment == Qt::AlignTop )
567  {
568  xShift = -( newWidth - currentWidth );
569  }
570  else if ( mVAlignment == Qt::AlignVCenter )
571  {
572  xShift = -( newWidth - currentWidth / 2.0 );
573  }
574  }
575  else if ( r >= 180 && r < 270 )
576  {
577  if ( mHAlignment == Qt::AlignHCenter )
578  {
579  xShift = -( newWidth - currentWidth ) / 2.0;
580  }
581  else if ( mHAlignment == Qt::AlignLeft )
582  {
583  xShift = -( newWidth - currentWidth );
584  }
585  if ( mVAlignment == Qt::AlignVCenter )
586  {
587  yShift = ( newHeight - currentHeight ) / 2.0;
588  }
589  else if ( mVAlignment == Qt::AlignTop )
590  {
591  yShift = ( newHeight - currentHeight );
592  }
593  }
594  else if ( r >= 270 && r < 360 )
595  {
596  if ( mHAlignment == Qt::AlignHCenter )
597  {
598  yShift = -( newHeight - currentHeight ) / 2.0;
599  }
600  else if ( mHAlignment == Qt::AlignLeft )
601  {
602  yShift = -( newHeight - currentHeight );
603  }
604  if ( mVAlignment == Qt::AlignBottom )
605  {
606  xShift = -( newWidth - currentWidth );
607  }
608  else if ( mVAlignment == Qt::AlignVCenter )
609  {
610  xShift = -( newWidth - currentWidth / 2.0 );
611  }
612  }
613 }
614 
615 QUrl QgsLayoutItemLabel::createStylesheetUrl() const
616 {
617  QString stylesheet;
618  stylesheet += QStringLiteral( "body { margin: %1 %2;" ).arg( std::max( mMarginY * mHtmlUnitsToLayoutUnits, 0.0 ) ).arg( std::max( mMarginX * mHtmlUnitsToLayoutUnits, 0.0 ) );
619  stylesheet += QgsFontUtils::asCSS( mFont, 0.352778 * mHtmlUnitsToLayoutUnits );
620  stylesheet += QStringLiteral( "color: rgba(%1,%2,%3,%4);" ).arg( mFontColor.red() ).arg( mFontColor.green() ).arg( mFontColor.blue() ).arg( QString::number( mFontColor.alphaF(), 'f', 4 ) );
621  stylesheet += QStringLiteral( "text-align: %1; }" ).arg( mHAlignment == Qt::AlignLeft ? QStringLiteral( "left" ) : mHAlignment == Qt::AlignRight ? QStringLiteral( "right" ) : mHAlignment == Qt::AlignHCenter ? QStringLiteral( "center" ) : QStringLiteral( "justify" ) );
622 
623  QByteArray ba;
624  ba.append( stylesheet.toUtf8() );
625  QUrl cssFileURL = QUrl( QString( "data:text/css;charset=utf-8;base64," + ba.toBase64() ) );
626 
627  return cssFileURL;
628 }
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
static QString asCSS(const QFont &font, double pointToPixelMultiplier=1.0)
Returns a CSS string representing the specified font as closely as possible.
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.
static QDomElement toXmlElement(const QFont &font, QDomDocument &document, const QString &elementName)
Returns a DOM element containing the properties of the font.
A layout item subclass for text labels.
Mode mode() const
Returns the label's current mode.
void setMarginX(double margin)
Sets the horizontal margin between the edge of the frame and the label contents, in layout units.
void setFrameEnabled(bool drawFrame) override
Sets whether this item has a frame drawn around it or not.
QRectF boundingRect() const override
QSizeF sizeForText() const
Returns the required item size (in layout units) for the label's text to fill the item.
void setMargin(double margin)
Sets the margin between the edge of the frame and the label contents.
int type() const override
static QgsLayoutItemLabel * create(QgsLayout *layout)
Returns a new label item for the specified layout.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
QFont font() const
Returns the label's current font.
QgsLayoutItemLabel(QgsLayout *layout)
Constructor for QgsLayoutItemLabel, with the specified parent layout.
void setText(const QString &text)
Sets the label's preset text.
void setFrameStrokeWidth(QgsLayoutMeasurement strokeWidth) override
Sets the frame stroke width.
void setMarginY(double margin)
Sets the vertical margin between the edge of the frame and the label contents, in layout units.
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
void setFont(const QFont &font)
Sets the label's current font.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
void setMode(Mode mode)
Sets the label's current mode, allowing the label to switch between font based and HTML based renderi...
QString displayName() const override
Gets item display name.
QString text() const
Returns the label's preset text.
void convertToStaticText()
Converts the label's text() to a static string, by evaluating any expressions included in the text an...
QString currentText() const
Returns the text as it appears on the label (with evaluated expressions and other dynamic content).
QIcon icon() const override
Returns the item's icon.
void adjustSizeToText()
Resizes the item so that the label's text fits to the item.
@ ModeHtml
Label displays rendered HTML content.
@ ModeFont
Label displays text rendered using a single font.
Layout graphical items for displaying a map.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
Contains settings and helpers relating to a render of a QgsLayoutItem.
Definition: qgslayoutitem.h:45
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Definition: qgslayoutitem.h:72
Base class for graphical items within a QgsLayout.
virtual void drawFrame(QgsRenderContext &context)
Draws the frame around the item.
virtual void setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual void setFrameEnabled(bool drawFrame)
Sets whether this item has a frame drawn around it or not.
virtual void invalidateCache()
Forces a deferred update of any cached image the item uses.
QString id() const
Returns the item's ID name.
bool frameEnabled() const
Returns true if the item includes a frame.
void refresh() override
Refreshes the item, causing a recalculation of any property overrides and recalculation of its positi...
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.
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
QPointer< QgsLayout > mLayout
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
Definition: qgslayoutsize.h:41
static double fontHeightMM(const QFont &font)
Calculate a font height in millimeters, including workarounds for QT font rendering issues.
static void drawText(QPainter *painter, QPointF position, const QString &text, const QFont &font, const QColor &color=QColor())
Draws text on a painter at a specific position, taking care of layout specific issues (calculation to...
static double textWidthMM(const QFont &font, const QString &text)
Calculate a font width in millimeters for a text string, including workarounds for QT font rendering ...
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:51
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
The class is used as a container of context for various read/write operations on other objects.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
QPainter * painter()
Returns the destination QPainter for the render operation.
Scoped object for saving and restoring a QPainter object's state.
@ LayoutMillimeters
Millimeters.
Definition: qgsunittypes.h:183
Represents a vector layer which manages a vector based data sets.
QWebPage subclass which redirects JavaScript errors and console output to the QGIS message log.
Definition: qgswebpage.h:218