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, [=](
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
793bool QgsFontButton::fontFromMimeData(
const QMimeData *mimeData, QFont &resultFont )
const
802 if ( e->type() == QEvent::EnabledChange )
806 QToolButton::changeEvent( e );
812 QToolButton::showEvent( e );
817 QToolButton::resizeEvent(
event );
823void QgsFontButton::updatePreview(
const QColor &color,
QgsTextFormat *format, QFont *font )
825 if ( mShowNoFormat && !mFormat.
isValid() )
827 setIcon( QPixmap() );
835 tempFormat = *format;
837 tempFormat = mFormat;
843 if ( color.isValid() )
850 tempFormat.
setSize( QToolButton::font().pointSizeF() - 2 );
853 QSize currentIconSize;
857 if ( !mIconSize.isValid() )
860 QStyleOptionToolButton opt;
861 initStyleOption( &opt );
862 const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
this );
865 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
866#elif defined( Q_OS_MAC )
867 mIconSize = QSize( buttonSize.width() - 10, height() - 2 );
869 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
872 currentIconSize = mIconSize;
878 currentIconSize = QSize( width() - 10, height() - 6 );
880 currentIconSize = QSize( width() - 10, height() - 12 );
884 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
890 QPixmap pixmap( currentIconSize * devicePixelRatioF() );
891 pixmap.fill( Qt::transparent );
892 pixmap.setDevicePixelRatio( devicePixelRatioF() );
895 p.setRenderHint( QPainter::Antialiasing );
896 const QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
925 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() ) );
929 QRectF textRect = rect;
930 textRect.setLeft( xtrans );
931 textRect.setWidth( textRect.width() - xtrans );
932 textRect.setTop( ytrans );
933 if ( textRect.height() > 300 )
934 textRect.setHeight( 300 );
935 if ( textRect.width() > 2000 )
936 textRect.setWidth( 2000 );
943 p.setBrush( Qt::NoBrush );
944 p.setPen( QColor( 0, 0, 0 ) );
945 p.setFont( tempFont );
946 QRectF textRect = rect;
947 textRect.setLeft( 2 );
948 p.drawText( textRect, Qt::AlignVCenter, text() );
953 setIconSize( currentIconSize );
966 bool hasAlpha =
false;
967 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
977 mDialogTitle = title;
@ 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.
void setUseAdvancedEffects(bool enabled)
Used to enable or disable advanced effects such as blend modes.
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 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 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.