Skip to content

Commit

Permalink
Cleanup layer dependency api
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugo Mercier committed Sep 1, 2016
1 parent bd3cf76 commit a86611b
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 102 deletions.
26 changes: 12 additions & 14 deletions python/core/qgsmaplayer.sip
Expand Up @@ -677,28 +677,21 @@ class QgsMapLayer : QObject
void emitStyleChanged();

/**
* Sets the list of layers that may modify data/geometries of this layer when modified.
* Sets the list of dependencies.
* @see dependencies()
*
* @param layersIds IDs of the layers that this layer depends on
* @returns false if a dependency cycle has been detected (the change dependency set is not changed in that case)
* @param layers set of QgsMapLayerDependency. Only user-defined dependencies will be added
* @returns false if a dependency cycle has been detected
* @note added in QGIS 3.0
*/
virtual bool setDataDependencies( const QSet<QString>& layersIds );

/**
* Sets the list of layers that may modify data/geometries of this layer when modified.
* @see dependencies()
*
* @param set of QgsMapLayerDependency. Only user-defined dependencies will be added
* @returns false if a dependency cycle has been detected (the change dependency set is not changed in that case)
*/
bool setDataDependencies( const QSet<QgsMapLayerDependency>& layers );
virtual bool setDependencies( const QSet<QgsMapLayerDependency>& layers );

/**
* Gets the list of dependencies. This includes data dependencies set by the user (@see setDataDependencies)
* as well as dependencies given by the provider
*
* @returns a set of QgsMapLayerDependency
* @note added in QGIS 3.0
*/
virtual QSet<QgsMapLayerDependency> dependencies() const;

Expand Down Expand Up @@ -756,6 +749,11 @@ class QgsMapLayer : QObject
*/
void configChanged();

/**
* Emitted when dependencies are changed.
*/
void dependenciesChanged();

protected:
/** Set the extent */
virtual void setExtent( const QgsRectangle &rect );
Expand Down Expand Up @@ -794,5 +792,5 @@ class QgsMapLayer : QObject
void setError( const QgsError &error );

//! Checks if new change dependency candidates introduce a cycle
bool hasDataDependencyCycle( const QSet<QgsMapLayerDependency>& layersIds ) const;
bool hasDependencyCycle( const QSet<QgsMapLayerDependency>& layersIds ) const;
};
14 changes: 7 additions & 7 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -422,21 +422,21 @@ class QgsVectorLayer : QgsMapLayer
const QList<QgsVectorJoinInfo> vectorJoins() const;

/**
* Sets the list of layers that may modify data/geometries of this layer when modified.
* This is meant mainly to declare database triggers between layers.
* When one of these layers is modified (feature added/deleted or geometry changed),
* dataChanged() will be emitted, allowing users of this layer to refresh / update it.
* Sets the list of dependencies.
* @see dependencies()
*
* @param layersIds IDs of the layers that this layer depends on
* @returns false if a dependency cycle has been detected (the change dependency set is not changed in that case)
* @param layers set of QgsMapLayerDependency. Only user-defined dependencies will be added
* @returns false if a dependency cycle has been detected
* @note added in QGIS 3.0
*/
bool setDataDependencies( const QSet<QString>& layersIds );
virtual bool setDependencies( const QSet<QgsMapLayerDependency>& layers );

/**
* Gets the list of dependencies. This includes data dependencies set by the user (@see setDataDependencies)
* as well as dependencies given by the provider
*
* @returns a set of QgsMapLayerDependency
* @note added in QGIS 3.0
*/
virtual QSet<QgsMapLayerDependency> dependencies() const;

Expand Down
8 changes: 4 additions & 4 deletions src/app/qgsvectorlayerproperties.cpp
Expand Up @@ -580,14 +580,14 @@ void QgsVectorLayerProperties::apply()
QgsExpressionContextUtils::setLayerVariables( mLayer, mVariableEditor->variablesInActiveScope() );
updateVariableEditor();

// save layer dependencies
QSet<QString> deps;
// save dependencies
QSet<QgsMapLayerDependency> deps;
Q_FOREACH ( const QgsLayerTreeLayer* layer, mLayersDependenciesTreeGroup->findLayers() )
{
if ( layer->isVisible() )
deps << layer->layerId();
deps << QgsMapLayerDependency( layer->layerId() );
}
if ( ! mLayer->setDataDependencies( deps ) )
if ( ! mLayer->setDependencies( deps ) )
{
QMessageBox::warning( nullptr, tr( "Dependency cycle" ), tr( "This configuration introduces a cycle in data dependencies and will be ignored" ) );
}
Expand Down
27 changes: 9 additions & 18 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -1720,38 +1720,29 @@ static bool _depHasCycleDFS( const QgsMapLayer* n, QHash<const QgsMapLayer*, int
return false;
}

bool QgsMapLayer::hasDataDependencyCycle( const QSet<QgsMapLayerDependency>& layers ) const
bool QgsMapLayer::hasDependencyCycle( const QSet<QgsMapLayerDependency>& layers ) const
{
QHash<const QgsMapLayer*, int> marks;
return _depHasCycleDFS( this, marks, this, layers );
}

QSet<QgsMapLayerDependency> QgsMapLayer::dependencies() const
{
return mDataDependencies;
return mDependencies;
}

bool QgsMapLayer::setDataDependencies( const QSet<QString>& layersIds )
bool QgsMapLayer::setDependencies( const QSet<QgsMapLayerDependency>& oDeps )
{
QSet<QgsMapLayerDependency> deps;
Q_FOREACH ( QString layerId, layersIds )
Q_FOREACH ( const QgsMapLayerDependency& dep, oDeps )
{
deps << QgsMapLayerDependency( layerId );
if ( dep.origin() == QgsMapLayerDependency::FromUser )
deps << dep;
}
if ( hasDataDependencyCycle( deps ) )
if ( hasDependencyCycle( deps ) )
return false;

mDataDependencies = deps;
mDependencies = deps;
emit dependenciesChanged();
return true;
}

bool QgsMapLayer::setDataDependencies( const QSet<QgsMapLayerDependency>& layers )
{
QSet<QString> deps;
Q_FOREACH ( const QgsMapLayerDependency& dep, layers )
{
if ( dep.origin() == QgsMapLayerDependency::FromUser && dep.type() == QgsMapLayerDependency::DataDependency )
deps << dep.layerId();
}
return setDataDependencies( deps );
}
28 changes: 13 additions & 15 deletions src/core/qgsmaplayer.h
Expand Up @@ -700,28 +700,21 @@ class CORE_EXPORT QgsMapLayer : public QObject
void emitStyleChanged();

/**
* Sets the list of layers that may modify data/geometries of this layer when modified.
* @see dependencies()
*
* @param layersIds IDs of the layers that this layer depends on
* @returns false if a dependency cycle has been detected (the change dependency set is not changed in that case)
*/
virtual bool setDataDependencies( const QSet<QString>& layersIds );

/**
* Sets the list of layers that may modify data/geometries of this layer when modified.
* Sets the list of dependencies.
* @see dependencies()
*
* @param layers set of QgsMapLayerDependency. Only user-defined dependencies will be added
* @returns false if a dependency cycle has been detected (the change dependency set is not changed in that case)
* @returns false if a dependency cycle has been detected
* @note added in QGIS 3.0
*/
bool setDataDependencies( const QSet<QgsMapLayerDependency>& layers );
virtual bool setDependencies( const QSet<QgsMapLayerDependency>& layers );

/**
* Gets the list of dependencies. This includes data dependencies set by the user (@see setDataDependencies)
* as well as dependencies given by the provider
*
* @returns a set of QgsMapLayerDependency
* @note added in QGIS 3.0
*/
virtual QSet<QgsMapLayerDependency> dependencies() const;

Expand Down Expand Up @@ -779,6 +772,11 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
void configChanged();

/**
* Emitted when dependencies are changed.
*/
void dependenciesChanged();

protected:
/** Set the extent */
virtual void setExtent( const QgsRectangle &rect );
Expand Down Expand Up @@ -864,10 +862,10 @@ class CORE_EXPORT QgsMapLayer : public QObject
QgsError mError;

//! List of layers that may modify this layer on modification
QSet<QgsMapLayerDependency> mDataDependencies;
QSet<QgsMapLayerDependency> mDependencies;

//! Checks whether a new set of data dependencies will introduce a cycle
bool hasDataDependencyCycle( const QSet<QgsMapLayerDependency>& layers ) const;
//! Checks whether a new set of dependencies will introduce a cycle
bool hasDependencyCycle( const QSet<QgsMapLayerDependency>& layers ) const;

private:
/**
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsproject.cpp
Expand Up @@ -893,7 +893,7 @@ bool QgsProject::read()
QMap<QString, QgsMapLayer*> existingMaps = QgsMapLayerRegistry::instance()->mapLayers();
for ( QMap<QString, QgsMapLayer*>::iterator it = existingMaps.begin(); it != existingMaps.end(); it++ )
{
it.value()->setDataDependencies( it.value()->dependencies() );
it.value()->setDependencies( it.value()->dependencies() );
}

// read the project: used by map canvas and legend
Expand Down Expand Up @@ -1001,7 +1001,7 @@ void QgsProject::onMapLayersAdded( const QList<QgsMapLayer*>& layers )
if ( deps.contains( layer->id() ) )
{
// reconnect to change signals
it.value()->setDataDependencies( deps );
it.value()->setDependencies( deps );
}
}
}
Expand Down
29 changes: 15 additions & 14 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -1458,14 +1458,14 @@ bool QgsVectorLayer::readXml( const QDomNode& layer_node )

QDomNode depsNode = layer_node.namedItem( "dataDependencies" );
QDomNodeList depsNodes = depsNode.childNodes();
QSet<QString> sources;
QSet<QgsMapLayerDependency> sources;
for ( int i = 0; i < depsNodes.count(); i++ )
{
QDomNode node = depsNodes.at( i );
QString source = depsNodes.at( i ).toElement().attribute( "id" );
sources << source;
sources << QgsMapLayerDependency( source );
}
setDataDependencies( sources );
setDependencies( sources );

setLegend( QgsMapLayerLegend::defaultVectorLegend( this ) );

Expand Down Expand Up @@ -4092,25 +4092,25 @@ QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFl
QSet<QgsMapLayerDependency> QgsVectorLayer::dependencies() const
{
if ( mDataProvider )
return mDataProvider->dependencies() + mDataDependencies;
return mDataDependencies;
return mDataProvider->dependencies() + mDependencies;
return mDependencies;
}

bool QgsVectorLayer::setDataDependencies( const QSet<QString>& layersIds )
bool QgsVectorLayer::setDependencies( const QSet<QgsMapLayerDependency>& oDeps )
{
QSet<QgsMapLayerDependency> deps;
Q_FOREACH ( QString layerId, layersIds )
Q_FOREACH ( const QgsMapLayerDependency& dep, oDeps )
{
deps << QgsMapLayerDependency( layerId );
if ( dep.origin() == QgsMapLayerDependency::FromUser )
deps << dep;
}

if ( hasDataDependencyCycle( deps ) )
if ( hasDependencyCycle( deps ) )
return false;

QSet<QgsMapLayerDependency> toAdd = deps - dependencies();

// disconnect layers that are not present in the list of dependencies anymore
Q_FOREACH ( const QgsMapLayerDependency& dep, mDataDependencies )
Q_FOREACH ( const QgsMapLayerDependency& dep, mDependencies )
{
QgsVectorLayer* lyr = static_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( dep.layerId() ) );
if ( lyr == nullptr )
Expand All @@ -4123,12 +4123,13 @@ bool QgsVectorLayer::setDataDependencies( const QSet<QString>& layersIds )

// assign new dependencies
if ( mDataProvider )
mDataDependencies = mDataProvider->dependencies() + deps;
mDependencies = mDataProvider->dependencies() + deps;
else
mDataDependencies = deps;
mDependencies = deps;
emit dependenciesChanged();

// connect to new layers
Q_FOREACH ( const QgsMapLayerDependency& dep, mDataDependencies )
Q_FOREACH ( const QgsMapLayerDependency& dep, mDependencies )
{
QgsVectorLayer* lyr = static_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( dep.layerId() ) );
if ( lyr == nullptr )
Expand Down
14 changes: 7 additions & 7 deletions src/core/qgsvectorlayer.h
Expand Up @@ -515,21 +515,21 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
const QList<QgsVectorJoinInfo> vectorJoins() const;

/**
* Sets the list of layers that may modify data/geometries of this layer when modified.
* This is meant mainly to declare database triggers between layers.
* When one of these layers is modified (feature added/deleted or geometry changed),
* dataChanged() will be emitted, allowing users of this layer to refresh / update it.
* Sets the list of dependencies.
* @see dependencies()
*
* @param layersIds IDs of the layers that this layer depends on
* @returns false if a dependency cycle has been detected (the change dependency set is not changed in that case)
* @param layers set of QgsMapLayerDependency. Only user-defined dependencies will be added
* @returns false if a dependency cycle has been detected
* @note added in QGIS 3.0
*/
bool setDataDependencies( const QSet<QString>& layersIds ) override;
virtual bool setDependencies( const QSet<QgsMapLayerDependency>& layers ) override;

/**
* Gets the list of dependencies. This includes data dependencies set by the user (@see setDataDependencies)
* as well as dependencies given by the provider
*
* @returns a set of QgsMapLayerDependency
* @note added in QGIS 3.0
*/
virtual QSet<QgsMapLayerDependency> dependencies() const override;

Expand Down

0 comments on commit a86611b

Please sign in to comment.