Skip to content

Commit

Permalink
Merge pull request #50812 from elpaso/bugfix-gh37434-default-style-name
Browse files Browse the repository at this point in the history
Bugfix default style name
  • Loading branch information
elpaso committed Nov 14, 2022
2 parents 17bca73 + 9b9e52d commit 1373d2b
Show file tree
Hide file tree
Showing 35 changed files with 668 additions and 23 deletions.
2 changes: 2 additions & 0 deletions .ci/test_blocklist_qt5.txt
Expand Up @@ -22,3 +22,5 @@ test_core_layerdefinition

# MSSQL requires the MSSQL docker
PyQgsProviderConnectionMssql
PyQgsStyleStorageMssql

1 change: 1 addition & 0 deletions .ci/test_blocklist_qt6.txt
Expand Up @@ -38,3 +38,4 @@ test_core_layerdefinition

# MSSQL requires the MSSQL docker
PyQgsProviderConnectionMssql
PyQgsStyleStorageMssql
13 changes: 13 additions & 0 deletions python/core/auto_generated/providers/qgsprovidermetadata.sip.in
Expand Up @@ -609,6 +609,19 @@ Saves a layer style to provider.
Loads a layer style defined by ``uri``

.. versionadded:: 3.10
%End

virtual QString loadStoredStyle( const QString &uri, QString &styleName, QString &errCause );
%Docstring
Loads a layer style from the provider storage, reporting its name.

:param uri: data source uri
:param styleName: the name of the style if available, empty otherwise
:param errCause: report errors

:return: the style QML (XML)

.. versionadded:: 3.30
%End

virtual bool saveLayerMetadata( const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage /Out/ ) throw( QgsNotSupportedException );
Expand Down
18 changes: 17 additions & 1 deletion python/core/auto_generated/providers/qgsproviderregistry.sip.in
Expand Up @@ -244,11 +244,27 @@ Saves a layer style to provider
.. versionadded:: 3.10
%End

QString loadStyle( const QString &providerKey, const QString &uri, QString &errCause );
QString loadStyle( const QString &providerKey, const QString &uri, QString &errCause );
%Docstring
Loads a layer style defined by ``uri``

:return: the style QML (XML)

.. versionadded:: 3.10
%End

QString loadStoredStyle( const QString &providerKey, const QString &uri, QString &styleName, QString &errCause );
%Docstring
Loads a layer style from the provider storage, reporting its name.

:param providerKey: name of the data provider
:param uri: data source uri
:param styleName: the name of the style if available, empty otherwise
:param errCause: report errors

:return: the style QML (XML)

.. versionadded:: 3.30
%End

bool saveLayerMetadata( const QString &providerKey, const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage /Out/ ) throw( QgsNotSupportedException );
Expand Down
Expand Up @@ -86,6 +86,8 @@ Constructor for LayerOptions with ``transformContext``.
QgsCoordinateTransformContext transformContext;

bool loadDefaultStyle;

bool loadAllStoredStyle;
};

QgsMapLayer *toLayer( const LayerOptions &options ) const /Factory/;
Expand Down
2 changes: 2 additions & 0 deletions python/core/auto_generated/qgsmaplayerfactory.sip.in
Expand Up @@ -54,6 +54,8 @@ Constructor for LayerOptions with ``transformContext``.
QgsCoordinateTransformContext transformContext;

bool loadDefaultStyle;

bool loadAllStoredStyles;
};

static QgsMapLayer *createLayer( const QString &uri, const QString &name, QgsMapLayerType type, const LayerOptions &options,
Expand Down
2 changes: 2 additions & 0 deletions python/core/auto_generated/vector/qgsvectorlayer.sip.in
Expand Up @@ -371,6 +371,8 @@ Constructor for LayerOptions.
bool skipCrsValidation;

bool forceReadOnly;

bool loadAllStoredStyles;
};

struct DeleteContext
Expand Down
1 change: 1 addition & 0 deletions src/app/layers/qgsapplayerhandling.cpp
Expand Up @@ -690,6 +690,7 @@ QList<QgsMapLayer *> QgsAppLayerHandling::addSublayers( const QList<QgsProviderS
{
QgsProviderSublayerDetails::LayerOptions options( QgsProject::instance()->transformContext() );
options.loadDefaultStyle = false;
options.loadAllStoredStyle = true;

std::unique_ptr<QgsMapLayer> layer( sublayer.toLayer( options ) );
if ( !layer )
Expand Down
16 changes: 13 additions & 3 deletions src/core/providers/ogr/qgsogrprovidermetadata.cpp
Expand Up @@ -673,6 +673,12 @@ bool LoadDataSourceLayerStylesAndLayer( const QString &uri,


QString QgsOgrProviderMetadata::loadStyle( const QString &uri, QString &errCause )
{
QString name;
return loadStoredStyle( uri, name, errCause );
}

QString QgsOgrProviderMetadata::loadStoredStyle( const QString &uri, QString &styleName, QString &errCause )
{
QgsOgrLayerUniquePtr layerStyles;
QgsOgrLayerUniquePtr userLayer;
Expand Down Expand Up @@ -710,6 +716,8 @@ QString QgsOgrProviderMetadata::loadStyle( const QString &uri, QString &errCause
{
styleQML = QString::fromUtf8(
OGR_F_GetFieldAsString( hFeat.get(), OGR_FD_GetFieldIndex( hLayerDefn, "styleQML" ) ) );
styleName = QString::fromUtf8(
OGR_F_GetFieldAsString( hFeat.get(), OGR_FD_GetFieldIndex( hLayerDefn, "styleName" ) ) );
break;
}

Expand All @@ -723,7 +731,8 @@ QString QgsOgrProviderMetadata::loadStyle( const QString &uri, QString &errCause
moreRecentTimestamp = ts;
styleQML = QString::fromUtf8(
OGR_F_GetFieldAsString( hFeat.get(), OGR_FD_GetFieldIndex( hLayerDefn, "styleQML" ) ) );

styleName = QString::fromUtf8(
OGR_F_GetFieldAsString( hFeat.get(), OGR_FD_GetFieldIndex( hLayerDefn, "styleName" ) ) );
}
}
OGR_L_ResetReading( hLayer );
Expand Down Expand Up @@ -796,6 +805,7 @@ int QgsOgrProviderMetadata::listStyles(
QMap<int, QString> mapIdToDescription;
QMap<qlonglong, QList<int> > mapTimestampToId;
int numberOfRelatedStyles = 0;

while ( true )
{
gdal::ogr_feature_unique_ptr hFeature( OGR_L_GetNextFeature( hLayer ) );
Expand Down Expand Up @@ -830,8 +840,8 @@ int QgsOgrProviderMetadata::listStyles(
int year, month, day, hour, minute, second, TZ;
OGR_F_GetFieldAsDateTime( hFeature.get(), OGR_FD_GetFieldIndex( hLayerDefn, "update_time" ),
&year, &month, &day, &hour, &minute, &second, &TZ );
qlonglong ts = second + minute * 60 + hour * 3600 + day * 24 * 3600 +
static_cast<qlonglong>( month ) * 31 * 24 * 3600 + static_cast<qlonglong>( year ) * 12 * 31 * 24 * 3600;
const qlonglong ts = second + minute * 60 + hour * 3600 + day * 24 * 3600 +
static_cast<qlonglong>( month ) * 31 * 24 * 3600 + static_cast<qlonglong>( year ) * 12 * 31 * 24 * 3600;

listTimestamp.append( ts );
mapIdToStyleName[fid] = styleName;
Expand Down
1 change: 1 addition & 0 deletions src/core/providers/ogr/qgsogrprovidermetadata.h
Expand Up @@ -66,6 +66,7 @@ class QgsOgrProviderMetadata final: public QgsProviderMetadata
const QString &uiFileContent, bool useAsDefault, QString &errCause ) override;
bool deleteStyleById( const QString &uri, const QString &styleId, QString &errCause ) override;
QString loadStyle( const QString &uri, QString &errCause ) override;
QString loadStoredStyle( const QString &uri, QString &name, QString &errCause ) override;
int listStyles( const QString &uri, QStringList &ids, QStringList &names,
QStringList &descriptions, QString &errCause ) override;
QString getStyleById( const QString &uri, const QString &styleId, QString &errCause ) override;
Expand Down
6 changes: 6 additions & 0 deletions src/core/providers/qgsprovidermetadata.cpp
Expand Up @@ -272,6 +272,12 @@ QString QgsProviderMetadata::loadStyle( const QString &, QString &errCause )
return QString();
}

QString QgsProviderMetadata::loadStoredStyle( const QString &, QString &, QString &errCause )
{
errCause = QObject::tr( "Provider %1 has no %2 method" ).arg( key(), QStringLiteral( "loadStoredStyle" ) );
return QString();
}

bool QgsProviderMetadata::saveLayerMetadata( const QString &, const QgsLayerMetadata &, QString & )
{
throw QgsNotSupportedException( QObject::tr( "Provider %1 does not support writing layer metadata" ).arg( key() ) );
Expand Down
10 changes: 10 additions & 0 deletions src/core/providers/qgsprovidermetadata.h
Expand Up @@ -655,6 +655,16 @@ class CORE_EXPORT QgsProviderMetadata : public QObject
*/
virtual QString loadStyle( const QString &uri, QString &errCause );

/**
* Loads a layer style from the provider storage, reporting its name.
* \param uri data source uri
* \param styleName the name of the style if available, empty otherwise
* \param errCause report errors
* \returns the style QML (XML)
* \since QGIS 3.30
*/
virtual QString loadStoredStyle( const QString &uri, QString &styleName, QString &errCause );

/**
* Saves \a metadata to the layer corresponding to the specified \a uri.
*
Expand Down
13 changes: 13 additions & 0 deletions src/core/providers/qgsproviderregistry.cpp
Expand Up @@ -707,6 +707,19 @@ QString QgsProviderRegistry::loadStyle( const QString &providerKey, const QStrin
return ret;
}

QString QgsProviderRegistry::loadStoredStyle( const QString &providerKey, const QString &uri, QString &styleName, QString &errCause )
{
QString ret;
QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
if ( meta )
ret = meta->loadStoredStyle( uri, styleName, errCause );
else
{
errCause = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
}
return ret;
}

bool QgsProviderRegistry::saveLayerMetadata( const QString &providerKey, const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage )
{
errorMessage.clear();
Expand Down
14 changes: 13 additions & 1 deletion src/core/providers/qgsproviderregistry.h
Expand Up @@ -276,9 +276,21 @@ class CORE_EXPORT QgsProviderRegistry

/**
* Loads a layer style defined by \a uri
* \returns the style QML (XML)
* \since QGIS 3.10
*/
QString loadStyle( const QString &providerKey, const QString &uri, QString &errCause );
QString loadStyle( const QString &providerKey, const QString &uri, QString &errCause );

/**
* Loads a layer style from the provider storage, reporting its name.
* \param providerKey name of the data provider
* \param uri data source uri
* \param styleName the name of the style if available, empty otherwise
* \param errCause report errors
* \returns the style QML (XML)
* \since QGIS 3.30
*/
QString loadStoredStyle( const QString &providerKey, const QString &uri, QString &styleName, QString &errCause );

/**
* Saves \a metadata to the layer corresponding to the specified \a uri.
Expand Down
1 change: 1 addition & 0 deletions src/core/providers/qgsprovidersublayerdetails.cpp
Expand Up @@ -23,6 +23,7 @@ QgsMapLayer *QgsProviderSublayerDetails::toLayer( const LayerOptions &options )
{
QgsMapLayerFactory::LayerOptions layerOptions( options.transformContext );
layerOptions.loadDefaultStyle = options.loadDefaultStyle;
layerOptions.loadAllStoredStyles = options.loadAllStoredStyle;
return QgsMapLayerFactory::createLayer( mUri, mName, mType, layerOptions, mProviderKey );
}

Expand Down
14 changes: 14 additions & 0 deletions src/core/providers/qgsprovidersublayerdetails.h
Expand Up @@ -106,6 +106,20 @@ class CORE_EXPORT QgsProviderSublayerDetails

//! Set to TRUE if the default layer style should be loaded
bool loadDefaultStyle = true;

/**
* Controls whether the stored styles will be all loaded.
*
* If TRUE and the layer's provider supports style stored in the
* data source all the available styles will be loaded in addition
* to the default one.
*
* If FALSE (the default), the layer's provider will only load
* the default style.
*
* \since QGIS 3.30
*/
bool loadAllStoredStyle = false;
};

/**
Expand Down
1 change: 1 addition & 0 deletions src/core/qgsmaplayerfactory.cpp
Expand Up @@ -81,6 +81,7 @@ QgsMapLayer *QgsMapLayerFactory::createLayer( const QString &uri, const QString
QgsVectorLayer::LayerOptions vectorOptions;
vectorOptions.transformContext = options.transformContext;
vectorOptions.loadDefaultStyle = options.loadDefaultStyle;
vectorOptions.loadAllStoredStyles = options.loadAllStoredStyles;
return new QgsVectorLayer( uri, name, provider, vectorOptions );
}

Expand Down
14 changes: 14 additions & 0 deletions src/core/qgsmaplayerfactory.h
Expand Up @@ -73,6 +73,20 @@ class CORE_EXPORT QgsMapLayerFactory

//! Set to TRUE if the default layer style should be loaded
bool loadDefaultStyle = true;

/**
* Controls whether the stored styles will be all loaded.
*
* If TRUE and the layer's provider supports style stored in the
* data source all the available styles will be loaded in addition
* to the default one.
*
* If FALSE (the default), the layer's provider will only load
* the default style.
*
* \since QGIS 3.30
*/
bool loadAllStoredStyles = false;
};

/**
Expand Down
45 changes: 42 additions & 3 deletions src/core/vector/qgsvectorlayer.cpp
Expand Up @@ -36,6 +36,7 @@
#include "qgsfeaturerequest.h"
#include "qgsfields.h"
#include "qgsmaplayerfactory.h"
#include "qgsmaplayerstylemanager.h"
#include "qgsgeometry.h"
#include "qgslayermetadataformatter.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -159,6 +160,7 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath,
, mRefreshRendererTimer( new QTimer( this ) )
{
mShouldValidateCrs = !options.skipCrsValidation;
mLoadAllStoredStyle = options.loadAllStoredStyles;

if ( options.fallbackCrs.isValid() )
setCrs( options.fallbackCrs, false );
Expand Down Expand Up @@ -1755,9 +1757,38 @@ void QgsVectorLayer::setDataSourcePrivate( const QString &dataSource, const QStr
QString QgsVectorLayer::loadDefaultStyle( bool &resultFlag )
{
// first try to load a user-defined default style - this should always take precedence
QString res = QgsMapLayer::loadDefaultStyle( resultFlag );
QString styleXml = QgsMapLayer::loadDefaultStyle( resultFlag );

if ( resultFlag )
return res;
{
// Try to load all stored styles from DB
if ( mLoadAllStoredStyle && mDataProvider && mDataProvider->isSaveAndLoadStyleToDatabaseSupported() )
{
QStringList ids, names, descriptions;
QString errorMessage;
listStylesInDatabase( ids, names, descriptions, errorMessage );
Q_ASSERT( ids.count() == names.count() );
const QString currentStyleName { mStyleManager->currentStyle() };
for ( int i = 0; i < static_cast<int>( ids.count() ); ++i )
{
if ( names.at( i ) == currentStyleName )
{
continue;
}
errorMessage.clear();
const QString styleXml { getStyleFromDatabase( ids.at( i ), errorMessage ) };
if ( ! styleXml.isEmpty() && errorMessage.isEmpty() )
{
mStyleManager->addStyle( names.at( i ), QgsMapLayerStyle( styleXml ) );
}
else
{
QgsDebugMsgLevel( QStringLiteral( "Error retrieving style %1 from DB: %2" ).arg( ids.at( i ), errorMessage ), 2 );
}
}
}
return styleXml ;
}

if ( isSpatial() && mDataProvider->capabilities() & QgsVectorDataProvider::CreateRenderer )
{
Expand Down Expand Up @@ -5559,10 +5590,13 @@ QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &resultFlag,
QgsDataSourceUri dsUri( theURI );
QString returnMessage;
QString qml, errorMsg;
QString styleName;
if ( !loadFromLocalDB && mDataProvider && mDataProvider->isSaveAndLoadStyleToDatabaseSupported() )
{
qml = QgsProviderRegistry::instance()->loadStyle( mProviderKey, mDataSource, errorMsg );
qml = QgsProviderRegistry::instance()->loadStoredStyle( mProviderKey, mDataSource, styleName, errorMsg );
}

// Style was successfully loaded from provider storage
if ( !qml.isEmpty() )
{
QDomDocument myDocument( QStringLiteral( "qgis" ) );
Expand All @@ -5575,6 +5609,11 @@ QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &resultFlag,
returnMessage = QgsMapLayer::loadNamedStyle( theURI, resultFlag, categories );
}

if ( ! styleName.isEmpty() )
{
styleManager()->renameStyle( styleManager()->currentStyle(), styleName );
}

if ( resultFlag )
emit styleLoaded( categories );

Expand Down

0 comments on commit 1373d2b

Please sign in to comment.