create QgsMapLayer::LayerFlags for Searchable, Identifiable and Removable (#7815)

* create QgsMapLayer::LayerFlags for Searchable, Identifiable and Removable

this brings back the information previously saved in the project node back to the layer node
this will allow to embed this information in layer styles

* skip unexisting flag node to avoid setting wrong value for flag

* mark QgsProject::(set)requiredLayers as deprecated

* better API docs

* use new API in current code

* more docs and more old API fixes

* fix bad conversion

* more old API fix

* add missing SIP_OUT

* s/testFlags/testFlag

* fix var name

* adapt project test to test flags

* remove debug calls

* fixeS
This commit is contained in:
Denis Rouzaud 2018-09-08 07:54:21 -04:00 committed by GitHub
parent 48dcab75cb
commit 89830f614e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 311 additions and 216 deletions

View File

@ -0,0 +1,4 @@
# The following has been generated automatically from src/core/qgsmaplayer.h
QgsMapLayer.LayerFlag.baseClass = QgsMapLayer
QgsMapLayer.LayerFlags.baseClass = QgsMapLayer
LayerFlags = QgsMapLayer # dirty hack since SIP seems to introduce the flags in module

View File

@ -66,6 +66,15 @@ This is the base class for all map layer types (vector, raster).
Metadata, Metadata,
}; };
enum LayerFlag
{
Identifiable,
Removable,
Searchable,
};
typedef QFlags<QgsMapLayer::LayerFlag> LayerFlags;
QgsMapLayer( QgsMapLayer::LayerType type = VectorLayer, const QString &name = QString(), const QString &source = QString() ); QgsMapLayer( QgsMapLayer::LayerType type = VectorLayer, const QString &name = QString(), const QString &source = QString() );
%Docstring %Docstring
Constructor for QgsMapLayer Constructor for QgsMapLayer
@ -91,6 +100,32 @@ is still unique.
QgsMapLayer::LayerType type() const; QgsMapLayer::LayerType type() const;
%Docstring %Docstring
Returns the type of the layer. Returns the type of the layer.
%End
QgsMapLayer::LayerFlags flags() const;
%Docstring
Returns the flags for this layer.
.. note::
Flags are options specified by the user used for the UI but are not preventing any API call.
For instance, even if the Removable flag is not set, the layer can still be removed with the API
but the action will not be listed in the legend menu.
.. versionadded:: 3.4
%End
void setFlags( QgsMapLayer::LayerFlags flags );
%Docstring
Returns the flags for this layer.
.. note::
Flags are options specified by the user used for the UI but are not preventing any API call.
For instance, even if the Removable flag is not set, the layer can still be removed with the API
but the action will not be listed in the legend menu.
.. versionadded:: 3.4
%End %End
static QString extensionPropertyType( PropertyType type ); static QString extensionPropertyType( PropertyType type );
@ -1473,6 +1508,8 @@ Checks whether a new set of dependencies will introduce a cycle
}; };
QFlags<QgsMapLayer::LayerFlag> operator|(QgsMapLayer::LayerFlag f1, QFlags<QgsMapLayer::LayerFlag> f2);
/************************************************************************ /************************************************************************

View File

@ -573,19 +573,25 @@ Returns pointer to the project's annotation manager.
%End %End
void setNonIdentifiableLayers( const QList<QgsMapLayer *> &layers ); void setNonIdentifiableLayers( const QList<QgsMapLayer *> &layers );
%Docstring %Docstring
Set a list of layers which should not be taken into account on map identification Set a list of layers which should not be taken into account on map identification
.. deprecated:: since QGIS 3.4 use QgsMapLayer.setFlags() instead
%End %End
void setNonIdentifiableLayers( const QStringList &layerIds ); void setNonIdentifiableLayers( const QStringList &layerIds );
%Docstring %Docstring
Set a list of layers which should not be taken into account on map identification Set a list of layers which should not be taken into account on map identification
.. deprecated:: since QGIS 3.4 use QgsMapLayer.setFlags() instead
%End %End
QStringList nonIdentifiableLayers() const; QStringList nonIdentifiableLayers() const;
%Docstring %Docstring
Gets the list of layers which currently should not be taken into account on map identification Gets the list of layers which currently should not be taken into account on map identification
.. deprecated:: since QGIS 3.4 use QgsMapLayer.setFlags() instead
%End %End
bool autoTransaction() const; bool autoTransaction() const;
@ -973,23 +979,27 @@ Sets the project's ``metadata`` store.
.. versionadded:: 3.2 .. versionadded:: 3.2
%End %End
QSet<QgsMapLayer *> requiredLayers() const; QSet<QgsMapLayer *> requiredLayers() const;
%Docstring %Docstring
Returns a set of map layers that are required in the project and therefore they should not get Returns a set of map layers that are required in the project and therefore they should not get
removed from the project. The set of layers may be configured by users in project properties. removed from the project. The set of layers may be configured by users in project properties.
and it is mainly a hint for the user interface to protect users from removing layers that important and it is mainly a hint for the user interface to protect users from removing layers that important
in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here. in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here.
.. deprecated:: since QGIS 3.4 use QgsMapLayer.flags() instead
.. versionadded:: 3.2 .. versionadded:: 3.2
%End %End
void setRequiredLayers( const QSet<QgsMapLayer *> &layers ); void setRequiredLayers( const QSet<QgsMapLayer *> &layers );
%Docstring %Docstring
Configures a set of map layers that are required in the project and therefore they should not get Configures a set of map layers that are required in the project and therefore they should not get
removed from the project. The set of layers may be configured by users in project properties. removed from the project. The set of layers may be configured by users in project properties.
and it is mainly a hint for the user interface to protect users from removing layers that important and it is mainly a hint for the user interface to protect users from removing layers that important
in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here. in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here.
.. deprecated:: since QGIS 3.4 use QgsMapLayer.setFlags() instead
.. versionadded:: 3.2 .. versionadded:: 3.2
%End %End
@ -1095,9 +1105,11 @@ Emitted when loading layers has produced some messages
.. versionadded:: 3.2 .. versionadded:: 3.2
%End %End
void nonIdentifiableLayersChanged( QStringList nonIdentifiableLayers ); void nonIdentifiableLayersChanged( QStringList nonIdentifiableLayers );
%Docstring %Docstring
Emitted when the list of layer which are excluded from map identification changes Emitted when the list of layer which are excluded from map identification changes
.. deprecated:: since QGIS 3.4
%End %End
void fileNameChanged(); void fileNameChanged();

View File

@ -1496,18 +1496,6 @@ If you need only the count of committed features call this method on this layer'
Make layer read-only (editing disabled) or not Make layer read-only (editing disabled) or not
:return: false if the layer is in editing yet :return: false if the layer is in editing yet
%End
bool searchable() const;
%Docstring
Returns true if the provider is in read-only mode
%End
void setSearchable( bool searchable );
%Docstring
Make layer searchable or not
.. versionadded:: 3.4
%End %End
bool changeGeometry( QgsFeatureId fid, QgsGeometry &geometry, bool skipDefaultValue = false ); bool changeGeometry( QgsFeatureId fid, QgsGeometry &geometry, bool skipDefaultValue = false );
@ -2592,13 +2580,6 @@ Emitted when the read only state of this layer is changed.
Only applies to manually set readonly state, not to the edit mode. Only applies to manually set readonly state, not to the edit mode.
.. versionadded:: 3.0 .. versionadded:: 3.0
%End
void searchableChanged();
%Docstring
Emitted when the search state of this layer is changed.
.. versionadded:: 3.4
%End %End
void symbolFeatureCountMapChanged(); void symbolFeatureCountMapChanged();

View File

@ -9569,10 +9569,9 @@ void QgisApp::removeLayer()
// extra check for required layers // extra check for required layers
// In theory it should not be needed because the remove action should be disabled // In theory it should not be needed because the remove action should be disabled
// if there are required layers in the selection... // if there are required layers in the selection...
const QSet<QgsMapLayer *> requiredLayers = QgsProject::instance()->requiredLayers();
for ( QgsMapLayer *layer : selectedLayers ) for ( QgsMapLayer *layer : selectedLayers )
{ {
if ( requiredLayers.contains( layer ) ) if ( !layer->flags().testFlag( QgsMapLayer::Removable ) )
return; return;
} }
@ -12052,10 +12051,9 @@ void QgisApp::legendLayerSelectionChanged()
// remove action - check for required layers // remove action - check for required layers
bool removeEnabled = true; bool removeEnabled = true;
const QSet<QgsMapLayer *> requiredLayers = QgsProject::instance()->requiredLayers();
for ( QgsLayerTreeLayer *nodeLayer : selectedLayers ) for ( QgsLayerTreeLayer *nodeLayer : selectedLayers )
{ {
if ( requiredLayers.contains( nodeLayer->layer() ) ) if ( !nodeLayer->layer()->flags().testFlag( QgsMapLayer::Removable ) )
{ {
removeEnabled = false; removeEnabled = false;
break; break;

View File

@ -720,10 +720,9 @@ void QgsAppLayerTreeViewMenuProvider::setSymbolLegendNodeColor( const QColor &co
bool QgsAppLayerTreeViewMenuProvider::removeActionEnabled() bool QgsAppLayerTreeViewMenuProvider::removeActionEnabled()
{ {
const QList<QgsLayerTreeLayer *> selectedLayers = mView->selectedLayerNodes(); const QList<QgsLayerTreeLayer *> selectedLayers = mView->selectedLayerNodes();
const QSet<QgsMapLayer *> requiredLayers = QgsProject::instance()->requiredLayers();
for ( QgsLayerTreeLayer *nodeLayer : selectedLayers ) for ( QgsLayerTreeLayer *nodeLayer : selectedLayers )
{ {
if ( requiredLayers.contains( nodeLayer->layer() ) ) if ( !nodeLayer->layer()->flags().testFlag( QgsMapLayer::Removable ) )
return false; return false;
} }
return true; return true;

View File

@ -24,15 +24,13 @@
QgsLayerCapabilitiesModel::QgsLayerCapabilitiesModel( QgsProject *project, QObject *parent ) QgsLayerCapabilitiesModel::QgsLayerCapabilitiesModel( QgsProject *project, QObject *parent )
: QSortFilterProxyModel( parent ) : QSortFilterProxyModel( parent )
{ {
mNonIdentifiableLayers = project->nonIdentifiableLayers(); const QMap<QString, QgsMapLayer *> &mapLayers = project->mapLayers();
mRequiredLayers = project->requiredLayers();
const QMap<QString, QgsMapLayer *> &mapLayers = QgsProject::instance()->mapLayers();
for ( QMap<QString, QgsMapLayer *>::const_iterator it = mapLayers.constBegin(); it != mapLayers.constEnd(); ++it ) for ( QMap<QString, QgsMapLayer *>::const_iterator it = mapLayers.constBegin(); it != mapLayers.constEnd(); ++it )
{ {
mReadOnlyLayers.insert( it.value(), it.value()->readOnly() ); mReadOnlyLayers.insert( it.value(), it.value()->readOnly() );
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ); mSearchableLayers.insert( it.value(), it.value()->type() == QgsMapLayer::VectorLayer && it.value()->flags().testFlag( QgsMapLayer::Searchable ) );
mSearchableLayers.insert( it.value(), vl && vl->searchable() ); mIdentifiableLayers.insert( it.value(), it.value()->flags().testFlag( QgsMapLayer::Identifiable ) );
mRemovableLayers.insert( it.value(), it.value()->flags().testFlag( QgsMapLayer::Removable ) );
} }
} }
@ -67,14 +65,14 @@ void QgsLayerCapabilitiesModel::toggleSelectedItems( const QModelIndexList &chec
} }
} }
QStringList QgsLayerCapabilitiesModel::nonIdentifiableLayers() const bool QgsLayerCapabilitiesModel::identifiable( QgsMapLayer *layer ) const
{ {
return mNonIdentifiableLayers; return mIdentifiableLayers.value( layer, true );
} }
QSet<QgsMapLayer *> QgsLayerCapabilitiesModel::requiredLayers() const bool QgsLayerCapabilitiesModel::removable( QgsMapLayer *layer ) const
{ {
return mRequiredLayers; return mRemovableLayers.value( layer, true );
} }
bool QgsLayerCapabilitiesModel::readOnly( QgsMapLayer *layer ) const bool QgsLayerCapabilitiesModel::readOnly( QgsMapLayer *layer ) const
@ -258,7 +256,7 @@ QVariant QgsLayerCapabilitiesModel::data( const QModelIndex &idx, int role ) con
if ( idx.column() == IdentifiableColumn ) if ( idx.column() == IdentifiableColumn )
{ {
if ( layer->isSpatial() ) if ( layer->isSpatial() )
return !mNonIdentifiableLayers.contains( layer->id() ) ? trueValue : falseValue; return mIdentifiableLayers.value( layer, true ) ? trueValue : falseValue;
} }
else if ( idx.column() == ReadOnlyColumn ) else if ( idx.column() == ReadOnlyColumn )
{ {
@ -272,7 +270,7 @@ QVariant QgsLayerCapabilitiesModel::data( const QModelIndex &idx, int role ) con
} }
else if ( idx.column() == RequiredColumn ) else if ( idx.column() == RequiredColumn )
{ {
return mRequiredLayers.contains( layer ) ? trueValue : falseValue; return !mRemovableLayers.value( layer, true ) ? trueValue : falseValue;
} }
} }
} }
@ -291,44 +289,50 @@ bool QgsLayerCapabilitiesModel::setData( const QModelIndex &index, const QVarian
{ {
if ( layer->isSpatial() ) if ( layer->isSpatial() )
{ {
bool nonIdentifiable = value == Qt::Unchecked; bool identifiable = value == Qt::Checked;
bool containsLayer = mNonIdentifiableLayers.contains( layer->id() ); if ( identifiable != mIdentifiableLayers.value( layer, true ) )
if ( containsLayer && !nonIdentifiable ) {
mNonIdentifiableLayers.removeAll( layer->id() ); mIdentifiableLayers.insert( layer, identifiable );
if ( !containsLayer && nonIdentifiable ) emit dataChanged( index, index );
mNonIdentifiableLayers.append( layer->id() ); return true;
emit dataChanged( index, index ); }
return true;
} }
} }
else if ( index.column() == ReadOnlyColumn ) else if ( index.column() == ReadOnlyColumn )
{ {
if ( layer->type() == QgsMapLayer::VectorLayer ) if ( layer->type() == QgsMapLayer::VectorLayer )
{ {
mReadOnlyLayers.insert( layer, value == Qt::Checked ); bool readOnly = value == Qt::Checked;
emit dataChanged( index, index ); if ( readOnly != mReadOnlyLayers.value( layer, true ) )
return true; {
mReadOnlyLayers.insert( layer, readOnly );
emit dataChanged( index, index );
return true;
}
} }
} }
else if ( index.column() == SearchableColumn ) else if ( index.column() == SearchableColumn )
{ {
if ( layer->type() == QgsMapLayer::VectorLayer ) if ( layer->type() == QgsMapLayer::VectorLayer )
{ {
mSearchableLayers.insert( layer, value == Qt::Checked ); bool searchable = value == Qt::Checked;
emit dataChanged( index, index ); if ( searchable != mSearchableLayers.value( layer, true ) )
return true; {
mSearchableLayers.insert( layer, searchable );
emit dataChanged( index, index );
return true;
}
} }
} }
else if ( index.column() == RequiredColumn ) else if ( index.column() == RequiredColumn )
{ {
bool required = value == Qt::Checked; bool removable = value == Qt::Unchecked;
bool containsLayer = mRequiredLayers.contains( layer ); if ( removable != mRemovableLayers.value( layer, true ) )
if ( containsLayer && !required ) {
mRequiredLayers.remove( layer ); mRemovableLayers.insert( layer, removable );
if ( !containsLayer && required ) emit dataChanged( index, index );
mRequiredLayers.insert( layer ); return true;
emit dataChanged( index, index ); }
return true;
} }
} }
} }

View File

@ -43,8 +43,8 @@ class APP_EXPORT QgsLayerCapabilitiesModel : public QSortFilterProxyModel
QgsLayerTreeModel *layerTreeModel() const; QgsLayerTreeModel *layerTreeModel() const;
void setLayerTreeModel( QgsLayerTreeModel *layerTreeModel ); void setLayerTreeModel( QgsLayerTreeModel *layerTreeModel );
QStringList nonIdentifiableLayers() const; bool identifiable( QgsMapLayer *layer ) const;
QSet<QgsMapLayer *> requiredLayers() const; bool removable( QgsMapLayer *layer ) const;
bool readOnly( QgsMapLayer *layer ) const; bool readOnly( QgsMapLayer *layer ) const;
bool searchable( QgsMapLayer *layer ) const; bool searchable( QgsMapLayer *layer ) const;
QgsMapLayer *mapLayer( const QModelIndex &idx ) const; QgsMapLayer *mapLayer( const QModelIndex &idx ) const;
@ -71,10 +71,12 @@ class APP_EXPORT QgsLayerCapabilitiesModel : public QSortFilterProxyModel
QString mFilterText; QString mFilterText;
bool mShowSpatialLayersOnly = false; bool mShowSpatialLayersOnly = false;
QStringList mNonIdentifiableLayers;
QSet<QgsMapLayer *> mRequiredLayers;
QHash<QgsMapLayer *, bool> mReadOnlyLayers; QHash<QgsMapLayer *, bool> mReadOnlyLayers;
QHash<QgsMapLayer *, bool> mSearchableLayers; QHash<QgsMapLayer *, bool> mSearchableLayers;
QHash<QgsMapLayer *, bool> mIdentifiableLayers;
QHash<QgsMapLayer *, bool> mRemovableLayers;
QgsLayerTreeModel *mLayerTreeModel = nullptr; QgsLayerTreeModel *mLayerTreeModel = nullptr;
}; };

View File

@ -1036,17 +1036,34 @@ void QgsProjectProperties::apply()
emit scalesChanged(); emit scalesChanged();
} }
QgsProject::instance()->setNonIdentifiableLayers( mLayerCapabilitiesModel->nonIdentifiableLayers() );
QgsProject::instance()->setRequiredLayers( mLayerCapabilitiesModel->requiredLayers() );
const QMap<QString, QgsMapLayer *> &mapLayers = QgsProject::instance()->mapLayers(); const QMap<QString, QgsMapLayer *> &mapLayers = QgsProject::instance()->mapLayers();
for ( QMap<QString, QgsMapLayer *>::const_iterator it = mapLayers.constBegin(); it != mapLayers.constEnd(); ++it ) for ( QMap<QString, QgsMapLayer *>::const_iterator it = mapLayers.constBegin(); it != mapLayers.constEnd(); ++it )
{ {
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() ); QgsMapLayer *layer = it.value();
QgsMapLayer::LayerFlags flags = layer->flags();
if ( mLayerCapabilitiesModel->identifiable( layer ) )
flags |= QgsMapLayer::Identifiable;
else
flags &= ~QgsMapLayer::Identifiable;
if ( mLayerCapabilitiesModel->removable( layer ) )
flags |= QgsMapLayer::Removable;
else
flags &= ~QgsMapLayer::Removable;
if ( mLayerCapabilitiesModel->searchable( layer ) )
flags |= QgsMapLayer::Searchable;
else
flags &= ~QgsMapLayer::Searchable;
layer->setFlags( flags );
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
if ( vl ) if ( vl )
{ {
// read only and searchable are for vector layers only for now // read only is for vector layers only for now
vl->setReadOnly( mLayerCapabilitiesModel->readOnly( vl ) ); vl->setReadOnly( mLayerCapabilitiesModel->readOnly( vl ) );
vl->setSearchable( mLayerCapabilitiesModel->searchable( vl ) );
} }
} }

View File

@ -144,6 +144,16 @@ QgsMapLayer::LayerType QgsMapLayer::type() const
return mLayerType; return mLayerType;
} }
QgsMapLayer::LayerFlags QgsMapLayer::flags() const
{
return mFlags;
}
void QgsMapLayer::setFlags( QgsMapLayer::LayerFlags flags )
{
mFlags = flags;
}
QString QgsMapLayer::id() const QString QgsMapLayer::id() const
{ {
return mID; return mID;
@ -389,6 +399,23 @@ bool QgsMapLayer::readLayerXml( const QDomElement &layerElement, QgsReadWriteCo
QDomElement metadataElem = layerElement.firstChildElement( QStringLiteral( "resourceMetadata" ) ); QDomElement metadataElem = layerElement.firstChildElement( QStringLiteral( "resourceMetadata" ) );
mMetadata.readMetadataXml( metadataElem ); mMetadata.readMetadataXml( metadataElem );
// flags
QDomElement flagsElem = layerElement.firstChildElement( QStringLiteral( "flags" ) );
QMetaEnum metaEnum = QMetaEnum::fromType<QgsMapLayer::LayerFlag>();
for ( int idx = 0; idx < metaEnum.keyCount(); ++idx )
{
const char *enumKey = metaEnum.key( idx );
QDomNode flagNode = flagsElem.namedItem( QString( enumKey ) );
if ( flagNode.isNull() )
continue;
bool flagValue = flagNode.toElement().text() == "1" ? true : false;
QgsMapLayer::LayerFlag enumValue = static_cast<QgsMapLayer::LayerFlag>( metaEnum.keyToValue( enumKey ) );
if ( mFlags.testFlag( enumValue ) && !flagValue )
mFlags &= ~enumValue;
else if ( !mFlags.testFlag( enumValue ) && flagValue )
mFlags |= enumValue;
}
return true; return true;
} // bool QgsMapLayer::readLayerXML } // bool QgsMapLayer::readLayerXML
@ -554,6 +581,21 @@ bool QgsMapLayer::writeLayerXml( QDomElement &layerElement, QDomDocument &docume
mMetadata.writeMetadataXml( myMetadataElem, document ); mMetadata.writeMetadataXml( myMetadataElem, document );
layerElement.appendChild( myMetadataElem ); layerElement.appendChild( myMetadataElem );
// flags
// this code is saving automatically all the flags entries
QDomElement layerFlagsElem = document.createElement( QStringLiteral( "flags" ) );
QMetaEnum metaEnum = QMetaEnum::fromType<QgsMapLayer::LayerFlag>();
for ( int idx = 0; idx < metaEnum.keyCount(); ++idx )
{
const char *enumKey = metaEnum.key( idx );
QgsMapLayer::LayerFlag enumValue = static_cast<QgsMapLayer::LayerFlag>( metaEnum.keyToValue( enumKey ) );
bool flagValue = mFlags.testFlag( enumValue );
QDomElement flagElem = document.createElement( enumKey );
flagElem.appendChild( document.createTextNode( QString::number( flagValue ) ) );
layerFlagsElem.appendChild( flagElem );
}
layerElement.appendChild( layerFlagsElem );
// now append layer node to map layer node // now append layer node to map layer node
writeCustomProperties( layerElement, document ); writeCustomProperties( layerElement, document );

View File

@ -118,6 +118,21 @@ class CORE_EXPORT QgsMapLayer : public QObject
Metadata, Metadata,
}; };
/**
* Flags for the map layer
* \note Flags are options specified by the user used for the UI but are not preventing any API call.
* \since QGIS 3.4
*/
enum LayerFlag
{
Identifiable = 1 << 0, //!< If the layer is identifiable using the identify map tool and as a WMS layer.
Removable = 1 << 1, //!< If the layer can be removed from the project. The layer will not be removable from the legend menu entry but can still be removed with an API call.
Searchable = 1 << 2, //!< Only for vector-layer, determines if the layer is used in the 'search all layers' locator.
};
Q_ENUM( LayerFlag )
Q_DECLARE_FLAGS( LayerFlags, LayerFlag )
Q_FLAG( LayerFlags )
/** /**
* Constructor for QgsMapLayer * Constructor for QgsMapLayer
* \param type layer type * \param type layer type
@ -146,6 +161,24 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/ */
QgsMapLayer::LayerType type() const; QgsMapLayer::LayerType type() const;
/**
* Returns the flags for this layer.
* \note Flags are options specified by the user used for the UI but are not preventing any API call.
* For instance, even if the Removable flag is not set, the layer can still be removed with the API
* but the action will not be listed in the legend menu.
* \since QGIS 3.4
*/
QgsMapLayer::LayerFlags flags() const;
/**
* Returns the flags for this layer.
\note Flags are options specified by the user used for the UI but are not preventing any API call.
* For instance, even if the Removable flag is not set, the layer can still be removed with the API
* but the action will not be listed in the legend menu.
* \since QGIS 3.4
*/
void setFlags( QgsMapLayer::LayerFlags flags );
/** /**
* Returns the extension of a Property. * Returns the extension of a Property.
* \returns The extension * \returns The extension
@ -1335,6 +1368,8 @@ class CORE_EXPORT QgsMapLayer : public QObject
//! Type of the layer (e.g., vector, raster) //! Type of the layer (e.g., vector, raster)
QgsMapLayer::LayerType mLayerType; QgsMapLayer::LayerType mLayerType;
LayerFlags mFlags = LayerFlags( Identifiable | Removable | Searchable );
//! Blend mode for the layer //! Blend mode for the layer
QPainter::CompositionMode mBlendMode = QPainter::CompositionMode_SourceOver; QPainter::CompositionMode mBlendMode = QPainter::CompositionMode_SourceOver;
@ -1375,6 +1410,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
}; };
Q_DECLARE_METATYPE( QgsMapLayer * ) Q_DECLARE_METATYPE( QgsMapLayer * )
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsMapLayer::LayerFlags )
#ifndef SIP_RUN #ifndef SIP_RUN

View File

@ -1271,6 +1271,27 @@ bool QgsProject::readProjectFile( const QString &filename )
mRootGroup->readLayerOrderFromXml( layerTreeCanvasElem ); mRootGroup->readLayerOrderFromXml( layerTreeCanvasElem );
} }
// Convert pre 3.4 to create layers flags
if ( QgsProjectVersion( 3, 4, 0 ) > fileVersion )
{
const QStringList requiredLayerIds = readListEntry( QStringLiteral( "RequiredLayers" ), QStringLiteral( "Layers" ) );
for ( const QString &layerId : requiredLayerIds )
{
if ( QgsMapLayer *layer = mapLayer( layerId ) )
{
layer->setFlags( layer->flags() & ~QgsMapLayer::Removable );
}
}
const QStringList disabledLayerIds = readListEntry( QStringLiteral( "Identify" ), QStringLiteral( "/disabledLayers" ) );
for ( const QString &layerId : disabledLayerIds )
{
if ( QgsMapLayer *layer = mapLayer( layerId ) )
{
layer->setFlags( layer->flags() & ~QgsMapLayer::Identifiable );
}
}
}
// make sure the are just valid layers // make sure the are just valid layers
QgsLayerTreeUtils::removeInvalidLayers( mRootGroup ); QgsLayerTreeUtils::removeInvalidLayers( mRootGroup );
@ -1323,7 +1344,9 @@ bool QgsProject::readProjectFile( const QString &filename )
if ( clean ) if ( clean )
setDirty( false ); setDirty( false );
Q_NOWARN_DEPRECATED_PUSH
emit nonIdentifiableLayersChanged( nonIdentifiableLayers() ); emit nonIdentifiableLayersChanged( nonIdentifiableLayers() );
Q_NOWARN_DEPRECATED_POP
if ( mTranslator ) if ( mTranslator )
{ {
@ -2224,18 +2247,6 @@ QgsLayerTreeGroup *QgsProject::createEmbeddedGroup( const QString &groupName, co
context.setPathResolver( pathResolver() ); context.setPathResolver( pathResolver() );
context.setProjectTranslator( this ); context.setProjectTranslator( this );
// store identify disabled layers of the embedded project
QSet<QString> embeddedIdentifyDisabledLayers;
QDomElement disabledLayersElem = projectDocument.documentElement().firstChildElement( QStringLiteral( "properties" ) ).firstChildElement( QStringLiteral( "Identify" ) ).firstChildElement( QStringLiteral( "disabledLayers" ) );
if ( !disabledLayersElem.isNull() )
{
QDomNodeList valueList = disabledLayersElem.elementsByTagName( QStringLiteral( "value" ) );
for ( int i = 0; i < valueList.size(); ++i )
{
embeddedIdentifyDisabledLayers.insert( valueList.at( i ).toElement().text() );
}
}
QgsLayerTreeGroup *root = new QgsLayerTreeGroup; QgsLayerTreeGroup *root = new QgsLayerTreeGroup;
QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral( "layer-tree-group" ) ); QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral( "layer-tree-group" ) );
@ -2269,16 +2280,9 @@ QgsLayerTreeGroup *QgsProject::createEmbeddedGroup( const QString &groupName, co
initializeEmbeddedSubtree( projectFilePath, newGroup ); initializeEmbeddedSubtree( projectFilePath, newGroup );
mLayerTreeRegistryBridge->setEnabled( true ); mLayerTreeRegistryBridge->setEnabled( true );
QStringList thisProjectIdentifyDisabledLayers = nonIdentifiableLayers();
// consider the layers might be identify disabled in its project // consider the layers might be identify disabled in its project
Q_FOREACH ( const QString &layerId, newGroup->findLayerIds() ) Q_FOREACH ( const QString &layerId, newGroup->findLayerIds() )
{ {
if ( embeddedIdentifyDisabledLayers.contains( layerId ) )
{
thisProjectIdentifyDisabledLayers.append( layerId );
}
QgsLayerTreeLayer *layer = newGroup->findLayer( layerId ); QgsLayerTreeLayer *layer = newGroup->findLayer( layerId );
if ( layer ) if ( layer )
{ {
@ -2287,8 +2291,6 @@ QgsLayerTreeGroup *QgsProject::createEmbeddedGroup( const QString &groupName, co
} }
} }
setNonIdentifiableLayers( thisProjectIdentifyDisabledLayers );
return newGroup; return newGroup;
} }
@ -2446,37 +2448,46 @@ const QgsAnnotationManager *QgsProject::annotationManager() const
void QgsProject::setNonIdentifiableLayers( const QList<QgsMapLayer *> &layers ) void QgsProject::setNonIdentifiableLayers( const QList<QgsMapLayer *> &layers )
{ {
QStringList currentLayers = nonIdentifiableLayers(); const QMap<QString, QgsMapLayer *> &projectLayers = mapLayers();
for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
QStringList newLayers;
Q_FOREACH ( QgsMapLayer *l, layers )
{ {
newLayers << l->id(); if ( layers.contains( it.value() ) == !it.value()->flags().testFlag( QgsMapLayer::Identifiable ) )
continue;
if ( layers.contains( it.value() ) )
it.value()->setFlags( it.value()->flags() & ~QgsMapLayer::Identifiable );
else
it.value()->setFlags( it.value()->flags() | QgsMapLayer::Identifiable );
} }
if ( newLayers == currentLayers ) emit nonIdentifiableLayersChanged( nonIdentifiableLayers() );
return;
QStringList disabledLayerIds;
Q_FOREACH ( QgsMapLayer *l, layers )
{
disabledLayerIds << l->id();
}
setNonIdentifiableLayers( disabledLayerIds );
} }
void QgsProject::setNonIdentifiableLayers( const QStringList &layerIds ) void QgsProject::setNonIdentifiableLayers( const QStringList &layerIds )
{ {
writeEntry( QStringLiteral( "Identify" ), QStringLiteral( "/disabledLayers" ), layerIds ); QList<QgsMapLayer *> nonIdentifiableLayers;
for ( const QString &layerId : layerIds )
emit nonIdentifiableLayersChanged( layerIds ); {
QgsMapLayer *layer = mapLayer( layerId );
if ( layer )
nonIdentifiableLayers << layer;
}
setNonIdentifiableLayers( nonIdentifiableLayers );
} }
QStringList QgsProject::nonIdentifiableLayers() const QStringList QgsProject::nonIdentifiableLayers() const
{ {
return readListEntry( QStringLiteral( "Identify" ), QStringLiteral( "/disabledLayers" ) ); QStringList nonIdentifiableLayers;
const QMap<QString, QgsMapLayer *> &layers = mapLayers();
for ( QMap<QString, QgsMapLayer *>::const_iterator it = layers.constBegin(); it != layers.constEnd(); ++it )
{
if ( !it.value()->flags().testFlag( QgsMapLayer::Identifiable ) )
{
nonIdentifiableLayers.append( it.value()->id() );
}
}
return nonIdentifiableLayers;
} }
bool QgsProject::autoTransaction() const bool QgsProject::autoTransaction() const
@ -2803,25 +2814,32 @@ void QgsProject::setMetadata( const QgsProjectMetadata &metadata )
QSet<QgsMapLayer *> QgsProject::requiredLayers() const QSet<QgsMapLayer *> QgsProject::requiredLayers() const
{ {
QSet<QgsMapLayer *> layers; QSet<QgsMapLayer *> requiredLayers;
const QStringList lst = readListEntry( QStringLiteral( "RequiredLayers" ), QStringLiteral( "Layers" ) );
for ( const QString &layerId : lst ) const QMap<QString, QgsMapLayer *> &layers = mapLayers();
for ( QMap<QString, QgsMapLayer *>::const_iterator it = layers.constBegin(); it != layers.constEnd(); ++it )
{ {
if ( QgsMapLayer *layer = mapLayer( layerId ) ) if ( !it.value()->flags().testFlag( QgsMapLayer::Removable ) )
layers.insert( layer ); {
requiredLayers.insert( it.value() );
}
} }
return layers; return requiredLayers;
} }
void QgsProject::setRequiredLayers( const QSet<QgsMapLayer *> &layers ) void QgsProject::setRequiredLayers( const QSet<QgsMapLayer *> &layers )
{ {
QStringList layerIds; const QMap<QString, QgsMapLayer *> &projectLayers = mapLayers();
layerIds.reserve( layers.count() ); for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
for ( QgsMapLayer *layer : layers )
{ {
layerIds << layer->id(); if ( layers.contains( it.value() ) == !it.value()->flags().testFlag( QgsMapLayer::Removable ) )
continue;
if ( layers.contains( it.value() ) )
it.value()->setFlags( it.value()->flags() & ~QgsMapLayer::Removable );
else
it.value()->setFlags( it.value()->flags() | QgsMapLayer::Removable );
} }
writeEntry( QStringLiteral( "RequiredLayers" ), QStringLiteral( "Layers" ), layerIds );
} }
void QgsProject::generateTsFile( const QString &locale ) void QgsProject::generateTsFile( const QString &locale )

View File

@ -553,18 +553,21 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
/** /**
* Set a list of layers which should not be taken into account on map identification * Set a list of layers which should not be taken into account on map identification
* \deprecated since QGIS 3.4 use QgsMapLayer::setFlags() instead
*/ */
void setNonIdentifiableLayers( const QList<QgsMapLayer *> &layers ); Q_DECL_DEPRECATED void setNonIdentifiableLayers( const QList<QgsMapLayer *> &layers );
/** /**
* Set a list of layers which should not be taken into account on map identification * Set a list of layers which should not be taken into account on map identification
* \deprecated since QGIS 3.4 use QgsMapLayer::setFlags() instead
*/ */
void setNonIdentifiableLayers( const QStringList &layerIds ); Q_DECL_DEPRECATED void setNonIdentifiableLayers( const QStringList &layerIds );
/** /**
* Gets the list of layers which currently should not be taken into account on map identification * Gets the list of layers which currently should not be taken into account on map identification
* \deprecated since QGIS 3.4 use QgsMapLayer::setFlags() instead
*/ */
QStringList nonIdentifiableLayers() const; Q_DECL_DEPRECATED QStringList nonIdentifiableLayers() const;
/** /**
* Transactional editing means that on supported datasources (postgres databases) the edit state of * Transactional editing means that on supported datasources (postgres databases) the edit state of
@ -953,18 +956,20 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
* removed from the project. The set of layers may be configured by users in project properties. * removed from the project. The set of layers may be configured by users in project properties.
* and it is mainly a hint for the user interface to protect users from removing layers that important * and it is mainly a hint for the user interface to protect users from removing layers that important
* in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here. * in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here.
* \deprecated since QGIS 3.4 use QgsMapLayer::flags() instead
* \since QGIS 3.2 * \since QGIS 3.2
*/ */
QSet<QgsMapLayer *> requiredLayers() const; Q_DECL_DEPRECATED QSet<QgsMapLayer *> requiredLayers() const;
/** /**
* Configures a set of map layers that are required in the project and therefore they should not get * Configures a set of map layers that are required in the project and therefore they should not get
* removed from the project. The set of layers may be configured by users in project properties. * removed from the project. The set of layers may be configured by users in project properties.
* and it is mainly a hint for the user interface to protect users from removing layers that important * and it is mainly a hint for the user interface to protect users from removing layers that important
* in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here. * in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here.
* \deprecated since QGIS 3.4 use QgsMapLayer::setFlags() instead
* \since QGIS 3.2 * \since QGIS 3.2
*/ */
void setRequiredLayers( const QSet<QgsMapLayer *> &layers ); Q_DECL_DEPRECATED void setRequiredLayers( const QSet<QgsMapLayer *> &layers );
/** /**
* Triggers the collection strings of .qgs to be included in ts file and calls writeTsFile() * Triggers the collection strings of .qgs to be included in ts file and calls writeTsFile()
@ -1058,8 +1063,11 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
*/ */
void loadingLayerMessageReceived( const QString &layerName, const QList<QgsReadWriteContext::ReadWriteMessage> &messages ); void loadingLayerMessageReceived( const QString &layerName, const QList<QgsReadWriteContext::ReadWriteMessage> &messages );
//! Emitted when the list of layer which are excluded from map identification changes /**
void nonIdentifiableLayersChanged( QStringList nonIdentifiableLayers ); * Emitted when the list of layer which are excluded from map identification changes
* \deprecated since QGIS 3.4
*/
Q_DECL_DEPRECATED void nonIdentifiableLayersChanged( QStringList nonIdentifiableLayers );
//! Emitted when the file name of the project changes //! Emitted when the file name of the project changes
void fileNameChanged(); void fileNameChanged();

View File

@ -2070,8 +2070,6 @@ bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMes
QDomElement mapLayerNode = layerNode.toElement(); QDomElement mapLayerNode = layerNode.toElement();
if ( mapLayerNode.attribute( QStringLiteral( "readOnly" ), QStringLiteral( "0" ) ).toInt() == 1 ) if ( mapLayerNode.attribute( QStringLiteral( "readOnly" ), QStringLiteral( "0" ) ).toInt() == 1 )
mReadOnly = true; mReadOnly = true;
if ( mapLayerNode.attribute( QStringLiteral( "searchable" ), QStringLiteral( "0" ) ).toInt() == 1 )
mSearchable = true;
updateFields(); updateFields();
@ -2378,9 +2376,6 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString
// save readonly state // save readonly state
node.toElement().setAttribute( QStringLiteral( "readOnly" ), mReadOnly ); node.toElement().setAttribute( QStringLiteral( "readOnly" ), mReadOnly );
// save searchable state
node.toElement().setAttribute( QStringLiteral( "searchable" ), mSearchable );
// save preview expression // save preview expression
QDomElement prevExpElem = doc.createElement( QStringLiteral( "previewExpression" ) ); QDomElement prevExpElem = doc.createElement( QStringLiteral( "previewExpression" ) );
QDomText prevExpText = doc.createTextNode( mDisplayExpression ); QDomText prevExpText = doc.createTextNode( mDisplayExpression );
@ -3112,26 +3107,12 @@ bool QgsVectorLayer::setReadOnly( bool readonly )
return true; return true;
} }
bool QgsVectorLayer::searchable() const
{
return mSearchable;
}
void QgsVectorLayer::setSearchable( bool searchable )
{
if ( searchable == mSearchable )
return;
mSearchable = searchable;
emit searchableChanged();
}
bool QgsVectorLayer::isModified() const bool QgsVectorLayer::isModified() const
{ {
emit beforeModifiedCheck(); emit beforeModifiedCheck();
return mEditBuffer && mEditBuffer->isModified(); return mEditBuffer && mEditBuffer->isModified();
} }
bool QgsVectorLayer::isAuxiliaryField( int index, int &srcIndex ) const bool QgsVectorLayer::isAuxiliaryField( int index, int &srcIndex ) const
{ {
bool auxiliaryField = false; bool auxiliaryField = false;

View File

@ -360,7 +360,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
Q_PROPERTY( QgsEditFormConfig editFormConfig READ editFormConfig WRITE setEditFormConfig NOTIFY editFormConfigChanged ) Q_PROPERTY( QgsEditFormConfig editFormConfig READ editFormConfig WRITE setEditFormConfig NOTIFY editFormConfigChanged )
Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged ) Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged )
Q_PROPERTY( double opacity READ opacity WRITE setOpacity NOTIFY opacityChanged ) Q_PROPERTY( double opacity READ opacity WRITE setOpacity NOTIFY opacityChanged )
Q_PROPERTY( bool searchable READ searchable WRITE setSearchable NOTIFY searchableChanged )
public: public:
@ -1383,17 +1382,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/ */
bool setReadOnly( bool readonly = true ); bool setReadOnly( bool readonly = true );
/**
* Returns true if the provider is in read-only mode
*/
bool searchable() const;
/**
* Make layer searchable or not
* \since QGIS 3.4
*/
void setSearchable( bool searchable );
/** /**
* Changes a feature's \a geometry within the layer's edit buffer * Changes a feature's \a geometry within the layer's edit buffer
* (but does not immediately commit the changes). The \a fid argument * (but does not immediately commit the changes). The \a fid argument
@ -2320,12 +2308,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/ */
void readOnlyChanged(); void readOnlyChanged();
/**
* Emitted when the search state of this layer is changed.
* \since QGIS 3.4
*/
void searchableChanged();
/** /**
* Emitted when the feature count for symbols on this layer has been recalculated. * Emitted when the feature count for symbols on this layer has been recalculated.
* *
@ -2392,9 +2374,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
//! Flag indicating whether the layer is in read-only mode (editing disabled) or not //! Flag indicating whether the layer is in read-only mode (editing disabled) or not
bool mReadOnly = false; bool mReadOnly = false;
//! Indicates whether the layer is searchable or not
bool mSearchable = true;
/** /**
* Set holding the feature IDs that are activated. Note that if a feature * Set holding the feature IDs that are activated. Note that if a feature
subsequently gets deleted (i.e. by its addition to mDeletedFeatureIds), subsequently gets deleted (i.e. by its addition to mDeletedFeatureIds),

View File

@ -141,8 +141,6 @@ QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( const Qg
{ {
QApplication::setOverrideCursor( Qt::WaitCursor ); QApplication::setOverrideCursor( Qt::WaitCursor );
QStringList noIdentifyLayerIdList = QgsProject::instance()->readListEntry( QStringLiteral( "Identify" ), QStringLiteral( "/disabledLayers" ) );
int layerCount; int layerCount;
if ( layerList.isEmpty() ) if ( layerList.isEmpty() )
layerCount = mCanvas->layerCount(); layerCount = mCanvas->layerCount();
@ -162,7 +160,7 @@ QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( const Qg
emit identifyProgress( i, mCanvas->layerCount() ); emit identifyProgress( i, mCanvas->layerCount() );
emit identifyMessage( tr( "Identifying on %1…" ).arg( layer->name() ) ); emit identifyMessage( tr( "Identifying on %1…" ).arg( layer->name() ) );
if ( noIdentifyLayerIdList.contains( layer->id() ) ) if ( !layer->flags().testFlag( QgsMapLayer::Identifiable ) )
continue; continue;
if ( identifyLayer( &results, layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType ) ) if ( identifyLayer( &results, layer, mLastGeometry, mLastExtent, mLastMapUnitsPerPixel, layerType ) )

View File

@ -65,15 +65,9 @@ QgsQuickFeatureLayerPairs QgsQuickIdentifyKit::identify( const QPointF &point, Q
} }
else else
{ {
QStringList noIdentifyLayerIdList;
if ( mMapSettings->project() )
{
noIdentifyLayerIdList = mMapSettings->project()->nonIdentifiableLayers();
}
for ( QgsMapLayer *layer : mMapSettings->mapSettings().layers() ) for ( QgsMapLayer *layer : mMapSettings->mapSettings().layers() )
{ {
if ( mMapSettings->project() && noIdentifyLayerIdList.contains( layer->id() ) ) if ( mMapSettings->project() && !layer->flags().testFlag( QgsMapLayer::Identifiable ) )
continue; continue;
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ); QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
@ -91,7 +85,6 @@ QgsQuickFeatureLayerPairs QgsQuickIdentifyKit::identify( const QPointF &point, Q
QgsDebugMsg( QStringLiteral( "IdentifyKit identified %1 results with TopDownStopAtFirst mode." ).arg( results.count() ) ); QgsDebugMsg( QStringLiteral( "IdentifyKit identified %1 results with TopDownStopAtFirst mode." ).arg( results.count() ) );
return results; return results;
} }
} }
QgsDebugMsg( QStringLiteral( "IdentifyKit identified %1 results" ).arg( results.count() ) ); QgsDebugMsg( QStringLiteral( "IdentifyKit identified %1 results" ).arg( results.count() ) );

View File

@ -771,7 +771,6 @@ namespace QgsWms
const QgsProject *project, const QString &version, const QgsProject *project, const QString &version,
const QgsServerRequest &request, bool projectSettings ) const QgsServerRequest &request, bool projectSettings )
{ {
QStringList nonIdentifiableLayers = project->nonIdentifiableLayers();
const QgsLayerTree *projectLayerTreeRoot = project->layerTreeRoot(); const QgsLayerTree *projectLayerTreeRoot = project->layerTreeRoot();
QDomElement layerParentElem = doc.createElement( QStringLiteral( "Layer" ) ); QDomElement layerParentElem = doc.createElement( QStringLiteral( "Layer" ) );
@ -936,7 +935,7 @@ namespace QgsWms
} }
// queryable layer // queryable layer
if ( project->nonIdentifiableLayers().contains( l->id() ) ) if ( !l->flags().testFlag( QgsMapLayer::Identifiable ) )
{ {
layerElem.setAttribute( QStringLiteral( "queryable" ), QStringLiteral( "0" ) ); layerElem.setAttribute( QStringLiteral( "queryable" ), QStringLiteral( "0" ) );
} }

View File

@ -247,7 +247,7 @@ namespace QgsWms
QDomElement layerElem = doc.createElement( QStringLiteral( "Layer" ) ); QDomElement layerElem = doc.createElement( QStringLiteral( "Layer" ) );
// queryable layer // queryable layer
if ( project->nonIdentifiableLayers().contains( l->id() ) ) if ( !l->flags().testFlag( QgsMapLayer::Identifiable ) )
{ {
layerElem.setAttribute( QStringLiteral( "queryable" ), QStringLiteral( "false" ) ); layerElem.setAttribute( QStringLiteral( "queryable" ), QStringLiteral( "false" ) );
} }

View File

@ -1253,7 +1253,7 @@ namespace QgsWms
if ( queryLayer == layerNickname( *layer ) ) if ( queryLayer == layerNickname( *layer ) )
{ {
validLayer = true; validLayer = true;
queryableLayer = !mProject->nonIdentifiableLayers().contains( layer->id() ) ; queryableLayer = layer->flags().testFlag( QgsMapLayer::Identifiable );
if ( !queryableLayer ) if ( !queryableLayer )
{ {
break; break;
@ -2946,20 +2946,13 @@ namespace QgsWms
void QgsRenderer::removeNonIdentifiableLayers( QList<QgsMapLayer *> &layers ) const void QgsRenderer::removeNonIdentifiableLayers( QList<QgsMapLayer *> &layers ) const
{ {
QStringList nonIdentifiableLayers = mProject->nonIdentifiableLayers(); QList<QgsMapLayer *>::iterator it = layers.begin();
if ( !nonIdentifiableLayers.isEmpty() ) while ( it != layers.end() )
{ {
QList<QgsMapLayer *> wantedLayers; if ( !( *it )->flags().testFlag( QgsMapLayer::Identifiable ) )
it = layers.erase( it );
for ( QgsMapLayer *layer : layers ) else
{ ++it;
if ( nonIdentifiableLayers.contains( layer->id() ) )
continue;
wantedLayers.append( layer );
}
layers = wantedLayers;
} }
} }

View File

@ -249,8 +249,6 @@ namespace QgsWmts
#endif #endif
QgsCoordinateReferenceSystem wgs84 = QgsCoordinateReferenceSystem::fromOgcWmsCrs( GEO_EPSG_CRS_AUTHID ); QgsCoordinateReferenceSystem wgs84 = QgsCoordinateReferenceSystem::fromOgcWmsCrs( GEO_EPSG_CRS_AUTHID );
QStringList nonIdentifiableLayers = project->nonIdentifiableLayers();
// WMTS Project configuration // WMTS Project configuration
bool wmtsProject = project->readBoolEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Project" ) ); bool wmtsProject = project->readBoolEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Project" ) );
@ -349,7 +347,7 @@ namespace QgsWmts
{ {
wgs84BoundingRect.combineExtentWith( QgsRectangle( -180, -90, 180, 90 ) ); wgs84BoundingRect.combineExtentWith( QgsRectangle( -180, -90, 180, 90 ) );
} }
if ( !queryable && !nonIdentifiableLayers.contains( l->id() ) ) if ( !queryable && l->flags().testFlag( QgsMapLayer::Identifiable ) )
{ {
queryable = true; queryable = true;
} }
@ -425,7 +423,7 @@ namespace QgsWmts
if ( wmtsJpegLayerIdList.contains( lId ) ) if ( wmtsJpegLayerIdList.contains( lId ) )
pLayer.formats << QStringLiteral( "image/jpeg" ); pLayer.formats << QStringLiteral( "image/jpeg" );
pLayer.queryable = ( !nonIdentifiableLayers.contains( l->id() ) ); pLayer.queryable = ( l->flags().testFlag( QgsMapLayer::Identifiable ) );
pLayer.maxScale = l->maximumScale(); pLayer.maxScale = l->maximumScale();
pLayer.minScale = l->minimumScale(); pLayer.minScale = l->minimumScale();

View File

@ -40,7 +40,7 @@ class TestQgsProject : public QObject
void testPathResolverSvg(); void testPathResolverSvg();
void testProjectUnits(); void testProjectUnits();
void variablesChanged(); void variablesChanged();
void testRequiredLayers(); void testLayerFlags();
}; };
void TestQgsProject::init() void TestQgsProject::init()
@ -356,7 +356,7 @@ void TestQgsProject::variablesChanged()
delete prj; delete prj;
} }
void TestQgsProject::testRequiredLayers() void TestQgsProject::testLayerFlags()
{ {
QString dataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt QString dataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt
QString layerPath = dataDir + "/points.shp"; QString layerPath = dataDir + "/points.shp";
@ -367,13 +367,9 @@ void TestQgsProject::testRequiredLayers()
prj.addMapLayer( layer1 ); prj.addMapLayer( layer1 );
prj.addMapLayer( layer2 ); prj.addMapLayer( layer2 );
QSet<QgsMapLayer *> reqLayers; layer2->setFlags( layer2->flags() & ~QgsMapLayer::Removable );
reqLayers << layer2;
prj.setRequiredLayers( reqLayers );
QSet<QgsMapLayer *> reqLayersReturned = prj.requiredLayers(); QString layer2id = layer2->id();
QCOMPARE( reqLayersReturned.count(), 1 );
QCOMPARE( *reqLayersReturned.constBegin(), layer2 );
QTemporaryFile f; QTemporaryFile f;
QVERIFY( f.open() ); QVERIFY( f.open() );
@ -385,9 +381,9 @@ void TestQgsProject::testRequiredLayers()
QgsProject prj2; QgsProject prj2;
prj2.setFileName( f.fileName() ); prj2.setFileName( f.fileName() );
QVERIFY( prj2.read() ); QVERIFY( prj2.read() );
QSet<QgsMapLayer *> reqLayersReturned2 = prj2.requiredLayers(); QgsMapLayer *layer = prj.mapLayer( layer2id );
QCOMPARE( reqLayersReturned2.count(), 1 ); QVERIFY( layer );
QCOMPARE( ( *reqLayersReturned.constBegin() )->name(), QString( "points 2" ) ); QVERIFY( !layer->flags().testFlag( QgsMapLayer::Removable ) );
} }