Skip to content

Commit

Permalink
Add layer resolver
Browse files Browse the repository at this point in the history
For reasons, layer ids configured in value relations do not always match.
In these cases QGIS resorts to advanced detection techniques to find the
layer anyway.
Let's do the same with a nice declarative approach.
  • Loading branch information
m-kuhn committed Jan 10, 2021
1 parent db8bbc2 commit 382e7b4
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ SET(QFIELD_CORE_SRCS
identifytool.cpp
layertreemapcanvasbridge.cpp
layertreemodel.cpp
layerresolver.cpp
legendimageprovider.cpp
linepolygonhighlight.cpp
locatormodelsuperbridge.cpp
Expand Down Expand Up @@ -94,6 +95,7 @@ SET(QFIELD_CORE_HDRS
identifytool.h
layertreemapcanvasbridge.h
layertreemodel.h
layerresolver.h
legendimageprovider.h
linepolygonhighlight.h
locatormodelsuperbridge.h
Expand Down
111 changes: 111 additions & 0 deletions src/core/layerresolver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include "layerresolver.h"
#include <qgsvectorlayerref.h>

LayerResolver::LayerResolver( QObject *parent )
: QObject( parent )
{

}

void LayerResolver::resolve()
{
if ( !mProject )
{
setLayer( nullptr );
return;
}

QgsVectorLayerRef ref { mLayerId,
mLayerName,
mLayerSource,
mLayerProviderName };
setLayer( ref.resolveByIdOrNameOnly( mProject ) );
}

QString LayerResolver::layerId() const
{
return mLayerId;
}

void LayerResolver::setLayerId( const QString &layerId )
{
if ( mLayerId == layerId )
return;

mLayerId = layerId;
resolve();
emit layerIdChanged();
}

QString LayerResolver::layerName() const
{
return mLayerName;
}

void LayerResolver::setLayerName( const QString &layerName )
{
if ( mLayerName == layerName )
return;

mLayerName = layerName;
resolve();
emit layerNameChanged();
}

QString LayerResolver::layerSource() const
{
return mLayerSource;
}

void LayerResolver::setLayerSource( const QString &layerSource )
{
if ( mLayerSource == layerSource )
return;

mLayerSource = layerSource;
emit layerSourceChanged();
}

QString LayerResolver::layerProviderName() const
{
return mLayerProviderName;
}

void LayerResolver::setLayerProviderName( const QString &layerProviderName )
{
if ( mLayerProviderName == layerProviderName )
return;

mLayerProviderName = layerProviderName;
resolve();
emit layerProviderNameChanged();
}

QgsVectorLayer *LayerResolver::currentLayer() const
{
return mLayer;
}

void LayerResolver::setLayer( QgsVectorLayer *layer )
{
if ( mLayer == layer )
return;

mLayer = layer;
emit currentLayerChanged();
}

QgsProject *LayerResolver::project() const
{
return mProject;
}

void LayerResolver::setProject( QgsProject *project )
{
if ( project == mProject )
return;

mProject = project;
resolve();
emit projectChanged();
}
87 changes: 87 additions & 0 deletions src/core/layerresolver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#ifndef LAYERRESOLVER_H
#define LAYERRESOLVER_H

#include <QObject>

class QgsVectorLayer;
class QgsProject;

/**
* Helper class to resolve layers by id, name, source and provider.
*/
class LayerResolver : public QObject
{
Q_OBJECT

/**
* The layer id to resolve
*/
Q_PROPERTY( QString layerId READ layerId WRITE setLayerId NOTIFY layerIdChanged )

/**
* The layer name to resolve
*/
Q_PROPERTY( QString layerName READ layerName WRITE setLayerName NOTIFY layerNameChanged )

/**
* The layer source to resolve
*/
Q_PROPERTY( QString layerSource READ layerSource WRITE setLayerSource NOTIFY layerSourceChanged )

/**
* The layer provider name to resolve
*/
Q_PROPERTY( QString layerProviderName READ layerProviderName WRITE setLayerProviderName NOTIFY layerProviderNameChanged )

/**
* The qgis project from which layers will be acquired
*/
Q_PROPERTY( QgsProject *project READ project WRITE setProject NOTIFY projectChanged )

/**
* Contains the layer after a successful resolving process
*/
Q_PROPERTY( QgsVectorLayer *currentLayer READ currentLayer NOTIFY currentLayerChanged )

public:
LayerResolver( QObject *parent = nullptr );

void resolve();

QString layerId() const;
void setLayerId( const QString &layerId );

QString layerName() const;
void setLayerName( const QString &layerName );

QString layerSource() const;
void setLayerSource( const QString &layerSource );

QString layerProviderName() const;
void setLayerProviderName( const QString &layerProviderName );

QgsVectorLayer *currentLayer() const;

QgsProject *project() const;
void setProject( QgsProject *project );

signals:
void layerIdChanged();
void layerNameChanged();
void layerSourceChanged();
void layerProviderNameChanged();
void currentLayerChanged();
void projectChanged();

private:
void setLayer( QgsVectorLayer *layer );

QString mLayerId;
QString mLayerName;
QString mLayerSource;
QString mLayerProviderName;
QgsProject *mProject = nullptr;
QgsVectorLayer *mLayer = nullptr;
};

#endif // LAYERRESOLVER_H
2 changes: 2 additions & 0 deletions src/core/qgismobileapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
#include "bluetoothdevicemodel.h"
#include "gnsspositioninformation.h"
#include "changelogcontents.h"
#include "layerresolver.h"

#define QUOTE(string) _QUOTE(string)
#define _QUOTE(string) #string
Expand Down Expand Up @@ -345,6 +346,7 @@ void QgisMobileapp::initDeclarative()
qmlRegisterType<BluetoothDeviceModel>( "org.qfield", 1, 0, "BluetoothDeviceModel" );
qmlRegisterType<BluetoothReceiver>( "org.qfield", 1, 0, "BluetoothReceiver" );
qmlRegisterType<ChangelogContents>( "org.qfield", 1, 0, "ChangelogContents" );
qmlRegisterType<LayerResolver>( "org.qfield", 1, 0, "LayerResolver" );

qRegisterMetaType<GnssPositionInformation>( "GnssPositionInformation" );

Expand Down
14 changes: 12 additions & 2 deletions src/qml/editorwidgets/ValueRelation.qml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ Item {
height: Number(config['AllowMulti']) !== 1 ? valueRelationCombobox.height : valueRelationList.height
enabled: true

LayerResolver {
id: layerResolver

layerId: config['Layer']
layerName: config['LayerName']
layerSource: config['LayerSource']
layerProviderName: config['LayerProviderName']
project: qgisProject
}

RelationCombobox {
id: valueRelationCombobox

Expand All @@ -32,7 +42,7 @@ Item {
attributeField: field
//passing "" instead of undefined, so the model is cleared on adding new features
attributeValue: value !== undefined ? value : ""
currentLayer: qgisProject.mapLayer(config['Layer'])
currentLayer: layerResolver.currentLayer
currentFormFeature: currentFeature
keyField: config['Key']
displayValueField: config['Value']
Expand Down Expand Up @@ -65,7 +75,7 @@ Item {
attributeField: field
//passing "" instead of undefined, so the model is cleared on adding new features
attributeValue: value !== undefined ? value : ""
currentLayer: qgisProject.mapLayer(config['Layer'])
currentLayer: layerResolver.currentLayer
currentFormFeature: currentFeature
keyField: config['Key']
displayValueField: config['Value']
Expand Down

0 comments on commit 382e7b4

Please sign in to comment.