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;