QGIS API Documentation  3.24.2-Tisler (13c1a02865)
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 "qgstextformat.h"
30 #include "qgstextrenderer.h"
31 #include "qgsexpressioncontext.h"
32 #include "qgsmapsettings.h"
33 #include "qgslayoutitemmap.h"
34 #include "qgssettings.h"
35 
36 #include "qgswebview.h"
37 #include "qgswebframe.h"
38 #include "qgswebpage.h"
39 
40 #include <QCoreApplication>
41 #include <QDate>
42 #include <QDomElement>
43 #include <QPainter>
44 #include <QTimer>
45 #include <QEventLoop>
46 #include <QThread>
47 
49  : QgsLayoutItem( layout )
50 {
51  mDistanceArea.reset( new QgsDistanceArea() );
52  mHtmlUnitsToLayoutUnits = htmlUnitsToLayoutUnits();
53 
54  //get default layout font from settings
55  const QgsSettings settings;
56  const QString defaultFontString = settings.value( QStringLiteral( "LayoutDesigner/defaultFont" ), QVariant(), QgsSettings::Gui ).toString();
57  if ( !defaultFontString.isEmpty() )
58  {
59  QFont f = mFormat.font();
60  f.setFamily( defaultFontString );
61  mFormat.setFont( f );
62  }
63 
64  //default to a 10 point font size
65  mFormat.setSize( 10 );
67 
68  //default to no background
69  setBackgroundEnabled( false );
70 
71  //a label added while atlas preview is enabled needs to have the expression context set,
72  //otherwise fields in the label aren't correctly evaluated until atlas preview feature changes (#9457)
73  refreshExpressionContext();
74 
75  // only possible on the main thread!
76  if ( QThread::currentThread() == QApplication::instance()->thread() )
77  {
78  mWebPage.reset( new QgsWebPage( this ) );
79  }
80  else
81  {
82  QgsMessageLog::logMessage( QObject::tr( "Cannot load HTML based item label in background threads" ) );
83  }
84  if ( mWebPage )
85  {
86  mWebPage->setIdentifier( tr( "Layout label item" ) );
87  mWebPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
88 
89  //This makes the background transparent. Found on http://blog.qt.digia.com/blog/2009/06/30/transparent-qwebview-or-qwebpage/
90  QPalette palette = mWebPage->palette();
91  palette.setBrush( QPalette::Base, Qt::transparent );
92  mWebPage->setPalette( palette );
93 
94  mWebPage->mainFrame()->setZoomFactor( 10.0 );
95  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
96  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
97 
98  connect( mWebPage.get(), &QWebPage::loadFinished, this, &QgsLayoutItemLabel::loadingHtmlFinished );
99  }
100 }
101 
103 {
104  return new QgsLayoutItemLabel( layout );
105 }
106 
108 {
110 }
111 
113 {
114  return QgsApplication::getThemeIcon( QStringLiteral( "/mLayoutItemLabel.svg" ) );
115 }
116 
118 {
119  QPainter *painter = context.renderContext().painter();
120  const QgsScopedQPainterState painterState( painter );
121 
122  double rectScale = 1.0;
123  if ( mMode == QgsLayoutItemLabel::ModeFont )
124  {
125  rectScale = context.renderContext().scaleFactor();
126  }
127  else
128  {
129  // painter is scaled to dots, so scale back to layout units
130  painter->scale( context.renderContext().scaleFactor(), context.renderContext().scaleFactor() );
131  }
132 
133  const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
134  const double xPenAdjust = mMarginX < 0 ? -penWidth : penWidth;
135  const double yPenAdjust = mMarginY < 0 ? -penWidth : penWidth;
136  const QRectF painterRect( ( xPenAdjust + mMarginX ) * rectScale,
137  ( yPenAdjust + mMarginY ) * rectScale,
138  ( rect().width() - 2 * xPenAdjust - 2 * mMarginX ) * rectScale,
139  ( rect().height() - 2 * yPenAdjust - 2 * mMarginY ) * rectScale );
140 
141  switch ( mMode )
142  {
143  case ModeHtml:
144  {
145  if ( mFirstRender )
146  {
147  contentChanged();
148  mFirstRender = false;
149  }
150 
151  if ( mWebPage )
152  {
153  painter->scale( 1.0 / mHtmlUnitsToLayoutUnits / 10.0, 1.0 / mHtmlUnitsToLayoutUnits / 10.0 );
154  mWebPage->setViewportSize( QSize( painterRect.width() * mHtmlUnitsToLayoutUnits * 10.0, painterRect.height() * mHtmlUnitsToLayoutUnits * 10.0 ) );
155  mWebPage->settings()->setUserStyleSheetUrl( createStylesheetUrl() );
156  mWebPage->mainFrame()->render( painter );
157  }
158  break;
159  }
160 
161  case ModeFont:
162  {
164  QgsTextRenderer::drawText( painterRect, 0,
166  currentText().split( '\n' ),
167  context.renderContext(),
168  mFormat,
169  true,
172  break;
173  }
174  }
175 }
176 
177 void QgsLayoutItemLabel::contentChanged()
178 {
179  switch ( mMode )
180  {
181  case ModeHtml:
182  {
183  const QString textToDraw = currentText();
184  if ( !mWebPage )
185  {
186  mHtmlLoaded = true;
187  return;
188  }
189 
190  //mHtmlLoaded tracks whether the QWebPage has completed loading
191  //its html contents, set it initially to false. The loadingHtmlFinished slot will
192  //set this to true after html is loaded.
193  mHtmlLoaded = false;
194 
195  const QUrl baseUrl = QUrl::fromLocalFile( mLayout->project()->absoluteFilePath() );
196  mWebPage->mainFrame()->setHtml( textToDraw, baseUrl );
197 
198  //For very basic html labels with no external assets, the html load will already be
199  //complete before we even get a chance to start the QEventLoop. Make sure we check
200  //this before starting the loop
201 
202  // important -- we CAN'T do this when it's a render inside the designer, otherwise the
203  // event loop will mess with the paint event and cause it to be deleted, and BOOM!
204  if ( !mHtmlLoaded && ( !mLayout || !mLayout->renderContext().isPreviewRender() ) )
205  {
206  //Setup event loop and timeout for rendering html
207  QEventLoop loop;
208 
209  //Connect timeout and webpage loadFinished signals to loop
210  connect( mWebPage.get(), &QWebPage::loadFinished, &loop, &QEventLoop::quit );
211 
212  // Start a 20 second timeout in case html loading will never complete
213  QTimer timeoutTimer;
214  timeoutTimer.setSingleShot( true );
215  connect( &timeoutTimer, &QTimer::timeout, &loop, &QEventLoop::quit );
216  timeoutTimer.start( 20000 );
217 
218  // Pause until html is loaded
219  loop.exec( QEventLoop::ExcludeUserInputEvents );
220  }
221  break;
222  }
223  case ModeFont:
224  invalidateCache();
225  break;
226  }
227 }
228 
229 void QgsLayoutItemLabel::loadingHtmlFinished( bool result )
230 {
231  Q_UNUSED( result )
232  mHtmlLoaded = true;
233  invalidateCache();
234  update();
235 }
236 
237 double QgsLayoutItemLabel::htmlUnitsToLayoutUnits()
238 {
239  if ( !mLayout )
240  {
241  return 1.0;
242  }
243 
244  //TODO : fix this more precisely so that the label's default text size is the same with or without "display as html"
245  return mLayout->convertToLayoutUnits( QgsLayoutMeasurement( mLayout->renderContext().dpi() / 72.0, QgsUnitTypes::LayoutMillimeters ) ); //webkit seems to assume a standard dpi of 72
246 }
247 
248 void QgsLayoutItemLabel::setText( const QString &text )
249 {
250  mText = text;
251  emit changed();
252 
253  contentChanged();
254 
255  if ( mLayout && id().isEmpty() && mMode != ModeHtml )
256  {
257  //notify the model that the display name has changed
258  mLayout->itemsModel()->updateItemDisplayName( this );
259  }
260 }
261 
263 {
264  if ( mode == mMode )
265  {
266  return;
267  }
268 
269  mMode = mode;
270  contentChanged();
271 
272  if ( mLayout && id().isEmpty() )
273  {
274  //notify the model that the display name has changed
275  mLayout->itemsModel()->updateItemDisplayName( this );
276  }
277 }
278 
279 void QgsLayoutItemLabel::refreshExpressionContext()
280 {
281  if ( !mLayout )
282  return;
283 
284  QgsVectorLayer *layer = mLayout->reportContext().layer();
285  //setup distance area conversion
286  if ( layer )
287  {
288  mDistanceArea->setSourceCrs( layer->crs(), mLayout->project()->transformContext() );
289  }
290  else
291  {
292  //set to composition's reference map's crs
293  QgsLayoutItemMap *referenceMap = mLayout->referenceMap();
294  if ( referenceMap )
295  mDistanceArea->setSourceCrs( referenceMap->crs(), mLayout->project()->transformContext() );
296  }
297  mDistanceArea->setEllipsoid( mLayout->project()->ellipsoid() );
298  contentChanged();
299 
300  update();
301 }
302 
304 {
305  QString displayText = mText;
306  replaceDateText( displayText );
307 
309 
310  return QgsExpression::replaceExpressionText( displayText, &context, mDistanceArea.get() );
311 }
312 
313 void QgsLayoutItemLabel::replaceDateText( QString &text ) const
314 {
315  const QString constant = QStringLiteral( "$CURRENT_DATE" );
316  const int currentDatePos = text.indexOf( constant );
317  if ( currentDatePos != -1 )
318  {
319  //check if there is a bracket just after $CURRENT_DATE
320  QString formatText;
321  const int openingBracketPos = text.indexOf( '(', currentDatePos );
322  const int closingBracketPos = text.indexOf( ')', openingBracketPos + 1 );
323  if ( openingBracketPos != -1 &&
324  closingBracketPos != -1 &&
325  ( closingBracketPos - openingBracketPos ) > 1 &&
326  openingBracketPos == currentDatePos + constant.size() )
327  {
328  formatText = text.mid( openingBracketPos + 1, closingBracketPos - openingBracketPos - 1 );
329  text.replace( currentDatePos, closingBracketPos - currentDatePos + 1, QDate::currentDate().toString( formatText ) );
330  }
331  else //no bracket
332  {
333  text.replace( QLatin1String( "$CURRENT_DATE" ), QDate::currentDate().toString() );
334  }
335  }
336 }
337 
338 void QgsLayoutItemLabel::setFont( const QFont &f )
339 {
340  mFormat.setFont( f );
341  if ( f.pointSizeF() > 0 )
342  mFormat.setSize( f.pointSizeF() );
343 }
344 
346 {
347  return mFormat;
348 }
349 
351 {
352  mFormat = format;
353 }
354 
355 void QgsLayoutItemLabel::setMargin( const double m )
356 {
357  mMarginX = m;
358  mMarginY = m;
359  prepareGeometryChange();
360 }
361 
362 void QgsLayoutItemLabel::setMarginX( const double margin )
363 {
364  mMarginX = margin;
365  prepareGeometryChange();
366 }
367 
368 void QgsLayoutItemLabel::setMarginY( const double margin )
369 {
370  mMarginY = margin;
371  prepareGeometryChange();
372 }
373 
375 {
376  const QSizeF newSize = sizeForText();
377 
378  //keep alignment point constant
379  double xShift = 0;
380  double yShift = 0;
381 
382  itemShiftAdjustSize( newSize.width(), newSize.height(), xShift, yShift );
383 
384  //update rect for data defined size and position
385  attemptSetSceneRect( QRectF( pos().x() + xShift, pos().y() + yShift, newSize.width(), newSize.height() ) );
386 }
387 
389 {
391 
392  const QStringList lines = currentText().split( '\n' );
393  const double textWidth = QgsTextRenderer::textWidth( context, mFormat, lines ) / context.convertToPainterUnits( 1, QgsUnitTypes::RenderMillimeters );
394  const double fontHeight = QgsTextRenderer::textHeight( context, mFormat, lines ) / context.convertToPainterUnits( 1, QgsUnitTypes::RenderMillimeters );
395 
396  const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
397 
398  const double width = textWidth + 2 * mMarginX + 2 * penWidth;
399  const double height = fontHeight + 2 * mMarginY + 2 * penWidth;
400 
401  return mLayout->convertToLayoutUnits( QgsLayoutSize( width, height, QgsUnitTypes::LayoutMillimeters ) );
402 }
403 
405 {
406  return mFormat.font();
407 }
408 
409 bool QgsLayoutItemLabel::writePropertiesToElement( QDomElement &layoutLabelElem, QDomDocument &doc, const QgsReadWriteContext &rwContext ) const
410 {
411  layoutLabelElem.setAttribute( QStringLiteral( "htmlState" ), static_cast< int >( mMode ) );
412 
413  layoutLabelElem.setAttribute( QStringLiteral( "labelText" ), mText );
414  layoutLabelElem.setAttribute( QStringLiteral( "marginX" ), QString::number( mMarginX ) );
415  layoutLabelElem.setAttribute( QStringLiteral( "marginY" ), QString::number( mMarginY ) );
416  layoutLabelElem.setAttribute( QStringLiteral( "halign" ), mHAlignment );
417  layoutLabelElem.setAttribute( QStringLiteral( "valign" ), mVAlignment );
418 
419  QDomElement textElem = mFormat.writeXml( doc, rwContext );
420  layoutLabelElem.appendChild( textElem );
421 
422  return true;
423 }
424 
425 bool QgsLayoutItemLabel::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext &context )
426 {
427  //restore label specific properties
428 
429  //text
430  mText = itemElem.attribute( QStringLiteral( "labelText" ) );
431 
432  //html state
433  mMode = static_cast< Mode >( itemElem.attribute( QStringLiteral( "htmlState" ) ).toInt() );
434 
435  //margin
436  bool marginXOk = false;
437  bool marginYOk = false;
438  mMarginX = itemElem.attribute( QStringLiteral( "marginX" ) ).toDouble( &marginXOk );
439  mMarginY = itemElem.attribute( QStringLiteral( "marginY" ) ).toDouble( &marginYOk );
440  if ( !marginXOk || !marginYOk )
441  {
442  //upgrade old projects where margins where stored in a single attribute
443  const double margin = itemElem.attribute( QStringLiteral( "margin" ), QStringLiteral( "1.0" ) ).toDouble();
444  mMarginX = margin;
445  mMarginY = margin;
446  }
447 
448  //Horizontal alignment
449  mHAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "halign" ) ).toInt() );
450 
451  //Vertical alignment
452  mVAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "valign" ) ).toInt() );
453 
454  //font
455  QDomNodeList textFormatNodeList = itemElem.elementsByTagName( QStringLiteral( "text-style" ) );
456  if ( !textFormatNodeList.isEmpty() )
457  {
458  QDomElement textFormatElem = textFormatNodeList.at( 0 ).toElement();
459  mFormat.readXml( textFormatElem, context );
460  }
461  else
462  {
463  QFont f;
464  if ( !QgsFontUtils::setFromXmlChildNode( f, itemElem, QStringLiteral( "LabelFont" ) ) )
465  {
466  f.fromString( itemElem.attribute( QStringLiteral( "font" ), QString() ) );
467  }
468  mFormat.setFont( f );
469  if ( f.pointSizeF() > 0 )
470  {
471  mFormat.setSize( f.pointSizeF() );
473  }
474  else if ( f.pixelSize() > 0 )
475  {
476  mFormat.setSize( f.pixelSize() );
478  }
479 
480  //font color
481  const QDomNodeList fontColorList = itemElem.elementsByTagName( QStringLiteral( "FontColor" ) );
482  if ( !fontColorList.isEmpty() )
483  {
484  const QDomElement fontColorElem = fontColorList.at( 0 ).toElement();
485  const int red = fontColorElem.attribute( QStringLiteral( "red" ), QStringLiteral( "0" ) ).toInt();
486  const int green = fontColorElem.attribute( QStringLiteral( "green" ), QStringLiteral( "0" ) ).toInt();
487  const int blue = fontColorElem.attribute( QStringLiteral( "blue" ), QStringLiteral( "0" ) ).toInt();
488  const int alpha = fontColorElem.attribute( QStringLiteral( "alpha" ), QStringLiteral( "255" ) ).toInt();
489  mFormat.setColor( QColor( red, green, blue, alpha ) );
490  }
491  else if ( textFormatNodeList.isEmpty() )
492  {
493  mFormat.setColor( QColor( 0, 0, 0 ) );
494  }
495  }
496 
497  return true;
498 }
499 
501 {
502  if ( !id().isEmpty() )
503  {
504  return id();
505  }
506 
507  switch ( mMode )
508  {
509  case ModeHtml:
510  return tr( "<HTML Label>" );
511 
512  case ModeFont:
513  {
514 
515  //if no id, default to portion of label text
516  const QString text = mText;
517  if ( text.isEmpty() )
518  {
519  return tr( "<Label>" );
520  }
521  if ( text.length() > 25 )
522  {
523  return QString( tr( "%1…" ) ).arg( text.left( 25 ).simplified() );
524  }
525  else
526  {
527  return text.simplified();
528  }
529  }
530  }
531  return QString(); // no warnings
532 }
533 
535 {
536  QRectF rectangle = rect();
537  const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
538  rectangle.adjust( -penWidth, -penWidth, penWidth, penWidth );
539 
540  if ( mMarginX < 0 )
541  {
542  rectangle.adjust( mMarginX, 0, -mMarginX, 0 );
543  }
544  if ( mMarginY < 0 )
545  {
546  rectangle.adjust( 0, mMarginY, 0, -mMarginY );
547  }
548 
549  return rectangle;
550 }
551 
552 void QgsLayoutItemLabel::setFrameEnabled( const bool drawFrame )
553 {
555  prepareGeometryChange();
556 }
557 
559 {
560  QgsLayoutItem::setFrameStrokeWidth( strokeWidth );
561  prepareGeometryChange();
562 }
563 
565 {
566  invalidateCache();
568  refreshExpressionContext();
569 }
570 
572 {
573  const QString evaluated = currentText();
574  if ( evaluated == mText )
575  return; // no changes
576 
577  setText( evaluated );
578 }
579 
580 void QgsLayoutItemLabel::itemShiftAdjustSize( double newWidth, double newHeight, double &xShift, double &yShift ) const
581 {
582  //keep alignment point constant
583  const double currentWidth = rect().width();
584  const double currentHeight = rect().height();
585  xShift = 0;
586  yShift = 0;
587 
588  const double r = rotation();
589  if ( r >= 0 && r < 90 )
590  {
591  if ( mHAlignment == Qt::AlignHCenter )
592  {
593  xShift = - ( newWidth - currentWidth ) / 2.0;
594  }
595  else if ( mHAlignment == Qt::AlignRight )
596  {
597  xShift = - ( newWidth - currentWidth );
598  }
599  if ( mVAlignment == Qt::AlignVCenter )
600  {
601  yShift = -( newHeight - currentHeight ) / 2.0;
602  }
603  else if ( mVAlignment == Qt::AlignBottom )
604  {
605  yShift = - ( newHeight - currentHeight );
606  }
607  }
608  if ( r >= 90 && r < 180 )
609  {
610  if ( mHAlignment == Qt::AlignHCenter )
611  {
612  yShift = -( newHeight - currentHeight ) / 2.0;
613  }
614  else if ( mHAlignment == Qt::AlignRight )
615  {
616  yShift = -( newHeight - currentHeight );
617  }
618  if ( mVAlignment == Qt::AlignTop )
619  {
620  xShift = -( newWidth - currentWidth );
621  }
622  else if ( mVAlignment == Qt::AlignVCenter )
623  {
624  xShift = -( newWidth - currentWidth / 2.0 );
625  }
626  }
627  else if ( r >= 180 && r < 270 )
628  {
629  if ( mHAlignment == Qt::AlignHCenter )
630  {
631  xShift = -( newWidth - currentWidth ) / 2.0;
632  }
633  else if ( mHAlignment == Qt::AlignLeft )
634  {
635  xShift = -( newWidth - currentWidth );
636  }
637  if ( mVAlignment == Qt::AlignVCenter )
638  {
639  yShift = ( newHeight - currentHeight ) / 2.0;
640  }
641  else if ( mVAlignment == Qt::AlignTop )
642  {
643  yShift = ( newHeight - currentHeight );
644  }
645  }
646  else if ( r >= 270 && r < 360 )
647  {
648  if ( mHAlignment == Qt::AlignHCenter )
649  {
650  yShift = -( newHeight - currentHeight ) / 2.0;
651  }
652  else if ( mHAlignment == Qt::AlignLeft )
653  {
654  yShift = -( newHeight - currentHeight );
655  }
656  if ( mVAlignment == Qt::AlignBottom )
657  {
658  xShift = -( newWidth - currentWidth );
659  }
660  else if ( mVAlignment == Qt::AlignVCenter )
661  {
662  xShift = -( newWidth - currentWidth / 2.0 );
663  }
664  }
665 }
666 
667 QUrl QgsLayoutItemLabel::createStylesheetUrl() const
668 {
669  QString stylesheet;
670  stylesheet += QStringLiteral( "body { margin: %1 %2;" ).arg( std::max( mMarginY * mHtmlUnitsToLayoutUnits, 0.0 ) ).arg( std::max( mMarginX * mHtmlUnitsToLayoutUnits, 0.0 ) );
671  QFont f = mFormat.font();
672  switch ( mFormat.sizeUnit() )
673  {
675  f.setPointSizeF( mFormat.size() / 0.352778 );
676  break;
678  f.setPixelSize( mFormat.size() );
679  break;
681  f.setPointSizeF( mFormat.size() );
682  break;
684  f.setPointSizeF( mFormat.size() * 72 );
685  break;
690  break;
691  }
692 
693  stylesheet += QgsFontUtils::asCSS( f, 0.352778 * mHtmlUnitsToLayoutUnits );
694  stylesheet += QStringLiteral( "color: rgba(%1,%2,%3,%4);" ).arg( mFormat.color().red() ).arg( mFormat.color().green() ).arg( mFormat.color().blue() ).arg( QString::number( mFormat.color().alphaF(), 'f', 4 ) );
695  stylesheet += QStringLiteral( "text-align: %1; }" ).arg( mHAlignment == Qt::AlignLeft ? QStringLiteral( "left" ) : mHAlignment == Qt::AlignRight ? QStringLiteral( "right" ) : mHAlignment == Qt::AlignHCenter ? QStringLiteral( "center" ) : QStringLiteral( "justify" ) );
696 
697  QByteArray ba;
698  ba.append( stylesheet.toUtf8() );
699  QUrl cssFileURL = QUrl( QString( "data:text/css;charset=utf-8;base64," + ba.toBase64() ) );
700 
701  return cssFileURL;
702 }
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
@ WrapLines
Automatically wrap long lines of text.
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.
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.
Q_DECL_DEPRECATED 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.
Q_DECL_DEPRECATED 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...
QgsTextFormat textFormat() const
Returns the text format used for drawing text in the label.
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for drawing text in the label.
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 QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
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.
Contains information about the context of a rendering operation.
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.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
Scoped object for saving and restoring a QPainter object's state.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Container for all settings relating to text rendering.
Definition: qgstextformat.h:41
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
double size() const
Returns the size for rendered text.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QColor color() const
Returns the color that text will be rendered in.
QFont font() const
Returns the font used for rendering text.
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static void drawText(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, VAlignment vAlignment=AlignTop, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags())
Draws text within a rectangle using the specified settings.
static HAlignment convertQtHAlignment(Qt::Alignment alignment)
Converts a Qt horizontal alignment flag to a QgsTextRenderer::HAlignment value.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, DrawMode mode=Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
static VAlignment convertQtVAlignment(Qt::Alignment alignment)
Converts a Qt vertical alignment flag to a QgsTextRenderer::VAlignment value.
@ LayoutMillimeters
Millimeters.
Definition: qgsunittypes.h:183
@ RenderUnknownUnit
Mixed or unknown units.
Definition: qgsunittypes.h:175
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:176
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
Definition: qgsunittypes.h:172
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:173
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:171
@ RenderInches
Inches.
Definition: qgsunittypes.h:174
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:170
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