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();
 
   57 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) 
   62   mSizeHint = QSize( std::max( minWidth, size.width() ), std::max( size.height(), fontHeight ) );
 
   75 void 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 );
 
  290   drag->exec( Qt::CopyAction );
 
  294 bool 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   double increment = ( 
event->modifiers() & Qt::ControlModifier ) ? 0.1 : 1;
 
  396   if ( 
event->delta() > 0 )
 
  404   size = std::max( size, 1.0 );
 
  418       QFont newFont = mFont;
 
  419       newFont.setPointSizeF( size );
 
  428 QPixmap QgsFontButton::createColorIcon( 
const QColor &color )
 const 
  433   pixmap.fill( Qt::transparent );
 
  439   p.setBrush( QBrush( color ) );
 
  442   p.setPen( QColor( 197, 197, 197 ) );
 
  448 QPixmap 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   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 );
 
  486       context.
setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 );
 
  503       QRectF textRect = rect;
 
  504       textRect.setLeft( xtrans );
 
  505       textRect.setWidth( textRect.width() - xtrans );
 
  506       textRect.setTop( ytrans );
 
  507       if ( textRect.height() > 300 )
 
  508         textRect.setHeight( 300 );
 
  509       if ( textRect.width() > 2000 )
 
  510         textRect.setWidth( 2000 );
 
  513                                  context, *tempFormat );
 
  518       p.setBrush( Qt::NoBrush );
 
  519       p.setPen( QColor( 0, 0, 0 ) );
 
  520       p.setFont( *tempFont );
 
  521       QRectF textRect = rect;
 
  522       textRect.setLeft( 2 );
 
  523       p.drawText( textRect, Qt::AlignVCenter, tr( 
"Aa" ) );
 
  532 void QgsFontButton::prepareMenu()
 
  542     mNullFormatAction = 
new QAction( mNullFormatString, 
this );
 
  543     mMenu->addAction( mNullFormatAction );
 
  547       mNullFormatAction->setCheckable( 
true );
 
  548       mNullFormatAction->setChecked( 
true );
 
  552   QWidgetAction *sizeAction = 
new QWidgetAction( mMenu );
 
  553   QWidget *sizeWidget = 
new QWidget();
 
  554   QVBoxLayout *sizeLayout = 
new QVBoxLayout();
 
  555   sizeLayout->setContentsMargins( 0, 0, 0, 3 );
 
  556   sizeLayout->setSpacing( 2 );
 
  558   QString fontHeaderLabel;
 
  566       fontHeaderLabel = tr( 
"Font size (pt)" );
 
  571   sizeLayout->addWidget( sizeLabel );
 
  574   sizeSpin->setDecimals( 4 );
 
  575   sizeSpin->setMaximum( 1e+9 );
 
  578   connect( sizeSpin, 
static_cast < void ( 
QgsDoubleSpinBox::* )( 
double ) 
> ( &QgsDoubleSpinBox::valueChanged ),
 
  579            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();
 
  611     f.setFamily( family );
 
  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]
 
  628           QFont f = newFormat.
font();
 
  629           f.setFamily( family );
 
  638           font.setFamily( family );
 
  645     connect( fontAction, &QAction::triggered, 
this, setFont );
 
  647   mMenu->addMenu( recentFontMenu );
 
  649   QAction *configureAction = 
new QAction( tr( 
"Configure Format…" ), 
this );
 
  650   mMenu->addAction( configureAction );
 
  651   connect( configureAction, &QAction::triggered, 
this, &QgsFontButton::showSettingsDialog );
 
  653   QAction *copyFormatAction = 
new QAction( tr( 
"Copy Format" ), 
this );
 
  654   mMenu->addAction( copyFormatAction );
 
  656   QAction *pasteFormatAction = 
new QAction( tr( 
"Paste Format" ), 
this );
 
  662   if ( mMode == 
ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
 
  666     pasteFormatAction->setIcon( createDragIcon( QSize( 
iconSize, 
iconSize ), &tempFormat ) );
 
  668   else if ( mMode == 
ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), tempFont ) )
 
  670     tempFont.setPointSize( 8 );
 
  671     pasteFormatAction->setIcon( createDragIcon( QSize( 
iconSize, 
iconSize ), 
nullptr, &tempFont ) );
 
  675     pasteFormatAction->setEnabled( 
false );
 
  677   mMenu->addAction( pasteFormatAction );
 
  682     mMenu->addSeparator();
 
  689     mMenu->addAction( colorAction );
 
  692     QColor alphaColor = mFormat.
color();
 
  693     alphaColor.setAlphaF( mFormat.
opacity() );
 
  699       double opacity = color.alphaF();
 
  702       if ( mNullFormatAction )
 
  703         mNullFormatAction->setChecked( 
false );
 
  708     mMenu->addAction( alphaAction );
 
  712     QList< QgsColorScheme * >::iterator it = schemeList.begin();
 
  713     for ( ; it != schemeList.end(); ++it )
 
  717       mMenu->addAction( colorAction );
 
  722     mMenu->addSeparator();
 
  724     QAction *copyColorAction = 
new QAction( tr( 
"Copy Color" ), 
this );
 
  725     mMenu->addAction( copyColorAction );
 
  728     QAction *pasteColorAction = 
new QAction( tr( 
"Paste Color" ), 
this );
 
  732     bool hasAlpha = 
false;
 
  733     if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
 
  735       pasteColorAction->setIcon( createColorIcon( clipColor ) );
 
  739       pasteColorAction->setEnabled( 
false );
 
  741     mMenu->addAction( pasteColorAction );
 
  746 void QgsFontButton::addRecentColor( 
const QColor &color )
 
  768   mExpressionContextGenerator = generator;
 
  789 bool QgsFontButton::formatFromMimeData( 
const QMimeData *mimeData, 
QgsTextFormat &resultFormat )
 const 
  796 bool QgsFontButton::fontFromMimeData( 
const QMimeData *mimeData, QFont &resultFont )
 const 
  805   if ( e->type() == QEvent::EnabledChange )
 
  809   QToolButton::changeEvent( e );
 
  815   QToolButton::showEvent( e );
 
  820   QToolButton::resizeEvent( 
event );
 
  826 void QgsFontButton::updatePreview( 
const QColor &color, 
QgsTextFormat *format, QFont *font )
 
  828   if ( mShowNoFormat && !mFormat.
isValid() )
 
  830     setIcon( QPixmap() );
 
  838     tempFormat = *format;
 
  840     tempFormat = mFormat;
 
  846   if ( color.isValid() )
 
  849   QSize currentIconSize;
 
  853     if ( !mIconSize.isValid() )
 
  856       QStyleOptionToolButton opt;
 
  857       initStyleOption( &opt );
 
  858       QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
 
  862       mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
 
  863 #elif defined(Q_OS_MAC) 
  864       mIconSize = QSize( buttonSize.width() - 10, height() - 2 );
 
  866       mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
 
  869     currentIconSize = mIconSize;
 
  875     currentIconSize = QSize( width() - 10, height() - 6 );
 
  877     currentIconSize = QSize( width() - 10, height() - 12 );
 
  881   if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
 
  887   QPixmap pixmap( currentIconSize );
 
  888   pixmap.fill( Qt::transparent );
 
  891   p.setRenderHint( QPainter::Antialiasing );
 
  892   QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
 
  903       context.
setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 );
 
  921       QRectF textRect = rect;
 
  922       textRect.setLeft( xtrans );
 
  923       textRect.setWidth( textRect.width() - xtrans );
 
  924       textRect.setTop( ytrans );
 
  925       if ( textRect.height() > 300 )
 
  926         textRect.setHeight( 300 );
 
  927       if ( textRect.width() > 2000 )
 
  928         textRect.setWidth( 2000 );
 
  931                                  context, tempFormat );
 
  936       p.setBrush( Qt::NoBrush );
 
  937       p.setPen( QColor( 0, 0, 0 ) );
 
  938       p.setFont( tempFont );
 
  939       QRectF textRect = rect;
 
  940       textRect.setLeft( 2 );
 
  941       p.drawText( textRect, Qt::AlignVCenter, text() );
 
  947   setIconSize( currentIconSize );
 
  960   bool hasAlpha = 
false;
 
  961   if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
 
  971   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.