Show favorited legend patches in legend patch button menu

This commit is contained in:
Nyall Dawson 2020-04-22 10:04:58 +10:00
parent 8a0e007ba5
commit ec2894ea32
7 changed files with 83 additions and 32 deletions

View File

@ -636,6 +636,15 @@ Changes a legend patch shape's name.
%Docstring
Returns a list of names of legend patch shapes in the style.
.. versionadded:: 3.14
%End
const QgsSymbol *previewSymbolForPatchShape( const QgsLegendPatchShape &shape ) const;
%Docstring
Returns a symbol to use for rendering preview icons for a patch ``shape``.
Ownership of the symbol is not transferred.
.. versionadded:: 3.14
%End

View File

@ -53,6 +53,13 @@ enum LegendPatchTable
QgsStyle *QgsStyle::sDefaultStyle = nullptr;
QgsStyle::QgsStyle()
{
mPatchMarkerSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
mPatchLineSymbol.reset( QgsLineSymbol::createSimple( QgsStringMap() ) );
mPatchFillSymbol.reset( QgsFillSymbol::createSimple( QgsStringMap() ) );
}
QgsStyle::~QgsStyle()
{
clear();
@ -1920,6 +1927,25 @@ QStringList QgsStyle::legendPatchShapeNames() const
return mLegendPatchShapes.keys();
}
const QgsSymbol *QgsStyle::previewSymbolForPatchShape( const QgsLegendPatchShape &shape ) const
{
switch ( shape.symbolType() )
{
case QgsSymbol::Marker:
return mPatchMarkerSymbol.get();
case QgsSymbol::Line:
return mPatchLineSymbol.get();
case QgsSymbol::Fill:
return mPatchFillSymbol.get();
case QgsSymbol::Hybrid:
break;
}
return nullptr;
}
int QgsStyle::tagId( const QString &name )
{
return getId( QStringLiteral( "tag" ), name );

View File

@ -165,7 +165,7 @@ class CORE_EXPORT QgsStyle : public QObject
/**
* Constructor for QgsStyle.
*/
QgsStyle() = default;
QgsStyle();
~QgsStyle() override;
/**
@ -663,6 +663,15 @@ class CORE_EXPORT QgsStyle : public QObject
*/
QStringList legendPatchShapeNames() const;
/**
* Returns a symbol to use for rendering preview icons for a patch \a shape.
*
* Ownership of the symbol is not transferred.
*
* \since QGIS 3.14
*/
const QgsSymbol *previewSymbolForPatchShape( const QgsLegendPatchShape &shape ) const;
/**
* Returns the default legend patch shape for the given symbol \a type.
*
@ -1007,6 +1016,10 @@ class CORE_EXPORT QgsStyle : public QObject
sqlite3_database_unique_ptr mCurrentDB;
std::unique_ptr< QgsSymbol > mPatchMarkerSymbol;
std::unique_ptr< QgsSymbol > mPatchLineSymbol;
std::unique_ptr< QgsSymbol > mPatchFillSymbol;
mutable QHash< QgsSymbol::SymbolType, QHash< QSizeF, QgsLegendPatchShape > > mDefaultPatchCache;
mutable QHash< QgsSymbol::SymbolType, QHash< QSizeF, QList< QList< QPolygonF > > > > mDefaultPatchQPolygonFCache;

View File

@ -33,10 +33,6 @@ QgsStyleModel::QgsStyleModel( QgsStyle *style, QObject *parent )
{
Q_ASSERT( mStyle );
mPatchMarkerSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
mPatchLineSymbol.reset( QgsLineSymbol::createSimple( QgsStringMap() ) );
mPatchFillSymbol.reset( QgsFillSymbol::createSimple( QgsStringMap() ) );
for ( QgsStyle::StyleEntity entity : ENTITIES )
{
mEntityNames.insert( entity, mStyle->allNames( entity ) );
@ -165,7 +161,7 @@ QVariant QgsStyleModel::data( const QModelIndex &index, int role ) const
int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
const QgsLegendPatchShape shape = mStyle->legendPatchShape( name );
if ( QgsSymbol *symbol = symbolForPatchShape( shape ) )
if ( const QgsSymbol *symbol = mStyle->previewSymbolForPatchShape( shape ) )
{
QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( symbol, QSize( width, height ), height / 20, nullptr, false, nullptr, &shape );
QByteArray data;
@ -304,7 +300,7 @@ QVariant QgsStyleModel::data( const QModelIndex &index, int role ) const
const QgsLegendPatchShape shape = mStyle->legendPatchShape( name );
if ( !shape.isNull() )
{
if ( QgsSymbol *symbol = symbolForPatchShape( shape ) )
if ( const QgsSymbol *symbol = mStyle->previewSymbolForPatchShape( shape ) )
{
if ( mAdditionalSizes.isEmpty() )
icon.addPixmap( QgsSymbolLayerUtils::symbolPreviewPixmap( symbol, QSize( 24, 24 ), 1, nullptr, false, mExpressionContext.get(), &shape ) );
@ -609,25 +605,6 @@ QgsStyle::StyleEntity QgsStyleModel::entityTypeFromRow( int row ) const
return QgsStyle::SymbolEntity;
}
QgsSymbol *QgsStyleModel::symbolForPatchShape( const QgsLegendPatchShape &shape ) const
{
switch ( shape.symbolType() )
{
case QgsSymbol::Marker:
return mPatchMarkerSymbol.get();
case QgsSymbol::Line:
return mPatchLineSymbol.get();
case QgsSymbol::Fill:
return mPatchFillSymbol.get();
case QgsSymbol::Hybrid:
break;
}
return nullptr;
}
int QgsStyleModel::offsetForEntity( QgsStyle::StyleEntity entity ) const
{
int offset = 0;

View File

@ -118,14 +118,8 @@ class CORE_EXPORT QgsStyleModel: public QAbstractItemModel
mutable QHash< QgsStyle::StyleEntity, QHash< QString, QIcon > > mIconCache;
std::unique_ptr< QgsSymbol > mPatchMarkerSymbol;
std::unique_ptr< QgsSymbol > mPatchLineSymbol;
std::unique_ptr< QgsSymbol > mPatchFillSymbol;
QgsStyle::StyleEntity entityTypeFromRow( int row ) const;
QgsSymbol *symbolForPatchShape( const QgsLegendPatchShape &shape ) const;
int offsetForEntity( QgsStyle::StyleEntity entity ) const;
};

View File

@ -16,6 +16,7 @@
#include "qgslegendpatchshapebutton.h"
#include "qgslegendpatchshapewidget.h"
#include "qgis.h"
#include "qgsguiutils.h"
#include <QMenu>
QgsLegendPatchShapeButton::QgsLegendPatchShapeButton( QWidget *parent, const QString &dialogTitle )
@ -187,6 +188,35 @@ void QgsLegendPatchShapeButton::prepareMenu()
mMenu->addAction( defaultAction );
connect( defaultAction, &QAction::triggered, this, [ = ] { setToDefault(); emit changed(); } );
mMenu->addSeparator();
QStringList patchNames = QgsStyle::defaultStyle()->symbolsOfFavorite( QgsStyle::LegendPatchShapeEntity );
patchNames.sort();
const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
for ( const QString &name : qgis::as_const( patchNames ) )
{
const QgsLegendPatchShape shape = QgsStyle::defaultStyle()->legendPatchShape( name );
if ( shape.symbolType() == mType )
{
if ( const QgsSymbol *symbol = QgsStyle::defaultStyle()->previewSymbolForPatchShape( shape ) )
{
QIcon icon = QgsSymbolLayerUtils::symbolPreviewPixmap( symbol, QSize( iconSize, iconSize ), 1, nullptr, false, nullptr, &shape );
QAction *action = new QAction( name, this );
action->setIcon( icon );
connect( action, &QAction::triggered, this, [ = ] { loadPatchFromStyle( name ); } );
mMenu->addAction( action );
}
}
}
}
void QgsLegendPatchShapeButton::loadPatchFromStyle( const QString &name )
{
if ( !QgsStyle::defaultStyle()->legendPatchShapeNames().contains( name ) )
return;
const QgsLegendPatchShape newShape = QgsStyle::defaultStyle()->legendPatchShape( name );
setShape( newShape );
}
void QgsLegendPatchShapeButton::changeEvent( QEvent *e )

View File

@ -145,6 +145,8 @@ class GUI_EXPORT QgsLegendPatchShapeButton : public QToolButton
*/
void prepareMenu();
void loadPatchFromStyle( const QString &name );
private:
QgsLegendPatchShape mShape;