35 #include <QDesktopWidget> 
   39   : QToolButton( parent )
 
   40   , mDialogTitle( dialogTitle.isEmpty() ? tr( 
"Text Format" ) : dialogTitle )
 
   41   , mNullFormatString( tr( 
"No Format" ) )
 
   43   setText( tr( 
"Font" ) );
 
   45   setAcceptDrops( 
true );
 
   46   connect( 
this, &QAbstractButton::clicked, 
this, &QgsFontButton::showSettingsDialog );
 
   49   mMenu = 
new QMenu( 
this );
 
   50   connect( mMenu, &QMenu::aboutToShow, 
this, &QgsFontButton::prepareMenu );
 
   52   setPopupMode( QToolButton::MenuButtonPopup );
 
   55   QSize size = QToolButton::minimumSizeHint();
 
   58   mSizeHint = QSize( std::max( minWidth, size.width() ), std::max( size.height(), fontHeight ) );
 
   71 void QgsFontButton::showSettingsDialog()
 
   78       if ( mExpressionContextGenerator )
 
   94         mActivePanel->setPanelTitle( mDialogTitle );
 
   95         mActivePanel->setContext( symbolContext );
 
  102       QgsTextFormatDialog dialog( mFormat, mMapCanvas, 
this, QgsGuiUtils::ModalDialogFlags, mLayer.data() );
 
  103       dialog.setWindowTitle( mDialogTitle );
 
  104       dialog.setContext( symbolContext );
 
  153   if ( mActivePanel && !format.
isValid() )
 
  154     mActivePanel->acceptPanel();
 
  159   if ( mActivePanel && format.
isValid() )
 
  160     mActivePanel->setFormat( format );
 
  173   QColor opaque = color;
 
  174   opaque.setAlphaF( 1.0 );
 
  176   if ( mNullFormatAction )
 
  177     mNullFormatAction->setChecked( 
false );
 
  179   if ( mFormat.
color() != opaque )
 
  192       QApplication::clipboard()->setMimeData( mFormat.
toMimeData() );
 
  205   if ( mMode == 
ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
 
  210   else if ( mMode == 
ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), font ) )
 
  219   if ( e->type() == QEvent::ToolTip )
 
  221     QHelpEvent *helpEvent = 
static_cast< QHelpEvent *
>( e );
 
  223     double fontSize = 0.0;
 
  227         fontSize = mFormat.
size();
 
  231         fontSize = mFont.pointSizeF();
 
  234     toolTip = QStringLiteral( 
"<b>%1</b><br>%2<br>Size: %3" ).arg( text(), mMode == 
ModeTextRenderer ? mFormat.
font().family() : mFont.family() ).arg( fontSize );
 
  235     QToolTip::showText( helpEvent->globalPos(), toolTip );
 
  237   return QToolButton::event( e );
 
  242   if ( e->button() == Qt::RightButton )
 
  244     QToolButton::showMenu();
 
  247   else if ( e->button() == Qt::LeftButton )
 
  249     mDragStartPosition = e->pos();
 
  251   QToolButton::mousePressEvent( e );
 
  258   if ( !( e->buttons() & Qt::LeftButton ) )
 
  261     QToolButton::mouseMoveEvent( e );
 
  265   if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
 
  268     QToolButton::mouseMoveEvent( e );
 
  273   QDrag *drag = 
new QDrag( 
this );
 
  286   drag->exec( Qt::CopyAction );
 
  290 bool QgsFontButton::colorFromMimeData( 
const QMimeData *mimeData, QColor &resultColor, 
bool &hasAlpha )
 
  295   if ( mimeColor.isValid() )
 
  297     resultColor = mimeColor;
 
  311   bool hasAlpha = 
false;
 
  313   if ( mMode == 
ModeTextRenderer && formatFromMimeData( e->mimeData(), format ) )
 
  315     e->acceptProposedAction();
 
  316     updatePreview( QColor(), &format );
 
  318   else if ( mMode == 
ModeQFont && fontFromMimeData( e->mimeData(), font ) )
 
  320     e->acceptProposedAction();
 
  321     updatePreview( QColor(), 
nullptr, &font );
 
  323   else if ( mMode == 
ModeTextRenderer && colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
 
  328     e->acceptProposedAction();
 
  329     updatePreview( mimeColor );
 
  346   bool hasAlpha = 
false;
 
  347   if ( mMode == 
ModeTextRenderer && formatFromMimeData( e->mimeData(), format ) )
 
  353   else if ( mMode == 
ModeQFont && fontFromMimeData( e->mimeData(), font ) )
 
  359   else if ( mMode == 
ModeTextRenderer && colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
 
  362     e->acceptProposedAction();
 
  368     mimeColor.setAlphaF( 1.0 );
 
  383       size = mFormat.
size();
 
  387       size = mFont.pointSizeF();
 
  391   double increment = ( 
event->modifiers() & Qt::ControlModifier ) ? 0.1 : 1;
 
  392   if ( 
event->delta() > 0 )
 
  400   size = std::max( size, 1.0 );
 
  414       QFont newFont = mFont;
 
  415       newFont.setPointSizeF( size );
 
  424 QPixmap QgsFontButton::createColorIcon( 
const QColor &color )
 const 
  429   pixmap.fill( Qt::transparent );
 
  435   p.setBrush( QBrush( color ) );
 
  438   p.setPen( QColor( 197, 197, 197 ) );
 
  444 QPixmap QgsFontButton::createDragIcon( QSize size, 
const QgsTextFormat *tempFormat, 
const QFont *tempFont )
 const 
  447     tempFormat = &mFormat;
 
  452   QPixmap pixmap( size.width(), size.height() );
 
  453   pixmap.fill( Qt::transparent );
 
  456   p.setRenderHint( QPainter::Antialiasing );
 
  457   QRect rect( 0, 0, size.width(), size.height() );
 
  459   if ( mMode == 
ModeQFont || tempFormat->
color().lightnessF() < 0.7 )
 
  461     p.setBrush( QBrush( QColor( 255, 255, 255 ) ) );
 
  462     p.setPen( QPen( QColor( 150, 150, 150 ), 0 ) );
 
  466     p.setBrush( QBrush( QColor( 0, 0, 0 ) ) );
 
  467     p.setPen( QPen( QColor( 100, 100, 100 ), 0 ) );
 
  470   p.setBrush( Qt::NoBrush );
 
  471   p.setPen( Qt::NoPen );
 
  482       context.
setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 );
 
  499       QRectF textRect = rect;
 
  500       textRect.setLeft( xtrans );
 
  501       textRect.setWidth( textRect.width() - xtrans );
 
  502       textRect.setTop( ytrans );
 
  503       if ( textRect.height() > 300 )
 
  504         textRect.setHeight( 300 );
 
  505       if ( textRect.width() > 2000 )
 
  506         textRect.setWidth( 2000 );
 
  509                                  context, *tempFormat );
 
  514       p.setBrush( Qt::NoBrush );
 
  515       p.setPen( QColor( 0, 0, 0 ) );
 
  516       p.setFont( *tempFont );
 
  517       QRectF textRect = rect;
 
  518       textRect.setLeft( 2 );
 
  519       p.drawText( textRect, Qt::AlignVCenter, tr( 
"Aa" ) );
 
  528 void QgsFontButton::prepareMenu()
 
  538     mNullFormatAction = 
new QAction( mNullFormatString, 
this );
 
  539     mMenu->addAction( mNullFormatAction );
 
  543       mNullFormatAction->setCheckable( 
true );
 
  544       mNullFormatAction->setChecked( 
true );
 
  548   QWidgetAction *sizeAction = 
new QWidgetAction( mMenu );
 
  549   QWidget *sizeWidget = 
new QWidget();
 
  550   QVBoxLayout *sizeLayout = 
new QVBoxLayout();
 
  551   sizeLayout->setContentsMargins( 0, 0, 0, 3 );
 
  552   sizeLayout->setSpacing( 2 );
 
  554   QString fontHeaderLabel;
 
  562       fontHeaderLabel = tr( 
"Font size (pt)" );
 
  567   sizeLayout->addWidget( sizeLabel );
 
  570   sizeSpin->setDecimals( 4 );
 
  571   sizeSpin->setMaximum( 1e+9 );
 
  574   connect( sizeSpin, 
static_cast < void ( 
QgsDoubleSpinBox::* )( 
double ) 
> ( &QgsDoubleSpinBox::valueChanged ),
 
  575            this, [ = ]( 
double value )
 
  580         if ( mNullFormatAction )
 
  581           mNullFormatAction->setChecked( 
false );
 
  585         mFont.setPointSizeF( value );
 
  591   QHBoxLayout *spinLayout = 
new QHBoxLayout();
 
  592   spinLayout->setContentsMargins( 4, 0, 4, 0 );
 
  593   spinLayout->addWidget( sizeSpin );
 
  594   sizeLayout->addLayout( spinLayout );
 
  595   sizeWidget->setLayout( sizeLayout );
 
  596   sizeAction->setDefaultWidget( sizeWidget );
 
  597   sizeWidget->setFocusProxy( sizeSpin );
 
  598   sizeWidget->setFocusPolicy( Qt::StrongFocus );
 
  599   mMenu->addAction( sizeAction );
 
  601   QMenu *recentFontMenu = 
new QMenu( tr( 
"Recent Fonts" ), mMenu );
 
  603   for ( 
const QString &family : recentFontFamilies )
 
  605     QAction *fontAction = 
new QAction( family, recentFontMenu );
 
  606     QFont f = fontAction->font();
 
  607     f.setFamily( family );
 
  608     fontAction->setFont( f );
 
  609     fontAction->setToolTip( family );
 
  610     recentFontMenu->addAction( fontAction );
 
  612          || ( mMode == 
ModeQFont && family == mFont.family() ) )
 
  614       fontAction->setCheckable( 
true );
 
  615       fontAction->setChecked( 
true );
 
  617     auto setFont = [
this, family]
 
  624           QFont f = newFormat.
font();
 
  625           f.setFamily( family );
 
  634           font.setFamily( family );
 
  641     connect( fontAction, &QAction::triggered, 
this, setFont );
 
  643   mMenu->addMenu( recentFontMenu );
 
  645   QAction *configureAction = 
new QAction( tr( 
"Configure Format…" ), 
this );
 
  646   mMenu->addAction( configureAction );
 
  647   connect( configureAction, &QAction::triggered, 
this, &QgsFontButton::showSettingsDialog );
 
  649   QAction *copyFormatAction = 
new QAction( tr( 
"Copy Format" ), 
this );
 
  650   mMenu->addAction( copyFormatAction );
 
  652   QAction *pasteFormatAction = 
new QAction( tr( 
"Paste Format" ), 
this );
 
  658   if ( mMode == 
ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
 
  662     pasteFormatAction->setIcon( createDragIcon( QSize( 
iconSize, 
iconSize ), &tempFormat ) );
 
  664   else if ( mMode == 
ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), tempFont ) )
 
  666     tempFont.setPointSize( 8 );
 
  667     pasteFormatAction->setIcon( createDragIcon( QSize( 
iconSize, 
iconSize ), 
nullptr, &tempFont ) );
 
  671     pasteFormatAction->setEnabled( 
false );
 
  673   mMenu->addAction( pasteFormatAction );
 
  678     mMenu->addSeparator();
 
  685     mMenu->addAction( colorAction );
 
  688     QColor alphaColor = mFormat.
color();
 
  689     alphaColor.setAlphaF( mFormat.
opacity() );
 
  695       double opacity = color.alphaF();
 
  698       if ( mNullFormatAction )
 
  699         mNullFormatAction->setChecked( 
false );
 
  704     mMenu->addAction( alphaAction );
 
  708     QList< QgsColorScheme * >::iterator it = schemeList.begin();
 
  709     for ( ; it != schemeList.end(); ++it )
 
  713       mMenu->addAction( colorAction );
 
  718     mMenu->addSeparator();
 
  720     QAction *copyColorAction = 
new QAction( tr( 
"Copy Color" ), 
this );
 
  721     mMenu->addAction( copyColorAction );
 
  724     QAction *pasteColorAction = 
new QAction( tr( 
"Paste Color" ), 
this );
 
  728     bool hasAlpha = 
false;
 
  729     if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
 
  731       pasteColorAction->setIcon( createColorIcon( clipColor ) );
 
  735       pasteColorAction->setEnabled( 
false );
 
  737     mMenu->addAction( pasteColorAction );
 
  742 void QgsFontButton::addRecentColor( 
const QColor &color )
 
  764   mExpressionContextGenerator = generator;
 
  785 bool QgsFontButton::formatFromMimeData( 
const QMimeData *mimeData, 
QgsTextFormat &resultFormat )
 const 
  792 bool QgsFontButton::fontFromMimeData( 
const QMimeData *mimeData, QFont &resultFont )
 const 
  801   if ( e->type() == QEvent::EnabledChange )
 
  805   QToolButton::changeEvent( e );
 
  811   QToolButton::showEvent( e );
 
  816   QToolButton::resizeEvent( 
event );
 
  822 void QgsFontButton::updatePreview( 
const QColor &color, 
QgsTextFormat *format, QFont *font )
 
  824   if ( mShowNoFormat && !mFormat.
isValid() )
 
  826     setIcon( QPixmap() );
 
  834     tempFormat = *format;
 
  836     tempFormat = mFormat;
 
  842   if ( color.isValid() )
 
  845   QSize currentIconSize;
 
  849     if ( !mIconSize.isValid() )
 
  852       QStyleOptionToolButton opt;
 
  853       initStyleOption( &opt );
 
  854       QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
 
  858       mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
 
  859 #elif defined(Q_OS_MAC) 
  860       mIconSize = QSize( buttonSize.width() - 10, height() - 2 );
 
  862       mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
 
  865     currentIconSize = mIconSize;
 
  871     currentIconSize = QSize( width() - 10, height() - 6 );
 
  873     currentIconSize = QSize( width() - 10, height() - 12 );
 
  877   if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
 
  883   QPixmap pixmap( currentIconSize );
 
  884   pixmap.fill( Qt::transparent );
 
  887   p.setRenderHint( QPainter::Antialiasing );
 
  888   QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
 
  899       context.
setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 );
 
  917       QRectF textRect = rect;
 
  918       textRect.setLeft( xtrans );
 
  919       textRect.setWidth( textRect.width() - xtrans );
 
  920       textRect.setTop( ytrans );
 
  921       if ( textRect.height() > 300 )
 
  922         textRect.setHeight( 300 );
 
  923       if ( textRect.width() > 2000 )
 
  924         textRect.setWidth( 2000 );
 
  927                                  context, tempFormat );
 
  932       p.setBrush( Qt::NoBrush );
 
  933       p.setPen( QColor( 0, 0, 0 ) );
 
  934       p.setFont( tempFont );
 
  935       QRectF textRect = rect;
 
  936       textRect.setLeft( 2 );
 
  937       p.drawText( textRect, Qt::AlignVCenter, text() );
 
  943   setIconSize( currentIconSize );
 
  956   bool hasAlpha = 
false;
 
  957   if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
 
  967   mDialogTitle = title;
 
static const double UI_SCALE_FACTOR
UI scaling factor.
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
QList< QgsColorScheme * > schemes() const
Returns all color schemes in the registry.
@ ShowInColorButtonMenu
Show scheme in color button drop-down menu.
A color swatch grid which can be embedded into a menu.
void setBaseColor(const QColor &baseColor)
Sets the base color for the color grid.
void colorChanged(const QColor &color)
Emitted when a color has been selected from the widget.
void setColor(const QColor &color, bool emitSignals=false) override
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
void setShowClearButton(bool showClearButton)
Sets whether the widget will show a clear button.
Abstract interface for generating an expression context.
virtual QgsExpressionContext createExpressionContext() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
static QMimeData * toMimeData(const QFont &font)
Returns new mime data representing the specified font settings.
static void addRecentFontFamily(const QString &family)
Adds a font family to the list of recently used font families.
static QFont fromMimeData(const QMimeData *data, bool *ok=nullptr)
Attempts to parse the provided mime data as a QFont.
static QStringList recentFontFamilies()
Returns a list of recently used font families.
Map canvas is a class for displaying all GIS data types on a canvas.
Perform transforms between map coordinates and device coordinates.
void setParameters(double mapUnitsPerPixel, double centerX, double centerY, int widthPixels, int heightPixels, double rotation)
Set parameters for use in transforming coordinates.
A bar for displaying non-blocking messages to the user.
static void addRecentColor(const QColor &color)
Adds a color to the list of recent colors.
Contains information about the context of a rendering operation.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
void setUseAdvancedEffects(bool enabled)
Used to enable or disable advanced effects such as blend modes.
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
@ Antialiasing
Use antialiasing while drawing.
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
void setExpressionContext(QgsExpressionContext *context)
Sets the optional expression context used for the widget.
QSizeF size() const
Returns the size of the background shape.
bool enabled() const
Returns whether the background is enabled.
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the shape size.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units used for the shape's size.
double size() const
Returns the size of the buffer.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the buffer size.
bool enabled() const
Returns whether the buffer is enabled.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
A simple dialog for customizing text formatting settings.
A panel widget for customizing text formatting settings.
Container for all settings relating to text rendering.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
static QgsTextFormat fromMimeData(const QMimeData *data, bool *ok=nullptr)
Attempts to parse the provided mime data as a QgsTextFormat.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
void setOpacity(double opacity)
Sets the text's opacity.
bool isValid() const
Returns true if the format is valid.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
double opacity() const
Returns the text's opacity.
double size() const
Returns the size for rendered text.
QMimeData * toMimeData() const
Returns new mime data representing the text format settings.
QColor color() const
Returns the color that text will be rendered in.
QFont font() const
Returns the font used for rendering text.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
@ AlignCenter
Center align.
static void drawText(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, VAlignment vAlignment=AlignTop)
Draws text within a rectangle using the specified settings.
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based data sets.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
QFont getFont(bool &ok, const QFont &initial, const QString &title)
Show font selection dialog.