Skip to content

Commit c6ffd54

Browse files
committedJun 30, 2017
Joined fields are updated according to the target field name in form
1 parent 73bb463 commit c6ffd54

8 files changed

+143
-0
lines changed
 

‎python/core/qgsvectorlayerjoinbuffer.sip

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,24 @@ Quick way to test if there is any join at all
9999
:rtype: list of int
100100
%End
101101

102+
QList<const QgsVectorLayerJoinInfo *> joinsWhereFieldIsId( const QgsField &field ) const;
103+
%Docstring
104+
Returns joins where the field of a target layer is considered as an id.
105+
\param field the field of a target layer
106+
:return: a list of vector joins
107+
.. versionadded:: 3.0
108+
:rtype: list of const QgsVectorLayerJoinInfo
109+
%End
110+
111+
QgsFeature joinedFeatureOf( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const;
112+
%Docstring
113+
Returns the joined feature corresponding to the feature.
114+
\param info the vector join information
115+
\param feature the feature of the target layer
116+
.. versionadded:: 3.0
117+
:rtype: QgsFeature
118+
%End
119+
102120
QgsVectorLayerJoinBuffer *clone() const /Factory/;
103121
%Docstring
104122
.. versionadded:: 2.6

‎python/core/qgsvectorlayerjoininfo.sip

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ Returns whether values from the joined layer should be cached in memory to speed
9999
.. versionadded:: 3.0
100100
%End
101101

102+
QString prefixedFieldName( const QgsField &field ) const;
103+
%Docstring
104+
Returns the prefixed name of the field.
105+
\param field the field
106+
:return: the prefixed name of the field
107+
.. versionadded:: 3.0
108+
:rtype: str
109+
%End
110+
102111
bool operator==( const QgsVectorLayerJoinInfo &other ) const;
103112

104113
void setJoinFieldNamesSubset( QStringList *fieldNamesSubset /Transfer/ );

‎src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ SET(QGIS_CORE_SRCS
286286
qgsvectorlayerfeatureiterator.cpp
287287
qgsvectorlayerexporter.cpp
288288
qgsvectorlayerjoinbuffer.cpp
289+
qgsvectorlayerjoininfo.cpp
289290
qgsvectorlayerlabeling.cpp
290291
qgsvectorlayerlabelprovider.cpp
291292
qgsvectorlayerrenderer.cpp

‎src/core/qgsvectorlayerjoinbuffer.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,44 @@ const QgsVectorLayerJoinInfo *QgsVectorLayerJoinBuffer::joinForFieldIndex( int i
394394
return &( mVectorJoins[sourceJoinIndex] );
395395
}
396396

397+
QList<const QgsVectorLayerJoinInfo *> QgsVectorLayerJoinBuffer::joinsWhereFieldIsId( const QgsField &field ) const
398+
{
399+
QList<const QgsVectorLayerJoinInfo *> infos;
400+
401+
for ( int i = 0; i < mVectorJoins.count(); i++ )
402+
{
403+
const QgsVectorLayerJoinInfo *info = &( mVectorJoins[i] );
404+
405+
if ( infos.contains( info ) )
406+
continue;
407+
408+
if ( info->targetFieldName() == field.name() )
409+
infos.append( info );
410+
}
411+
412+
return infos;
413+
}
414+
415+
QgsFeature QgsVectorLayerJoinBuffer::joinedFeatureOf( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const
416+
{
417+
QgsFeature joinedFeature;
418+
419+
if ( info.joinLayer() )
420+
{
421+
const QVariant targetValue = feature.attribute( info.targetFieldName() );
422+
const QString filter = QString( "\"%1\" = %2" ).arg( info.joinFieldName(), targetValue.toString() );
423+
424+
QgsFeatureRequest request;
425+
request.setFilterExpression( filter );
426+
request.setLimit( 1 );
427+
428+
QgsFeatureIterator it = info.joinLayer()->getFeatures( request );
429+
it.nextFeature( joinedFeature );
430+
}
431+
432+
return joinedFeature;
433+
}
434+
397435
QgsVectorLayerJoinBuffer *QgsVectorLayerJoinBuffer::clone() const
398436
{
399437
QgsVectorLayerJoinBuffer *cloned = new QgsVectorLayerJoinBuffer( mLayer );

‎src/core/qgsvectorlayerjoinbuffer.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,20 @@ class CORE_EXPORT QgsVectorLayerJoinBuffer : public QObject
8484
//! \since QGIS 2.6
8585
static QVector<int> joinSubsetIndices( QgsVectorLayer *joinLayer, const QStringList &joinFieldsSubset );
8686

87+
/** Returns joins where the field of a target layer is considered as an id.
88+
* \param field the field of a target layer
89+
* \returns a list of vector joins
90+
* \since QGIS3.0
91+
*/
92+
QList<const QgsVectorLayerJoinInfo *> joinsWhereFieldIsId( const QgsField &field ) const;
93+
94+
/** Returns the joined feature corresponding to the feature.
95+
* \param info the vector join information
96+
* \param feature the feature of the target layer
97+
* \since QGIS 3.0
98+
*/
99+
QgsFeature joinedFeatureOf( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const;
100+
87101
//! Create a copy of the join buffer
88102
//! \since QGIS 2.6
89103
QgsVectorLayerJoinBuffer *clone() const SIP_FACTORY;

‎src/core/qgsvectorlayerjoininfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ class CORE_EXPORT QgsVectorLayerJoinInfo
6666
*/
6767
void setDynamicFormEnabled( bool enabled ) { mDynamicForm = enabled; }
6868

69+
/** Returns the prefixed name of the field.
70+
* \param field the field
71+
* \returns the prefixed name of the field
72+
* \since QGIS 3.0
73+
*/
74+
QString prefixedFieldName( const QgsField &field ) const;
75+
6976
bool operator==( const QgsVectorLayerJoinInfo &other ) const
7077
{
7178
return mTargetFieldName == other.mTargetFieldName &&

‎src/gui/qgsattributeform.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include "qgssettings.h"
3434
#include "qgsscrollarea.h"
3535
#include "qgsgui.h"
36+
#include "qgsvectorlayerjoinbuffer.h"
37+
#include "qgsvectorlayerutils.h"
3638

3739
#include <QDir>
3840
#include <QTextStream>
@@ -659,6 +661,9 @@ void QgsAttributeForm::onAttributeChanged( const QVariant &value )
659661
{
660662
emit attributeChanged( eww->field().name(), value );
661663
}
664+
665+
updateJoinedFields( *eww );
666+
662667
break;
663668
}
664669
case MultiEditMode:
@@ -1930,3 +1935,50 @@ void QgsAttributeForm::ContainerInformation::apply( QgsExpressionContext *expres
19301935
isVisible = newVisibility;
19311936
}
19321937
}
1938+
1939+
QgsFeature QgsAttributeForm::joinedFeature( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const
1940+
{
1941+
QgsFeature joinedFeature = mLayer->joinBuffer()->joinedFeatureOf( info, feature );
1942+
1943+
if ( !joinedFeature.isValid() )
1944+
joinedFeature = QgsVectorLayerUtils::createFeature( info.joinLayer(), QgsGeometry(), QgsAttributeMap() );
1945+
1946+
return joinedFeature;
1947+
}
1948+
1949+
void QgsAttributeForm::updateJoinedFields( const QgsEditorWidgetWrapper &eww )
1950+
{
1951+
QgsFeature formFeature;
1952+
QgsField field = eww.layer()->fields().field( eww.fieldIdx() );
1953+
QList<const QgsVectorLayerJoinInfo *> infos = eww.layer()->joinBuffer()->joinsWhereFieldIsId( field );
1954+
1955+
if ( infos.count() == 0 || !currentFormFeature( formFeature ) )
1956+
return;
1957+
1958+
Q_FOREACH ( const QgsVectorLayerJoinInfo *info, infos )
1959+
{
1960+
if ( !info->isDynamicFormEnabled() )
1961+
continue;
1962+
1963+
QgsFeature joinFeature = joinedFeature( *info, formFeature );
1964+
1965+
QStringList *subsetFields = info->joinFieldNamesSubset();
1966+
if ( subsetFields )
1967+
{
1968+
Q_FOREACH ( const QString &field, *subsetFields )
1969+
{
1970+
QString prefixedName = info->prefixedFieldName( field );
1971+
changeAttribute( prefixedName, joinFeature.attribute( field ) );
1972+
}
1973+
}
1974+
else
1975+
{
1976+
for ( int i = 0; i < joinFeature.fields().count(); i++ )
1977+
{
1978+
QgsField field = joinFeature.fields().field( i );
1979+
QString prefixedName = info->prefixedFieldName( field );
1980+
changeAttribute( prefixedName, joinFeature.attribute( field.name() ) );
1981+
}
1982+
}
1983+
}
1984+
}

‎src/gui/qgsattributeform.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
273273

274274
void initPython();
275275

276+
QgsFeature joinedFeature( const QgsVectorLayerJoinInfo &info, const QgsFeature &feature ) const;
277+
278+
void updateJoinedFields( const QgsEditorWidgetWrapper &eww );
279+
276280
struct WidgetInfo
277281
{
278282
WidgetInfo()

0 commit comments

Comments
 (0)
Please sign in to comment.