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 const 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 const double increment = (
event->modifiers() & Qt::ControlModifier ) ? 0.1 : 1;
392 if (
event->angleDelta().y() > 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 const 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 );
491 ? fontSize * tempFormat->
buffer().
size() / 100
499 ? fontSize * tempFormat->
buffer().
size() / 100
504 QRectF textRect = rect;
505 textRect.setLeft( xtrans );
506 textRect.setWidth( textRect.width() - xtrans );
507 textRect.setTop( ytrans );
508 if ( textRect.height() > 300 )
509 textRect.setHeight( 300 );
510 if ( textRect.width() > 2000 )
511 textRect.setWidth( 2000 );
514 context, *tempFormat );
519 p.setBrush( Qt::NoBrush );
520 p.setPen( QColor( 0, 0, 0 ) );
521 p.setFont( *tempFont );
522 QRectF textRect = rect;
523 textRect.setLeft( 2 );
524 p.drawText( textRect, Qt::AlignVCenter, tr(
"Aa" ) );
533 void QgsFontButton::prepareMenu()
543 mNullFormatAction =
new QAction( mNullFormatString,
this );
544 mMenu->addAction( mNullFormatAction );
548 mNullFormatAction->setCheckable(
true );
549 mNullFormatAction->setChecked(
true );
553 QWidgetAction *sizeAction =
new QWidgetAction( mMenu );
554 QWidget *sizeWidget =
new QWidget();
555 QVBoxLayout *sizeLayout =
new QVBoxLayout();
556 sizeLayout->setContentsMargins( 0, 0, 0, 3 );
557 sizeLayout->setSpacing( 2 );
559 QString fontHeaderLabel;
567 fontHeaderLabel = tr(
"Font size (pt)" );
572 sizeLayout->addWidget( sizeLabel );
575 sizeSpin->setDecimals( 4 );
576 sizeSpin->setMaximum( 1e+9 );
579 connect( sizeSpin,
static_cast < void (
QgsDoubleSpinBox::* )(
double )
> ( &QgsDoubleSpinBox::valueChanged ),
580 this, [ = ](
double value )
585 if ( mNullFormatAction )
586 mNullFormatAction->setChecked(
false );
590 mFont.setPointSizeF( value );
596 QHBoxLayout *spinLayout =
new QHBoxLayout();
597 spinLayout->setContentsMargins( 4, 0, 4, 0 );
598 spinLayout->addWidget( sizeSpin );
599 sizeLayout->addLayout( spinLayout );
600 sizeWidget->setLayout( sizeLayout );
601 sizeAction->setDefaultWidget( sizeWidget );
602 sizeWidget->setFocusProxy( sizeSpin );
603 sizeWidget->setFocusPolicy( Qt::StrongFocus );
604 mMenu->addAction( sizeAction );
606 QMenu *recentFontMenu =
new QMenu( tr(
"Recent Fonts" ), mMenu );
608 for (
const QString &family : recentFontFamilies )
610 QAction *fontAction =
new QAction( family, recentFontMenu );
611 QFont f = fontAction->font();
612 f.setFamily( family );
613 fontAction->setFont( f );
614 fontAction->setToolTip( family );
615 recentFontMenu->addAction( fontAction );
617 || ( mMode ==
ModeQFont && family == mFont.family() ) )
619 fontAction->setCheckable(
true );
620 fontAction->setChecked(
true );
622 auto setFont = [
this, family]
629 QFont f = newFormat.
font();
630 f.setFamily( family );
639 font.setFamily( family );
646 connect( fontAction, &QAction::triggered,
this, setFont );
648 mMenu->addMenu( recentFontMenu );
650 QAction *configureAction =
new QAction( tr(
"Configure Format…" ),
this );
651 mMenu->addAction( configureAction );
652 connect( configureAction, &QAction::triggered,
this, &QgsFontButton::showSettingsDialog );
654 QAction *copyFormatAction =
new QAction( tr(
"Copy Format" ),
this );
655 mMenu->addAction( copyFormatAction );
657 QAction *pasteFormatAction =
new QAction( tr(
"Paste Format" ),
this );
663 if ( mMode ==
ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
667 pasteFormatAction->setIcon( createDragIcon( QSize(
iconSize,
iconSize ), &tempFormat ) );
669 else if ( mMode ==
ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), tempFont ) )
671 tempFont.setPointSize( 8 );
672 pasteFormatAction->setIcon( createDragIcon( QSize(
iconSize,
iconSize ),
nullptr, &tempFont ) );
676 pasteFormatAction->setEnabled(
false );
678 mMenu->addAction( pasteFormatAction );
683 mMenu->addSeparator();
690 mMenu->addAction( colorAction );
693 QColor alphaColor = mFormat.
color();
694 alphaColor.setAlphaF( mFormat.
opacity() );
700 const double opacity = color.alphaF();
703 if ( mNullFormatAction )
704 mNullFormatAction->setChecked(
false );
709 mMenu->addAction( alphaAction );
713 QList< QgsColorScheme * >::iterator it = schemeList.begin();
714 for ( ; it != schemeList.end(); ++it )
718 mMenu->addAction( colorAction );
723 mMenu->addSeparator();
725 QAction *copyColorAction =
new QAction( tr(
"Copy Color" ),
this );
726 mMenu->addAction( copyColorAction );
729 QAction *pasteColorAction =
new QAction( tr(
"Paste Color" ),
this );
733 bool hasAlpha =
false;
734 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
736 pasteColorAction->setIcon( createColorIcon( clipColor ) );
740 pasteColorAction->setEnabled(
false );
742 mMenu->addAction( pasteColorAction );
747 void QgsFontButton::addRecentColor(
const QColor &color )
769 mExpressionContextGenerator = generator;
790 bool QgsFontButton::formatFromMimeData(
const QMimeData *mimeData,
QgsTextFormat &resultFormat )
const
797 bool QgsFontButton::fontFromMimeData(
const QMimeData *mimeData, QFont &resultFont )
const
806 if ( e->type() == QEvent::EnabledChange )
810 QToolButton::changeEvent( e );
816 QToolButton::showEvent( e );
821 QToolButton::resizeEvent(
event );
827 void QgsFontButton::updatePreview(
const QColor &color,
QgsTextFormat *format, QFont *font )
829 if ( mShowNoFormat && !mFormat.
isValid() )
831 setIcon( QPixmap() );
839 tempFormat = *format;
841 tempFormat = mFormat;
847 if ( color.isValid() )
850 QSize currentIconSize;
854 if ( !mIconSize.isValid() )
857 QStyleOptionToolButton opt;
858 initStyleOption( &opt );
859 const QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
863 mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
864 #elif defined(Q_OS_MAC)
865 mIconSize = QSize( buttonSize.width() - 10, height() - 2 );
867 mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
870 currentIconSize = mIconSize;
876 currentIconSize = QSize( width() - 10, height() - 6 );
878 currentIconSize = QSize( width() - 10, height() - 12 );
882 if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
888 QPixmap pixmap( currentIconSize );
889 pixmap.fill( Qt::transparent );
892 p.setRenderHint( QPainter::Antialiasing );
893 const QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
904 context.
setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 );
927 QRectF textRect = rect;
928 textRect.setLeft( xtrans );
929 textRect.setWidth( textRect.width() - xtrans );
930 textRect.setTop( ytrans );
931 if ( textRect.height() > 300 )
932 textRect.setHeight( 300 );
933 if ( textRect.width() > 2000 )
934 textRect.setWidth( 2000 );
937 context, tempFormat );
942 p.setBrush( Qt::NoBrush );
943 p.setPen( QColor( 0, 0, 0 ) );
944 p.setFont( tempFont );
945 QRectF textRect = rect;
946 textRect.setLeft( 2 );
947 p.drawText( textRect, Qt::AlignVCenter, text() );
953 setIconSize( currentIconSize );
966 bool hasAlpha =
false;
967 if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
977 mDialogTitle = title;
@ 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 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 setUseAdvancedEffects(bool enabled)
Used to enable or disable advanced effects such as blend modes.
double convertToPainterUnits(double size, QgsUnitTypes::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.
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.
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.
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.
static void drawText(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, VAlignment vAlignment=AlignTop, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags())
Draws text within a rectangle using the specified settings.
@ AlignCenter
Center align.
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
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.