mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
[needs-docs] New gui widget QgsFontButton
A standard widget for configuring text format properties for use with QgsTextRenderer/QgsTextFormat. It's modelled heavily off QgsColorButton, and supports lots of nice things like dragging formats between buttons, copying and pasting format settings, dropping colors from color buttons, dragging colors from font buttons to color buttons, directly setting font size and opacity/color without having to open a dialog.
This commit is contained in:
parent
a73131176f
commit
0b9fb5d6e1
@ -1231,6 +1231,22 @@ class QgsTextFormat
|
||||
:rtype: QDomElement
|
||||
%End
|
||||
|
||||
QMimeData *toMimeData() const /Factory/;
|
||||
%Docstring
|
||||
Returns new mime data representing the text format settings.
|
||||
Caller takes responsibility for deleting the returned object.
|
||||
.. seealso:: fromMimeData()
|
||||
:rtype: QMimeData
|
||||
%End
|
||||
|
||||
static QgsTextFormat fromMimeData( const QMimeData *data, bool *ok /Out/ = 0 );
|
||||
%Docstring
|
||||
Attempts to parse the provided mime ``data`` as a QgsTextFormat.
|
||||
If data can be parsed as a text format, ``ok`` will be set to true.
|
||||
.. seealso:: toMimeData()
|
||||
:rtype: QgsTextFormat
|
||||
%End
|
||||
|
||||
bool containsAdvancedEffects() const;
|
||||
%Docstring
|
||||
Returns true if any component of the font format requires advanced effects
|
||||
|
||||
@ -110,6 +110,7 @@
|
||||
%Include qgsfilterlineedit.sip
|
||||
%Include qgsfloatingwidget.sip
|
||||
%Include qgsfocuswatcher.sip
|
||||
%Include qgsfontbutton.sip
|
||||
%Include qgsformannotation.sip
|
||||
%Include qgsgradientcolorrampdialog.sip
|
||||
%Include qgsgradientstopeditor.sip
|
||||
|
||||
151
python/gui/qgsfontbutton.sip
Normal file
151
python/gui/qgsfontbutton.sip
Normal file
@ -0,0 +1,151 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsfontbutton.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsFontButton : QToolButton
|
||||
{
|
||||
%Docstring
|
||||
A button for customising QgsTextFormat settings.
|
||||
|
||||
The button will open a detailed text format settings dialog when clicked. An attached drop down
|
||||
menu allows for copying and pasting text styles, picking colors for the text, and for dropping
|
||||
colors from other color widgets.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsfontbutton.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsFontButton( QWidget *parent /TransferThis/ = 0, const QString &dialogTitle = QString() );
|
||||
%Docstring
|
||||
Construct a new font button.
|
||||
Use ``parent`` to attach a parent QWidget to the dialog.
|
||||
Use ``dialogTitle`` string to define the title to show in the text settings dialog.
|
||||
%End
|
||||
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
void setDialogTitle( const QString &title );
|
||||
%Docstring
|
||||
Sets the ``title`` for the text settings dialog window.
|
||||
.. seealso:: dialogTitle()
|
||||
%End
|
||||
|
||||
QString dialogTitle() const;
|
||||
%Docstring
|
||||
Returns the title for the text settings dialog window.
|
||||
.. seealso:: setDialogTitle()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QgsMapCanvas *mapCanvas() const;
|
||||
%Docstring
|
||||
Returns the map canvas associated with the widget.
|
||||
.. seealso:: setMapCanvas()
|
||||
:rtype: QgsMapCanvas
|
||||
%End
|
||||
|
||||
void setMapCanvas( QgsMapCanvas *canvas );
|
||||
%Docstring
|
||||
Sets a map ``canvas`` to associate with the widget. This allows the
|
||||
widget to fetch current settings from the map canvas, such as current scale.
|
||||
.. seealso:: mapCanvas()
|
||||
%End
|
||||
|
||||
QgsTextFormat textFormat() const;
|
||||
%Docstring
|
||||
Returns the current text formatting set by the widget.
|
||||
.. seealso:: setTextFormat()
|
||||
:rtype: QgsTextFormat
|
||||
%End
|
||||
|
||||
public slots:
|
||||
|
||||
void setTextFormat( const QgsTextFormat &format );
|
||||
%Docstring
|
||||
Sets the current text ``format`` to show in the widget.
|
||||
.. seealso:: textFormat()
|
||||
%End
|
||||
|
||||
void setColor( const QColor &color );
|
||||
%Docstring
|
||||
Sets the current ``color`` for the text. Will emit a changed signal if the color is different
|
||||
to the previous text color.
|
||||
%End
|
||||
|
||||
void copyFormat();
|
||||
%Docstring
|
||||
Copies the current text format to the clipboard.
|
||||
.. seealso:: pasteFormat()
|
||||
%End
|
||||
|
||||
void pasteFormat();
|
||||
%Docstring
|
||||
Pastes a format from the clipboard. If clipboard does not contain a valid
|
||||
format then no change is applied.
|
||||
.. seealso:: copyFormat()
|
||||
%End
|
||||
|
||||
void copyColor();
|
||||
%Docstring
|
||||
Copies the current text color to the clipboard.
|
||||
.. seealso:: pasteColor()
|
||||
%End
|
||||
|
||||
void pasteColor();
|
||||
%Docstring
|
||||
Pastes a color from the clipboard to the text format. If clipboard does not contain a valid
|
||||
color or string representation of a color, then no change is applied.
|
||||
.. seealso:: copyColor()
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void changed();
|
||||
%Docstring
|
||||
Emitted when the widget's text format settings are changed.
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool event( QEvent *e );
|
||||
|
||||
virtual void changeEvent( QEvent *e );
|
||||
|
||||
virtual void showEvent( QShowEvent *e );
|
||||
|
||||
virtual void resizeEvent( QResizeEvent *event );
|
||||
|
||||
|
||||
virtual void mousePressEvent( QMouseEvent *e );
|
||||
|
||||
virtual void mouseMoveEvent( QMouseEvent *e );
|
||||
|
||||
|
||||
virtual void dragEnterEvent( QDragEnterEvent *e );
|
||||
|
||||
|
||||
virtual void dragLeaveEvent( QDragLeaveEvent *e );
|
||||
|
||||
|
||||
virtual void dropEvent( QDropEvent *e );
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsfontbutton.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
@ -1594,6 +1594,49 @@ QDomElement QgsTextFormat::writeXml( QDomDocument &doc, const QgsReadWriteContex
|
||||
return textStyleElem;
|
||||
}
|
||||
|
||||
QMimeData *QgsTextFormat::toMimeData() const
|
||||
{
|
||||
//set both the mime color data, and the text (format settings).
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setColorData( QVariant( color() ) );
|
||||
|
||||
QgsReadWriteContext rwContext;
|
||||
QDomDocument textDoc;
|
||||
QDomElement textElem = writeXml( textDoc, rwContext );
|
||||
textDoc.appendChild( textElem );
|
||||
mimeData->setText( textDoc.toString() );
|
||||
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
QgsTextFormat QgsTextFormat::fromMimeData( const QMimeData *data, bool *ok )
|
||||
{
|
||||
if ( ok )
|
||||
*ok = false;
|
||||
QgsTextFormat format;
|
||||
if ( !data )
|
||||
return format;
|
||||
|
||||
QString text = data->text();
|
||||
if ( !text.isEmpty() )
|
||||
{
|
||||
QDomDocument doc;
|
||||
QDomElement elem;
|
||||
QgsReadWriteContext rwContext;
|
||||
|
||||
if ( doc.setContent( text ) )
|
||||
{
|
||||
elem = doc.documentElement();
|
||||
|
||||
format.readXml( elem, rwContext );
|
||||
if ( ok )
|
||||
*ok = true;
|
||||
return format;
|
||||
}
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
bool QgsTextFormat::containsAdvancedEffects() const
|
||||
{
|
||||
if ( d->blendMode != QPainter::CompositionMode_SourceOver )
|
||||
|
||||
@ -1068,6 +1068,20 @@ class CORE_EXPORT QgsTextFormat
|
||||
*/
|
||||
QDomElement writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const;
|
||||
|
||||
/**
|
||||
* Returns new mime data representing the text format settings.
|
||||
* Caller takes responsibility for deleting the returned object.
|
||||
* \see fromMimeData()
|
||||
*/
|
||||
QMimeData *toMimeData() const SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Attempts to parse the provided mime \a data as a QgsTextFormat.
|
||||
* If data can be parsed as a text format, \a ok will be set to true.
|
||||
* \see toMimeData()
|
||||
*/
|
||||
static QgsTextFormat fromMimeData( const QMimeData *data, bool *ok SIP_OUT = nullptr );
|
||||
|
||||
/** Returns true if any component of the font format requires advanced effects
|
||||
* such as blend modes, which require output in raster formats to be fully respected.
|
||||
*/
|
||||
|
||||
@ -227,6 +227,7 @@ SET(QGIS_GUI_SRCS
|
||||
qgsfilterlineedit.cpp
|
||||
qgsfloatingwidget.cpp
|
||||
qgsfocuswatcher.cpp
|
||||
qgsfontbutton.cpp
|
||||
qgsformannotation.cpp
|
||||
qgsgeometryrubberband.cpp
|
||||
qgsgradientcolorrampdialog.cpp
|
||||
@ -387,6 +388,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgsfilterlineedit.h
|
||||
qgsfloatingwidget.h
|
||||
qgsfocuswatcher.h
|
||||
qgsfontbutton.h
|
||||
qgsformannotation.h
|
||||
qgsgradientcolorrampdialog.h
|
||||
qgsgradientstopeditor.h
|
||||
|
||||
646
src/gui/qgsfontbutton.cpp
Normal file
646
src/gui/qgsfontbutton.cpp
Normal file
@ -0,0 +1,646 @@
|
||||
/***************************************************************************
|
||||
qgsfontbutton.h
|
||||
---------------
|
||||
Date : May 2017
|
||||
Copyright : (C) 2017 by Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsfontbutton.h"
|
||||
#include "qgstextformatwidget.h"
|
||||
#include "qgssymbollayerutils.h"
|
||||
#include "qgscolorscheme.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgscolorwidgets.h"
|
||||
#include "qgscolorschemeregistry.h"
|
||||
#include "qgscolorswatchgrid.h"
|
||||
#include "qgsdoublespinbox.h"
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgsmenuheader.h"
|
||||
#include <QMenu>
|
||||
#include <QClipboard>
|
||||
#include <QDrag>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
QgsFontButton::QgsFontButton( QWidget *parent, const QString &dialogTitle )
|
||||
: QToolButton( parent )
|
||||
, mDialogTitle( dialogTitle.isEmpty() ? tr( "Text Format" ) : dialogTitle )
|
||||
, mMenu( nullptr )
|
||||
|
||||
{
|
||||
setAcceptDrops( true );
|
||||
setMinimumSize( QSize( 24, 16 ) );
|
||||
connect( this, &QAbstractButton::clicked, this, &QgsFontButton::showSettingsDialog );
|
||||
|
||||
//setup dropdown menu
|
||||
mMenu = new QMenu( this );
|
||||
connect( mMenu, &QMenu::aboutToShow, this, &QgsFontButton::prepareMenu );
|
||||
setMenu( mMenu );
|
||||
setPopupMode( QToolButton::MenuButtonPopup );
|
||||
}
|
||||
|
||||
QSize QgsFontButton::sizeHint() const
|
||||
{
|
||||
//make sure height of button looks good under different platforms
|
||||
#ifdef Q_OS_WIN
|
||||
return QSize( 120, 22 );
|
||||
#else
|
||||
return QSize( 120, 28 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void QgsFontButton::showSettingsDialog()
|
||||
{
|
||||
QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
|
||||
if ( panel && panel->dockMode() )
|
||||
{
|
||||
QgsTextFormatPanelWidget *formatWidget = new QgsTextFormatPanelWidget( mFormat, mMapCanvas, this );
|
||||
formatWidget->setPanelTitle( mDialogTitle );
|
||||
|
||||
connect( formatWidget, &QgsTextFormatPanelWidget::widgetChanged, this, [ this, formatWidget ] { this->setTextFormat( formatWidget->format() ); } );
|
||||
panel->openPanel( formatWidget );
|
||||
return;
|
||||
}
|
||||
|
||||
QgsTextFormatDialog dialog( mFormat, mMapCanvas, this );
|
||||
dialog.setWindowTitle( mDialogTitle );
|
||||
if ( dialog.exec() )
|
||||
{
|
||||
setTextFormat( dialog.format() );
|
||||
}
|
||||
|
||||
// reactivate button's window
|
||||
activateWindow();
|
||||
}
|
||||
|
||||
QgsMapCanvas *QgsFontButton::mapCanvas() const
|
||||
{
|
||||
return mMapCanvas;
|
||||
}
|
||||
|
||||
void QgsFontButton::setMapCanvas( QgsMapCanvas *mapCanvas )
|
||||
{
|
||||
mMapCanvas = mapCanvas;
|
||||
}
|
||||
|
||||
void QgsFontButton::setTextFormat( const QgsTextFormat &format )
|
||||
{
|
||||
mFormat = format;
|
||||
updatePreview();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsFontButton::setColor( const QColor &color )
|
||||
{
|
||||
QColor opaque = color;
|
||||
opaque.setAlphaF( 1.0 );
|
||||
|
||||
if ( mFormat.color() != opaque )
|
||||
{
|
||||
mFormat.setColor( opaque );
|
||||
updatePreview();
|
||||
emit changed();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFontButton::copyFormat()
|
||||
{
|
||||
QApplication::clipboard()->setMimeData( mFormat.toMimeData() );
|
||||
}
|
||||
|
||||
void QgsFontButton::pasteFormat()
|
||||
{
|
||||
QgsTextFormat tempFormat;
|
||||
if ( formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
|
||||
{
|
||||
setTextFormat( tempFormat );
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsFontButton::event( QEvent *e )
|
||||
{
|
||||
if ( e->type() == QEvent::ToolTip )
|
||||
{
|
||||
QString toolTip = QStringLiteral( "%1\nSize: %2" ).arg( mFormat.font().family() ).arg( mFormat.size() );
|
||||
setToolTip( toolTip );
|
||||
}
|
||||
return QToolButton::event( e );
|
||||
}
|
||||
|
||||
void QgsFontButton::mousePressEvent( QMouseEvent *e )
|
||||
{
|
||||
if ( e->button() == Qt::RightButton )
|
||||
{
|
||||
QToolButton::showMenu();
|
||||
return;
|
||||
}
|
||||
else if ( e->button() == Qt::LeftButton )
|
||||
{
|
||||
mDragStartPosition = e->pos();
|
||||
}
|
||||
QToolButton::mousePressEvent( e );
|
||||
}
|
||||
|
||||
void QgsFontButton::mouseMoveEvent( QMouseEvent *e )
|
||||
{
|
||||
//handle dragging fonts from button
|
||||
|
||||
if ( !( e->buttons() & Qt::LeftButton ) )
|
||||
{
|
||||
//left button not depressed, so not a drag
|
||||
QToolButton::mouseMoveEvent( e );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( e->pos() - mDragStartPosition ).manhattanLength() < QApplication::startDragDistance() )
|
||||
{
|
||||
//mouse not moved, so not a drag
|
||||
QToolButton::mouseMoveEvent( e );
|
||||
return;
|
||||
}
|
||||
|
||||
//user is dragging color
|
||||
QDrag *drag = new QDrag( this );
|
||||
drag->setMimeData( mFormat.toMimeData() );
|
||||
drag->setPixmap( createDragIcon() );
|
||||
drag->exec( Qt::CopyAction );
|
||||
setDown( false );
|
||||
}
|
||||
|
||||
bool QgsFontButton::colorFromMimeData( const QMimeData *mimeData, QColor &resultColor, bool &hasAlpha )
|
||||
{
|
||||
hasAlpha = false;
|
||||
QColor mimeColor = QgsSymbolLayerUtils::colorFromMimeData( mimeData, hasAlpha );
|
||||
|
||||
if ( mimeColor.isValid() )
|
||||
{
|
||||
resultColor = mimeColor;
|
||||
return true;
|
||||
}
|
||||
|
||||
//could not get color from mime data
|
||||
return false;
|
||||
}
|
||||
|
||||
void QgsFontButton::dragEnterEvent( QDragEnterEvent *e )
|
||||
{
|
||||
//is dragged data valid color data?
|
||||
QColor mimeColor;
|
||||
QgsTextFormat format;
|
||||
bool hasAlpha = false;
|
||||
|
||||
if ( formatFromMimeData( e->mimeData(), format ) )
|
||||
{
|
||||
e->acceptProposedAction();
|
||||
updatePreview( QColor(), &format );
|
||||
}
|
||||
else if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
|
||||
{
|
||||
//if so, we accept the drag, and temporarily change the button's color
|
||||
//to match the dragged color. This gives immediate feedback to the user
|
||||
//that colors can be dropped here
|
||||
e->acceptProposedAction();
|
||||
updatePreview( mimeColor );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFontButton::dragLeaveEvent( QDragLeaveEvent *e )
|
||||
{
|
||||
Q_UNUSED( e );
|
||||
//reset button color
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
void QgsFontButton::dropEvent( QDropEvent *e )
|
||||
{
|
||||
//is dropped data valid color data?
|
||||
QColor mimeColor;
|
||||
QgsTextFormat format;
|
||||
bool hasAlpha = false;
|
||||
if ( formatFromMimeData( e->mimeData(), format ) )
|
||||
{
|
||||
setTextFormat( format );
|
||||
return;
|
||||
}
|
||||
else if ( colorFromMimeData( e->mimeData(), mimeColor, hasAlpha ) )
|
||||
{
|
||||
//accept drop and set new color
|
||||
e->acceptProposedAction();
|
||||
|
||||
if ( hasAlpha )
|
||||
{
|
||||
mFormat.setOpacity( mimeColor.alphaF() );
|
||||
}
|
||||
mimeColor.setAlphaF( 1.0 );
|
||||
mFormat.setColor( mimeColor );
|
||||
QgsRecentColorScheme::addRecentColor( mimeColor );
|
||||
updatePreview();
|
||||
emit changed();
|
||||
}
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
QPixmap QgsFontButton::createMenuIcon( const QColor &color ) const
|
||||
{
|
||||
//create an icon pixmap
|
||||
QPixmap pixmap( 16, 16 );
|
||||
pixmap.fill( Qt::transparent );
|
||||
|
||||
QPainter p;
|
||||
p.begin( &pixmap );
|
||||
|
||||
//draw color over pattern
|
||||
p.setBrush( QBrush( color ) );
|
||||
|
||||
//draw border
|
||||
p.setPen( QColor( 197, 197, 197 ) );
|
||||
p.drawRect( 0, 0, 15, 15 );
|
||||
p.end();
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QPixmap QgsFontButton::createDragIcon( QSize size, const QgsTextFormat *tempFormat ) const
|
||||
{
|
||||
if ( !tempFormat )
|
||||
tempFormat = &mFormat;
|
||||
|
||||
//create an icon pixmap
|
||||
QPixmap pixmap( size.width(), size.height() );
|
||||
pixmap.fill( Qt::transparent );
|
||||
QPainter p;
|
||||
p.begin( &pixmap );
|
||||
p.setRenderHint( QPainter::Antialiasing );
|
||||
QRect rect( 0, 0, size.width(), size.height() );
|
||||
|
||||
if ( tempFormat->color().lightnessF() < 0.7 )
|
||||
{
|
||||
p.setBrush( QBrush( QColor( 255, 255, 255 ) ) );
|
||||
p.setPen( QPen( QColor( 150, 150, 150 ), 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
p.setBrush( QBrush( QColor( 0, 0, 0 ) ) );
|
||||
p.setPen( QPen( QColor( 100, 100, 100 ), 0 ) );
|
||||
}
|
||||
p.drawRect( rect );
|
||||
p.setBrush( Qt::NoBrush );
|
||||
p.setPen( Qt::NoPen );
|
||||
|
||||
|
||||
QgsRenderContext context;
|
||||
QgsMapToPixel newCoordXForm;
|
||||
newCoordXForm.setParameters( 1, 0, 0, 0, 0, 0 );
|
||||
context.setMapToPixel( newCoordXForm );
|
||||
|
||||
context.setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 );
|
||||
context.setUseAdvancedEffects( true );
|
||||
context.setPainter( &p );
|
||||
|
||||
// slightly inset text to account for buffer/background
|
||||
double xtrans = 0;
|
||||
if ( tempFormat->buffer().enabled() )
|
||||
xtrans = context.convertToPainterUnits( tempFormat->buffer().size(), tempFormat->buffer().sizeUnit(), tempFormat->buffer().sizeMapUnitScale() );
|
||||
if ( tempFormat->background().enabled() && tempFormat->background().sizeType() != QgsTextBackgroundSettings::SizeFixed )
|
||||
xtrans = qMax( xtrans, context.convertToPainterUnits( tempFormat->background().size().width(), tempFormat->background().sizeUnit(), tempFormat->background().sizeMapUnitScale() ) );
|
||||
|
||||
double ytrans = 0.0;
|
||||
if ( tempFormat->buffer().enabled() )
|
||||
ytrans = qMax( ytrans, context.convertToPainterUnits( tempFormat->buffer().size(), tempFormat->buffer().sizeUnit(), tempFormat->buffer().sizeMapUnitScale() ) );
|
||||
if ( tempFormat->background().enabled() )
|
||||
ytrans = qMax( ytrans, context.convertToPainterUnits( tempFormat->background().size().height(), tempFormat->background().sizeUnit(), tempFormat->background().sizeMapUnitScale() ) );
|
||||
|
||||
QRectF textRect = rect;
|
||||
textRect.setLeft( xtrans );
|
||||
textRect.setWidth( textRect.width() - xtrans );
|
||||
textRect.setTop( ytrans );
|
||||
if ( textRect.height() > 300 )
|
||||
textRect.setHeight( 300 );
|
||||
if ( textRect.width() > 2000 )
|
||||
textRect.setWidth( 2000 );
|
||||
|
||||
QgsTextRenderer::drawText( textRect, 0, QgsTextRenderer::AlignCenter, QStringList() << tr( "Aa" ),
|
||||
context, *tempFormat );
|
||||
|
||||
p.end();
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
void QgsFontButton::prepareMenu()
|
||||
{
|
||||
//we need to tear down and rebuild this menu every time it is shown. Otherwise the space allocated to any
|
||||
//QgsColorSwatchGridAction is not recalculated by Qt and the swatch grid may not be the correct size
|
||||
//for the number of colors shown in the grid. Note that we MUST refresh color swatch grids every time this
|
||||
//menu is opened, otherwise color schemes like the recent color scheme grid are meaningless
|
||||
mMenu->clear();
|
||||
|
||||
#if 0 // too slow if many fonts...
|
||||
QMenu *fontMenu = new QMenu( mFormat.font().family(), mMenu );
|
||||
QFontDatabase db;
|
||||
Q_FOREACH ( const QString &family, db.families() )
|
||||
{
|
||||
QAction *fontAction = new QAction( family, fontMenu );
|
||||
QFont f = fontAction->font();
|
||||
f.setFamily( family );
|
||||
fontAction->setFont( f );
|
||||
fontAction->setToolTip( family );
|
||||
fontMenu->addAction( fontAction );
|
||||
if ( family == mFormat.font().family() )
|
||||
{
|
||||
fontAction->setCheckable( true );
|
||||
fontAction->setChecked( true );
|
||||
}
|
||||
auto setFont = [this, family]
|
||||
{
|
||||
QFont f = mFormat.font();
|
||||
f.setFamily( family );
|
||||
mFormat.setFont( f );
|
||||
updatePreview();
|
||||
emit changed();
|
||||
};
|
||||
connect( fontAction, &QAction::triggered, this, setFont );
|
||||
}
|
||||
mMenu->addMenu( fontMenu );
|
||||
#endif
|
||||
|
||||
QWidgetAction *sizeAction = new QWidgetAction( mMenu );
|
||||
QWidget *sizeWidget = new QWidget();
|
||||
QVBoxLayout *sizeLayout = new QVBoxLayout();
|
||||
sizeLayout->setMargin( 0 );
|
||||
sizeLayout->setContentsMargins( 0, 0, 0, 3 );
|
||||
sizeLayout->setSpacing( 2 );
|
||||
|
||||
QgsMenuHeader *sizeLabel = new QgsMenuHeader( tr( "Font size (%1)" ).arg( QgsUnitTypes::toString( mFormat.sizeUnit() ) ) );
|
||||
sizeLayout->addWidget( sizeLabel );
|
||||
|
||||
QgsDoubleSpinBox *sizeSpin = new QgsDoubleSpinBox( nullptr );
|
||||
sizeSpin->setDecimals( 4 );
|
||||
sizeSpin->setMaximum( 1e+9 );
|
||||
sizeSpin->setShowClearButton( false );
|
||||
sizeSpin->setValue( mFormat.size() );
|
||||
connect( sizeSpin, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ),
|
||||
this, [ = ]( double value )
|
||||
{
|
||||
mFormat.setSize( value );
|
||||
updatePreview();
|
||||
emit changed();
|
||||
} );
|
||||
QHBoxLayout *spinLayout = new QHBoxLayout();
|
||||
spinLayout->setMargin( 0 );
|
||||
spinLayout->setContentsMargins( 4, 0, 4, 0 );
|
||||
spinLayout->addWidget( sizeSpin );
|
||||
sizeLayout->addLayout( spinLayout );
|
||||
sizeWidget->setLayout( sizeLayout );
|
||||
sizeAction->setDefaultWidget( sizeWidget );
|
||||
sizeWidget->setFocusProxy( sizeSpin );
|
||||
sizeWidget->setFocusPolicy( Qt::StrongFocus );
|
||||
mMenu->addAction( sizeAction );
|
||||
|
||||
QAction *configureAction = new QAction( tr( "Configure format..." ), this );
|
||||
mMenu->addAction( configureAction );
|
||||
connect( configureAction, &QAction::triggered, this, &QgsFontButton::showSettingsDialog );
|
||||
|
||||
QAction *copyFormatAction = new QAction( tr( "Copy format" ), this );
|
||||
mMenu->addAction( copyFormatAction );
|
||||
connect( copyFormatAction, &QAction::triggered, this, &QgsFontButton::copyFormat );
|
||||
QAction *pasteFormatAction = new QAction( tr( "Paste format" ), this );
|
||||
//enable or disable paste action based on current clipboard contents. We always show the paste
|
||||
//action, even if it's disabled, to give hint to the user that pasting colors is possible
|
||||
QgsTextFormat tempFormat;
|
||||
if ( formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
|
||||
{
|
||||
tempFormat.setSizeUnit( QgsUnitTypes::RenderPixels );
|
||||
tempFormat.setSize( 14 );
|
||||
pasteFormatAction->setIcon( createDragIcon( QSize( 16, 16 ), &tempFormat ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pasteFormatAction->setEnabled( false );
|
||||
}
|
||||
mMenu->addAction( pasteFormatAction );
|
||||
connect( pasteFormatAction, &QAction::triggered, this, &QgsFontButton::pasteFormat );
|
||||
|
||||
mMenu->addSeparator();
|
||||
|
||||
QgsColorWheel *colorWheel = new QgsColorWheel( mMenu );
|
||||
colorWheel->setColor( mFormat.color() );
|
||||
QgsColorWidgetAction *colorAction = new QgsColorWidgetAction( colorWheel, mMenu, mMenu );
|
||||
colorAction->setDismissOnColorSelection( false );
|
||||
connect( colorAction, &QgsColorWidgetAction::colorChanged, this, &QgsFontButton::setColor );
|
||||
mMenu->addAction( colorAction );
|
||||
|
||||
QgsColorRampWidget *alphaRamp = new QgsColorRampWidget( mMenu, QgsColorWidget::Alpha, QgsColorRampWidget::Horizontal );
|
||||
QColor alphaColor = mFormat.color();
|
||||
alphaColor.setAlphaF( mFormat.opacity() );
|
||||
alphaRamp->setColor( alphaColor );
|
||||
QgsColorWidgetAction *alphaAction = new QgsColorWidgetAction( alphaRamp, mMenu, mMenu );
|
||||
alphaAction->setDismissOnColorSelection( false );
|
||||
connect( alphaAction, &QgsColorWidgetAction::colorChanged, this, [ = ]( const QColor & color )
|
||||
{
|
||||
double opacity = color.alphaF();
|
||||
mFormat.setOpacity( opacity );
|
||||
updatePreview();
|
||||
emit changed();
|
||||
} );
|
||||
connect( colorAction, &QgsColorWidgetAction::colorChanged, alphaRamp, [alphaRamp]( const QColor & color ) { alphaRamp->setColor( color, false ); }
|
||||
);
|
||||
mMenu->addAction( alphaAction );
|
||||
|
||||
//get schemes with ShowInColorButtonMenu flag set
|
||||
QList< QgsColorScheme * > schemeList = QgsApplication::colorSchemeRegistry()->schemes( QgsColorScheme::ShowInColorButtonMenu );
|
||||
QList< QgsColorScheme * >::iterator it = schemeList.begin();
|
||||
for ( ; it != schemeList.end(); ++it )
|
||||
{
|
||||
QgsColorSwatchGridAction *colorAction = new QgsColorSwatchGridAction( *it, mMenu, QStringLiteral( "labeling" ), this );
|
||||
colorAction->setBaseColor( mFormat.color() );
|
||||
mMenu->addAction( colorAction );
|
||||
connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsFontButton::setColor );
|
||||
connect( colorAction, &QgsColorSwatchGridAction::colorChanged, this, &QgsFontButton::addRecentColor );
|
||||
}
|
||||
|
||||
mMenu->addSeparator();
|
||||
|
||||
QAction *copyColorAction = new QAction( tr( "Copy color" ), this );
|
||||
mMenu->addAction( copyColorAction );
|
||||
connect( copyColorAction, &QAction::triggered, this, &QgsFontButton::copyColor );
|
||||
|
||||
QAction *pasteColorAction = new QAction( tr( "Paste color" ), this );
|
||||
//enable or disable paste action based on current clipboard contents. We always show the paste
|
||||
//action, even if it's disabled, to give hint to the user that pasting colors is possible
|
||||
QColor clipColor;
|
||||
bool hasAlpha = false;
|
||||
if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
|
||||
{
|
||||
pasteColorAction->setIcon( createMenuIcon( clipColor ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pasteColorAction->setEnabled( false );
|
||||
}
|
||||
mMenu->addAction( pasteColorAction );
|
||||
connect( pasteColorAction, &QAction::triggered, this, &QgsFontButton::pasteColor );
|
||||
|
||||
}
|
||||
|
||||
void QgsFontButton::addRecentColor( const QColor &color )
|
||||
{
|
||||
QgsRecentColorScheme::addRecentColor( color );
|
||||
}
|
||||
|
||||
bool QgsFontButton::formatFromMimeData( const QMimeData *mimeData, QgsTextFormat &resultFormat ) const
|
||||
{
|
||||
bool ok = false;
|
||||
resultFormat = QgsTextFormat::fromMimeData( mimeData, &ok );
|
||||
return ok;
|
||||
}
|
||||
|
||||
void QgsFontButton::changeEvent( QEvent *e )
|
||||
{
|
||||
if ( e->type() == QEvent::EnabledChange )
|
||||
{
|
||||
updatePreview();
|
||||
}
|
||||
QToolButton::changeEvent( e );
|
||||
}
|
||||
|
||||
void QgsFontButton::showEvent( QShowEvent *e )
|
||||
{
|
||||
updatePreview();
|
||||
QToolButton::showEvent( e );
|
||||
}
|
||||
|
||||
void QgsFontButton::resizeEvent( QResizeEvent *event )
|
||||
{
|
||||
QToolButton::resizeEvent( event );
|
||||
//recalculate icon size and redraw icon
|
||||
mIconSize = QSize();
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
void QgsFontButton::updatePreview( const QColor &color, QgsTextFormat *format )
|
||||
{
|
||||
QgsTextFormat tempFormat;
|
||||
|
||||
if ( format )
|
||||
tempFormat = *format;
|
||||
else
|
||||
tempFormat = mFormat;
|
||||
|
||||
if ( color.isValid() )
|
||||
tempFormat.setColor( color );
|
||||
|
||||
QSize currentIconSize;
|
||||
//icon size is button size with a small margin
|
||||
if ( menu() )
|
||||
{
|
||||
if ( !mIconSize.isValid() )
|
||||
{
|
||||
//calculate size of push button part of widget (ie, without the menu dropdown button part)
|
||||
QStyleOptionToolButton opt;
|
||||
initStyleOption( &opt );
|
||||
QRect buttonSize = QApplication::style()->subControlRect( QStyle::CC_ToolButton, &opt, QStyle::SC_ToolButton,
|
||||
this );
|
||||
//make sure height of icon looks good under different platforms
|
||||
#ifdef Q_OS_WIN
|
||||
mIconSize = QSize( buttonSize.width() - 10, height() - 6 );
|
||||
#else
|
||||
mIconSize = QSize( buttonSize.width() - 10, height() - 12 );
|
||||
#endif
|
||||
}
|
||||
currentIconSize = mIconSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
//no menu
|
||||
#ifdef Q_OS_WIN
|
||||
currentIconSize = QSize( width() - 10, height() - 6 );
|
||||
#else
|
||||
currentIconSize = QSize( width() - 10, height() - 12 );
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( !currentIconSize.isValid() || currentIconSize.width() <= 0 || currentIconSize.height() <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//create an icon pixmap
|
||||
QPixmap pixmap( currentIconSize );
|
||||
pixmap.fill( Qt::transparent );
|
||||
QPainter p;
|
||||
p.begin( &pixmap );
|
||||
p.setRenderHint( QPainter::Antialiasing );
|
||||
QRect rect( 0, 0, currentIconSize.width(), currentIconSize.height() );
|
||||
|
||||
QgsRenderContext context;
|
||||
QgsMapToPixel newCoordXForm;
|
||||
newCoordXForm.setParameters( 1, 0, 0, 0, 0, 0 );
|
||||
context.setMapToPixel( newCoordXForm );
|
||||
|
||||
context.setScaleFactor( QgsApplication::desktop()->logicalDpiX() / 25.4 );
|
||||
context.setUseAdvancedEffects( true );
|
||||
context.setPainter( &p );
|
||||
|
||||
// slightly inset text to account for buffer/background
|
||||
double xtrans = 0;
|
||||
if ( tempFormat.buffer().enabled() )
|
||||
xtrans = context.convertToPainterUnits( tempFormat.buffer().size(), tempFormat.buffer().sizeUnit(), tempFormat.buffer().sizeMapUnitScale() );
|
||||
if ( tempFormat.background().enabled() && tempFormat.background().sizeType() != QgsTextBackgroundSettings::SizeFixed )
|
||||
xtrans = qMax( xtrans, context.convertToPainterUnits( tempFormat.background().size().width(), tempFormat.background().sizeUnit(), tempFormat.background().sizeMapUnitScale() ) );
|
||||
|
||||
double ytrans = 0.0;
|
||||
if ( tempFormat.buffer().enabled() )
|
||||
ytrans = qMax( ytrans, context.convertToPainterUnits( tempFormat.buffer().size(), tempFormat.buffer().sizeUnit(), tempFormat.buffer().sizeMapUnitScale() ) );
|
||||
if ( tempFormat.background().enabled() )
|
||||
ytrans = qMax( ytrans, context.convertToPainterUnits( tempFormat.background().size().height(), tempFormat.background().sizeUnit(), tempFormat.background().sizeMapUnitScale() ) );
|
||||
|
||||
QRectF textRect = rect;
|
||||
textRect.setLeft( xtrans );
|
||||
textRect.setWidth( textRect.width() - xtrans );
|
||||
textRect.setTop( ytrans );
|
||||
if ( textRect.height() > 300 )
|
||||
textRect.setHeight( 300 );
|
||||
if ( textRect.width() > 2000 )
|
||||
textRect.setWidth( 2000 );
|
||||
|
||||
QgsTextRenderer::drawText( textRect, 0, QgsTextRenderer::AlignLeft, QStringList() << "Font",
|
||||
context, tempFormat );
|
||||
|
||||
p.end();
|
||||
setIconSize( currentIconSize );
|
||||
setIcon( pixmap );
|
||||
}
|
||||
|
||||
void QgsFontButton::copyColor()
|
||||
{
|
||||
//copy color
|
||||
QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::colorToMimeData( mFormat.color() ) );
|
||||
}
|
||||
|
||||
void QgsFontButton::pasteColor()
|
||||
{
|
||||
QColor clipColor;
|
||||
bool hasAlpha = false;
|
||||
if ( colorFromMimeData( QApplication::clipboard()->mimeData(), clipColor, hasAlpha ) )
|
||||
{
|
||||
//paste color
|
||||
setColor( clipColor );
|
||||
QgsRecentColorScheme::addRecentColor( clipColor );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFontButton::setDialogTitle( const QString &title )
|
||||
{
|
||||
mDialogTitle = title;
|
||||
}
|
||||
|
||||
QString QgsFontButton::dialogTitle() const
|
||||
{
|
||||
return mDialogTitle;
|
||||
}
|
||||
210
src/gui/qgsfontbutton.h
Normal file
210
src/gui/qgsfontbutton.h
Normal file
@ -0,0 +1,210 @@
|
||||
/***************************************************************************
|
||||
qgsfontbutton.h
|
||||
---------------
|
||||
Date : May 2017
|
||||
Copyright : (C) 2017 by Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSFONTBUTTON_H
|
||||
#define QGSFONTBUTTON_H
|
||||
|
||||
#include "qgis_gui.h"
|
||||
#include "qgis.h"
|
||||
#include "qgstextrenderer.h"
|
||||
|
||||
#include <QToolButton>
|
||||
|
||||
class QgsMapCanvas;
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* \class QgsFontButton
|
||||
* A button for customising QgsTextFormat settings.
|
||||
*
|
||||
* The button will open a detailed text format settings dialog when clicked. An attached drop down
|
||||
* menu allows for copying and pasting text styles, picking colors for the text, and for dropping
|
||||
* colors from other color widgets.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class GUI_EXPORT QgsFontButton : public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( QString dialogTitle READ dialogTitle WRITE setDialogTitle )
|
||||
Q_PROPERTY( QgsTextFormat textFormat READ textFormat WRITE setTextFormat NOTIFY changed )
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Construct a new font button.
|
||||
* Use \a parent to attach a parent QWidget to the dialog.
|
||||
* Use \a dialogTitle string to define the title to show in the text settings dialog.
|
||||
*/
|
||||
QgsFontButton( QWidget *parent SIP_TRANSFERTHIS = nullptr, const QString &dialogTitle = QString() );
|
||||
|
||||
virtual QSize sizeHint() const override;
|
||||
|
||||
/**
|
||||
* Sets the \a title for the text settings dialog window.
|
||||
* \see dialogTitle()
|
||||
*/
|
||||
void setDialogTitle( const QString &title );
|
||||
|
||||
/**
|
||||
* Returns the title for the text settings dialog window.
|
||||
* \see setDialogTitle()
|
||||
*/
|
||||
QString dialogTitle() const;
|
||||
|
||||
/**
|
||||
* Returns the map canvas associated with the widget.
|
||||
* \see setMapCanvas()
|
||||
*/
|
||||
QgsMapCanvas *mapCanvas() const;
|
||||
|
||||
/**
|
||||
* Sets a map \a canvas to associate with the widget. This allows the
|
||||
* widget to fetch current settings from the map canvas, such as current scale.
|
||||
* \see mapCanvas()
|
||||
*/
|
||||
void setMapCanvas( QgsMapCanvas *canvas );
|
||||
|
||||
/**
|
||||
* Returns the current text formatting set by the widget.
|
||||
* \see setTextFormat()
|
||||
*/
|
||||
QgsTextFormat textFormat() const { return mFormat; }
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
* Sets the current text \a format to show in the widget.
|
||||
* \see textFormat()
|
||||
*/
|
||||
void setTextFormat( const QgsTextFormat &format );
|
||||
|
||||
/**
|
||||
* Sets the current \a color for the text. Will emit a changed signal if the color is different
|
||||
* to the previous text color.
|
||||
*/
|
||||
void setColor( const QColor &color );
|
||||
|
||||
/** Copies the current text format to the clipboard.
|
||||
* \see pasteFormat()
|
||||
*/
|
||||
void copyFormat();
|
||||
|
||||
/**
|
||||
* Pastes a format from the clipboard. If clipboard does not contain a valid
|
||||
* format then no change is applied.
|
||||
* \see copyFormat()
|
||||
*/
|
||||
void pasteFormat();
|
||||
|
||||
/** Copies the current text color to the clipboard.
|
||||
* \see pasteColor()
|
||||
*/
|
||||
void copyColor();
|
||||
|
||||
/**
|
||||
* Pastes a color from the clipboard to the text format. If clipboard does not contain a valid
|
||||
* color or string representation of a color, then no change is applied.
|
||||
* \see copyColor()
|
||||
*/
|
||||
void pasteColor();
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
* Emitted when the widget's text format settings are changed.
|
||||
*/
|
||||
void changed();
|
||||
|
||||
protected:
|
||||
|
||||
bool event( QEvent *e ) override;
|
||||
void changeEvent( QEvent *e ) override;
|
||||
void showEvent( QShowEvent *e ) override;
|
||||
void resizeEvent( QResizeEvent *event ) override;
|
||||
|
||||
// Reimplemented to detect right mouse button clicks on the color button and allow dragging colors
|
||||
void mousePressEvent( QMouseEvent *e ) override;
|
||||
// Reimplemented to allow dragging fonts from button
|
||||
void mouseMoveEvent( QMouseEvent *e ) override;
|
||||
|
||||
// Reimplemented to accept dragged colors
|
||||
void dragEnterEvent( QDragEnterEvent *e ) override;
|
||||
|
||||
// Reimplemented to reset button appearance after drag leave
|
||||
void dragLeaveEvent( QDragLeaveEvent *e ) override;
|
||||
|
||||
// Reimplemented to accept dropped colors
|
||||
void dropEvent( QDropEvent *e ) override;
|
||||
|
||||
private slots:
|
||||
|
||||
void showSettingsDialog();
|
||||
|
||||
/** Creates the drop down menu entries
|
||||
*/
|
||||
void prepareMenu();
|
||||
|
||||
void addRecentColor( const QColor &color );
|
||||
|
||||
private:
|
||||
|
||||
QString mDialogTitle;
|
||||
QgsTextFormat mFormat;
|
||||
|
||||
QgsMapCanvas *mMapCanvas = nullptr;
|
||||
|
||||
QPoint mDragStartPosition;
|
||||
|
||||
QMenu *mMenu = nullptr;
|
||||
|
||||
QSize mIconSize;
|
||||
|
||||
/**
|
||||
* Attempts to parse mimeData as a text format.
|
||||
* \returns true if mime data could be intrepreted as a format
|
||||
* \param mimeData mime data
|
||||
* \param resultFormat destination for text format
|
||||
* \see colorFromMimeData
|
||||
*/
|
||||
bool formatFromMimeData( const QMimeData *mimeData, QgsTextFormat &resultFormat ) const;
|
||||
|
||||
/** Attempts to parse mimeData as a color, either via the mime data's color data or by
|
||||
* parsing a textual representation of a color.
|
||||
* \returns true if mime data could be intrepreted as a color
|
||||
* \param mimeData mime data
|
||||
* \param resultColor QColor to store evaluated color
|
||||
* \param hasAlpha will be set to true if mime data also included an alpha component
|
||||
* \see formatFromMimeData
|
||||
*/
|
||||
bool colorFromMimeData( const QMimeData *mimeData, QColor &resultColor, bool &hasAlpha );
|
||||
|
||||
/**
|
||||
* Create a \a color icon for display in the drop down menu.
|
||||
*/
|
||||
QPixmap createMenuIcon( const QColor &color ) const;
|
||||
|
||||
/**
|
||||
* Creates a drag icon showing the current font style.
|
||||
*/
|
||||
QPixmap createDragIcon( QSize size = QSize( 50, 50 ), const QgsTextFormat *tempFormat = nullptr ) const;
|
||||
|
||||
/**
|
||||
* Regenerates the text preview. If \a color is specified, a temporary color preview
|
||||
* is shown instead.
|
||||
*/
|
||||
void updatePreview( const QColor &color = QColor(), QgsTextFormat *tempFormat = nullptr );
|
||||
};
|
||||
|
||||
#endif // QGSFONTBUTTON_H
|
||||
@ -61,6 +61,7 @@ ADD_PYTHON_TEST(PyQgsField test_qgsfield.py)
|
||||
ADD_PYTHON_TEST(PyQgsFieldModel test_qgsfieldmodel.py)
|
||||
ADD_PYTHON_TEST(PyQgsFilterLineEdit test_qgsfilterlineedit.py)
|
||||
ADD_PYTHON_TEST(PyQgsFloatingWidget test_qgsfloatingwidget.py)
|
||||
ADD_PYTHON_TEST(PyQgsFontButton test_qgsfontbutton.py)
|
||||
ADD_PYTHON_TEST(PyQgsFontUtils test_qgsfontutils.py)
|
||||
ADD_PYTHON_TEST(PyQgsGeometryAvoidIntersections test_qgsgeometry_avoid_intersections.py)
|
||||
ADD_PYTHON_TEST(PyQgsGeometryGeneratorSymbolLayer test_qgsgeometrygeneratorsymbollayer.py)
|
||||
|
||||
93
tests/src/python/test_qgsfontbutton.py
Normal file
93
tests/src/python/test_qgsfontbutton.py
Normal file
@ -0,0 +1,93 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""QGIS Unit tests for QgsFontButton.
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
__author__ = 'Nyall Dawson'
|
||||
__date__ = '04/06/2017'
|
||||
__copyright__ = 'Copyright 2017, The QGIS Project'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import qgis # NOQA
|
||||
|
||||
from qgis.core import QgsTextFormat
|
||||
from qgis.gui import QgsFontButton, QgsMapCanvas
|
||||
from qgis.testing import start_app, unittest
|
||||
from qgis.PyQt.QtGui import QColor
|
||||
from qgis.PyQt.QtTest import QSignalSpy
|
||||
from utilities import getTestFont
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
class TestQgsFontButton(unittest.TestCase):
|
||||
|
||||
def testGettersSetters(self):
|
||||
button = QgsFontButton()
|
||||
canvas = QgsMapCanvas()
|
||||
|
||||
button.setDialogTitle('test title')
|
||||
self.assertEqual(button.dialogTitle(), 'test title')
|
||||
|
||||
button.setMapCanvas(canvas)
|
||||
self.assertEqual(button.mapCanvas(), canvas)
|
||||
|
||||
def testSetGetFormat(self):
|
||||
button = QgsFontButton()
|
||||
|
||||
s = QgsTextFormat()
|
||||
s.setFont(getTestFont())
|
||||
s.setNamedStyle('Italic')
|
||||
s.setSize(5)
|
||||
s.setColor(QColor(255, 0, 0))
|
||||
s.setOpacity(0.5)
|
||||
|
||||
signal_spy = QSignalSpy(button.changed)
|
||||
button.setTextFormat(s)
|
||||
self.assertEqual(len(signal_spy), 1)
|
||||
|
||||
r = button.textFormat()
|
||||
self.assertEqual(r.font().family(), 'QGIS Vera Sans')
|
||||
self.assertEqual(r.namedStyle(), 'Italic')
|
||||
self.assertEqual(r.size(), 5)
|
||||
self.assertEqual(r.color(), QColor(255, 0, 0))
|
||||
self.assertEqual(r.opacity(), 0.5)
|
||||
|
||||
def testSetColor(self):
|
||||
button = QgsFontButton()
|
||||
|
||||
s = QgsTextFormat()
|
||||
s.setFont(getTestFont())
|
||||
s.setNamedStyle('Italic')
|
||||
s.setSize(5)
|
||||
s.setColor(QColor(255, 0, 0))
|
||||
s.setOpacity(0.5)
|
||||
button.setTextFormat(s)
|
||||
|
||||
signal_spy = QSignalSpy(button.changed)
|
||||
button.setColor(QColor(0, 255, 0))
|
||||
self.assertEqual(len(signal_spy), 1)
|
||||
|
||||
r = button.textFormat()
|
||||
self.assertEqual(r.font().family(), 'QGIS Vera Sans')
|
||||
self.assertEqual(r.namedStyle(), 'Italic')
|
||||
self.assertEqual(r.size(), 5)
|
||||
self.assertEqual(r.color().name(), QColor(0, 255, 0).name())
|
||||
self.assertEqual(r.opacity(), 0.5)
|
||||
|
||||
# set same color, should not emit signal
|
||||
button.setColor(QColor(0, 255, 0))
|
||||
self.assertEqual(len(signal_spy), 1)
|
||||
|
||||
# color with transparency - should be stripped
|
||||
button.setColor(QColor(0, 255, 0, 100))
|
||||
r = button.textFormat()
|
||||
self.assertEqual(r.color(), QColor(0, 255, 0))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@ -324,6 +324,16 @@ class PyQgsTextRenderer(unittest.TestCase):
|
||||
t.readXml(parent, QgsReadWriteContext())
|
||||
self.checkTextFormat(t)
|
||||
|
||||
def testFormatToFromMimeData(self):
|
||||
"""Test converting format to and from mime data"""
|
||||
s = self.createFormatSettings()
|
||||
md = s.toMimeData()
|
||||
from_mime, ok = QgsTextFormat.fromMimeData(None)
|
||||
self.assertFalse(ok)
|
||||
from_mime, ok = QgsTextFormat.fromMimeData(md)
|
||||
self.assertTrue(ok)
|
||||
self.checkTextFormat(from_mime)
|
||||
|
||||
def containsAdvancedEffects(self):
|
||||
t = QgsTextFormat()
|
||||
self.assertFalse(t.containsAdvancedEffects())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user