QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
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
20#include <memory>
21
22#include "qgsdistancearea.h"
23#include "qgsexpression.h"
25#include "qgsfontutils.h"
26#include "qgslayout.h"
27#include "qgslayoutitemmap.h"
29#include "qgslayoutmodel.h"
32#include "qgslayoututils.h"
33#include "qgssettings.h"
34#include "qgstextformat.h"
35#include "qgstextrenderer.h"
36#include "qgsvectorlayer.h"
37
38#include <QCoreApplication>
39#include <QDate>
40#include <QDomElement>
41#include <QPainter>
42#include <QString>
43#include <QTextDocument>
44
45#include "moc_qgslayoutitemlabel.cpp"
46
47using namespace Qt::StringLiterals;
48
51{
52 mDistanceArea = std::make_unique<QgsDistanceArea>( );
53 mHtmlUnitsToLayoutUnits = htmlUnitsToLayoutUnits();
54
55 //get default layout font from settings
56 const QgsSettings settings;
57 const QString defaultFontString = settings.value( u"LayoutDesigner/defaultFont"_s, QVariant(), QgsSettings::Gui ).toString();
58 if ( !defaultFontString.isEmpty() )
59 {
60 QFont f = mFormat.font();
61 QgsFontUtils::setFontFamily( f, defaultFontString );
62 mFormat.setFont( f );
63 }
64
65 //default to a 10 point font size
66 mFormat.setSize( 10 );
67 mFormat.setSizeUnit( Qgis::RenderUnit::Points );
68
69 connect( this, &QgsLayoutItem::sizePositionChanged, this, [this]
70 {
71 updateBoundingRect();
72 } );
73
74 //default to no background
75 setBackgroundEnabled( false );
76
77 //a label added while atlas preview is enabled needs to have the expression context set,
78 //otherwise fields in the label aren't correctly evaluated until atlas preview feature changes (#9457)
79 refreshExpressionContext();
80}
81
86
91
93{
94 return QgsApplication::getThemeIcon( u"/mLayoutItemLabel.svg"_s );
95}
96
98{
99 QPainter *painter = context.renderContext().painter();
100 const QgsScopedQPainterState painterState( painter );
101
102 const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
103 const double xPenAdjust = mMarginX < 0 ? -penWidth : penWidth;
104 const double yPenAdjust = mMarginY < 0 ? -penWidth : penWidth;
105
106 QRectF painterRect;
107 if ( mMode == QgsLayoutItemLabel::ModeFont )
108 {
109 const double rectScale = context.renderContext().scaleFactor();
110 painterRect = QRectF( ( xPenAdjust + mMarginX ) * rectScale,
111 ( yPenAdjust + mMarginY ) * rectScale,
112 ( rect().width() - 2 * xPenAdjust - 2 * mMarginX ) * rectScale,
113 ( rect().height() - 2 * yPenAdjust - 2 * mMarginY ) * rectScale );
114 }
115 else
116 {
117 // The adjustment value was found through trial and error, the author has however no clue as to where it comes from
118#if QT_VERSION >= QT_VERSION_CHECK( 6, 7, 0 )
119 constexpr double adjustmentFactor = 4.18;
120#else
121 constexpr double adjustmentFactor = 3.77;
122#endif
123 const double rectScale = context.renderContext().scaleFactor() * adjustmentFactor;
124 // The left/right margin is handled by the stylesheet while the top/bottom margin is ignored by QTextDocument
125 painterRect = QRectF( 0, 0,
126 ( rect().width() ) * rectScale,
127 ( rect().height() - yPenAdjust - mMarginY ) * rectScale );
128 painter->translate( 0, ( yPenAdjust + mMarginY ) * context.renderContext().scaleFactor() );
129 painter->scale( context.renderContext().scaleFactor() / adjustmentFactor, context.renderContext().scaleFactor() / adjustmentFactor );
130 }
131
132 switch ( mMode )
133 {
134 case ModeHtml:
135 {
136 QTextDocument document;
137 document.setDocumentMargin( 0 );
138 document.setPageSize( QSizeF( painterRect.width() / context.renderContext().scaleFactor(), painterRect.height() / context.renderContext().scaleFactor() ) );
139 document.setDefaultStyleSheet( createStylesheet() );
140
141 document.setDefaultFont( createDefaultFont() );
142
143 QTextOption textOption = document.defaultTextOption();
144 textOption.setAlignment( mHAlignment );
145 document.setDefaultTextOption( textOption );
146
147 document.setHtml( u"<body>%1</body>"_s.arg( currentText() ) );
148 document.drawContents( painter, painterRect );
149 break;
150 }
151
152 case ModeFont:
153 {
155 QgsTextRenderer::drawText( painterRect, 0,
157 currentText().split( '\n' ),
158 context.renderContext(),
159 mFormat,
160 true,
163 break;
164 }
165 }
166}
167
168void QgsLayoutItemLabel::contentChanged()
169{
170 switch ( mMode )
171 {
172 case ModeHtml:
173 {
175 break;
176 }
177 case ModeFont:
179 break;
180 }
181}
182
183void QgsLayoutItemLabel::setText( const QString &text )
184{
185 mText = text;
186 emit changed();
187
188 contentChanged();
189
190 if ( mLayout && id().isEmpty() && mMode != ModeHtml )
191 {
192 //notify the model that the display name has changed
193 mLayout->itemsModel()->updateItemDisplayName( this );
194 }
195}
196
198{
199 if ( mode == mMode )
200 {
201 return;
202 }
203
204 mMode = mode;
205 contentChanged();
206
207 if ( mLayout && id().isEmpty() )
208 {
209 //notify the model that the display name has changed
210 mLayout->itemsModel()->updateItemDisplayName( this );
211 }
212}
213
214void QgsLayoutItemLabel::refreshExpressionContext()
215{
216 if ( !mLayout )
217 return;
218
219 QgsVectorLayer *layer = mLayout->reportContext().layer();
220 //setup distance area conversion
221 if ( layer )
222 {
223 mDistanceArea->setSourceCrs( layer->crs(), mLayout->project()->transformContext() );
224 }
225 else
226 {
227 //set to composition's reference map's crs
228 QgsLayoutItemMap *referenceMap = mLayout->referenceMap();
229 if ( referenceMap )
230 mDistanceArea->setSourceCrs( referenceMap->crs(), mLayout->project()->transformContext() );
231 }
232 mDistanceArea->setEllipsoid( mLayout->project()->ellipsoid() );
233 contentChanged();
234
235 update();
236}
237
238void QgsLayoutItemLabel::updateBoundingRect()
239{
240 QRectF rectangle = rect();
241 const double frameExtension = frameEnabled() ? pen().widthF() / 2.0 : 0.0;
242 if ( frameExtension > 0 )
243 rectangle.adjust( -frameExtension, -frameExtension, frameExtension, frameExtension );
244
245 if ( mMarginX < 0 )
246 {
247 rectangle.adjust( mMarginX, 0, -mMarginX, 0 );
248 }
249 if ( mMarginY < 0 )
250 {
251 rectangle.adjust( 0, mMarginY, 0, -mMarginY );
252 }
253
254 if ( rectangle != mCurrentRectangle )
255 {
256 prepareGeometryChange();
257 mCurrentRectangle = rectangle;
258 }
260}
261
263{
264 QString displayText = mText;
265 replaceDateText( displayText );
266
268
269 return QgsExpression::replaceExpressionText( displayText, &context, mDistanceArea.get() );
270}
271
272void QgsLayoutItemLabel::replaceDateText( QString &text ) const
273{
274 const QString constant = u"$CURRENT_DATE"_s;
275 const int currentDatePos = text.indexOf( constant );
276 if ( currentDatePos != -1 )
277 {
278 //check if there is a bracket just after $CURRENT_DATE
279 QString formatText;
280 const int openingBracketPos = text.indexOf( '(', currentDatePos );
281 const int closingBracketPos = text.indexOf( ')', openingBracketPos + 1 );
282 if ( openingBracketPos != -1 &&
283 closingBracketPos != -1 &&
284 ( closingBracketPos - openingBracketPos ) > 1 &&
285 openingBracketPos == currentDatePos + constant.size() )
286 {
287 formatText = text.mid( openingBracketPos + 1, closingBracketPos - openingBracketPos - 1 );
288 text.replace( currentDatePos, closingBracketPos - currentDatePos + 1, QDate::currentDate().toString( formatText ) );
289 }
290 else //no bracket
291 {
292 text.replace( "$CURRENT_DATE"_L1, QDate::currentDate().toString() );
293 }
294 }
295}
296
297void QgsLayoutItemLabel::setFont( const QFont &f )
298{
299 mFormat.setFont( f );
300 if ( f.pointSizeF() > 0 )
301 mFormat.setSize( f.pointSizeF() );
303}
304
306{
307 return mFormat;
308}
309
311{
312 mFormat = format;
314}
315
316void QgsLayoutItemLabel::setMargin( const double m )
317{
318 mMarginX = m;
319 mMarginY = m;
320 updateBoundingRect();
321}
322
323void QgsLayoutItemLabel::setMarginX( const double margin )
324{
325 mMarginX = margin;
326 updateBoundingRect();
327}
328
329void QgsLayoutItemLabel::setMarginY( const double margin )
330{
331 mMarginY = margin;
332 updateBoundingRect();
333}
334
336{
337 const QSizeF newSize = sizeForText();
338
339 //keep alignment point constant
340 double xShift = 0;
341 double yShift = 0;
342
343 itemShiftAdjustSize( newSize.width(), newSize.height(), xShift, yShift );
344
345 //update rect for data defined size and position
346 attemptSetSceneRect( QRectF( pos().x() + xShift, pos().y() + yShift, newSize.width(), newSize.height() ) );
347}
348
350{
351 const QSizeF newSize = sizeForText();
352 const double newWidth = newSize.width();
353 const double newHeight = newSize.height();
354 const double currentWidth = rect().width();
355 const double currentHeight = rect().height();
356
357 //keep reference point constant
358 double xShift = 0;
359 double yShift = 0;
360 switch ( referencePoint )
361 {
363 xShift = 0;
364 yShift = 0;
365 break;
367 xShift = - ( newWidth - currentWidth ) / 2.0;
368 yShift = 0;
369 break;
370
372 xShift = - ( newWidth - currentWidth );
373 yShift = 0;
374 break;
375
377 xShift = 0;
378 yShift = -( newHeight - currentHeight ) / 2.0;
379 break;
380
382 xShift = - ( newWidth - currentWidth ) / 2.0;
383 yShift = -( newHeight - currentHeight ) / 2.0;
384 break;
385
387 xShift = - ( newWidth - currentWidth );
388 yShift = -( newHeight - currentHeight ) / 2.0;
389 break;
390
392 xShift = 0;
393 yShift = - ( newHeight - currentHeight );
394 break;
395
397 xShift = - ( newWidth - currentWidth ) / 2.0;
398 yShift = - ( newHeight - currentHeight );
399 break;
400
402 xShift = - ( newWidth - currentWidth );
403 yShift = - ( newHeight - currentHeight );
404 break;
405 }
406
407 //update rect for data defined size and position
408 attemptSetSceneRect( QRectF( pos().x() + xShift, pos().y() + yShift, newSize.width(), newSize.height() ) );
409}
410
412{
415
416 const QStringList lines = currentText().split( '\n' );
417 const double textWidth = std::ceil( QgsTextRenderer::textWidth( context, mFormat, lines ) + 1 ) / context.convertToPainterUnits( 1, Qgis::RenderUnit::Millimeters );
418 const double fontHeight = std::ceil( QgsTextRenderer::textHeight( context, mFormat, lines ) + 1 ) / context.convertToPainterUnits( 1, Qgis::RenderUnit::Millimeters );
419
420 const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
421
422 const double width = textWidth + 2 * mMarginX + 2 * penWidth;
423 const double height = fontHeight + 2 * mMarginY + 2 * penWidth;
424
425 return mLayout->convertToLayoutUnits( QgsLayoutSize( width, height, Qgis::LayoutUnit::Millimeters ) );
426}
427
429{
430 return mFormat.font();
431}
432
433bool QgsLayoutItemLabel::writePropertiesToElement( QDomElement &layoutLabelElem, QDomDocument &doc, const QgsReadWriteContext &rwContext ) const
434{
435 layoutLabelElem.setAttribute( u"htmlState"_s, static_cast< int >( mMode ) );
436
437 layoutLabelElem.setAttribute( u"labelText"_s, mText );
438 layoutLabelElem.setAttribute( u"marginX"_s, QString::number( mMarginX ) );
439 layoutLabelElem.setAttribute( u"marginY"_s, QString::number( mMarginY ) );
440 layoutLabelElem.setAttribute( u"halign"_s, mHAlignment );
441 layoutLabelElem.setAttribute( u"valign"_s, mVAlignment );
442
443 QDomElement textElem = mFormat.writeXml( doc, rwContext );
444 layoutLabelElem.appendChild( textElem );
445
446 return true;
447}
448
449bool QgsLayoutItemLabel::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext &context )
450{
451 //restore label specific properties
452
453 //text
454 mText = itemElem.attribute( u"labelText"_s );
455
456 //html state
457 mMode = static_cast< Mode >( itemElem.attribute( u"htmlState"_s ).toInt() );
458
459 //margin
460 bool marginXOk = false;
461 bool marginYOk = false;
462 mMarginX = itemElem.attribute( u"marginX"_s ).toDouble( &marginXOk );
463 mMarginY = itemElem.attribute( u"marginY"_s ).toDouble( &marginYOk );
464 if ( !marginXOk || !marginYOk )
465 {
466 //upgrade old projects where margins where stored in a single attribute
467 const double margin = itemElem.attribute( u"margin"_s, u"1.0"_s ).toDouble();
468 mMarginX = margin;
469 mMarginY = margin;
470 }
471
472 //Horizontal alignment
473 mHAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( u"halign"_s ).toInt() );
474
475 //Vertical alignment
476 mVAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( u"valign"_s ).toInt() );
477
478 //font
479 QDomNodeList textFormatNodeList = itemElem.elementsByTagName( u"text-style"_s );
480 if ( !textFormatNodeList.isEmpty() )
481 {
482 QDomElement textFormatElem = textFormatNodeList.at( 0 ).toElement();
483 mFormat.readXml( textFormatElem, context );
484 }
485 else
486 {
487 QFont f;
488 if ( !QgsFontUtils::setFromXmlChildNode( f, itemElem, u"LabelFont"_s ) )
489 {
490 f.fromString( itemElem.attribute( u"font"_s, QString() ) );
491 }
492 mFormat.setFont( f );
493 if ( f.pointSizeF() > 0 )
494 {
495 mFormat.setSize( f.pointSizeF() );
496 mFormat.setSizeUnit( Qgis::RenderUnit::Points );
497 }
498 else if ( f.pixelSize() > 0 )
499 {
500 mFormat.setSize( f.pixelSize() );
501 mFormat.setSizeUnit( Qgis::RenderUnit::Pixels );
502 }
503
504 //font color
505 const QDomNodeList fontColorList = itemElem.elementsByTagName( u"FontColor"_s );
506 if ( !fontColorList.isEmpty() )
507 {
508 const QDomElement fontColorElem = fontColorList.at( 0 ).toElement();
509 const int red = fontColorElem.attribute( u"red"_s, u"0"_s ).toInt();
510 const int green = fontColorElem.attribute( u"green"_s, u"0"_s ).toInt();
511 const int blue = fontColorElem.attribute( u"blue"_s, u"0"_s ).toInt();
512 const int alpha = fontColorElem.attribute( u"alpha"_s, u"255"_s ).toInt();
513 mFormat.setColor( QColor( red, green, blue, alpha ) );
514 }
515 else if ( textFormatNodeList.isEmpty() )
516 {
517 mFormat.setColor( QColor( 0, 0, 0 ) );
518 }
519 }
520
521 updateBoundingRect();
522
523 return true;
524}
525
527{
528 if ( !id().isEmpty() )
529 {
530 return id();
531 }
532
533 switch ( mMode )
534 {
535 case ModeHtml:
536 return tr( "<HTML Label>" );
537
538 case ModeFont:
539 {
540
541 //if no id, default to portion of label text
542 const QString text = mText;
543 if ( text.isEmpty() )
544 {
545 return tr( "<Label>" );
546 }
547 if ( text.length() > 25 )
548 {
549 return QString( tr( "%1…" ) ).arg( text.left( 25 ).simplified() );
550 }
551 else
552 {
553 return text.simplified();
554 }
555 }
556 }
557 return QString(); // no warnings
558}
559
561{
562 return mCurrentRectangle;
563}
564
566{
568 updateBoundingRect();
569}
570
572{
574 updateBoundingRect();
575}
576
578{
581 refreshExpressionContext();
582}
583
585{
586 const QString evaluated = currentText();
587 if ( evaluated == mText )
588 return; // no changes
589
590 setText( evaluated );
591}
592
593void QgsLayoutItemLabel::itemShiftAdjustSize( double newWidth, double newHeight, double &xShift, double &yShift ) const
594{
595 //keep alignment point constant
596 const double currentWidth = rect().width();
597 const double currentHeight = rect().height();
598 xShift = 0;
599 yShift = 0;
600
601 const double r = rotation();
602 if ( r >= 0 && r < 90 )
603 {
604 if ( mHAlignment == Qt::AlignHCenter )
605 {
606 xShift = - ( newWidth - currentWidth ) / 2.0;
607 }
608 else if ( mHAlignment == Qt::AlignRight )
609 {
610 xShift = - ( newWidth - currentWidth );
611 }
612 if ( mVAlignment == Qt::AlignVCenter )
613 {
614 yShift = -( newHeight - currentHeight ) / 2.0;
615 }
616 else if ( mVAlignment == Qt::AlignBottom )
617 {
618 yShift = - ( newHeight - currentHeight );
619 }
620 }
621 if ( r >= 90 && r < 180 )
622 {
623 if ( mHAlignment == Qt::AlignHCenter )
624 {
625 yShift = -( newHeight - currentHeight ) / 2.0;
626 }
627 else if ( mHAlignment == Qt::AlignRight )
628 {
629 yShift = -( newHeight - currentHeight );
630 }
631 if ( mVAlignment == Qt::AlignTop )
632 {
633 xShift = -( newWidth - currentWidth );
634 }
635 else if ( mVAlignment == Qt::AlignVCenter )
636 {
637 xShift = -( newWidth - currentWidth / 2.0 );
638 }
639 }
640 else if ( r >= 180 && r < 270 )
641 {
642 if ( mHAlignment == Qt::AlignHCenter )
643 {
644 xShift = -( newWidth - currentWidth ) / 2.0;
645 }
646 else if ( mHAlignment == Qt::AlignLeft )
647 {
648 xShift = -( newWidth - currentWidth );
649 }
650 if ( mVAlignment == Qt::AlignVCenter )
651 {
652 yShift = ( newHeight - currentHeight ) / 2.0;
653 }
654 else if ( mVAlignment == Qt::AlignTop )
655 {
656 yShift = ( newHeight - currentHeight );
657 }
658 }
659 else if ( r >= 270 && r < 360 )
660 {
661 if ( mHAlignment == Qt::AlignHCenter )
662 {
663 yShift = -( newHeight - currentHeight ) / 2.0;
664 }
665 else if ( mHAlignment == Qt::AlignLeft )
666 {
667 yShift = -( newHeight - currentHeight );
668 }
669 if ( mVAlignment == Qt::AlignBottom )
670 {
671 xShift = -( newWidth - currentWidth );
672 }
673 else if ( mVAlignment == Qt::AlignVCenter )
674 {
675 xShift = -( newWidth - currentWidth / 2.0 );
676 }
677 }
678}
679
680QFont QgsLayoutItemLabel::createDefaultFont() const
681{
682 QFont f = mFormat.font();
683 switch ( mFormat.sizeUnit() )
684 {
686 f.setPointSizeF( mFormat.size() / 0.352778 );
687 break;
689 f.setPixelSize( mFormat.size() );
690 break;
692 f.setPointSizeF( mFormat.size() );
693 break;
695 f.setPointSizeF( mFormat.size() * 72 );
696 break;
701 break;
702 }
703 return f;
704}
705
706double QgsLayoutItemLabel::htmlUnitsToLayoutUnits()
707{
708 if ( !mLayout )
709 {
710 return 1.0;
711 }
712
713 //TODO : fix this more precisely so that the label's default text size is the same with or without "display as html"
714 return mLayout->convertToLayoutUnits( QgsLayoutMeasurement( mLayout->renderContext().dpi() / 72.0, Qgis::LayoutUnit::Millimeters ) ); //webkit seems to assume a standard dpi of 72
715}
716
717QString QgsLayoutItemLabel::createStylesheet() const
718{
719 QString stylesheet;
720
721 stylesheet += u"body { margin: %1 %2;"_s.arg( std::max( mMarginY * mHtmlUnitsToLayoutUnits, 0.0 ) ).arg( std::max( mMarginX * mHtmlUnitsToLayoutUnits, 0.0 ) );
722 stylesheet += mFormat.asCSS( 0.352778 * mHtmlUnitsToLayoutUnits );
723 stylesheet += u"text-align: %1; }"_s.arg( mHAlignment == Qt::AlignLeft ? u"left"_s : mHAlignment == Qt::AlignRight ? u"right"_s : mHAlignment == Qt::AlignHCenter ? u"center"_s : u"justify"_s );
724
725 return stylesheet;
726}
727
728QUrl QgsLayoutItemLabel::createStylesheetUrl() const
729{
730 QByteArray ba;
731 ba.append( createStylesheet().toUtf8() );
732 QUrl cssFileURL = QUrl( QString( "data:text/css;charset=utf-8;base64," + ba.toBase64() ) );
733
734 return cssFileURL;
735}
@ Millimeters
Millimeters.
Definition qgis.h:5276
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
Definition qgis.h:5259
@ Millimeters
Millimeters.
Definition qgis.h:5256
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5260
@ Unknown
Mixed or unknown units.
Definition qgis.h:5262
@ MapUnits
Map units.
Definition qgis.h:5257
@ Pixels
Pixels.
Definition qgis.h:5258
@ Inches
Inches.
Definition qgis.h:5261
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5263
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
Definition qgis.h:2820
@ WrapLines
Automatically wrap long lines of text.
Definition qgis.h:3467
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
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 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 void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
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.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
Contains settings and helpers relating to a render of a QgsLayoutItem.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
virtual void drawFrame(QgsRenderContext &context)
Draws the frame around the item.
friend class QgsLayout
virtual void setFrameStrokeWidth(QgsLayoutMeasurement width)
Sets the frame stroke width.
QgsLayoutItem(QgsLayout *layout, bool manageZValue=true)
Constructor for QgsLayoutItem, with the specified parent layout.
ReferencePoint referencePoint() const
Returns the reference point for positioning of the layout item.
ReferencePoint
Fixed position reference point.
@ LowerMiddle
Lower center of item.
@ MiddleLeft
Middle left of item.
@ Middle
Center of item.
@ UpperRight
Upper right corner of item.
@ LowerLeft
Lower left corner of item.
@ UpperLeft
Upper left corner of item.
@ UpperMiddle
Upper center of item.
@ MiddleRight
Middle right of item.
@ LowerRight
Lower right corner of item.
friend class QgsLayoutItemMap
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.
void sizePositionChanged()
Emitted when the item's size or position changes.
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.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
QPointer< QgsLayout > mLayout
Provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts.
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:90
A container for the context for various read/write operations on 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.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
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.
Stores settings for use within QGIS.
Definition qgssettings.h:68
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.
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 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(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
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 Qgis::TextHorizontalAlignment convertQtHAlignment(Qt::Alignment alignment)
Converts a Qt horizontal alignment flag to a Qgis::TextHorizontalAlignment value.
Represents a vector layer which manages a vector based dataset.