QGIS API Documentation 4.1.0-Master (467af3bbe65)
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"
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 QString defaultFontString = QgsLayout::settingsLayoutDefaultFont->value();
57 if ( !defaultFontString.isEmpty() )
58 {
59 QFont f = mFormat.font();
60 QgsFontUtils::setFontFamily( f, defaultFontString );
61 mFormat.setFont( f );
62 }
63
64 //default to a 10 point font size
65 mFormat.setSize( 10 );
66 mFormat.setSizeUnit( Qgis::RenderUnit::Points );
67
68 connect( this, &QgsLayoutItem::sizePositionChanged, this, [this] { updateBoundingRect(); } );
69
70 //default to no background
71 setBackgroundEnabled( false );
72
73 //a label added while atlas preview is enabled needs to have the expression context set,
74 //otherwise fields in the label aren't correctly evaluated until atlas preview feature changes (#9457)
75 refreshExpressionContext();
76}
77
82
87
89{
90 return QgsApplication::getThemeIcon( u"/mLayoutItemLabel.svg"_s );
91}
92
94{
95 QPainter *painter = context.renderContext().painter();
96 const QgsScopedQPainterState painterState( painter );
97
98 const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
99 const double xPenAdjust = mMarginX < 0 ? -penWidth : penWidth;
100 const double yPenAdjust = mMarginY < 0 ? -penWidth : penWidth;
101
102 QRectF painterRect;
103 if ( mMode == QgsLayoutItemLabel::ModeFont )
104 {
105 const double rectScale = context.renderContext().scaleFactor();
106 painterRect
107 = QRectF( ( xPenAdjust + mMarginX ) * rectScale, ( yPenAdjust + mMarginY ) * rectScale, ( rect().width() - 2 * xPenAdjust - 2 * mMarginX ) * rectScale, ( rect().height() - 2 * yPenAdjust - 2 * mMarginY ) * rectScale );
108 }
109 else
110 {
111 // The adjustment value was found through trial and error, the author has however no clue as to where it comes from
112#if QT_VERSION >= QT_VERSION_CHECK( 6, 7, 0 )
113 constexpr double adjustmentFactor = 4.18;
114#else
115 constexpr double adjustmentFactor = 3.77;
116#endif
117 const double rectScale = context.renderContext().scaleFactor() * adjustmentFactor;
118 // The left/right margin is handled by the stylesheet while the top/bottom margin is ignored by QTextDocument
119 painterRect = QRectF( 0, 0, ( rect().width() ) * rectScale, ( rect().height() - yPenAdjust - mMarginY ) * rectScale );
120 painter->translate( 0, ( yPenAdjust + mMarginY ) * context.renderContext().scaleFactor() );
121 painter->scale( context.renderContext().scaleFactor() / adjustmentFactor, context.renderContext().scaleFactor() / adjustmentFactor );
122 }
123
124 switch ( mMode )
125 {
126 case ModeHtml:
127 {
128 QTextDocument document;
129 document.setDocumentMargin( 0 );
130 document.setPageSize( QSizeF( painterRect.width() / context.renderContext().scaleFactor(), painterRect.height() / context.renderContext().scaleFactor() ) );
131 document.setDefaultStyleSheet( createStylesheet() );
132
133 document.setDefaultFont( createDefaultFont() );
134
135 QTextOption textOption = document.defaultTextOption();
136 textOption.setAlignment( mHAlignment );
137 document.setDefaultTextOption( textOption );
138
139 document.setHtml( u"<body>%1</body>"_s.arg( currentText() ) );
140 document.drawContents( painter, painterRect );
141 break;
142 }
143
144 case ModeFont:
145 {
148 drawText( painterRect, 0, QgsTextRenderer::convertQtHAlignment( mHAlignment ), currentText().split( '\n' ), context.renderContext(), mFormat, true, QgsTextRenderer::convertQtVAlignment( mVAlignment ), Qgis::TextRendererFlag::WrapLines );
149 break;
150 }
151 }
152}
153
154void QgsLayoutItemLabel::contentChanged()
155{
156 switch ( mMode )
157 {
158 case ModeHtml:
159 {
161 break;
162 }
163 case ModeFont:
165 break;
166 }
167}
168
169void QgsLayoutItemLabel::setText( const QString &text )
170{
171 mText = text;
172 emit changed();
173
174 contentChanged();
175
176 if ( mLayout && id().isEmpty() && mMode != ModeHtml )
177 {
178 //notify the model that the display name has changed
179 mLayout->itemsModel()->updateItemDisplayName( this );
180 }
181}
182
184{
185 if ( mode == mMode )
186 {
187 return;
188 }
189
190 mMode = mode;
191 contentChanged();
192
193 if ( mLayout && id().isEmpty() )
194 {
195 //notify the model that the display name has changed
196 mLayout->itemsModel()->updateItemDisplayName( this );
197 }
198}
199
200void QgsLayoutItemLabel::refreshExpressionContext()
201{
202 if ( !mLayout )
203 return;
204
205 QgsVectorLayer *layer = mLayout->reportContext().layer();
206 //setup distance area conversion
207 if ( layer )
208 {
209 mDistanceArea->setSourceCrs( layer->crs(), mLayout->project()->transformContext() );
210 }
211 else
212 {
213 //set to composition's reference map's crs
214 QgsLayoutItemMap *referenceMap = mLayout->referenceMap();
215 if ( referenceMap )
216 mDistanceArea->setSourceCrs( referenceMap->crs(), mLayout->project()->transformContext() );
217 }
218 mDistanceArea->setEllipsoid( mLayout->project()->ellipsoid() );
219 contentChanged();
220
221 update();
222}
223
224void QgsLayoutItemLabel::updateBoundingRect()
225{
226 QRectF rectangle = rect();
227 const double frameExtension = frameEnabled() ? pen().widthF() / 2.0 : 0.0;
228 if ( frameExtension > 0 )
229 rectangle.adjust( -frameExtension, -frameExtension, frameExtension, frameExtension );
230
231 if ( mMarginX < 0 )
232 {
233 rectangle.adjust( mMarginX, 0, -mMarginX, 0 );
234 }
235 if ( mMarginY < 0 )
236 {
237 rectangle.adjust( 0, mMarginY, 0, -mMarginY );
238 }
239
240 if ( rectangle != mCurrentRectangle )
241 {
242 prepareGeometryChange();
243 mCurrentRectangle = rectangle;
244 }
246}
247
249{
250 QString displayText = mText;
251 replaceDateText( displayText );
252
254
255 return QgsExpression::replaceExpressionText( displayText, &context, mDistanceArea.get() );
256}
257
258void QgsLayoutItemLabel::replaceDateText( QString &text ) const
259{
260 const QString constant = u"$CURRENT_DATE"_s;
261 const int currentDatePos = text.indexOf( constant );
262 if ( currentDatePos != -1 )
263 {
264 //check if there is a bracket just after $CURRENT_DATE
265 QString formatText;
266 const int openingBracketPos = text.indexOf( '(', currentDatePos );
267 const int closingBracketPos = text.indexOf( ')', openingBracketPos + 1 );
268 if ( openingBracketPos != -1 && closingBracketPos != -1 && ( closingBracketPos - openingBracketPos ) > 1 && openingBracketPos == currentDatePos + constant.size() )
269 {
270 formatText = text.mid( openingBracketPos + 1, closingBracketPos - openingBracketPos - 1 );
271 text.replace( currentDatePos, closingBracketPos - currentDatePos + 1, QDate::currentDate().toString( formatText ) );
272 }
273 else //no bracket
274 {
275 text.replace( "$CURRENT_DATE"_L1, QDate::currentDate().toString() );
276 }
277 }
278}
279
280void QgsLayoutItemLabel::setFont( const QFont &f )
281{
282 mFormat.setFont( f );
283 if ( f.pointSizeF() > 0 )
284 mFormat.setSize( f.pointSizeF() );
286}
287
289{
290 return mFormat;
291}
292
294{
295 mFormat = format;
297}
298
299void QgsLayoutItemLabel::setMargin( const double m )
300{
301 mMarginX = m;
302 mMarginY = m;
303 updateBoundingRect();
304}
305
306void QgsLayoutItemLabel::setMarginX( const double margin )
307{
308 mMarginX = margin;
309 updateBoundingRect();
310}
311
312void QgsLayoutItemLabel::setMarginY( const double margin )
313{
314 mMarginY = margin;
315 updateBoundingRect();
316}
317
319{
320 const QSizeF newSize = sizeForText();
321
322 //keep alignment point constant
323 double xShift = 0;
324 double yShift = 0;
325
326 itemShiftAdjustSize( newSize.width(), newSize.height(), xShift, yShift );
327
328 //update rect for data defined size and position
329 attemptSetSceneRect( QRectF( pos().x() + xShift, pos().y() + yShift, newSize.width(), newSize.height() ) );
330}
331
333{
334 const QSizeF newSize = sizeForText();
335 const double newWidth = newSize.width();
336 const double newHeight = newSize.height();
337 const double currentWidth = rect().width();
338 const double currentHeight = rect().height();
339
340 //keep reference point constant
341 double xShift = 0;
342 double yShift = 0;
343 switch ( referencePoint )
344 {
346 xShift = 0;
347 yShift = 0;
348 break;
350 xShift = -( newWidth - currentWidth ) / 2.0;
351 yShift = 0;
352 break;
353
355 xShift = -( newWidth - currentWidth );
356 yShift = 0;
357 break;
358
360 xShift = 0;
361 yShift = -( newHeight - currentHeight ) / 2.0;
362 break;
363
365 xShift = -( newWidth - currentWidth ) / 2.0;
366 yShift = -( newHeight - currentHeight ) / 2.0;
367 break;
368
370 xShift = -( newWidth - currentWidth );
371 yShift = -( newHeight - currentHeight ) / 2.0;
372 break;
373
375 xShift = 0;
376 yShift = -( newHeight - currentHeight );
377 break;
378
380 xShift = -( newWidth - currentWidth ) / 2.0;
381 yShift = -( newHeight - currentHeight );
382 break;
383
385 xShift = -( newWidth - currentWidth );
386 yShift = -( newHeight - currentHeight );
387 break;
388 }
389
390 //update rect for data defined size and position
391 attemptSetSceneRect( QRectF( pos().x() + xShift, pos().y() + yShift, newSize.width(), newSize.height() ) );
392}
393
395{
398
399 const QStringList lines = currentText().split( '\n' );
400 const double textWidth = std::ceil( QgsTextRenderer::textWidth( context, mFormat, lines ) + 1 ) / context.convertToPainterUnits( 1, Qgis::RenderUnit::Millimeters );
401 const double fontHeight = std::ceil( QgsTextRenderer::textHeight( context, mFormat, lines ) + 1 ) / context.convertToPainterUnits( 1, Qgis::RenderUnit::Millimeters );
402
403 const double penWidth = frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
404
405 const double width = textWidth + 2 * mMarginX + 2 * penWidth;
406 const double height = fontHeight + 2 * mMarginY + 2 * penWidth;
407
408 return mLayout->convertToLayoutUnits( QgsLayoutSize( width, height, Qgis::LayoutUnit::Millimeters ) );
409}
410
412{
413 return mFormat.font();
414}
415
416bool QgsLayoutItemLabel::writePropertiesToElement( QDomElement &layoutLabelElem, QDomDocument &doc, const QgsReadWriteContext &rwContext ) const
417{
418 layoutLabelElem.setAttribute( u"htmlState"_s, static_cast< int >( mMode ) );
419
420 layoutLabelElem.setAttribute( u"labelText"_s, mText );
421 layoutLabelElem.setAttribute( u"marginX"_s, QString::number( mMarginX ) );
422 layoutLabelElem.setAttribute( u"marginY"_s, QString::number( mMarginY ) );
423 layoutLabelElem.setAttribute( u"halign"_s, mHAlignment );
424 layoutLabelElem.setAttribute( u"valign"_s, mVAlignment );
425
426 QDomElement textElem = mFormat.writeXml( doc, rwContext );
427 layoutLabelElem.appendChild( textElem );
428
429 return true;
430}
431
432bool QgsLayoutItemLabel::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &, const QgsReadWriteContext &context )
433{
434 //restore label specific properties
435
436 //text
437 mText = itemElem.attribute( u"labelText"_s );
438
439 //html state
440 mMode = static_cast< Mode >( itemElem.attribute( u"htmlState"_s ).toInt() );
441
442 //margin
443 bool marginXOk = false;
444 bool marginYOk = false;
445 mMarginX = itemElem.attribute( u"marginX"_s ).toDouble( &marginXOk );
446 mMarginY = itemElem.attribute( u"marginY"_s ).toDouble( &marginYOk );
447 if ( !marginXOk || !marginYOk )
448 {
449 //upgrade old projects where margins where stored in a single attribute
450 const double margin = itemElem.attribute( u"margin"_s, u"1.0"_s ).toDouble();
451 mMarginX = margin;
452 mMarginY = margin;
453 }
454
455 //Horizontal alignment
456 mHAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( u"halign"_s ).toInt() );
457
458 //Vertical alignment
459 mVAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( u"valign"_s ).toInt() );
460
461 //font
462 QDomNodeList textFormatNodeList = itemElem.elementsByTagName( u"text-style"_s );
463 if ( !textFormatNodeList.isEmpty() )
464 {
465 QDomElement textFormatElem = textFormatNodeList.at( 0 ).toElement();
466 mFormat.readXml( textFormatElem, context );
467 }
468 else
469 {
470 QFont f;
471 if ( !QgsFontUtils::setFromXmlChildNode( f, itemElem, u"LabelFont"_s ) )
472 {
473 f.fromString( itemElem.attribute( u"font"_s, QString() ) );
474 }
475 mFormat.setFont( f );
476 if ( f.pointSizeF() > 0 )
477 {
478 mFormat.setSize( f.pointSizeF() );
479 mFormat.setSizeUnit( Qgis::RenderUnit::Points );
480 }
481 else if ( f.pixelSize() > 0 )
482 {
483 mFormat.setSize( f.pixelSize() );
484 mFormat.setSizeUnit( Qgis::RenderUnit::Pixels );
485 }
486
487 //font color
488 const QDomNodeList fontColorList = itemElem.elementsByTagName( u"FontColor"_s );
489 if ( !fontColorList.isEmpty() )
490 {
491 const QDomElement fontColorElem = fontColorList.at( 0 ).toElement();
492 const int red = fontColorElem.attribute( u"red"_s, u"0"_s ).toInt();
493 const int green = fontColorElem.attribute( u"green"_s, u"0"_s ).toInt();
494 const int blue = fontColorElem.attribute( u"blue"_s, u"0"_s ).toInt();
495 const int alpha = fontColorElem.attribute( u"alpha"_s, u"255"_s ).toInt();
496 mFormat.setColor( QColor( red, green, blue, alpha ) );
497 }
498 else if ( textFormatNodeList.isEmpty() )
499 {
500 mFormat.setColor( QColor( 0, 0, 0 ) );
501 }
502 }
503
504 updateBoundingRect();
505
506 return true;
507}
508
510{
511 if ( !id().isEmpty() )
512 {
513 return id();
514 }
515
516 switch ( mMode )
517 {
518 case ModeHtml:
519 return tr( "<HTML Label>" );
520
521 case ModeFont:
522 {
523 //if no id, default to portion of label text
524 const QString text = mText;
525 if ( text.isEmpty() )
526 {
527 return tr( "<Label>" );
528 }
529 if ( text.length() > 25 )
530 {
531 return QString( tr( "%1…" ) ).arg( text.left( 25 ).simplified() );
532 }
533 else
534 {
535 return text.simplified();
536 }
537 }
538 }
539 return QString(); // no warnings
540}
541
543{
544 return mCurrentRectangle;
545}
546
548{
550 updateBoundingRect();
551}
552
554{
556 updateBoundingRect();
557}
558
560{
563 refreshExpressionContext();
564}
565
567{
568 const QString evaluated = currentText();
569 if ( evaluated == mText )
570 return; // no changes
571
572 setText( evaluated );
573}
574
575void QgsLayoutItemLabel::itemShiftAdjustSize( double newWidth, double newHeight, double &xShift, double &yShift ) const
576{
577 //keep alignment point constant
578 const double currentWidth = rect().width();
579 const double currentHeight = rect().height();
580 xShift = 0;
581 yShift = 0;
582
583 const double r = rotation();
584 if ( r >= 0 && r < 90 )
585 {
586 if ( mHAlignment == Qt::AlignHCenter )
587 {
588 xShift = -( newWidth - currentWidth ) / 2.0;
589 }
590 else if ( mHAlignment == Qt::AlignRight )
591 {
592 xShift = -( newWidth - currentWidth );
593 }
594 if ( mVAlignment == Qt::AlignVCenter )
595 {
596 yShift = -( newHeight - currentHeight ) / 2.0;
597 }
598 else if ( mVAlignment == Qt::AlignBottom )
599 {
600 yShift = -( newHeight - currentHeight );
601 }
602 }
603 if ( r >= 90 && r < 180 )
604 {
605 if ( mHAlignment == Qt::AlignHCenter )
606 {
607 yShift = -( newHeight - currentHeight ) / 2.0;
608 }
609 else if ( mHAlignment == Qt::AlignRight )
610 {
611 yShift = -( newHeight - currentHeight );
612 }
613 if ( mVAlignment == Qt::AlignTop )
614 {
615 xShift = -( newWidth - currentWidth );
616 }
617 else if ( mVAlignment == Qt::AlignVCenter )
618 {
619 xShift = -( newWidth - currentWidth / 2.0 );
620 }
621 }
622 else if ( r >= 180 && r < 270 )
623 {
624 if ( mHAlignment == Qt::AlignHCenter )
625 {
626 xShift = -( newWidth - currentWidth ) / 2.0;
627 }
628 else if ( mHAlignment == Qt::AlignLeft )
629 {
630 xShift = -( newWidth - currentWidth );
631 }
632 if ( mVAlignment == Qt::AlignVCenter )
633 {
634 yShift = ( newHeight - currentHeight ) / 2.0;
635 }
636 else if ( mVAlignment == Qt::AlignTop )
637 {
638 yShift = ( newHeight - currentHeight );
639 }
640 }
641 else if ( r >= 270 && r < 360 )
642 {
643 if ( mHAlignment == Qt::AlignHCenter )
644 {
645 yShift = -( newHeight - currentHeight ) / 2.0;
646 }
647 else if ( mHAlignment == Qt::AlignLeft )
648 {
649 yShift = -( newHeight - currentHeight );
650 }
651 if ( mVAlignment == Qt::AlignBottom )
652 {
653 xShift = -( newWidth - currentWidth );
654 }
655 else if ( mVAlignment == Qt::AlignVCenter )
656 {
657 xShift = -( newWidth - currentWidth / 2.0 );
658 }
659 }
660}
661
662QFont QgsLayoutItemLabel::createDefaultFont() const
663{
664 QFont f = mFormat.font();
665 switch ( mFormat.sizeUnit() )
666 {
668 f.setPointSizeF( mFormat.size() / 0.352778 );
669 break;
671 f.setPixelSize( mFormat.size() );
672 break;
674 f.setPointSizeF( mFormat.size() );
675 break;
677 f.setPointSizeF( mFormat.size() * 72 );
678 break;
683 break;
684 }
685 return f;
686}
687
688double QgsLayoutItemLabel::htmlUnitsToLayoutUnits()
689{
690 if ( !mLayout )
691 {
692 return 1.0;
693 }
694
695 //TODO : fix this more precisely so that the label's default text size is the same with or without "display as html"
696 return mLayout->convertToLayoutUnits( QgsLayoutMeasurement( mLayout->renderContext().dpi() / 72.0, Qgis::LayoutUnit::Millimeters ) ); //webkit seems to assume a standard dpi of 72
697}
698
699QString QgsLayoutItemLabel::createStylesheet() const
700{
701 QString stylesheet;
702
703 stylesheet += u"body { margin: %1 %2;"_s.arg( std::max( mMarginY * mHtmlUnitsToLayoutUnits, 0.0 ) ).arg( std::max( mMarginX * mHtmlUnitsToLayoutUnits, 0.0 ) );
704 stylesheet += mFormat.asCSS( 0.352778 * mHtmlUnitsToLayoutUnits );
705 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 );
706
707 return stylesheet;
708}
709
710QUrl QgsLayoutItemLabel::createStylesheetUrl() const
711{
712 QByteArray ba;
713 ba.append( createStylesheet().toUtf8() );
714 QUrl cssFileURL = QUrl( QString( "data:text/css;charset=utf-8;base64," + ba.toBase64() ) );
715
716 return cssFileURL;
717}
@ Millimeters
Millimeters.
Definition qgis.h:5460
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
Definition qgis.h:5443
@ Millimeters
Millimeters.
Definition qgis.h:5440
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5444
@ Unknown
Mixed or unknown units.
Definition qgis.h:5446
@ MapUnits
Map units.
Definition qgis.h:5441
@ Pixels
Pixels.
Definition qgis.h:5442
@ Inches
Inches.
Definition qgis.h:5445
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5447
@ ApplyScalingWorkaroundForTextRendering
Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters ...
Definition qgis.h:2911
@ WrapLines
Automatically wrap long lines of text.
Definition qgis.h:3574
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.
static const QgsSettingsEntryString * settingsLayoutDefaultFont
Settings entry for the default font family used for new layout items.
Definition qgslayout.h:668
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.
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.