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