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 );
156 void QgsLayoutItemLabel::contentChanged()
174 const QUrl baseUrl = QUrl::fromLocalFile(
mLayout->project()->absoluteFilePath() );
175 mWebPage->mainFrame()->setHtml( textToDraw, baseUrl );
183 if ( !mHtmlLoaded && ( !
mLayout || !
mLayout->renderContext().isPreviewRender() ) )
189 connect( mWebPage.get(), &QWebPage::loadFinished, &loop, &QEventLoop::quit );
193 timeoutTimer.setSingleShot(
true );
194 connect( &timeoutTimer, &QTimer::timeout, &loop, &QEventLoop::quit );
195 timeoutTimer.start( 20000 );
198 loop.exec( QEventLoop::ExcludeUserInputEvents );
207 void QgsLayoutItemLabel::loadingHtmlFinished(
bool result )
215 double QgsLayoutItemLabel::htmlUnitsToLayoutUnits()
236 mLayout->itemsModel()->updateItemDisplayName(
this );
250 if (
mLayout &&
id().isEmpty() )
253 mLayout->itemsModel()->updateItemDisplayName(
this );
257 void QgsLayoutItemLabel::refreshExpressionContext()
266 mDistanceArea->setSourceCrs( layer->
crs(),
mLayout->project()->transformContext() );
273 mDistanceArea->setSourceCrs( referenceMap->
crs(),
mLayout->project()->transformContext() );
275 mDistanceArea->setEllipsoid(
mLayout->project()->ellipsoid() );
283 QString displayText = mText;
284 replaceDateText( displayText );
291 void QgsLayoutItemLabel::replaceDateText( QString &text )
const
293 QString constant = QStringLiteral(
"$CURRENT_DATE" );
294 int currentDatePos =
text.indexOf( constant );
295 if ( currentDatePos != -1 )
299 int openingBracketPos =
text.indexOf(
'(', currentDatePos );
300 int closingBracketPos =
text.indexOf(
')', openingBracketPos + 1 );
301 if ( openingBracketPos != -1 &&
302 closingBracketPos != -1 &&
303 ( closingBracketPos - openingBracketPos ) > 1 &&
304 openingBracketPos == currentDatePos + constant.size() )
306 formatText =
text.mid( openingBracketPos + 1, closingBracketPos - openingBracketPos - 1 );
307 text.replace( currentDatePos, closingBracketPos - currentDatePos + 1, QDate::currentDate().toString( formatText ) );
311 text.replace( QLatin1String(
"$CURRENT_DATE" ), QDate::currentDate().toString() );
325 prepareGeometryChange();
331 prepareGeometryChange();
337 prepareGeometryChange();
348 itemShiftAdjustSize( newSize.width(), newSize.height(), xShift, yShift );
351 attemptSetSceneRect( QRectF( pos().x() + xShift, pos().y() + yShift, newSize.width(), newSize.height() ) );
359 double penWidth =
frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
361 double width = textWidth + 2 * mMarginX + 2 * penWidth;
362 double height = fontHeight + 2 * mMarginY + 2 * penWidth;
374 layoutLabelElem.setAttribute( QStringLiteral(
"htmlState" ),
static_cast< int >( mMode ) );
376 layoutLabelElem.setAttribute( QStringLiteral(
"labelText" ), mText );
377 layoutLabelElem.setAttribute( QStringLiteral(
"marginX" ), QString::number( mMarginX ) );
378 layoutLabelElem.setAttribute( QStringLiteral(
"marginY" ), QString::number( mMarginY ) );
379 layoutLabelElem.setAttribute( QStringLiteral(
"halign" ), mHAlignment );
380 layoutLabelElem.setAttribute( QStringLiteral(
"valign" ), mVAlignment );
384 layoutLabelElem.appendChild( labelFontElem );
387 QDomElement fontColorElem = doc.createElement( QStringLiteral(
"FontColor" ) );
388 fontColorElem.setAttribute( QStringLiteral(
"red" ), mFontColor.red() );
389 fontColorElem.setAttribute( QStringLiteral(
"green" ), mFontColor.green() );
390 fontColorElem.setAttribute( QStringLiteral(
"blue" ), mFontColor.blue() );
391 fontColorElem.setAttribute( QStringLiteral(
"alpha" ), mFontColor.alpha() );
392 layoutLabelElem.appendChild( fontColorElem );
402 mText = itemElem.attribute( QStringLiteral(
"labelText" ) );
405 mMode =
static_cast< Mode >( itemElem.attribute( QStringLiteral(
"htmlState" ) ).toInt() );
408 bool marginXOk =
false;
409 bool marginYOk =
false;
410 mMarginX = itemElem.attribute( QStringLiteral(
"marginX" ) ).toDouble( &marginXOk );
411 mMarginY = itemElem.attribute( QStringLiteral(
"marginY" ) ).toDouble( &marginYOk );
412 if ( !marginXOk || !marginYOk )
415 double margin = itemElem.attribute( QStringLiteral(
"margin" ), QStringLiteral(
"1.0" ) ).toDouble();
421 mHAlignment =
static_cast< Qt::AlignmentFlag
>( itemElem.attribute( QStringLiteral(
"halign" ) ).toInt() );
424 mVAlignment =
static_cast< Qt::AlignmentFlag
>( itemElem.attribute( QStringLiteral(
"valign" ) ).toInt() );
430 QDomNodeList fontColorList = itemElem.elementsByTagName( QStringLiteral(
"FontColor" ) );
431 if ( !fontColorList.isEmpty() )
433 QDomElement fontColorElem = fontColorList.at( 0 ).toElement();
434 int red = fontColorElem.attribute( QStringLiteral(
"red" ), QStringLiteral(
"0" ) ).toInt();
435 int green = fontColorElem.attribute( QStringLiteral(
"green" ), QStringLiteral(
"0" ) ).toInt();
436 int blue = fontColorElem.attribute( QStringLiteral(
"blue" ), QStringLiteral(
"0" ) ).toInt();
437 int alpha = fontColorElem.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"255" ) ).toInt();
438 mFontColor = QColor( red, green, blue, alpha );
442 mFontColor = QColor( 0, 0, 0 );
450 if ( !
id().isEmpty() )
458 return tr(
"<HTML Label>" );
464 QString
text = mText;
465 if (
text.isEmpty() )
467 return tr(
"<Label>" );
469 if (
text.length() > 25 )
471 return QString( tr(
"%1…" ) ).arg(
text.left( 25 ).simplified() );
475 return text.simplified();
484 QRectF rectangle = rect();
485 double penWidth =
frameEnabled() ? ( pen().widthF() / 2.0 ) : 0;
486 rectangle.adjust( -penWidth, -penWidth, penWidth, penWidth );
490 rectangle.adjust( mMarginX, 0, -mMarginX, 0 );
494 rectangle.adjust( 0, mMarginY, 0, -mMarginY );
503 prepareGeometryChange();
509 prepareGeometryChange();
516 refreshExpressionContext();
519 void QgsLayoutItemLabel::itemShiftAdjustSize(
double newWidth,
double newHeight,
double &xShift,
double &yShift )
const
522 double currentWidth = rect().width();
523 double currentHeight = rect().height();
527 double r = rotation();
528 if ( r >= 0 && r < 90 )
530 if ( mHAlignment == Qt::AlignHCenter )
532 xShift = - ( newWidth - currentWidth ) / 2.0;
534 else if ( mHAlignment == Qt::AlignRight )
536 xShift = - ( newWidth - currentWidth );
538 if ( mVAlignment == Qt::AlignVCenter )
540 yShift = -( newHeight - currentHeight ) / 2.0;
542 else if ( mVAlignment == Qt::AlignBottom )
544 yShift = - ( newHeight - currentHeight );
547 if ( r >= 90 && r < 180 )
549 if ( mHAlignment == Qt::AlignHCenter )
551 yShift = -( newHeight - currentHeight ) / 2.0;
553 else if ( mHAlignment == Qt::AlignRight )
555 yShift = -( newHeight - currentHeight );
557 if ( mVAlignment == Qt::AlignTop )
559 xShift = -( newWidth - currentWidth );
561 else if ( mVAlignment == Qt::AlignVCenter )
563 xShift = -( newWidth - currentWidth / 2.0 );
566 else if ( r >= 180 && r < 270 )
568 if ( mHAlignment == Qt::AlignHCenter )
570 xShift = -( newWidth - currentWidth ) / 2.0;
572 else if ( mHAlignment == Qt::AlignLeft )
574 xShift = -( newWidth - currentWidth );
576 if ( mVAlignment == Qt::AlignVCenter )
578 yShift = ( newHeight - currentHeight ) / 2.0;
580 else if ( mVAlignment == Qt::AlignTop )
582 yShift = ( newHeight - currentHeight );
585 else if ( r >= 270 && r < 360 )
587 if ( mHAlignment == Qt::AlignHCenter )
589 yShift = -( newHeight - currentHeight ) / 2.0;
591 else if ( mHAlignment == Qt::AlignLeft )
593 yShift = -( newHeight - currentHeight );
595 if ( mVAlignment == Qt::AlignBottom )
597 xShift = -( newWidth - currentWidth );
599 else if ( mVAlignment == Qt::AlignVCenter )
601 xShift = -( newWidth - currentWidth / 2.0 );
606 QUrl QgsLayoutItemLabel::createStylesheetUrl()
const
609 stylesheet += QStringLiteral(
"body { margin: %1 %2;" ).arg( std::max( mMarginY * mHtmlUnitsToLayoutUnits, 0.0 ) ).arg( std::max( mMarginX * mHtmlUnitsToLayoutUnits, 0.0 ) );
611 stylesheet += QStringLiteral(
"color: rgba(%1,%2,%3,%4);" ).arg( mFontColor.red() ).arg( mFontColor.green() ).arg( mFontColor.blue() ).arg( QString::number( mFontColor.alphaF(),
'f', 4 ) );
612 stylesheet += QStringLiteral(
"text-align: %1; }" ).arg( mHAlignment == Qt::AlignLeft ? QStringLiteral(
"left" ) : mHAlignment == Qt::AlignRight ? QStringLiteral(
"right" ) : mHAlignment == Qt::AlignHCenter ? QStringLiteral(
"center" ) : QStringLiteral(
"justify" ) );
615 ba.append( stylesheet.toUtf8() );
616 QUrl cssFileURL = QUrl(
"data:text/css;charset=utf-8;base64," + ba.toBase64() );