/*************************************************************************** qgsfontbutton.h --------------- Date : May 2017 Copyright : (C) 2017 by Nyall Dawson Email : nyall dot dawson at gmail dot com *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "qgsfontbutton.h" #include "qgstextformatwidget.h" #include "qgssymbollayerutils.h" #include "qgscolorscheme.h" #include "qgsmapcanvas.h" #include "qgscolorwidgets.h" #include "qgscolorschemeregistry.h" #include "qgscolorswatchgrid.h" #include "qgsdoublespinbox.h" #include "qgsunittypes.h" #include "qgsmenuheader.h" #include "qgsfontutils.h" #include #include #include #include #include QgsFontButton::QgsFontButton( QWidget *parent, const QString &dialogTitle ) : QToolButton( parent ) , mDialogTitle( dialogTitle.isEmpty() ? tr( "Text Format" ) : dialogTitle ) { setText( tr( "Font" ) ); setAcceptDrops( true ); connect( this, &QAbstractButton::clicked, this, &QgsFontButton::showSettingsDialog ); //setup dropdown menu mMenu = new QMenu( this ); connect( mMenu, &QMenu::aboutToShow, this, &QgsFontButton::prepareMenu ); setMenu( mMenu ); setPopupMode( QToolButton::MenuButtonPopup ); //make sure height of button looks good under different platforms QSize size = QToolButton::minimumSizeHint(); int fontHeight = Qgis::UI_SCALE_FACTOR * fontMetrics().height() * 1.4; mSizeHint = QSize( size.width(), std::max( size.height(), fontHeight ) ); } QSize QgsFontButton::minimumSizeHint() const { return mSizeHint; } QSize QgsFontButton::sizeHint() const { return mSizeHint; } void QgsFontButton::showSettingsDialog() { switch ( mMode ) { case ModeTextRenderer: { QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this ); if ( panel && panel->dockMode() ) { QgsTextFormatPanelWidget *formatWidget = new QgsTextFormatPanelWidget( mFormat, mMapCanvas, this ); formatWidget->setPanelTitle( mDialogTitle ); connect( formatWidget, &QgsTextFormatPanelWidget::widgetChanged, this, [ this, formatWidget ] { this->setTextFormat( formatWidget->format() ); } ); panel->openPanel( formatWidget ); return; } QgsTextFormatDialog dialog( mFormat, mMapCanvas, this ); dialog.setWindowTitle( mDialogTitle ); if ( dialog.exec() ) { setTextFormat( dialog.format() ); QgsFontUtils::addRecentFontFamily( mFormat.font().family() ); } break; } case ModeQFont: { bool ok; QFont newFont = QgsGuiUtils::getFont( ok, mFont, mDialogTitle ); if ( ok ) { QgsFontUtils::addRecentFontFamily( newFont.family() ); setCurrentFont( newFont ); } break; } } // reactivate button's window activateWindow(); raise(); } QgsMapCanvas *QgsFontButton::mapCanvas() const { return mMapCanvas; } void QgsFontButton::setMapCanvas( QgsMapCanvas *mapCanvas ) { mMapCanvas = mapCanvas; } void QgsFontButton::setTextFormat( const QgsTextFormat &format ) { mFormat = format; updatePreview(); emit changed(); } void QgsFontButton::setColor( const QColor &color ) { QColor opaque = color; opaque.setAlphaF( 1.0 ); if ( mFormat.color() != opaque ) { mFormat.setColor( opaque ); updatePreview(); emit changed(); } } void QgsFontButton::copyFormat() { switch ( mMode ) { case ModeTextRenderer: QApplication::clipboard()->setMimeData( mFormat.toMimeData() ); break; case ModeQFont: QApplication::clipboard()->setMimeData( QgsFontUtils::toMimeData( mFont ) ); break; } } void QgsFontButton::pasteFormat() { QgsTextFormat tempFormat; QFont font; if ( mMode == ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) ) { setTextFormat( tempFormat ); QgsFontUtils::addRecentFontFamily( mFormat.font().family() ); } else if ( mMode == ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), font ) ) { QgsFontUtils::addRecentFontFamily( font.family() ); setCurrentFont( font ); } } bool QgsFontButton::event( QEvent *e ) { if ( e->type() == QEvent::ToolTip ) { QHelpEvent *helpEvent = static_cast< QHelpEvent *>( e ); QString toolTip; double fontSize = 0.0; switch ( mMode ) { case ModeTextRenderer: fontSize = mFormat.size(); break; case ModeQFont: fontSize = mFont.pointSizeF(); break; } toolTip = QStringLiteral( "%1
%2
Size: %3" ).arg( text(), mFormat.font().family() ).arg( fontSize ); QToolTip::showText( helpEvent->globalPos(), toolTip ); } return QToolButton::event( e ); } void QgsFontButton::mousePressEvent( QMouseEvent *e ) { if ( e->button() == Qt::RightButton ) { QToolButton::showMenu(); return; } else if ( e->button() == Qt::LeftButton ) { mDragStartPosition = e->pos(); } QToolButton::mousePressEvent( e ); } void QgsFontButton::mouseMoveEvent( QMouseEvent *e ) { //handle dragging fonts from button if ( !( e->buttons() & Qt::LeftButton ) ) { //left button not depressed, so not a drag QToolButton::mouseMoveEvent( e ); return; } if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() ) { //mouse not moved, so not a drag QToolButton::mouseMoveEvent( e ); return; } //user is dragging font QDrag *drag = new QDrag( this ); switch ( mMode ) { case ModeTextRenderer: drag->setMimeData( mFormat.toMimeData() ); break; case ModeQFont: drag->setMimeData( QgsFontUtils::toMimeData( mFont ) ); break; } drag->setPixmap( createDragIcon() ); drag->exec( Qt::CopyAction ); setDown( false ); } bool QgsFontButton::colorFromMimeData( const QMimeData *mimeData, QColor &resultColor, bool &hasAlpha ) { hasAlpha = false; QColor mimeColor = QgsSymbolLayerUtils::colorFromMimeData( mimeData, hasAlpha ); if ( mimeColor.isValid() ) { resultColor = mimeColor; return true; } //could not get color from mime data return false; } void QgsFontButton::dragEnterEvent( QDragEnterEvent *e ) { //is dragged data valid font data? QColor mimeColor; QgsTextFormat format; QFont font; bool hasAlpha = false; if ( mMode == ModeTextRenderer && formatFromMimeData( e->mimeData(), format ) ) { e->acceptProposedAction(); updatePreview( QColor(), &format ); } else if ( mMode == ModeQFont && fontFromMimeData( e->mimeData(), font ) ) { e->acceptProposedAction(); updatePreview( QColor(), nullptr, &font ); } else if ( mMode == ModeTextRenderer && colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) ) { //if so, we accept the drag, and temporarily change the button's color //to match the dragged color. This gives immediate feedback to the user //that colors can be dropped here e->acceptProposedAction(); updatePreview( mimeColor ); } } void QgsFontButton::dragLeaveEvent( QDragLeaveEvent *e ) { Q_UNUSED( e ); //reset button color updatePreview(); } void QgsFontButton::dropEvent( QDropEvent *e ) { //is dropped data valid format data? QColor mimeColor; QgsTextFormat format; QFont font; bool hasAlpha = false; if ( mMode == ModeTextRenderer && formatFromMimeData( e->mimeData(), format ) ) { setTextFormat( format ); QgsFontUtils::addRecentFontFamily( mFormat.font().family() ); return; } else if ( mMode == ModeQFont && fontFromMimeData( e->mimeData(), font ) ) { QgsFontUtils::addRecentFontFamily( font.family() ); setCurrentFont( font ); return; } else if ( mMode == ModeTextRenderer && colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) ) { //accept drop and set new color e->acceptProposedAction(); if ( hasAlpha ) { mFormat.setOpacity( mimeColor.alphaF() ); } mimeColor.setAlphaF( 1.0 ); mFormat.setColor( mimeColor ); QgsRecentColorScheme::addRecentColor( mimeColor ); updatePreview(); emit changed(); } updatePreview(); } void QgsFontButton::wheelEvent( QWheelEvent *event ) { double size = 0; switch ( mMode ) { case ModeTextRenderer: size = mFormat.size(); break; case ModeQFont: size = mFont.pointSizeF(); break; } double increment = event->modifiers() & Qt::ControlModifier ? 0.1 : 1; if ( event->delta() > 0 ) { size += increment; } else { size -= increment; } size = std::max( size, 1.0 ); switch ( mMode ) { case ModeTextRenderer: { QgsTextFormat newFormat = mFormat; newFormat.setSize( size ); setTextFormat( newFormat ); break; } case ModeQFont: { QFont newFont = mFont; newFont.setPointSizeF( size ); setCurrentFont( newFont ); break; } } event->accept(); } QPixmap QgsFontButton::createColorIcon( const QColor &color ) const { //create an icon pixmap QPixmap pixmap( 16, 16 ); pixmap.fill( Qt::transparent ); QPainter p; p.begin( &pixmap ); //draw color over pattern p.setBrush( QBrush( color ) ); //draw border p.setPen( QColor( 197, 197, 197 ) ); p.drawRect( 0, 0, 15, 15 ); p.end(); return pixmap; } QPixmap QgsFontButton::createDragIcon( QSize size, const QgsTextFormat *tempFormat, const QFont *tempFont ) const { if ( !tempFormat ) tempFormat = &mFormat; if ( !tempFont ) tempFont = &mFont; //create an icon pixmap QPixmap pixmap( size.width(), size.height() ); pixmap.fill( Qt::transparent ); QPainter p; p.begin( &pixmap ); p.setRenderHint( QPainter::Antialiasing ); QRect rect( 0, 0, size.width(), size.height() ); if ( mMode == ModeQFont || tempFormat->color().lightnessF() < 0.7 ) { p.setBrush( QBrush( QColor( 255, 255, 255 ) ) ); p.setPen( QPen( QColor( 150, 150, 150 ), 0 ) ); } else { p.setBrush( QBrush( QColor( 0, 0, 0 ) ) ); p.setPen( QPen( QColor( 100, 100, 100 ), 0 ) ); } p.drawRect( rect ); p.setBrush( Qt::NoBrush ); p.setPen( Qt::NoPen ); switch ( mMode ) { case ModeTextRenderer: { QgsRenderContext context; QgsMapToPixel newCoordXForm; newCoordXForm.setParameters( 1, 0, 0, 0, 0, 0 ); context.setMapToPixel( newCoordXForm ); context.setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 ); context.setUseAdvancedEffects( true ); context.setPainter( &p ); // slightly inset text to account for buffer/background double xtrans = 0; if ( tempFormat->buffer().enabled() ) xtrans = context.convertToPainterUnits( tempFormat->buffer().size(), tempFormat->buffer().sizeUnit(), tempFormat->buffer().sizeMapUnitScale() ); if ( tempFormat->background().enabled() && tempFormat->background().sizeType() != QgsTextBackgroundSettings::SizeFixed ) xtrans = std::max( xtrans, context.convertToPainterUnits( tempFormat->background().size().width(), tempFormat->background().sizeUnit(), tempFormat->background().sizeMapUnitScale() ) ); double ytrans = 0.0; if ( tempFormat->buffer().enabled() ) ytrans = std::max( ytrans, context.convertToPainterUnits( tempFormat->buffer().size(), tempFormat->buffer().sizeUnit(), tempFormat->buffer().sizeMapUnitScale() ) ); if ( tempFormat->background().enabled() ) ytrans = std::max( ytrans, context.convertToPainterUnits( tempFormat->background().size().height(), tempFormat->background().sizeUnit(), tempFormat->background().sizeMapUnitScale() ) ); QRectF textRect = rect; textRect.setLeft( xtrans ); textRect.setWidth( textRect.width() - xtrans ); textRect.setTop( ytrans ); if ( textRect.height() > 300 ) textRect.setHeight( 300 ); if ( textRect.width() > 2000 ) textRect.setWidth( 2000 ); QgsTextRenderer::drawText( textRect, 0, QgsTextRenderer::AlignCenter, QStringList() << tr( "Aa" ), context, *tempFormat ); break; } case ModeQFont: { p.setBrush( Qt::NoBrush ); p.setPen( QColor( 0, 0, 0 ) ); p.setFont( *tempFont ); QRectF textRect = rect; textRect.setLeft( 2 ); p.drawText( textRect, Qt::AlignVCenter, tr( "Aa" ) ); break; } } p.end(); return pixmap; } void QgsFontButton::prepareMenu() { //we need to tear down and rebuild this menu every time it is shown. Otherwise the space allocated to any //QgsColorSwatchGridAction is not recalculated by Qt and the swatch grid may not be the correct size //for the number of colors shown in the grid. Note that we MUST refresh color swatch grids every time this //menu is opened, otherwise color schemes like the recent color scheme grid are meaningless mMenu->clear(); QWidgetAction *sizeAction = new QWidgetAction( mMenu ); QWidget *sizeWidget = new QWidget(); QVBoxLayout *sizeLayout = new QVBoxLayout(); sizeLayout->setMargin( 0 ); sizeLayout->setContentsMargins( 0, 0, 0, 3 ); sizeLayout->setSpacing( 2 ); QString fontHeaderLabel; switch ( mMode ) { case ModeTextRenderer: fontHeaderLabel = tr( "Font size (%1)" ).arg( QgsUnitTypes::toString( mFormat.sizeUnit() ) ); break; case ModeQFont: fontHeaderLabel = tr( "Font size (pt)" ); break; } QgsMenuHeader *sizeLabel = new QgsMenuHeader( fontHeaderLabel ); sizeLayout->addWidget( sizeLabel ); QgsDoubleSpinBox *sizeSpin = new QgsDoubleSpinBox( nullptr ); sizeSpin->setDecimals( 4 ); sizeSpin->setMaximum( 1e+9 ); sizeSpin->setShowClearButton( false ); sizeSpin->setValue( mMode == ModeTextRenderer ? mFormat.size() : mFont.pointSizeF() ); connect( sizeSpin, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( double value ) { switch ( mMode ) { case ModeTextRenderer: mFormat.setSize( value ); break; case ModeQFont: mFont.setPointSizeF( value ); break; } updatePreview(); emit changed(); } ); QHBoxLayout *spinLayout = new QHBoxLayout(); spinLayout->setMargin( 0 ); spinLayout->setContentsMargins( 4, 0, 4, 0 ); spinLayout->addWidget( sizeSpin ); sizeLayout->addLayout( spinLayout ); sizeWidget->setLayout( sizeLayout ); sizeAction->setDefaultWidget( sizeWidget ); sizeWidget->setFocusProxy( sizeSpin ); sizeWidget->setFocusPolicy( Qt::StrongFocus ); mMenu->addAction( sizeAction ); QMenu *recentFontMenu = new QMenu( tr( "Recent fonts" ), mMenu ); Q_FOREACH ( const QString &family, QgsFontUtils::recentFontFamilies() ) { QAction *fontAction = new QAction( family, recentFontMenu ); QFont f = fontAction->font(); f.setFamily( family ); fontAction->setFont( f ); fontAction->setToolTip( family ); recentFontMenu->addAction( fontAction ); if ( ( mMode == ModeTextRenderer && family == mFormat.font().family() ) || ( mMode == ModeQFont && family == mFont.family() ) ) { fontAction->setCheckable( true ); fontAction->setChecked( true ); } auto setFont = [this, family] { switch ( mMode ) { case ModeTextRenderer: { QgsTextFormat newFormat = mFormat; QFont f = newFormat.font(); f.setFamily( family ); newFormat.setFont( f ); setTextFormat( newFormat ); QgsFontUtils::addRecentFontFamily( mFormat.font().family() ); break; } case ModeQFont: { QFont font = mFont; font.setFamily( family ); setCurrentFont( font ); QgsFontUtils::addRecentFontFamily( family ); break; } } }; connect( fontAction, &QAction::triggered, this, setFont ); } mMenu->addMenu( recentFontMenu ); QAction *configureAction = new QAction( tr( "Configure Format…" ), this ); mMenu->addAction( configureAction ); connect( configureAction, &QAction::triggered, this, &QgsFontButton::showSettingsDialog ); QAction *copyFormatAction = new QAction( tr( "Copy Format" ), this ); mMenu->addAction( copyFormatAction ); connect( copyFormatAction, &QAction::triggered, this, &QgsFontButton::copyFormat ); QAction *pasteFormatAction = new QAction( tr( "Paste Format" ), this ); //enable or disable paste action based on current clipboard contents. We always show the paste //action, even if it's disabled, to give hint to the user that pasting colors is possible QgsTextFormat tempFormat; QFont tempFont; if ( mMode == ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) ) { tempFormat.setSizeUnit( QgsUnitTypes::RenderPixels ); tempFormat.setSize( 14 ); pasteFormatAction->setIcon( createDragIcon( QSize( 16, 16 ), &tempFormat ) ); } else if ( mMode == ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), tempFont ) ) { tempFont.setPointSize( 8 ); pasteFormatAction->setIcon( createDragIcon( QSize( 16, 16 ), nullptr, &tempFont ) ); } else { pasteFormatAction->setEnabled( false ); } mMenu->addAction( pasteFormatAction ); connect( pasteFormatAction, &QAction::triggered, this, &QgsFontButton::pasteFormat ); if ( mMode == ModeTextRenderer ) { mMenu->addSeparator(); QgsColorWheel *colorWheel = new QgsColorWheel( mMenu ); colorWheel->setColor( mFormat.color() ); QgsColorWidgetAction *colorAction = new QgsColorWidgetAction( colorWheel, mMenu, mMenu ); colorAction->setDismissOnColorSelection( false ); connect( colorAction, &QgsColorWidgetAction::colorChanged, this, &QgsFontButton::setColor ); mMenu->addAction( colorAction ); QgsColorRampWidget *alphaRamp = new QgsColorRampWidget( mMenu, QgsColorWidget::Alpha, QgsColorRampWidget::Horizontal ); QColor alphaColor = mFormat.color(); alphaColor.setAlphaF( mFormat.opacity() ); alphaRamp->setColor( alphaColor ); QgsColorWidgetAction *alphaAction = new QgsColorWidgetAction( alphaRamp, mMenu, mMenu ); alphaAction->setDismissOnColorSelection( false ); connect( alphaAction, &QgsColorWidgetAction::colorChanged, this, [ = ]( const QColor & color ) { double opacity = color.alphaF(); mFormat.setOpacity( opacity ); updatePreview(); emit changed(); } ); connect( colorAction, &QgsColorWidgetAction::colorChanged, alphaRamp, [alphaRamp]( const QColor & color ) { alphaRamp->setColor( color, false ); } ); mMenu->addAction( alphaAction ); //get schemes with ShowInColorButtonMenu flag set QList< QgsColorScheme * > schemeList = QgsApplication::colorSchemeRegistry()->schemes( QgsColorScheme::ShowInColorButtonMenu ); QList< QgsColorScheme * >::iterator it = schemeList.begin(); for ( ; it != schemeList.end(); ++it ) { QgsColorSwatchGridAction *colorAction = new QgsColorSwatchGridAction( *it, mMenu, QStringLiteral( "labeling" ), this ); colorAction->setBaseColor( mFormat.color() ); mMenu->addAction( colorAction ); connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsFontButton::setColor ); connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsFontButton::addRecentColor ); } mMenu->addSeparator(); QAction *copyColorAction = new QAction( tr( "Copy Color" ), this ); mMenu->addAction( copyColorAction ); connect( copyColorAction, &QAction::triggered, this, &QgsFontButton::copyColor ); QAction *pasteColorAction = new QAction( tr( "Paste Color" ), this ); //enable or disable paste action based on current clipboard contents. We always show the paste //action, even if it's disabled, to give hint to the user that pasting colors is possible QColor clipColor; bool hasAlpha = false; if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) ) { pasteColorAction->setIcon( createColorIcon( clipColor ) ); } else { pasteColorAction->setEnabled( false ); } mMenu->addAction( pasteColorAction ); connect( pasteColorAction, &QAction::triggered, this, &QgsFontButton::pasteColor ); } } void QgsFontButton::addRecentColor( const QColor &color ) { QgsRecentColorScheme::addRecentColor( color ); } QFont QgsFontButton::currentFont() const { return mFont; } void QgsFontButton::setCurrentFont( const QFont &font ) { mFont = font; updatePreview(); emit changed(); } QgsFontButton::Mode QgsFontButton::mode() const { return mMode; } void QgsFontButton::setMode( Mode mode ) { mMode = mode; updatePreview(); } bool QgsFontButton::formatFromMimeData( const QMimeData *mimeData, QgsTextFormat &resultFormat ) const { bool ok = false; resultFormat = QgsTextFormat::fromMimeData( mimeData, &ok ); return ok; } bool QgsFontButton::fontFromMimeData( const QMimeData *mimeData, QFont &resultFont ) const { bool ok = false; resultFont = QgsFontUtils::fromMimeData( mimeData, &ok ); return ok; } void QgsFontButton::changeEvent( QEvent *e ) { if ( e->type() == QEvent::EnabledChange ) { updatePreview(); } QToolButton::changeEvent( e ); } void QgsFontButton::showEvent( QShowEvent *e ) { updatePreview(); QToolButton::showEvent( e ); } void QgsFontButton::resizeEvent( QResizeEvent *event ) { QToolButton::resizeEvent( event ); //recalculate icon size and redraw icon mIconSize = QSize(); updatePreview(); } void QgsFontButton::updatePreview( const QColor &color, QgsTextFormat *format, QFont *font ) { QgsTextFormat tempFormat; QFont tempFont; if ( format ) tempFormat = *format; else tempFormat = mFormat; if ( font ) tempFont = *font; else tempFont = mFont; if ( color.isValid() ) tempFormat.setColor( color ); QSize currentIconSize; //icon size is button size with a small margin if ( menu() ) { if ( !mIconSize.isValid() ) { //calculate size of push button part of widget (ie, without the menu dropdown button part) QStyleOptionToolButton opt; initStyleOption( &opt ); QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton, this ); //make sure height of icon looks good under different platforms #ifdef Q_OS_WIN mIconSize = QSize( buttonSize.width() - 10, height() - 6 ); #else mIconSize = QSize( buttonSize.width() - 10, height() - 12 ); #endif } currentIconSize = mIconSize; } else { //no menu #ifdef Q_OS_WIN currentIconSize = QSize( width() - 10, height() - 6 ); #else currentIconSize = QSize( width() - 10, height() - 12 ); #endif } if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 ) { return; } //create an icon pixmap QPixmap pixmap( currentIconSize ); pixmap.fill( Qt::transparent ); QPainter p; p.begin( &pixmap ); p.setRenderHint( QPainter::Antialiasing ); QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() ); switch ( mMode ) { case ModeTextRenderer: { QgsRenderContext context; QgsMapToPixel newCoordXForm; newCoordXForm.setParameters( 1, 0, 0, 0, 0, 0 ); context.setMapToPixel( newCoordXForm ); context.setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 ); context.setUseAdvancedEffects( true ); context.setPainter( &p ); // slightly inset text to account for buffer/background double xtrans = 0; if ( tempFormat.buffer().enabled() ) xtrans = context.convertToPainterUnits( tempFormat.buffer().size(), tempFormat.buffer().sizeUnit(), tempFormat.buffer().sizeMapUnitScale() ); if ( tempFormat.background().enabled() && tempFormat.background().sizeType() != QgsTextBackgroundSettings::SizeFixed ) xtrans = std::max( xtrans, context.convertToPainterUnits( tempFormat.background().size().width(), tempFormat.background().sizeUnit(), tempFormat.background().sizeMapUnitScale() ) ); double ytrans = 0.0; if ( tempFormat.buffer().enabled() ) ytrans = std::max( ytrans, context.convertToPainterUnits( tempFormat.buffer().size(), tempFormat.buffer().sizeUnit(), tempFormat.buffer().sizeMapUnitScale() ) ); if ( tempFormat.background().enabled() ) ytrans = std::max( ytrans, context.convertToPainterUnits( tempFormat.background().size().height(), tempFormat.background().sizeUnit(), tempFormat.background().sizeMapUnitScale() ) ); QRectF textRect = rect; textRect.setLeft( xtrans ); textRect.setWidth( textRect.width() - xtrans ); textRect.setTop( ytrans ); if ( textRect.height() > 300 ) textRect.setHeight( 300 ); if ( textRect.width() > 2000 ) textRect.setWidth( 2000 ); QgsTextRenderer::drawText( textRect, 0, QgsTextRenderer::AlignLeft, QStringList() << text(), context, tempFormat ); break; } case ModeQFont: { p.setBrush( Qt::NoBrush ); p.setPen( QColor( 0, 0, 0 ) ); p.setFont( tempFont ); QRectF textRect = rect; textRect.setLeft( 2 ); p.drawText( textRect, Qt::AlignVCenter, text() ); break; } } p.end(); setIconSize( currentIconSize ); setIcon( pixmap ); } void QgsFontButton::copyColor() { //copy color QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mFormat.color() ) ); } void QgsFontButton::pasteColor() { QColor clipColor; bool hasAlpha = false; if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) ) { //paste color setColor( clipColor ); QgsRecentColorScheme::addRecentColor( clipColor ); } } void QgsFontButton::setDialogTitle( const QString &title ) { mDialogTitle = title; } QString QgsFontButton::dialogTitle() const { return mDialogTitle; }