Skip to content

Commit

Permalink
Merge pull request #33436 from signedav/relating_values
Browse files Browse the repository at this point in the history
List referenced layer values in Expression Builder
  • Loading branch information
m-kuhn committed Dec 20, 2019
2 parents d211de2 + ea912a1 commit 2a01772
Show file tree
Hide file tree
Showing 17 changed files with 362 additions and 27 deletions.
Expand Up @@ -40,6 +40,9 @@ Default constructor of field formatter for a relation reference field.



virtual QVariantList availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const;



};

Expand Down
Expand Up @@ -46,6 +46,9 @@ Default constructor of field formatter for a value map field.

virtual QVariant sortValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const;


virtual QVariantList availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const;

};

/************************************************************************
Expand Down
Expand Up @@ -128,6 +128,9 @@ Returns the (possibly NULL) layer from the widget's ``config`` and ``project``
.. versionadded:: 3.8
%End


virtual QVariantList availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const;

};


Expand Down
65 changes: 64 additions & 1 deletion python/core/auto_generated/qgsfieldformatter.sip.in
Expand Up @@ -9,6 +9,40 @@



class QgsFieldFormatterContext
{
%Docstring
A context for field formatter containing information like the project

.. versionadded:: 3.12
%End

%TypeHeaderCode
#include "qgsfieldformatter.h"
%End
public:

QgsFieldFormatterContext();
%Docstring
Constructor
%End

QgsProject *project() const;
%Docstring
Returns the project used in field formatter

.. seealso:: :py:func:`setProject`
%End

void setProject( QgsProject *project );
%Docstring
Sets the ``project`` used in field formatter

.. seealso:: :py:func:`project`
%End

};

class QgsFieldFormatter
{
%Docstring
Expand All @@ -17,7 +51,7 @@ A field formatter helps to handle and display values for a field.
It allows for using a shared configuration with the editor widgets
for representation of attribute values.
Field kits normally have one single instance which is managed by the
QgsFieldFormatterRegistry. Custom field formatters should be registered there and
:py:class:`QgsFieldFormatterRegistry`. Custom field formatters should be registered there and
field formatters for use within code should normally be obtained from there.

This is an abstract base class and will always need to be subclassed.
Expand All @@ -37,6 +71,13 @@ Default constructor

virtual ~QgsFieldFormatter();

enum Flag
{
CanProvideAvailableValues
};
typedef QFlags<QgsFieldFormatter::Flag> Flags;


virtual QString id() const = 0;
%Docstring
Returns a unique id for this field formatter.
Expand Down Expand Up @@ -87,6 +128,28 @@ make use of a cache if present.
%End


virtual QVariantList availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const;
%Docstring
Returns a list of the values that would be possible to select with this widget type
On a RelationReference that would be the parents ids or on ValueMap all the configured keys
according to the settings in the ``config``

.. versionadded:: 3.12
%End

Flags flags() const;
%Docstring
Returns the flags

.. versionadded:: 3.12
%End

void setFlags( const Flags &flags );
%Docstring
Sets the ``flags``

.. versionadded:: 3.12
%End

};

Expand Down
26 changes: 24 additions & 2 deletions python/gui/auto_generated/qgsexpressionbuilderwidget.sip.in
Expand Up @@ -323,12 +323,34 @@ with the context.

void loadSampleValues();
%Docstring
Load sample values into the sample value area
Load sample values into the sample value area.
Including available values, in case the formatter can
provide them (eg. RelationReference).
%End

void loadAllValues();
%Docstring
Load all unique values from the set layer into the sample area
Load all unique values from the set layer into the sample area.
Including all available values, in case the formatter can
provide them (eg. RelationReference).
%End

void loadSampleUsedValues();
%Docstring
Load used sample values into the sample value area.
Only the used ones. Without available values, even if the
formatter can provide them (eg. RelationReference).

.. versionadded:: 3.12
%End

void loadAllUsedValues();
%Docstring
Load all unique values from the set layer into the sample area.
Only the used ones. Without available values, even if the
formatter can provide them (eg. RelationReference).

.. versionadded:: 3.12
%End

void autosave();
Expand Down
20 changes: 20 additions & 0 deletions src/core/fieldformatter/qgsrelationreferencefieldformatter.cpp
Expand Up @@ -23,6 +23,11 @@
#include "qgsvectorlayer.h"
#include "qgsexpressioncontextutils.h"

QgsRelationReferenceFieldFormatter::QgsRelationReferenceFieldFormatter()
{
setFlags( flags() | QgsFieldFormatter::CanProvideAvailableValues );
}

QString QgsRelationReferenceFieldFormatter::id() const
{
return QStringLiteral( "RelationReference" );
Expand Down Expand Up @@ -181,3 +186,18 @@ QList<QgsVectorLayerRef> QgsRelationReferenceFieldFormatter::layerDependencies(
}};
return result;
}

QVariantList QgsRelationReferenceFieldFormatter::availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const
{
QVariantList values;
if ( context.project() )
{
const QgsVectorLayer *referencedLayer = context.project()->relationManager()->relation( config[QStringLiteral( "Relation" )].toString() ).referencedLayer();
if ( referencedLayer )
{
int fieldIndex = context.project()->relationManager()->relation( config[QStringLiteral( "Relation" )].toString() ).referencedFields().first();
values = referencedLayer->uniqueValues( fieldIndex, countLimit ).toList();
}
}
return values;
}
4 changes: 3 additions & 1 deletion src/core/fieldformatter/qgsrelationreferencefieldformatter.h
Expand Up @@ -34,7 +34,7 @@ class CORE_EXPORT QgsRelationReferenceFieldFormatter : public QgsFieldFormatter
/**
* Default constructor of field formatter for a relation reference field.
*/
QgsRelationReferenceFieldFormatter() = default;
QgsRelationReferenceFieldFormatter();

QString id() const override;

Expand All @@ -46,6 +46,8 @@ class CORE_EXPORT QgsRelationReferenceFieldFormatter : public QgsFieldFormatter

QList<QgsVectorLayerRef> layerDependencies( const QVariantMap &config ) const override SIP_SKIP;

QVariantList availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const override;

//friend class TestQgsRelationReferenceFieldFormatter;

};
Expand Down
21 changes: 21 additions & 0 deletions src/core/fieldformatter/qgsvaluemapfieldformatter.cpp
Expand Up @@ -19,6 +19,11 @@

const QString QgsValueMapFieldFormatter::NULL_VALUE = QStringLiteral( "{2839923C-8B7D-419E-B84B-CA2FE9B80EC7}" );

QgsValueMapFieldFormatter::QgsValueMapFieldFormatter()
{
setFlags( flags() | QgsFieldFormatter::CanProvideAvailableValues );
}

QString QgsValueMapFieldFormatter::id() const
{
return QStringLiteral( "ValueMap" );
Expand Down Expand Up @@ -62,3 +67,19 @@ QVariant QgsValueMapFieldFormatter::sortValue( QgsVectorLayer *layer, int fieldI
{
return representValue( layer, fieldIndex, config, cache, value );
}

QVariantList QgsValueMapFieldFormatter::availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const
{
Q_UNUSED( context )

QVariantList values;
const QList<QVariant> valueList = config.value( QStringLiteral( "map" ) ).toList();
for ( const QVariant &item : valueList )
{
values.append( item.toMap().constBegin().value() );
if ( values.count() == countLimit )
break;
}

return values;
}
4 changes: 3 additions & 1 deletion src/core/fieldformatter/qgsvaluemapfieldformatter.h
Expand Up @@ -49,13 +49,15 @@ class CORE_EXPORT QgsValueMapFieldFormatter : public QgsFieldFormatter
/**
* Default constructor of field formatter for a value map field.
*/
QgsValueMapFieldFormatter() = default;
QgsValueMapFieldFormatter();

QString id() const override;

QString representValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const override;

QVariant sortValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const override;

QVariantList availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const override;
};

#endif // QGSVALUEMAPFIELDKIT_H
21 changes: 21 additions & 0 deletions src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp
Expand Up @@ -40,6 +40,11 @@ bool orderByValueLessThan( const QgsValueRelationFieldFormatter::ValueRelationIt
return qgsVariantLessThan( p1.value, p2.value );
}

QgsValueRelationFieldFormatter::QgsValueRelationFieldFormatter()
{
setFlags( flags() | QgsFieldFormatter::CanProvideAvailableValues );
}

QString QgsValueRelationFieldFormatter::id() const
{
return QStringLiteral( "ValueRelation" );
Expand Down Expand Up @@ -183,6 +188,22 @@ QList<QgsVectorLayerRef> QgsValueRelationFieldFormatter::layerDependencies( cons
return result;
}

QVariantList QgsValueRelationFieldFormatter::availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const
{
QVariantList values;

if ( context.project() )
{
const QgsVectorLayer *referencedLayer = qobject_cast<QgsVectorLayer *>( context.project()->mapLayer( config[QStringLiteral( "Layer" )].toString() ) );
if ( referencedLayer )
{
int fieldIndex = referencedLayer->fields().indexOf( config.value( QStringLiteral( "Key" ) ).toString() );
values = referencedLayer->uniqueValues( fieldIndex, countLimit ).toList();
}
}
return values;
}

QStringList QgsValueRelationFieldFormatter::valueToStringList( const QVariant &value )
{
QStringList checkList;
Expand Down
4 changes: 3 additions & 1 deletion src/core/fieldformatter/qgsvaluerelationfieldformatter.h
Expand Up @@ -56,7 +56,7 @@ class CORE_EXPORT QgsValueRelationFieldFormatter : public QgsFieldFormatter
/**
* Constructor for QgsValueRelationFieldFormatter.
*/
QgsValueRelationFieldFormatter() = default;
QgsValueRelationFieldFormatter();

QString id() const override;
QString representValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const override;
Expand Down Expand Up @@ -126,6 +126,8 @@ class CORE_EXPORT QgsValueRelationFieldFormatter : public QgsFieldFormatter
static QgsVectorLayer *resolveLayer( const QVariantMap &config, const QgsProject *project );

QList<QgsVectorLayerRef> layerDependencies( const QVariantMap &config ) const override SIP_SKIP;

QVariantList availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const override;
};

Q_DECLARE_METATYPE( QgsValueRelationFieldFormatter::ValueRelationCache )
Expand Down
14 changes: 14 additions & 0 deletions src/core/qgsfieldformatter.cpp
Expand Up @@ -68,3 +68,17 @@ QList<QgsVectorLayerRef> QgsFieldFormatter::layerDependencies( const QVariantMap
Q_UNUSED( config )
return QList<QgsVectorLayerRef>();
}

QVariantList QgsFieldFormatter::availableValues( const QVariantMap &config, int countLimit, const QgsFieldFormatterContext &context ) const
{
Q_UNUSED( config )
Q_UNUSED( countLimit )
Q_UNUSED( context )

return QVariantList();
}

void QgsFieldFormatter::setFlags( const Flags &flags )
{
mFlags = flags;
}

0 comments on commit 2a01772

Please sign in to comment.