Skip to content

Commit

Permalink
Show favorited legend patches in legend patch button menu
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Apr 22, 2020
1 parent 8a0e007 commit ec2894e
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 32 deletions.
9 changes: 9 additions & 0 deletions python/core/auto_generated/symbology/qgsstyle.sip.in
Expand Up @@ -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

Expand Down
26 changes: 26 additions & 0 deletions src/core/symbology/qgsstyle.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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 );
Expand Down
15 changes: 14 additions & 1 deletion src/core/symbology/qgsstyle.h
Expand Up @@ -165,7 +165,7 @@ class CORE_EXPORT QgsStyle : public QObject
/**
* Constructor for QgsStyle.
*/
QgsStyle() = default;
QgsStyle();
~QgsStyle() override;

/**
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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;

Expand Down
27 changes: 2 additions & 25 deletions src/core/symbology/qgsstylemodel.cpp
Expand Up @@ -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 ) );
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 ) );
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 0 additions & 6 deletions src/core/symbology/qgsstylemodel.h
Expand Up @@ -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;

};
Expand Down
30 changes: 30 additions & 0 deletions src/gui/qgslegendpatchshapebutton.cpp
Expand Up @@ -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 )
Expand Down Expand Up @@ -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 )
Expand Down
2 changes: 2 additions & 0 deletions src/gui/qgslegendpatchshapebutton.h
Expand Up @@ -145,6 +145,8 @@ class GUI_EXPORT QgsLegendPatchShapeButton : public QToolButton
*/
void prepareMenu();

void loadPatchFromStyle( const QString &name );

private:

QgsLegendPatchShape mShape;
Expand Down

0 comments on commit ec2894e

Please sign in to comment.