QGIS API Documentation  2.99.0-Master (40f86b2)
qgscomposerlabel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposerlabel.cpp
3  -------------------
4  begin : January 2005
5  copyright : (C) 2005 by Radim Blazek
6  email : [email protected]
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 "qgscomposerlabel.h"
19 #include "qgscomposition.h"
20 #include "qgscomposerutils.h"
21 #include "qgsexpression.h"
23 #include "qgscomposermodel.h"
24 #include "qgsvectorlayer.h"
25 #include "qgsproject.h"
26 #include "qgsdistancearea.h"
27 #include "qgsfontutils.h"
28 #include "qgsexpressioncontext.h"
29 #include "qgsmapsettings.h"
30 #include "qgscomposermap.h"
31 #include "qgssettings.h"
32 
33 #include "qgswebview.h"
34 #include "qgswebframe.h"
35 #include "qgswebpage.h"
36 
37 #include <QCoreApplication>
38 #include <QDate>
39 #include <QDomElement>
40 #include <QPainter>
41 #include <QTimer>
42 #include <QEventLoop>
43 
45  : QgsComposerItem( composition )
46  , mHtmlState( 0 )
47  , mHtmlUnitsToMM( 1.0 )
48  , mHtmlLoaded( false )
49  , mMarginX( 1.0 )
50  , mMarginY( 1.0 )
51  , mFontColor( QColor( 0, 0, 0 ) )
52  , mHAlignment( Qt::AlignLeft )
53  , mVAlignment( Qt::AlignTop )
54  , mDistanceArea( nullptr )
55 {
56  mDistanceArea = new QgsDistanceArea();
57  mHtmlUnitsToMM = htmlUnitsToMM();
58 
59  //get default composer font from settings
60  QgsSettings settings;
61  QString defaultFontString = settings.value( QStringLiteral( "Composer/defaultFont" ) ).toString();
62  if ( !defaultFontString.isEmpty() )
63  {
64  mFont.setFamily( defaultFontString );
65  }
66 
67  //default to a 10 point font size
68  mFont.setPointSizeF( 10 );
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)
76 
77  if ( mComposition )
78  {
79  //connect to atlas feature changes
80  //to update the expression context
82  connect( mComposition, &QgsComposition::refreshItemsTriggered, this, &QgsComposerLabel::contentChanged );
83  }
84 
85  mWebPage = new QgsWebPage( this );
86  mWebPage->setIdentifier( tr( "Composer 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  //webPage->setAttribute(Qt::WA_OpaquePaintEvent, false); //this does not compile, why ?
94 
95  mWebPage->mainFrame()->setZoomFactor( 10.0 );
96  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
97  mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
98 
99  connect( mWebPage, &QWebPage::loadFinished, this, &QgsComposerLabel::loadingHtmlFinished );
100 }
101 
103 {
104  delete mDistanceArea;
105  delete mWebPage;
106 }
107 
108 void QgsComposerLabel::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget )
109 {
110  Q_UNUSED( itemStyle );
111  Q_UNUSED( pWidget );
112  if ( !painter )
113  {
114  return;
115  }
116  if ( !shouldDrawItem() )
117  {
118  return;
119  }
120 
121  drawBackground( painter );
122  painter->save();
123 
124  //antialiasing on
125  painter->setRenderHint( QPainter::Antialiasing, true );
126 
127  double penWidth = hasFrame() ? ( pen().widthF() / 2.0 ) : 0;
128  double xPenAdjust = mMarginX < 0 ? -penWidth : penWidth;
129  double yPenAdjust = mMarginY < 0 ? -penWidth : penWidth;
130  QRectF painterRect( xPenAdjust + mMarginX, yPenAdjust + mMarginY, rect().width() - 2 * xPenAdjust - 2 * mMarginX, rect().height() - 2 * yPenAdjust - 2 * mMarginY );
131 
132  if ( mHtmlState )
133  {
134  if ( mFirstRender )
135  {
136  contentChanged();
137  mFirstRender = false;
138  }
139  painter->scale( 1.0 / mHtmlUnitsToMM / 10.0, 1.0 / mHtmlUnitsToMM / 10.0 );
140  mWebPage->setViewportSize( QSize( painterRect.width() * mHtmlUnitsToMM * 10.0, painterRect.height() * mHtmlUnitsToMM * 10.0 ) );
141  mWebPage->settings()->setUserStyleSheetUrl( createStylesheetUrl() );
142  mWebPage->mainFrame()->render( painter );
143  }
144  else
145  {
146  const QString textToDraw = displayText();
147  painter->setFont( mFont );
148  //debug
149  //painter->setPen( QColor( Qt::red ) );
150  //painter->drawRect( painterRect );
151  QgsComposerUtils::drawText( painter, painterRect, textToDraw, mFont, mFontColor, mHAlignment, mVAlignment, Qt::TextWordWrap );
152  }
153 
154  painter->restore();
155 
156  drawFrame( painter );
157  if ( isSelected() )
158  {
159  drawSelectionBoxes( painter );
160  }
161 }
162 
163 void QgsComposerLabel::contentChanged()
164 {
165  if ( mHtmlState )
166  {
167  const QString textToDraw = displayText();
168 
169  //mHtmlLoaded tracks whether the QWebPage has completed loading
170  //its html contents, set it initially to false. The loadingHtmlFinished slot will
171  //set this to true after html is loaded.
172  mHtmlLoaded = false;
173 
174  const QUrl baseUrl = QUrl::fromLocalFile( mComposition->project()->fileInfo().absoluteFilePath() );
175  mWebPage->mainFrame()->setHtml( textToDraw, baseUrl );
176 
177  //For very basic html labels with no external assets, the html load will already be
178  //complete before we even get a chance to start the QEventLoop. Make sure we check
179  //this before starting the loop
180  if ( !mHtmlLoaded )
181  {
182  //Setup event loop and timeout for rendering html
183  QEventLoop loop;
184 
185  //Connect timeout and webpage loadFinished signals to loop
186  connect( mWebPage, &QWebPage::loadFinished, &loop, &QEventLoop::quit );
187 
188  // Start a 20 second timeout in case html loading will never complete
189  QTimer timeoutTimer;
190  timeoutTimer.setSingleShot( true );
191  connect( &timeoutTimer, &QTimer::timeout, &loop, &QEventLoop::quit );
192  timeoutTimer.start( 20000 );
193 
194  // Pause until html is loaded
195  loop.exec();
196  }
197  }
198 }
199 
200 /*Track when QWebPage has finished loading its html contents*/
201 void QgsComposerLabel::loadingHtmlFinished( bool result )
202 {
203  Q_UNUSED( result );
204  mHtmlLoaded = true;
205 }
206 
207 double QgsComposerLabel::htmlUnitsToMM()
208 {
209  if ( !mComposition )
210  {
211  return 1.0;
212  }
213 
214  //TODO : fix this more precisely so that the label's default text size is the same with or without "display as html"
215  return ( mComposition->printResolution() / 72.0 ); //webkit seems to assume a standard dpi of 72
216 }
217 
218 void QgsComposerLabel::setText( const QString &text )
219 {
220  mText = text;
221  emit itemChanged();
222 
223  contentChanged();
224 
225  if ( mComposition && id().isEmpty() && !mHtmlState )
226  {
227  //notify the model that the display name has changed
229  }
230 }
231 
233 {
234  if ( state == mHtmlState )
235  {
236  return;
237  }
238 
239  mHtmlState = state;
240  contentChanged();
241 
242  if ( mComposition && id().isEmpty() )
243  {
244  //notify the model that the display name has changed
246  }
247 }
248 
250 {
251  if ( !mComposition )
252  return;
253 
254  QgsVectorLayer *layer = nullptr;
256  {
258  }
259 
260  //setup distance area conversion
261  if ( layer )
262  {
263  mDistanceArea->setSourceCrs( layer->crs().srsid() );
264  }
265  else
266  {
267  //set to composition's reference map's crs
268  QgsComposerMap *referenceMap = mComposition->referenceMap();
269  if ( referenceMap )
270  mDistanceArea->setSourceCrs( referenceMap->crs().srsid() );
271  }
272  mDistanceArea->setEllipsoidalMode( true );
273  mDistanceArea->setEllipsoid( mComposition->project()->ellipsoid() );
274  contentChanged();
275 
276  update();
277 }
278 
280 {
281  QString displayText = mText;
282  replaceDateText( displayText );
283 
285 
286  return QgsExpression::replaceExpressionText( displayText, &context, mDistanceArea );
287 }
288 
289 void QgsComposerLabel::replaceDateText( QString &text ) const
290 {
291  QString constant = QStringLiteral( "$CURRENT_DATE" );
292  int currentDatePos = text.indexOf( constant );
293  if ( currentDatePos != -1 )
294  {
295  //check if there is a bracket just after $CURRENT_DATE
296  QString formatText;
297  int openingBracketPos = text.indexOf( '(', currentDatePos );
298  int closingBracketPos = text.indexOf( ')', openingBracketPos + 1 );
299  if ( openingBracketPos != -1 &&
300  closingBracketPos != -1 &&
301  ( closingBracketPos - openingBracketPos ) > 1 &&
302  openingBracketPos == currentDatePos + constant.size() )
303  {
304  formatText = text.mid( openingBracketPos + 1, closingBracketPos - openingBracketPos - 1 );
305  text.replace( currentDatePos, closingBracketPos - currentDatePos + 1, QDate::currentDate().toString( formatText ) );
306  }
307  else //no bracket
308  {
309  text.replace( QLatin1String( "$CURRENT_DATE" ), QDate::currentDate().toString() );
310  }
311  }
312 }
313 
314 void QgsComposerLabel::setFont( const QFont &f )
315 {
316  mFont = f;
317 }
318 
319 void QgsComposerLabel::setMargin( const double m )
320 {
321  mMarginX = m;
322  mMarginY = m;
323  prepareGeometryChange();
324 }
325 
326 void QgsComposerLabel::setMarginX( const double margin )
327 {
328  mMarginX = margin;
329  prepareGeometryChange();
330 }
331 
332 void QgsComposerLabel::setMarginY( const double margin )
333 {
334  mMarginY = margin;
335  prepareGeometryChange();
336 }
337 
339 {
340  double textWidth = QgsComposerUtils::textWidthMM( mFont, displayText() );
341  double fontHeight = QgsComposerUtils::fontHeightMM( mFont );
342 
343  double penWidth = hasFrame() ? ( pen().widthF() / 2.0 ) : 0;
344 
345  double width = textWidth + 2 * mMarginX + 2 * penWidth + 1;
346  double height = fontHeight + 2 * mMarginY + 2 * penWidth;
347 
348  //keep alignment point constant
349  double xShift = 0;
350  double yShift = 0;
351  itemShiftAdjustSize( width, height, xShift, yShift );
352 
353  //update rect for data defined size and position
354  QRectF evaluatedRect = evalItemRect( QRectF( pos().x() + xShift, pos().y() + yShift, width, height ) );
355  setSceneRect( evaluatedRect );
356 }
357 
359 {
360  return mFont;
361 }
362 
363 bool QgsComposerLabel::writeXml( QDomElement &elem, QDomDocument &doc ) const
364 {
365  if ( elem.isNull() )
366  {
367  return false;
368  }
369 
370  QDomElement composerLabelElem = doc.createElement( QStringLiteral( "ComposerLabel" ) );
371 
372  composerLabelElem.setAttribute( QStringLiteral( "htmlState" ), mHtmlState );
373 
374  composerLabelElem.setAttribute( QStringLiteral( "labelText" ), mText );
375  composerLabelElem.setAttribute( QStringLiteral( "marginX" ), QString::number( mMarginX ) );
376  composerLabelElem.setAttribute( QStringLiteral( "marginY" ), QString::number( mMarginY ) );
377  composerLabelElem.setAttribute( QStringLiteral( "halign" ), mHAlignment );
378  composerLabelElem.setAttribute( QStringLiteral( "valign" ), mVAlignment );
379 
380  //font
381  QDomElement labelFontElem = QgsFontUtils::toXmlElement( mFont, doc, QStringLiteral( "LabelFont" ) );
382  composerLabelElem.appendChild( labelFontElem );
383 
384  //font color
385  QDomElement fontColorElem = doc.createElement( QStringLiteral( "FontColor" ) );
386  fontColorElem.setAttribute( QStringLiteral( "red" ), mFontColor.red() );
387  fontColorElem.setAttribute( QStringLiteral( "green" ), mFontColor.green() );
388  fontColorElem.setAttribute( QStringLiteral( "blue" ), mFontColor.blue() );
389  composerLabelElem.appendChild( fontColorElem );
390 
391  elem.appendChild( composerLabelElem );
392  return _writeXml( composerLabelElem, doc );
393 }
394 
395 bool QgsComposerLabel::readXml( const QDomElement &itemElem, const QDomDocument &doc )
396 {
397  if ( itemElem.isNull() )
398  {
399  return false;
400  }
401 
402  //restore label specific properties
403 
404  //text
405  mText = itemElem.attribute( QStringLiteral( "labelText" ) );
406 
407  //html state
408  mHtmlState = itemElem.attribute( QStringLiteral( "htmlState" ) ).toInt();
409 
410  //margin
411  bool marginXOk = false;
412  bool marginYOk = false;
413  mMarginX = itemElem.attribute( QStringLiteral( "marginX" ) ).toDouble( &marginXOk );
414  mMarginY = itemElem.attribute( QStringLiteral( "marginY" ) ).toDouble( &marginYOk );
415  if ( !marginXOk || !marginYOk )
416  {
417  //upgrade old projects where margins where stored in a single attribute
418  double margin = itemElem.attribute( QStringLiteral( "margin" ), QStringLiteral( "1.0" ) ).toDouble();
419  mMarginX = margin;
420  mMarginY = margin;
421  }
422 
423  //Horizontal alignment
424  mHAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "halign" ) ).toInt() );
425 
426  //Vertical alignment
427  mVAlignment = static_cast< Qt::AlignmentFlag >( itemElem.attribute( QStringLiteral( "valign" ) ).toInt() );
428 
429  //font
430  QgsFontUtils::setFromXmlChildNode( mFont, itemElem, QStringLiteral( "LabelFont" ) );
431 
432  //font color
433  QDomNodeList fontColorList = itemElem.elementsByTagName( QStringLiteral( "FontColor" ) );
434  if ( !fontColorList.isEmpty() )
435  {
436  QDomElement fontColorElem = fontColorList.at( 0 ).toElement();
437  int red = fontColorElem.attribute( QStringLiteral( "red" ), QStringLiteral( "0" ) ).toInt();
438  int green = fontColorElem.attribute( QStringLiteral( "green" ), QStringLiteral( "0" ) ).toInt();
439  int blue = fontColorElem.attribute( QStringLiteral( "blue" ), QStringLiteral( "0" ) ).toInt();
440  mFontColor = QColor( red, green, blue );
441  }
442  else
443  {
444  mFontColor = QColor( 0, 0, 0 );
445  }
446 
447  //restore general composer item properties
448  QDomNodeList composerItemList = itemElem.elementsByTagName( QStringLiteral( "ComposerItem" ) );
449  if ( !composerItemList.isEmpty() )
450  {
451  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
452 
453  //rotation
454  if ( !qgsDoubleNear( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble(), 0.0 ) )
455  {
456  //check for old (pre 2.1) rotation attribute
457  setItemRotation( composerItemElem.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble() );
458  }
459 
460  _readXml( composerItemElem, doc );
461  }
462  emit itemChanged();
463  return true;
464 }
465 
467 {
468  if ( !id().isEmpty() )
469  {
470  return id();
471  }
472 
473  if ( mHtmlState )
474  {
475  return tr( "<HTML label>" );
476  }
477 
478  //if no id, default to portion of label text
479  QString text = mText;
480  if ( text.isEmpty() )
481  {
482  return tr( "<label>" );
483  }
484  if ( text.length() > 25 )
485  {
486  return QString( tr( "%1..." ) ).arg( text.left( 25 ).simplified() );
487  }
488  else
489  {
490  return text.simplified();
491  }
492 }
493 
495 {
496  QRectF rectangle = rect();
497  double penWidth = hasFrame() ? ( pen().widthF() / 2.0 ) : 0;
498  rectangle.adjust( -penWidth, -penWidth, penWidth, penWidth );
499 
500  if ( mMarginX < 0 )
501  {
502  rectangle.adjust( mMarginX, 0, -mMarginX, 0 );
503  }
504  if ( mMarginY < 0 )
505  {
506  rectangle.adjust( 0, mMarginY, 0, -mMarginY );
507  }
508 
509  return rectangle;
510 }
511 
513 {
515  prepareGeometryChange();
516 }
517 
518 void QgsComposerLabel::setFrameStrokeWidth( const double strokeWidth )
519 {
521  prepareGeometryChange();
522 }
523 
524 void QgsComposerLabel::itemShiftAdjustSize( double newWidth, double newHeight, double &xShift, double &yShift ) const
525 {
526  //keep alignment point constant
527  double currentWidth = rect().width();
528  double currentHeight = rect().height();
529  xShift = 0;
530  yShift = 0;
531 
532  if ( mItemRotation >= 0 && mItemRotation < 90 )
533  {
534  if ( mHAlignment == Qt::AlignHCenter )
535  {
536  xShift = - ( newWidth - currentWidth ) / 2.0;
537  }
538  else if ( mHAlignment == Qt::AlignRight )
539  {
540  xShift = - ( newWidth - currentWidth );
541  }
542  if ( mVAlignment == Qt::AlignVCenter )
543  {
544  yShift = -( newHeight - currentHeight ) / 2.0;
545  }
546  else if ( mVAlignment == Qt::AlignBottom )
547  {
548  yShift = - ( newHeight - currentHeight );
549  }
550  }
551  if ( mItemRotation >= 90 && mItemRotation < 180 )
552  {
553  if ( mHAlignment == Qt::AlignHCenter )
554  {
555  yShift = -( newHeight - currentHeight ) / 2.0;
556  }
557  else if ( mHAlignment == Qt::AlignRight )
558  {
559  yShift = -( newHeight - currentHeight );
560  }
561  if ( mVAlignment == Qt::AlignTop )
562  {
563  xShift = -( newWidth - currentWidth );
564  }
565  else if ( mVAlignment == Qt::AlignVCenter )
566  {
567  xShift = -( newWidth - currentWidth / 2.0 );
568  }
569  }
570  else if ( mItemRotation >= 180 && mItemRotation < 270 )
571  {
572  if ( mHAlignment == Qt::AlignHCenter )
573  {
574  xShift = -( newWidth - currentWidth ) / 2.0;
575  }
576  else if ( mHAlignment == Qt::AlignLeft )
577  {
578  xShift = -( newWidth - currentWidth );
579  }
580  if ( mVAlignment == Qt::AlignVCenter )
581  {
582  yShift = ( newHeight - currentHeight ) / 2.0;
583  }
584  else if ( mVAlignment == Qt::AlignTop )
585  {
586  yShift = ( newHeight - currentHeight );
587  }
588  }
589  else if ( mItemRotation >= 270 && mItemRotation < 360 )
590  {
591  if ( mHAlignment == Qt::AlignHCenter )
592  {
593  yShift = -( newHeight - currentHeight ) / 2.0;
594  }
595  else if ( mHAlignment == Qt::AlignLeft )
596  {
597  yShift = -( newHeight - currentHeight );
598  }
599  if ( mVAlignment == Qt::AlignBottom )
600  {
601  xShift = -( newWidth - currentWidth );
602  }
603  else if ( mVAlignment == Qt::AlignVCenter )
604  {
605  xShift = -( newWidth - currentWidth / 2.0 );
606  }
607  }
608 }
609 
610 QUrl QgsComposerLabel::createStylesheetUrl() const
611 {
612  QString stylesheet;
613  stylesheet += QStringLiteral( "body { margin: %1 %2;" ).arg( qMax( mMarginY * mHtmlUnitsToMM, 0.0 ) ).arg( qMax( mMarginX * mHtmlUnitsToMM, 0.0 ) );
614  stylesheet += QgsFontUtils::asCSS( mFont, 0.352778 * mHtmlUnitsToMM );
615  stylesheet += QStringLiteral( "color: %1;" ).arg( mFontColor.name() );
616  stylesheet += QStringLiteral( "text-align: %1; }" ).arg( mHAlignment == Qt::AlignLeft ? "left" : mHAlignment == Qt::AlignRight ? "right" : "center" );
617 
618  QByteArray ba;
619  ba.append( stylesheet.toUtf8() );
620  QUrl cssFileURL = QUrl( "data:text/css;charset=utf-8;base64," + ba.toBase64() );
621 
622  return cssFileURL;
623 }
void setHtmlState(int state)
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
virtual void setFrameStrokeWidth(const double strokeWidth)
Sets frame stroke width.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:51
void setIdentifier(const QString &identifier)
Sets an identifier for the QgsWebPage.
Definition: qgswebpage.h:227
QString displayText() const
Returns the text as it appears on screen (with replaced data field)
QgsComposerModel * itemsModel()
Returns the items model attached to the composition.
void itemChanged()
Emitted when the item changes.
bool readXml(const QDomElement &itemElem, const QDomDocument &doc) override
Sets state from Dom document.
void setSourceCrs(long srsid)
sets source spatial reference system (by QGIS CRS)
int printResolution() const
A item that forms part of a map composition.
QRectF evalItemRect(const QRectF &newRect, const bool resizeOnly=false, const QgsExpressionContext *context=nullptr)
Evaluates an item&#39;s bounding rect to consider data defined position and size of item and reference po...
static void drawText(QPainter *painter, QPointF pos, const QString &text, const QFont &font, const QColor &color=QColor())
Draws text on a painter at a specific position, taking care of composer specific issues (calculation ...
virtual void drawFrame(QPainter *p)
Draw black frame around item.
virtual void setFrameEnabled(const bool drawFrame)
Set whether this item has a frame drawn around it or not.
bool setEllipsoid(const QString &ellipsoid)
Sets ellipsoid by its acronym.
void setFont(const QFont &f)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:198
void updateItemDisplayName(QgsComposerItem *item)
Must be called when an item&#39;s display name is modified.
static QString asCSS(const QFont &font, double pointToPixelMultiplier=1.0)
Returns a CSS string representing the specified font as closely as possible.
void refreshItemsTriggered()
Is emitted when item in the composition must be refreshed.
bool _writeXml(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document. Usually called from writeXml methods of ...
virtual void drawSelectionBoxes(QPainter *p)
Draws additional graphics on selected items.
QgsComposerMap * referenceMap() const
Returns the map item which will be used to generate corresponding world files when the composition is...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsCoordinateReferenceSystem crs() const
Returns the layer&#39;s spatial reference system.
QgsComposerLabel(QgsComposition *composition)
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.
bool _readXml(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document. Usually called from readXml methods of su...
void setBackgroundEnabled(const bool drawBackground)
Set whether this item has a Background drawn around it or not.
QRectF boundingRect() const override
In case of negative margins, the bounding rect may be larger than the label&#39;s frame.
void setMarginX(const double margin)
Sets the horizontal margin between the edge of the frame and the label contents.
Graphics scene for map printing.
Object representing map window.
void featureChanged(QgsFeature *feature)
Is emitted when the current atlas feature changes.
void setMarginY(const double margin)
Sets the vertical margin between the edge of the frame and the label contents.
virtual QgsExpressionContext createExpressionContext() const override
Creates an expression context relating to the item&#39;s current state.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget) override
Reimplementation of QCanvasItem::paint.
General purpose distance and area calculator.
static double textWidthMM(const QFont &font, const QString &text)
Calculate font width in millimeters for a string, including workarounds for QT font rendering issues...
QgsComposition * mComposition
static double fontHeightMM(const QFont &font)
Calculate font height in millimeters, including workarounds for QT font rendering issues The font hei...
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used for rendering the map.
QFileInfo fileInfo() const
Returns QFileInfo object for the project&#39;s associated file.
Definition: qgsproject.cpp:417
static QgsNetworkAccessManager * instance()
returns a pointer to the single instance
QgsProject * project() const
The project associated with the composition.
virtual void setItemRotation(const double r, const bool adjustPosition=false)
Sets the item rotation.
virtual void drawBackground(QPainter *p)
Draw background.
void setMargin(const double m)
Sets the margin between the edge of the frame and the label contents.
virtual void setSceneRect(const QRectF &rectangle)
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=Section::NoSection) const
Returns the value for setting key.
void setText(const QString &text)
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
QgsAtlasComposition & atlasComposition()
bool writeXml(QDomElement &elem, QDomDocument &doc) const override
Stores state in Dom element.
virtual void setFrameStrokeWidth(const double strokeWidth) override
Reimplemented to call prepareGeometryChange after changing stroke width.
bool hasFrame() const
Whether this item has a frame or not.
static QDomElement toXmlElement(const QFont &font, QDomDocument &document, const QString &elementName)
Returns a DOM element containing the properties of the font.
QString ellipsoid() const
Returns a proj string representing the project&#39;s ellipsoid setting, e.g., "WGS84".
Definition: qgsproject.cpp:438
long srsid() const
Returns the internal CRS ID, if available.
Represents a vector layer which manages a vector based data sets.
QString id() const
Get item&#39;s id (which is not necessarly unique)
QWebPage subclass which redirects JavaScript errors and console output to the QGIS message log...
Definition: qgswebpage.h:208
double mItemRotation
Item rotation in degrees, clockwise.
bool enabled() const
Returns whether the atlas generation is enabled.
void adjustSizeToText()
Resizes the widget such that the text fits to the item. Keeps top left point.
void setEllipsoidalMode(bool flag)
Sets whether coordinates must be projected to ellipsoid before measuring.
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...
virtual void setFrameEnabled(const bool drawFrame) override
Reimplemented to call prepareGeometryChange after toggling frame.
virtual QString displayName() const override
Get item display name.