17#include "moc_qgsfontbutton.cpp" 
   40  : QToolButton( parent )
 
   41  , mDialogTitle( dialogTitle.isEmpty() ? tr( 
"Text Format" ) : dialogTitle )
 
   42  , mNullFormatString( tr( 
"No Format" ) )
 
   44  setText( tr( 
"Font" ) );
 
   46  setAcceptDrops( 
true );
 
   47  connect( 
this, &QAbstractButton::clicked, 
this, &QgsFontButton::showSettingsDialog );
 
   50  mMenu = 
new QMenu( 
this );
 
   51  connect( mMenu, &QMenu::aboutToShow, 
this, &QgsFontButton::prepareMenu );
 
   53  setPopupMode( QToolButton::MenuButtonPopup );
 
   56  const QSize size = QToolButton::minimumSizeHint();
 
   59  mSizeHint = QSize( std::max( minWidth, size.width() ), std::max( size.height(), fontHeight ) );
 
 
   75void QgsFontButton::showSettingsDialog()
 
   82      if ( mExpressionContextGenerator )
 
   98        mActivePanel->setPanelTitle( mDialogTitle );
 
   99        mActivePanel->setContext( symbolContext );
 
  106      QgsTextFormatDialog dialog( mFormat, mMapCanvas, 
this, QgsGuiUtils::ModalDialogFlags, mLayer.data() );
 
  107      dialog.setWindowTitle( mDialogTitle );
 
  108      dialog.setContext( symbolContext );
 
  157  if ( mActivePanel && !format.
isValid() )
 
  158    mActivePanel->acceptPanel();
 
  163  if ( mActivePanel && format.
isValid() )
 
  164    mActivePanel->setFormat( format );
 
 
  177  QColor opaque = color;
 
  178  opaque.setAlphaF( 1.0 );
 
  180  if ( mNullFormatAction )
 
  181    mNullFormatAction->setChecked( 
false );
 
  183  if ( mFormat.
color() != opaque )
 
 
  196      QApplication::clipboard()->setMimeData( mFormat.
toMimeData() );
 
 
  209  if ( mMode == 
ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
 
  214  else if ( mMode == 
ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), font ) )
 
 
  223  if ( e->type() == QEvent::ToolTip )
 
  225    QHelpEvent *helpEvent = 
static_cast<QHelpEvent *
>( e );
 
  227    double fontSize = 0.0;
 
  231        fontSize = mFormat.
size();
 
  235        fontSize = mFont.pointSizeF();
 
  238    toolTip = QStringLiteral( 
"<b>%1</b><br>%2<br>Size: %3" ).arg( text(), mMode == 
ModeTextRenderer ? mFormat.
font().family() : mFont.family() ).arg( fontSize );
 
  239    QToolTip::showText( helpEvent->globalPos(), toolTip );
 
  241  return QToolButton::event( e );
 
 
  246  if ( e->button() == Qt::RightButton )
 
  248    QToolButton::showMenu();
 
  251  else if ( e->button() == Qt::LeftButton )
 
  253    mDragStartPosition = e->pos();
 
  255  QToolButton::mousePressEvent( e );
 
 
  262  if ( !( e->buttons() & Qt::LeftButton ) )
 
  265    QToolButton::mouseMoveEvent( e );
 
  269  if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
 
  272    QToolButton::mouseMoveEvent( e );
 
  277  QDrag *drag = 
new QDrag( 
this );
 
  289  drag->setPixmap( createDragIcon( QSize( iconSize, iconSize ) ) );
 
  290  drag->exec( Qt::CopyAction );
 
 
  294bool QgsFontButton::colorFromMimeData( 
const QMimeData *mimeData, QColor &resultColor, 
bool &hasAlpha )
 
  299  if ( mimeColor.isValid() )
 
  301    resultColor = mimeColor;
 
  315  bool hasAlpha = 
false;
 
  317  if ( mMode == 
ModeTextRenderer && formatFromMimeData( e->mimeData(), format ) )
 
  319    e->acceptProposedAction();
 
  320    updatePreview( QColor(), &format );
 
  322  else if ( mMode == 
ModeQFont && fontFromMimeData( e->mimeData(), font ) )
 
  324    e->acceptProposedAction();
 
  325    updatePreview( QColor(), 
nullptr, &font );
 
  327  else if ( mMode == 
ModeTextRenderer && colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
 
  332    e->acceptProposedAction();
 
  333    updatePreview( mimeColor );
 
 
  350  bool hasAlpha = 
false;
 
  351  if ( mMode == 
ModeTextRenderer && formatFromMimeData( e->mimeData(), format ) )
 
  357  else if ( mMode == 
ModeQFont && fontFromMimeData( e->mimeData(), font ) )
 
  363  else if ( mMode == 
ModeTextRenderer && colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
 
  366    e->acceptProposedAction();
 
  372    mimeColor.setAlphaF( 1.0 );
 
 
  387      size = mFormat.
size();
 
  391      size = mFont.pointSizeF();
 
  395  const double increment = ( 
event->modifiers() & Qt::ControlModifier ) ? 0.1 : 1;
 
  396  if ( 
event->angleDelta().y() > 0 )
 
  404  size = std::max( size, 1.0 );
 
  418      QFont newFont = mFont;
 
  419      newFont.setPointSizeF( size );
 
 
  428QPixmap QgsFontButton::createColorIcon( 
const QColor &color )
 const 
  432  QPixmap pixmap( iconSize, iconSize );
 
  433  pixmap.fill( Qt::transparent );
 
  439  p.setBrush( QBrush( color ) );
 
  442  p.setPen( QColor( 197, 197, 197 ) );
 
  443  p.drawRect( 0, 0, iconSize - 1, iconSize - 1 );
 
  448QPixmap QgsFontButton::createDragIcon( QSize size, 
const QgsTextFormat *tempFormat, 
const QFont *tempFont )
 const 
  451    tempFormat = &mFormat;
 
  456  QPixmap pixmap( size.width(), size.height() );
 
  457  pixmap.fill( Qt::transparent );
 
  460  p.setRenderHint( QPainter::Antialiasing );
 
  461  const QRect rect( 0, 0, size.width(), size.height() );
 
  463  if ( mMode == 
ModeQFont || tempFormat->
color().lightnessF() < 0.7 )
 
  465    p.setBrush( QBrush( QColor( 255, 255, 255 ) ) );
 
  466    p.setPen( QPen( QColor( 150, 150, 150 ), 0 ) );
 
  470    p.setBrush( QBrush( QColor( 0, 0, 0 ) ) );
 
  471    p.setPen( QPen( QColor( 100, 100, 100 ), 0 ) );
 
  474  p.setBrush( Qt::NoBrush );
 
  475  p.setPen( Qt::NoPen );
 
  495                   ? fontSize * tempFormat->
buffer().
size() / 100
 
  502        ytrans = std::max( ytrans, tempFormat->
buffer().
sizeUnit() == 
Qgis::RenderUnit::Percentage ? fontSize * tempFormat->
buffer().
size() / 100 : context.convertToPainterUnits( tempFormat->buffer().size(), tempFormat->buffer().sizeUnit(), tempFormat->buffer().sizeMapUnitScale() ) );
 
  506      QRectF textRect = rect;
 
  507      textRect.setLeft( xtrans );
 
  508      textRect.setWidth( textRect.width() - xtrans );
 
  509      textRect.setTop( ytrans );
 
  510      if ( textRect.height() > 300 )
 
  511        textRect.setHeight( 300 );
 
  512      if ( textRect.width() > 2000 )
 
  513        textRect.setWidth( 2000 );
 
  520      p.setBrush( Qt::NoBrush );
 
  521      p.setPen( QColor( 0, 0, 0 ) );
 
  522      p.setFont( *tempFont );
 
  523      QRectF textRect = rect;
 
  524      textRect.setLeft( 2 );
 
  525      p.drawText( textRect, Qt::AlignVCenter, tr( 
"Aa" ) );
 
  534void QgsFontButton::prepareMenu()
 
  544    mNullFormatAction = 
new QAction( mNullFormatString, 
this );
 
  545    mMenu->addAction( mNullFormatAction );
 
  549      mNullFormatAction->setCheckable( 
true );
 
  550      mNullFormatAction->setChecked( 
true );
 
  554  QWidgetAction *sizeAction = 
new QWidgetAction( mMenu );
 
  555  QWidget *sizeWidget = 
new QWidget();
 
  556  QVBoxLayout *sizeLayout = 
new QVBoxLayout();
 
  557  sizeLayout->setContentsMargins( 0, 0, 0, 3 );
 
  558  sizeLayout->setSpacing( 2 );
 
  560  QString fontHeaderLabel;
 
  568      fontHeaderLabel = tr( 
"Font size (pt)" );
 
  573  sizeLayout->addWidget( sizeLabel );
 
  576  sizeSpin->setDecimals( 4 );
 
  577  sizeSpin->setMaximum( 1e+9 );
 
  580  connect( sizeSpin, 
static_cast<void ( 
QgsDoubleSpinBox::* )( 
double )
>( &QgsDoubleSpinBox::valueChanged ), 
this, [
this]( 
double value ) {
 
  584        if ( mNullFormatAction )
 
  585          mNullFormatAction->setChecked( 
false );
 
  589        mFont.setPointSizeF( value );
 
  595  QHBoxLayout *spinLayout = 
new QHBoxLayout();
 
  596  spinLayout->setContentsMargins( 4, 0, 4, 0 );
 
  597  spinLayout->addWidget( sizeSpin );
 
  598  sizeLayout->addLayout( spinLayout );
 
  599  sizeWidget->setLayout( sizeLayout );
 
  600  sizeAction->setDefaultWidget( sizeWidget );
 
  601  sizeWidget->setFocusProxy( sizeSpin );
 
  602  sizeWidget->setFocusPolicy( Qt::StrongFocus );
 
  603  mMenu->addAction( sizeAction );
 
  605  QMenu *recentFontMenu = 
new QMenu( tr( 
"Recent Fonts" ), mMenu );
 
  607  for ( 
const QString &family : recentFontFamilies )
 
  609    QAction *fontAction = 
new QAction( family, recentFontMenu );
 
  610    QFont f = fontAction->font();
 
  612    fontAction->setFont( f );
 
  613    fontAction->setToolTip( family );
 
  614    recentFontMenu->addAction( fontAction );
 
  616         || ( mMode == 
ModeQFont && family == mFont.family() ) )
 
  618      fontAction->setCheckable( 
true );
 
  619      fontAction->setChecked( 
true );
 
  621    auto setFont = [
this, family] {
 
  627          QFont f = newFormat.
font();
 
  644    connect( fontAction, &QAction::triggered, 
this, setFont );
 
  646  mMenu->addMenu( recentFontMenu );
 
  648  QAction *configureAction = 
new QAction( tr( 
"Configure Format…" ), 
this );
 
  649  mMenu->addAction( configureAction );
 
  650  connect( configureAction, &QAction::triggered, 
this, &QgsFontButton::showSettingsDialog );
 
  652  QAction *copyFormatAction = 
new QAction( tr( 
"Copy Format" ), 
this );
 
  653  mMenu->addAction( copyFormatAction );
 
  655  QAction *pasteFormatAction = 
new QAction( tr( 
"Paste Format" ), 
this );
 
  661  if ( mMode == 
ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
 
  665    pasteFormatAction->setIcon( createDragIcon( QSize( iconSize, iconSize ), &tempFormat ) );
 
  667  else if ( mMode == 
ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), tempFont ) )
 
  669    tempFont.setPointSize( 8 );
 
  670    pasteFormatAction->setIcon( createDragIcon( QSize( iconSize, iconSize ), 
nullptr, &tempFont ) );
 
  674    pasteFormatAction->setEnabled( 
false );
 
  676  mMenu->addAction( pasteFormatAction );
 
  681    mMenu->addSeparator();
 
  688    mMenu->addAction( colorAction );
 
  691    QColor alphaColor = mFormat.
color();
 
  692    alphaColor.setAlphaF( mFormat.
opacity() );
 
  697      const double opacity = color.alphaF();
 
  700      if ( mNullFormatAction )
 
  701        mNullFormatAction->setChecked( 
false );
 
  705    mMenu->addAction( alphaAction );
 
  709    QList<QgsColorScheme *>::iterator it = schemeList.begin();
 
  710    for ( ; it != schemeList.end(); ++it )
 
  714      mMenu->addAction( colorAction );
 
  719    mMenu->addSeparator();
 
  721    QAction *copyColorAction = 
new QAction( tr( 
"Copy Color" ), 
this );
 
  722    mMenu->addAction( copyColorAction );
 
  725    QAction *pasteColorAction = 
new QAction( tr( 
"Paste Color" ), 
this );
 
  729    bool hasAlpha = 
false;
 
  730    if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
 
  732      pasteColorAction->setIcon( createColorIcon( clipColor ) );
 
  736      pasteColorAction->setEnabled( 
false );
 
  738    mMenu->addAction( pasteColorAction );
 
  743void QgsFontButton::addRecentColor( 
const QColor &color )
 
  765  mExpressionContextGenerator = generator;
 
 
  786bool QgsFontButton::formatFromMimeData( 
const QMimeData *mimeData, 
QgsTextFormat &resultFormat )
 const 
  796bool QgsFontButton::fontFromMimeData( 
const QMimeData *mimeData, QFont &resultFont )
 const 
  808  if ( e->type() == QEvent::EnabledChange )
 
  812  QToolButton::changeEvent( e );
 
 
  818  QToolButton::showEvent( e );
 
 
  823  QToolButton::resizeEvent( 
event );
 
 
  829void QgsFontButton::updatePreview( 
const QColor &color, 
QgsTextFormat *format, QFont *font )
 
  831  if ( mShowNoFormat && !mFormat.
isValid() )
 
  833    setIcon( QPixmap() );
 
  841    tempFormat = *format;
 
  843    tempFormat = mFormat;
 
  849  if ( color.isValid() )
 
  856  tempFormat.
setSize( QToolButton::font().pointSizeF() - 2 );
 
  859  QSize currentIconSize;
 
  863    if ( !mIconSize.isValid() )
 
  866      QStyleOptionToolButton opt;
 
  867      initStyleOption( &opt );
 
  868      const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton, 
this );
 
  871      mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
 
  872#elif defined( Q_OS_MAC ) 
  873      mIconSize = QSize( buttonSize.width() - 10, height() - 2 );
 
  875      mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
 
  878    currentIconSize = mIconSize;
 
  884    currentIconSize = QSize( width() - 10, height() - 6 );
 
  886    currentIconSize = QSize( width() - 10, height() - 12 );
 
  890  if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
 
  896  QPixmap pixmap( currentIconSize * devicePixelRatioF() );
 
  897  pixmap.fill( Qt::transparent );
 
  898  pixmap.setDevicePixelRatio( devicePixelRatioF() );
 
  901  p.setRenderHint( QPainter::Antialiasing );
 
  902  const QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
 
  931        ytrans = std::max( ytrans, tempFormat.
buffer().
sizeUnit() == 
Qgis::RenderUnit::Percentage ? fontSize * tempFormat.
buffer().
size() / 100 : context.convertToPainterUnits( tempFormat.buffer().size(), tempFormat.buffer().sizeUnit(), tempFormat.buffer().sizeMapUnitScale() ) );
 
  935      QRectF textRect = rect;
 
  936      textRect.setLeft( xtrans );
 
  937      textRect.setWidth( textRect.width() - xtrans );
 
  938      textRect.setTop( ytrans );
 
  939      if ( textRect.height() > 300 )
 
  940        textRect.setHeight( 300 );
 
  941      if ( textRect.width() > 2000 )
 
  942        textRect.setWidth( 2000 );
 
  949      p.setBrush( Qt::NoBrush );
 
  950      p.setPen( QColor( 0, 0, 0 ) );
 
  951      p.setFont( tempFont );
 
  952      QRectF textRect = rect;
 
  953      textRect.setLeft( 2 );
 
  954      p.drawText( textRect, Qt::AlignVCenter, text() );
 
  959  setIconSize( currentIconSize );
 
  972  bool hasAlpha = 
false;
 
  973  if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
 
 
  983  mDialogTitle = title;
 
 
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
 
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size)
 
@ Points
Points (e.g., for font sizes)
 
@ Antialiasing
Use antialiasing while drawing.
 
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 setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
 
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)
Sets 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 setDevicePixelRatio(float ratio)
Sets the device pixel ratio.
 
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
 
void setRasterizedRenderingPolicy(Qgis::RasterizedRenderingPolicy policy)
Sets the policy controlling when rasterisation of content during renders is permitted.
 
void setFlag(Qgis::RenderContextFlag 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...
 
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
 
A utility class for dynamic handling of changes to screen properties.
 
double screenDpi() const
Returns the current screen DPI for the screen that the parent widget appears on.
 
void screenDpiChanged(double dpi)
Emitted whenever the screen dpi associated with the widget is changed.
 
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.
 
Qgis::RenderUnit sizeUnit() const
Returns the units used for the shape's size.
 
Qgis::RenderUnit sizeUnit() const
Returns the units for the buffer 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.
 
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.
 
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the size.
 
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.
 
void setSizeUnit(Qgis::RenderUnit unit)
Sets 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.
 
Qgis::RenderUnit sizeUnit() const
Returns 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.
 
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
 
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
 
Represents a vector layer which manages a vector based dataset.
 
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.