Joined fields are updated according to the target field name in form

This commit is contained in:
Blottiere Paul 2017-06-30 06:46:22 +01:00
parent 73bb463c05
commit c6ffd54170
8 changed files with 143 additions and 0 deletions

View File

@ -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

View File

@ -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/ );

View File

@ -286,6 +286,7 @@ SET(QGIS_CORE_SRCS
qgsvectorlayerfeatureiterator.cpp
qgsvectorlayerexporter.cpp
qgsvectorlayerjoinbuffer.cpp
qgsvectorlayerjoininfo.cpp
qgsvectorlayerlabeling.cpp
qgsvectorlayerlabelprovider.cpp
qgsvectorlayerrenderer.cpp

View File

@ -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 );

View File

@ -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;

View File

@ -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 &&

View File

@ -33,6 +33,8 @@
#include "qgssettings.h"
#include "qgsscrollarea.h"
#include "qgsgui.h"
#include "qgsvectorlayerjoinbuffer.h"
#include "qgsvectorlayerutils.h"
#include <QDir>
#include <QTextStream>
@ -659,6 +661,9 @@ void QgsAttributeForm::onAttributeChanged( const QVariant &value )
{
emit attributeChanged( eww->field().name(), value );
}
updateJoinedFields( *eww );
break;
}
case MultiEditMode:
@ -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() ) );
}
}
}
}

View File

@ -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()