Skip to content

Commit

Permalink
Possibility to select an image as legend placeholder
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Jul 2, 2021
1 parent 991f935 commit b7b9470
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 39 deletions.
16 changes: 16 additions & 0 deletions python/core/auto_generated/qgsmaplayer.sip.in
Expand Up @@ -1429,6 +1429,22 @@ Returns the layer's temporal properties. This may be ``None``, depending on the
Returns the layer's elevation properties. This may be ``None``, depending on the layer type.

.. versionadded:: 3.18
%End

QString legendPlaceholderImage() const;
%Docstring
Returns path to the placeholder image or an empty string if a generated legend is shown

:return: placholder image path
%End

void setLegendPlaceholderImage( const QString &imgPath );
%Docstring
Set placeholder image for legend. If the string is empty, a generated legend will be shown.

:param imgPath: file path to the placeholder image

.. versionadded:: 3.22
%End

public slots:
Expand Down
12 changes: 0 additions & 12 deletions python/core/auto_generated/raster/qgsrasterlayer.sip.in
Expand Up @@ -420,18 +420,6 @@ to be drawn outside the data extent.
virtual QgsMapLayerTemporalProperties *temporalProperties();


bool usePlaceholderLegendIcon() const;
%Docstring
True if a placeholder legend is shown in the legend rather than all the color entries
%End

void setUsePlaceholderLegendIcon( bool usePlaceholderIcon );
%Docstring
Set if a placeholder legend is shown in the legend

:param usePlaceholderIcon: true if placeholder icon will be shown instead of symbology items
%End

public slots:
void showStatusMessage( const QString &message );

Expand Down
4 changes: 4 additions & 0 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -406,6 +406,8 @@ bool QgsMapLayer::readLayerXml( const QDomElement &layerElement, QgsReadWriteCon
mWgs84Extent = QgsXmlUtils::readRectangle( wgs84ExtentNode.toElement() );
}

mLegendPlaceholderImage = layerElement.attribute( QStringLiteral( "legendPlaceholderImage" ) );

return ! layerError;
} // bool QgsMapLayer::readLayerXML

Expand Down Expand Up @@ -576,6 +578,8 @@ bool QgsMapLayer::writeLayerXml( QDomElement &layerElement, QDomDocument &docume
mMetadata.writeMetadataXml( myMetadataElem, document );
layerElement.appendChild( myMetadataElem );

layerElement.setAttribute( QStringLiteral( "legendPlaceholderImage" ), mLegendPlaceholderImage );

// now append layer node to map layer node
return writeXml( layerElement, document, context );
}
Expand Down
16 changes: 16 additions & 0 deletions src/core/qgsmaplayer.h
Expand Up @@ -1279,6 +1279,19 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
virtual QgsMapLayerElevationProperties *elevationProperties() { return nullptr; }

/**
* Returns path to the placeholder image or an empty string if a generated legend is shown
* \return placholder image path
*/
QString legendPlaceholderImage() const { return mLegendPlaceholderImage;}

/**
* Set placeholder image for legend. If the string is empty, a generated legend will be shown.
* \param imgPath file path to the placeholder image
* \since QGIS 3.22
*/
void setLegendPlaceholderImage( const QString &imgPath ) { mLegendPlaceholderImage = imgPath; }

public slots:

/**
Expand Down Expand Up @@ -1867,6 +1880,9 @@ class CORE_EXPORT QgsMapLayer : public QObject
//! To avoid firing multiple time repaintRequested signal on circular layer circular dependencies
bool mRepaintRequestedFired = false;

//! Path to placeholder image for layer legend. If the string is empty, a generated legend is shown
QString mLegendPlaceholderImage;

friend class QgsVectorLayer;
};

Expand Down
5 changes: 3 additions & 2 deletions src/core/qgsmaplayerlegend.cpp
Expand Up @@ -502,9 +502,10 @@ QList<QgsLayerTreeModelLegendNode *> QgsDefaultRasterLayerLegend::createLayerTre
nodes << new QgsWmsLegendNode( nodeLayer );
}

if ( mLayer->usePlaceholderLegendIcon() )
QString placeholderImage = mLayer->legendPlaceholderImage();
if ( !placeholderImage.isEmpty() )
{
nodes << new QgsSimpleLegendNode( nodeLayer, QString(), QgsIconUtils::iconRaster() );
nodes << new QgsImageLegendNode( nodeLayer, QImage( placeholderImage ) );
}
else if ( mLayer->renderer() )
nodes.append( mLayer->renderer()->createLegendNodes( nodeLayer ) );
Expand Down
4 changes: 0 additions & 4 deletions src/core/raster/qgsrasterlayer.cpp
Expand Up @@ -2163,8 +2163,6 @@ bool QgsRasterLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &c

readStyleManager( layer_node );

mUsePlaceholderLegendIcon = layer_node.toElement().attribute( QStringLiteral( "usePlaceholderLegendIcon" ), QStringLiteral( "0" ) ).compare( QStringLiteral( "1" ) ) == 0;

return res;
}

Expand Down Expand Up @@ -2280,8 +2278,6 @@ bool QgsRasterLayer::writeXml( QDomNode &layer_node,

writeStyleManager( layer_node, document );

mapLayerNode.setAttribute( QStringLiteral( "usePlaceholderLegendIcon" ), mUsePlaceholderLegendIcon );

//write out the symbology
QString errorMsg;
return writeSymbology( layer_node, document, errorMsg, context );
Expand Down
11 changes: 0 additions & 11 deletions src/core/raster/qgsrasterlayer.h
Expand Up @@ -467,15 +467,6 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer

QgsMapLayerTemporalProperties *temporalProperties() override;

//! True if a placeholder legend is shown in the legend rather than all the color entries
bool usePlaceholderLegendIcon() const { return mUsePlaceholderLegendIcon; }

/**
* Set if a placeholder legend is shown in the legend
* \param usePlaceholderIcon true if placeholder icon will be shown instead of symbology items
*/
void setUsePlaceholderLegendIcon( bool usePlaceholderIcon ) { mUsePlaceholderLegendIcon = usePlaceholderIcon; }

public slots:
void showStatusMessage( const QString &message );

Expand Down Expand Up @@ -574,8 +565,6 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer

QDomDocument mOriginalStyleDocument;
QDomElement mOriginalStyleElement;

bool mUsePlaceholderLegendIcon = false;
};

// clazy:excludeall=qstring-allocations
Expand Down
16 changes: 14 additions & 2 deletions src/gui/raster/qgsrasterlayerproperties.cpp
Expand Up @@ -914,7 +914,7 @@ void QgsRasterLayerProperties::sync()
QVariant wmsBackgroundLayer = mRasterLayer->customProperty( QStringLiteral( "WMSBackgroundLayer" ), false );
mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );

mPlaceholderIconCheckBox->setCheckState( mRasterLayer->usePlaceholderLegendIcon() ? Qt::Checked : Qt::Unchecked );
mLegendPlaceholderLineEdit->setText( mRasterLayer->legendPlaceholderImage() );
mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );

mTemporalWidget->syncToLayer();
Expand Down Expand Up @@ -947,7 +947,7 @@ void QgsRasterLayerProperties::apply()
/*
* Legend Tab
*/
mRasterLayer->setUsePlaceholderLegendIcon( mPlaceholderIconCheckBox->isChecked() );
mRasterLayer->setLegendPlaceholderImage( mLegendPlaceholderLineEdit->text() );
mLegendConfigEmbeddedWidget->applyToLayer();

QgsDebugMsgLevel( QStringLiteral( "apply processing symbology tab" ), 3 );
Expand Down Expand Up @@ -1277,6 +1277,18 @@ void QgsRasterLayerProperties::urlClicked( const QUrl &url )
QDesktopServices::openUrl( url );
}

void QgsRasterLayerProperties::on_mLegendPlaceholderToolButton_clicked()
{
QgsSettings myQSettings;
QString myLastDir = myQSettings.value( QStringLiteral( "lastPlaceholderDir" ), QDir::homePath() ).toString();
QString myFileName = QFileDialog::getOpenFileName( this, tr( "Open file" ), myLastDir );
if ( !myFileName.isEmpty() )
{
mLegendPlaceholderLineEdit->setText( myFileName );
myQSettings.setValue( QStringLiteral( "lastPlaceholderDir" ), QFileInfo( myFileName ).absolutePath() );
}
}

void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged( int index )
{
if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || ! mRasterLayer->renderer() )
Expand Down
2 changes: 2 additions & 0 deletions src/gui/raster/qgsrasterlayerproperties.h
Expand Up @@ -214,6 +214,8 @@ class GUI_EXPORT QgsRasterLayerProperties : public QgsOptionsDialogBase, private

void urlClicked( const QUrl &url );

void on_mLegendPlaceholderToolButton_clicked();

private:
QPushButton *mBtnStyle = nullptr;
QPushButton *mBtnMetadata = nullptr;
Expand Down
44 changes: 36 additions & 8 deletions src/ui/qgsrasterlayerpropertiesbase.ui
Expand Up @@ -1740,15 +1740,14 @@ p, li { white-space: pre-wrap; }
</widget>
<widget class="QWidget" name="mOptsPage_Legend">
<layout class="QGridLayout" name="gridLayout_15">
<item row="0" column="0">
<widget class="QCheckBox" name="mPlaceholderIconCheckBox">
<property name="text">
<string>Show placeholder icon in legend</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Embedded Widgets in Legend</string>
</property>
Expand All @@ -1759,6 +1758,35 @@ p, li { white-space: pre-wrap; }
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="mPlaceholderImageGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Legend placeholder image</string>
</property>
<layout class="QGridLayout" name="gridLayout_16">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="mLegendPlaceholderLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="mLegendPlaceholderToolButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="mOptsPage_Server">
Expand Down Expand Up @@ -1788,7 +1816,7 @@ p, li { white-space: pre-wrap; }
<rect>
<x>0</x>
<y>0</y>
<width>394</width>
<width>629</width>
<height>793</height>
</rect>
</property>
Expand Down

0 comments on commit b7b9470

Please sign in to comment.