Skip to content

Commit

Permalink
Joined fields are updated according to the target field name in form
Browse files Browse the repository at this point in the history
  • Loading branch information
pblottiere committed Jun 30, 2017
1 parent 73bb463 commit c6ffd54
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 0 deletions.
18 changes: 18 additions & 0 deletions python/core/qgsvectorlayerjoinbuffer.sip
Expand Up @@ -99,6 +99,24 @@ Quick way to test if there is any join at all
:rtype: list of int
%End

QList<const QgsVectorLayerJoinInfo *> joinsWhereFieldIsId( const QgsField &field ) const;
%Docstring
Returns joins where the field of a target layer is considered as an id.
\param field the field of a target layer
:return: a list of vector joins
.. versionadded:: 3.0
:rtype: list of const QgsVectorLayerJoinInfo
%End

QgsFeature joinedFeatureOf( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const;
%Docstring
Returns the joined feature corresponding to the feature.
\param info the vector join information
\param feature the feature of the target layer
.. versionadded:: 3.0
:rtype: QgsFeature
%End

QgsVectorLayerJoinBuffer *clone() const /Factory/;
%Docstring
.. versionadded:: 2.6
Expand Down
9 changes: 9 additions & 0 deletions python/core/qgsvectorlayerjoininfo.sip
Expand Up @@ -99,6 +99,15 @@ Returns whether values from the joined layer should be cached in memory to speed
.. versionadded:: 3.0
%End

QString prefixedFieldName( const QgsField &field ) const;
%Docstring
Returns the prefixed name of the field.
\param field the field
:return: the prefixed name of the field
.. versionadded:: 3.0
:rtype: str
%End

bool operator==( const QgsVectorLayerJoinInfo &other ) const;

void setJoinFieldNamesSubset( QStringList *fieldNamesSubset /Transfer/ );
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -286,6 +286,7 @@ SET(QGIS_CORE_SRCS
qgsvectorlayerfeatureiterator.cpp
qgsvectorlayerexporter.cpp
qgsvectorlayerjoinbuffer.cpp
qgsvectorlayerjoininfo.cpp
qgsvectorlayerlabeling.cpp
qgsvectorlayerlabelprovider.cpp
qgsvectorlayerrenderer.cpp
Expand Down
38 changes: 38 additions & 0 deletions src/core/qgsvectorlayerjoinbuffer.cpp
Expand Up @@ -394,6 +394,44 @@ const QgsVectorLayerJoinInfo *QgsVectorLayerJoinBuffer::joinForFieldIndex( int i
return &( mVectorJoins[sourceJoinIndex] );
}

QList<const QgsVectorLayerJoinInfo *> QgsVectorLayerJoinBuffer::joinsWhereFieldIsId( const QgsField &field ) const
{
QList<const QgsVectorLayerJoinInfo *> infos;

for ( int i = 0; i < mVectorJoins.count(); i++ )
{
const QgsVectorLayerJoinInfo *info = &( mVectorJoins[i] );

if ( infos.contains( info ) )
continue;

if ( info->targetFieldName() == field.name() )
infos.append( info );
}

return infos;
}

QgsFeature QgsVectorLayerJoinBuffer::joinedFeatureOf( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const
{
QgsFeature joinedFeature;

if ( info.joinLayer() )
{
const QVariant targetValue = feature.attribute( info.targetFieldName() );
const QString filter = QString( "\"%1\" = %2" ).arg( info.joinFieldName(), targetValue.toString() );

QgsFeatureRequest request;
request.setFilterExpression( filter );
request.setLimit( 1 );

QgsFeatureIterator it = info.joinLayer()->getFeatures( request );
it.nextFeature( joinedFeature );
}

return joinedFeature;
}

QgsVectorLayerJoinBuffer *QgsVectorLayerJoinBuffer::clone() const
{
QgsVectorLayerJoinBuffer *cloned = new QgsVectorLayerJoinBuffer( mLayer );
Expand Down
14 changes: 14 additions & 0 deletions src/core/qgsvectorlayerjoinbuffer.h
Expand Up @@ -84,6 +84,20 @@ class CORE_EXPORT QgsVectorLayerJoinBuffer : public QObject
//! \since QGIS 2.6
static QVector<int> joinSubsetIndices( QgsVectorLayer *joinLayer, const QStringList &joinFieldsSubset );

/** Returns joins where the field of a target layer is considered as an id.
* \param field the field of a target layer
* \returns a list of vector joins
* \since QGIS3.0
*/
QList<const QgsVectorLayerJoinInfo *> joinsWhereFieldIsId( const QgsField &field ) const;

/** Returns the joined feature corresponding to the feature.
* \param info the vector join information
* \param feature the feature of the target layer
* \since QGIS 3.0
*/
QgsFeature joinedFeatureOf( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const;

//! Create a copy of the join buffer
//! \since QGIS 2.6
QgsVectorLayerJoinBuffer *clone() const SIP_FACTORY;
Expand Down
7 changes: 7 additions & 0 deletions src/core/qgsvectorlayerjoininfo.h
Expand Up @@ -66,6 +66,13 @@ class CORE_EXPORT QgsVectorLayerJoinInfo
*/
void setDynamicFormEnabled( bool enabled ) { mDynamicForm = enabled; }

/** Returns the prefixed name of the field.
* \param field the field
* \returns the prefixed name of the field
* \since QGIS 3.0
*/
QString prefixedFieldName( const QgsField &field ) const;

bool operator==( const QgsVectorLayerJoinInfo &other ) const
{
return mTargetFieldName == other.mTargetFieldName &&
Expand Down
52 changes: 52 additions & 0 deletions src/gui/qgsattributeform.cpp
Expand Up @@ -33,6 +33,8 @@
#include "qgssettings.h"
#include "qgsscrollarea.h"
#include "qgsgui.h"
#include "qgsvectorlayerjoinbuffer.h"
#include "qgsvectorlayerutils.h"

#include <QDir>
#include <QTextStream>
Expand Down Expand Up @@ -659,6 +661,9 @@ void QgsAttributeForm::onAttributeChanged( const QVariant &value )
{
emit attributeChanged( eww->field().name(), value );
}

updateJoinedFields( *eww );

break;
}
case MultiEditMode:
Expand Down Expand Up @@ -1930,3 +1935,50 @@ void QgsAttributeForm::ContainerInformation::apply( QgsExpressionContext *expres
isVisible = newVisibility;
}
}

QgsFeature QgsAttributeForm::joinedFeature( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const
{
QgsFeature joinedFeature = mLayer->joinBuffer()->joinedFeatureOf( info, feature );

if ( !joinedFeature.isValid() )
joinedFeature = QgsVectorLayerUtils::createFeature( info.joinLayer(), QgsGeometry(), QgsAttributeMap() );

return joinedFeature;
}

void QgsAttributeForm::updateJoinedFields( const QgsEditorWidgetWrapper &eww )
{
QgsFeature formFeature;
QgsField field = eww.layer()->fields().field( eww.fieldIdx() );
QList<const QgsVectorLayerJoinInfo *> infos = eww.layer()->joinBuffer()->joinsWhereFieldIsId( field );

if ( infos.count() == 0 || !currentFormFeature( formFeature ) )
return;

Q_FOREACH ( const QgsVectorLayerJoinInfo *info, infos )
{
if ( !info->isDynamicFormEnabled() )
continue;

QgsFeature joinFeature = joinedFeature( *info, formFeature );

QStringList *subsetFields = info->joinFieldNamesSubset();
if ( subsetFields )
{
Q_FOREACH ( const QString &field, *subsetFields )
{
QString prefixedName = info->prefixedFieldName( field );
changeAttribute( prefixedName, joinFeature.attribute( field ) );
}
}
else
{
for ( int i = 0; i < joinFeature.fields().count(); i++ )
{
QgsField field = joinFeature.fields().field( i );
QString prefixedName = info->prefixedFieldName( field );
changeAttribute( prefixedName, joinFeature.attribute( field.name() ) );
}
}
}
}
4 changes: 4 additions & 0 deletions src/gui/qgsattributeform.h
Expand Up @@ -273,6 +273,10 @@ class GUI_EXPORT QgsAttributeForm : public QWidget

void initPython();

QgsFeature joinedFeature( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const;

void updateJoinedFields( const QgsEditorWidgetWrapper &eww );

struct WidgetInfo
{
WidgetInfo()
Expand Down

0 comments on commit c6ffd54

Please sign in to comment.