38 #include <QCoreApplication>
40 #include <QDomElement>
49 mHtmlUnitsToLayoutUnits = htmlUnitsToLayoutUnits();
53 QString defaultFontString = settings.
value( QStringLiteral(
"LayoutDesigner/defaultFont" ), QVariant(),
QgsSettings::Gui ).toString();
54 if ( !defaultFontString.isEmpty() )
56 mFont.setFamily( defaultFontString );
60 mFont.setPointSizeF( 10 );
67 refreshExpressionContext();
70 if ( QThread::currentThread() == QApplication::instance()->thread() )
80 mWebPage->setIdentifier( tr(
"Layout label item" ) );
84 QPalette palette = mWebPage->palette();
85 palette.setBrush( QPalette::Base, Qt::transparent );
86 mWebPage->setPalette( palette );
88 mWebPage->mainFrame()->setZoomFactor( 10.0 );
89 mWebPage->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
90 mWebPage->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
92 connect( mWebPage.get(), &QWebPage::loadFinished,
this, &QgsLayoutItemLabel::loadingHtmlFinished );
119 double penWidth =
frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
120 double xPenAdjust = mMarginX < 0 ? -penWidth : penWidth;
121 double yPenAdjust = mMarginY < 0 ? -penWidth : penWidth;
122 QRectF painterRect( xPenAdjust + mMarginX, yPenAdjust + mMarginY, rect().width() - 2 * xPenAdjust - 2 * mMarginX, rect().height() - 2 * yPenAdjust - 2 * mMarginY );
131 mFirstRender =
false;
136 painter->scale( 1.0 / mHtmlUnitsToLayoutUnits / 10.0, 1.0 / mHtmlUnitsToLayoutUnits / 10.0 );
137 mWebPage->setViewportSize( QSize( painterRect.width() * mHtmlUnitsToLayoutUnits * 10.0, painterRect.height() * mHtmlUnitsToLayoutUnits * 10.0 ) );
138 mWebPage->settings()->setUserStyleSheetUrl( createStylesheetUrl() );
139 mWebPage->mainFrame()->render( painter );
147 painter->setFont( mFont );
148 QgsLayoutUtils::drawText( painter, painterRect, textToDraw, mFont, mFontColor, mHAlignment, mVAlignment, Qt::TextWordWrap );
154 void QgsLayoutItemLabel::contentChanged()
172 const QUrl baseUrl = QUrl::fromLocalFile(
mLayout->project()->absoluteFilePath() );
173 mWebPage->mainFrame()->setHtml( textToDraw, baseUrl );
181 if ( !mHtmlLoaded && ( !
mLayout || !
mLayout->renderContext().isPreviewRender() ) )
187 connect( mWebPage.get(), &QWebPage::loadFinished, &loop, &QEventLoop::quit );
191 timeoutTimer.setSingleShot(
true );
192 connect( &timeoutTimer, &QTimer::timeout, &loop, &QEventLoop::quit );
193 timeoutTimer.start( 20000 );
196 loop.exec( QEventLoop::ExcludeUserInputEvents );
205 void QgsLayoutItemLabel::loadingHtmlFinished(
bool result )
213 double QgsLayoutItemLabel::htmlUnitsToLayoutUnits()
234 mLayout->itemsModel()->updateItemDisplayName(
this );
248 if (
mLayout &&
id().isEmpty() )
251 mLayout->itemsModel()->updateItemDisplayName(
this );
255 void QgsLayoutItemLabel::refreshExpressionContext()
264 mDistanceArea->setSourceCrs( layer->
crs(),
mLayout->project()->transformContext() );
271 mDistanceArea->setSourceCrs( referenceMap->
crs(),
mLayout->project()->transformContext() );
273 mDistanceArea->setEllipsoid(
mLayout->project()->ellipsoid() );
281 QString displayText = mText;
282 replaceDateText( displayText );
289 void QgsLayoutItemLabel::replaceDateText( QString &text )
const
291 QString constant = QStringLiteral(
"$CURRENT_DATE" );
292 int currentDatePos =
text.indexOf( constant );
293 if ( currentDatePos != -1 )
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() )
304 formatText =
text.mid( openingBracketPos + 1, closingBracketPos - openingBracketPos - 1 );
305 text.replace( currentDatePos, closingBracketPos - currentDatePos + 1, QDate::currentDate().toString( formatText ) );
309 text.replace( QLatin1String(
"$CURRENT_DATE" ), QDate::currentDate().toString() );
323 prepareGeometryChange();
329 prepareGeometryChange();
335 prepareGeometryChange();
346 itemShiftAdjustSize( newSize.width(), newSize.height(), xShift, yShift );
349 attemptSetSceneRect( QRectF( pos().x() + xShift, pos().y() + yShift, newSize.width(), newSize.height() ) );
357 double penWidth =
frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
359 double width = textWidth + 2 * mMarginX + 2 * penWidth;
360 double height = fontHeight + 2 * mMarginY + 2 * penWidth;
372 layoutLabelElem.setAttribute( QStringLiteral(
"htmlState" ),
static_cast< int >( mMode ) );
374 layoutLabelElem.setAttribute( QStringLiteral(
"labelText" ), mText );
375 layoutLabelElem.setAttribute( QStringLiteral(
"marginX" ), QString::number( mMarginX ) );
376 layoutLabelElem.setAttribute( QStringLiteral(
"marginY" ), QString::number( mMarginY ) );
377 layoutLabelElem.setAttribute( QStringLiteral(
"halign" ), mHAlignment );
378 layoutLabelElem.setAttribute( QStringLiteral(
"valign" ), mVAlignment );
382 layoutLabelElem.appendChild( labelFontElem );
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 fontColorElem.setAttribute( QStringLiteral(
"alpha" ), mFontColor.alpha() );
390 layoutLabelElem.appendChild( fontColorElem );
400 mText = itemElem.attribute( QStringLiteral(
"labelText" ) );
403 mMode =
static_cast< Mode >( itemElem.attribute( QStringLiteral(
"htmlState" ) ).toInt() );
406 bool marginXOk =
false;
407 bool marginYOk =
false;
408 mMarginX = itemElem.attribute( QStringLiteral(
"marginX" ) ).toDouble( &marginXOk );
409 mMarginY = itemElem.attribute( QStringLiteral(
"marginY" ) ).toDouble( &marginYOk );
410 if ( !marginXOk || !marginYOk )
413 double margin = itemElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"1.0" ) ).toDouble();
419 mHAlignment =
static_cast< Qt::AlignmentFlag
>( itemElem.attribute( QStringLiteral(
"halign" ) ).toInt() );
422 mVAlignment =
static_cast< Qt::AlignmentFlag
>( itemElem.attribute( QStringLiteral(
"valign" ) ).toInt() );
428 QDomNodeList fontColorList = itemElem.elementsByTagName( QStringLiteral(
"FontColor" ) );
429 if ( !fontColorList.isEmpty() )
431 QDomElement fontColorElem = fontColorList.at( 0 ).toElement();
432 int red = fontColorElem.attribute( QStringLiteral(
"red" ), QStringLiteral(
"0" ) ).toInt();
433 int green = fontColorElem.attribute( QStringLiteral(
"green" ), QStringLiteral(
"0" ) ).toInt();
434 int blue = fontColorElem.attribute( QStringLiteral(
"blue" ), QStringLiteral(
"0" ) ).toInt();
435 int alpha = fontColorElem.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"255" ) ).toInt();
436 mFontColor = QColor( red, green, blue, alpha );
440 mFontColor = QColor( 0, 0, 0 );
448 if ( !
id().isEmpty() )
456 return tr(
"<HTML Label>" );
462 QString
text = mText;
463 if (
text.isEmpty() )
465 return tr(
"<Label>" );
467 if (
text.length() > 25 )
469 return QString( tr(
"%1…" ) ).arg(
text.left( 25 ).simplified() );
473 return text.simplified();
482 QRectF rectangle = rect();
483 double penWidth =
frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
484 rectangle.adjust( -penWidth, -penWidth, penWidth, penWidth );
488 rectangle.adjust( mMarginX, 0, -mMarginX, 0 );
492 rectangle.adjust( 0, mMarginY, 0, -mMarginY );
501 prepareGeometryChange();
507 prepareGeometryChange();
514 refreshExpressionContext();
517 void QgsLayoutItemLabel::itemShiftAdjustSize(
double newWidth,
double newHeight,
double &xShift,
double &yShift )
const
520 double currentWidth = rect().width();
521 double currentHeight = rect().height();
525 double r = rotation();
526 if ( r >= 0 && r < 90 )
528 if ( mHAlignment == Qt::AlignHCenter )
530 xShift = - ( newWidth - currentWidth ) / 2.0;
532 else if ( mHAlignment == Qt::AlignRight )
534 xShift = - ( newWidth - currentWidth );
536 if ( mVAlignment == Qt::AlignVCenter )
538 yShift = -( newHeight - currentHeight ) / 2.0;
540 else if ( mVAlignment == Qt::AlignBottom )
542 yShift = - ( newHeight - currentHeight );
545 if ( r >= 90 && r < 180 )
547 if ( mHAlignment == Qt::AlignHCenter )
549 yShift = -( newHeight - currentHeight ) / 2.0;
551 else if ( mHAlignment == Qt::AlignRight )
553 yShift = -( newHeight - currentHeight );
555 if ( mVAlignment == Qt::AlignTop )
557 xShift = -( newWidth - currentWidth );
559 else if ( mVAlignment == Qt::AlignVCenter )
561 xShift = -( newWidth - currentWidth / 2.0 );
564 else if ( r >= 180 && r < 270 )
566 if ( mHAlignment == Qt::AlignHCenter )
568 xShift = -( newWidth - currentWidth ) / 2.0;
570 else if ( mHAlignment == Qt::AlignLeft )
572 xShift = -( newWidth - currentWidth );
574 if ( mVAlignment == Qt::AlignVCenter )
576 yShift = ( newHeight - currentHeight ) / 2.0;
578 else if ( mVAlignment == Qt::AlignTop )
580 yShift = ( newHeight - currentHeight );
583 else if ( r >= 270 && r < 360 )
585 if ( mHAlignment == Qt::AlignHCenter )
587 yShift = -( newHeight - currentHeight ) / 2.0;
589 else if ( mHAlignment == Qt::AlignLeft )
591 yShift = -( newHeight - currentHeight );
593 if ( mVAlignment == Qt::AlignBottom )
595 xShift = -( newWidth - currentWidth );
597 else if ( mVAlignment == Qt::AlignVCenter )
599 xShift = -( newWidth - currentWidth / 2.0 );
604 QUrl QgsLayoutItemLabel::createStylesheetUrl()
const
607 stylesheet += QStringLiteral(
"body { margin: %1 %2;" ).arg( std::max( mMarginY * mHtmlUnitsToLayoutUnits, 0.0 ) ).arg( std::max( mMarginX * mHtmlUnitsToLayoutUnits, 0.0 ) );
609 stylesheet += QStringLiteral(
"color: rgba(%1,%2,%3,%4);" ).arg( mFontColor.red() ).arg( mFontColor.green() ).arg( mFontColor.blue() ).arg( QString::number( mFontColor.alphaF(),
'f', 4 ) );
610 stylesheet += QStringLiteral(
"text-align: %1; }" ).arg( mHAlignment == Qt::AlignLeft ? QStringLiteral(
"left" ) : mHAlignment == Qt::AlignRight ? QStringLiteral(
"right" ) : mHAlignment == Qt::AlignHCenter ? QStringLiteral(
"center" ) : QStringLiteral(
"justify" ) );
613 ba.append( stylesheet.toUtf8() );
614 QUrl cssFileURL = QUrl( QString(
"data:text/css;charset=utf-8;base64," + ba.toBase64() ) );