mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-06 00:07:29 -04:00
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:
parent
48dcab75cb
commit
89830f614e
4
python/core/auto_additions/qgsmaplayer.py
Normal file
4
python/core/auto_additions/qgsmaplayer.py
Normal 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
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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 ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 );
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 )
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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),
|
||||||
|
@ -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 ) )
|
||||||
|
@ -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() ) );
|
||||||
|
@ -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" ) );
|
||||||
}
|
}
|
||||||
|
@ -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" ) );
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user