Move layerDependencies to formatter

... from the widget
This commit is contained in:
Alessandro Pasotti 2019-12-13 11:54:25 +01:00
parent 929aa0ae39
commit 4ad62aa6ff
19 changed files with 70 additions and 80 deletions

View File

@ -38,6 +38,9 @@ Default constructor of field formatter for a relation reference field.
virtual QVariant createCache( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config ) const;
virtual QList<QgsVectorLayerRef> layerDependencies( const QVariantMap &config ) const;
};
/************************************************************************

View File

@ -128,7 +128,7 @@ Returns the (possibly NULL) layer from the widget's ``config`` and ``project``
.. versionadded:: 3.8
%End
virtual QList<QgsVectorLayerRef> layerDependencies( const QVariantMap &config ) const;
};

View File

@ -85,6 +85,9 @@ make use of a cache if present.
.. versionadded:: 3.0
%End
};
/************************************************************************

View File

@ -10,6 +10,7 @@
class QgsEditorWidgetWrapper : QgsWidgetWrapper
{
%Docstring
@ -187,7 +188,6 @@ of attribute values failing enforced field constraints.
.. versionadded:: 3.0
%End
QString constraintFailureReason() const;
%Docstring
Returns the reason why a constraint check has failed (or an empty string

View File

@ -1998,13 +1998,11 @@ QList<QgsVectorLayerRef> QgisApp::findBrokenWidgetDependencies( QgsVectorLayer *
// Check for missing layer widget dependencies
for ( int i = 0; i < vl->fields().count(); i++ )
{
std::unique_ptr<QgsEditorWidgetWrapper> ww;
ww.reset( QgsGui::editorWidgetRegistry()->create( vl, i, nullptr, nullptr ) );
// ww should never be null in real life, but it is in QgisApp tests because
// QgsEditorWidgetRegistry widget factories is empty
if ( ww )
const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( vl, vl->fields().field( i ).name() );
QgsFieldFormatter *fieldFormatter = QgsApplication::fieldFormatterRegistry()->fieldFormatter( setup.type() );
if ( fieldFormatter )
{
const auto constDependencies { ww->layerDependencies() };
const auto constDependencies { fieldFormatter->layerDependencies( setup.config() ) };
for ( const QgsVectorLayerRef &dependency : constDependencies )
{
const QgsVectorLayer *depVl { QgsVectorLayerRef( dependency ).resolveWeakly(

View File

@ -160,3 +160,17 @@ QVariant QgsRelationReferenceFieldFormatter::createCache( QgsVectorLayer *layer,
return QVariant::fromValue<QMap<QVariant, QString>>( cache );
}
QList<QgsVectorLayerRef> QgsRelationReferenceFieldFormatter::layerDependencies( const QVariantMap &config ) const
{
const QList<QgsVectorLayerRef> result {{
QgsVectorLayerRef(
config.value( QStringLiteral( "ReferencedLayerId" ) ).toString(),
config.value( QStringLiteral( "ReferencedLayerName" ) ).toString(),
config.value( QStringLiteral( "ReferencedLayerDataSource" ) ).toString(),
config.value( QStringLiteral( "ReferencedLayerProviderKey" ) ).toString() )
}};
return result;
}

View File

@ -43,6 +43,8 @@ class CORE_EXPORT QgsRelationReferenceFieldFormatter : public QgsFieldFormatter
QVariant sortValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const override;
QVariant createCache( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config ) const override;
QList<QgsVectorLayerRef> layerDependencies( const QVariantMap &config ) const override;
};
#endif // QGSRELATIONREFERENCEFIELDKIT_H

View File

@ -168,6 +168,21 @@ QgsValueRelationFieldFormatter::ValueRelationCache QgsValueRelationFieldFormatte
return cache;
}
QList<QgsVectorLayerRef> QgsValueRelationFieldFormatter::layerDependencies( const QVariantMap &config ) const
{
QList<QgsVectorLayerRef> result;
const QString layerId { config.value( QStringLiteral( "Layer" ) ).toString() };
const QString layerName { config.value( QStringLiteral( "LayerName" ) ).toString() };
const QString providerName { config.value( QStringLiteral( "LayerProviderName" ) ).toString() };
const QString layerSource { config.value( QStringLiteral( "LayerSource" ) ).toString() };
if ( ! layerId.isEmpty() && ! layerName.isEmpty() && ! providerName.isEmpty() && ! layerSource.isEmpty() )
{
result.append( QgsVectorLayerRef( layerId, layerName, layerSource, providerName ) );
}
return result;
}
QStringList QgsValueRelationFieldFormatter::valueToStringList( const QVariant &value )
{
QStringList checkList;
@ -291,4 +306,3 @@ QgsVectorLayer *QgsValueRelationFieldFormatter::resolveLayer( const QVariantMap
config.value( QStringLiteral( "LayerProviderName" ) ).toString() };
return ref.resolveByIdOrNameOnly( project );
}

View File

@ -125,8 +125,7 @@ class CORE_EXPORT QgsValueRelationFieldFormatter : public QgsFieldFormatter
*/
static QgsVectorLayer *resolveLayer( const QVariantMap &config, const QgsProject *project );
QList<QgsVectorLayerRef> layerDependencies( const QVariantMap &config ) const override;
};
Q_DECLARE_METATYPE( QgsValueRelationFieldFormatter::ValueRelationCache )

View File

@ -62,3 +62,9 @@ QVariant QgsFieldFormatter::createCache( QgsVectorLayer *layer, int fieldIndex,
return QVariant();
}
QList<QgsVectorLayerRef> QgsFieldFormatter::layerDependencies( const QVariantMap &config ) const
{
Q_UNUSED( config )
return QList<QgsVectorLayerRef>();
}

View File

@ -20,6 +20,7 @@
#include <QVariant>
#include "qgis_core.h"
#include "qgsvectorlayerref.h"
class QgsVectorLayer;
@ -96,6 +97,22 @@ class CORE_EXPORT QgsFieldFormatter
* \since QGIS 3.0
*/
virtual QVariant createCache( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config ) const;
/**
* Returns a list of weak layer references to other layers required by this formatter
* for the given \a config.
* The default implementation returns an empty list.
*
* This method should be reimplemented by formatters that handle relations with other layers,
* (e.g. ValueRelation) and can be used by client code to warn the user about
* missing required dependencies or to add some resolution logic in order
* to load the missing dependency.
* \note not available in Python bindings
* \since QGIS 3.12
*/
virtual QList< QgsVectorLayerRef > layerDependencies( const QVariantMap &config ) const SIP_SKIP;
};
#endif // QGSFIELDKIT_H

View File

@ -675,6 +675,7 @@ cl::Program QgsOpenClUtils::buildProgram( const QString &source, QgsOpenClUtils:
QString err = QObject::tr( "Error building OpenCL program: %1" )
.arg( build_log );
QgsMessageLog::logMessage( err, LOGMESSAGE_TAG, Qgis::Critical );
qDebug() << source;
if ( exceptionBehavior == Throw )
throw e;
}

View File

@ -267,10 +267,6 @@ bool QgsEditorWidgetWrapper::isBlockingCommit() const
return mIsBlockingCommit;
}
QList<QgsVectorLayerRef> QgsEditorWidgetWrapper::layerDependencies() const
{
return QList<QgsVectorLayerRef>();
}
QString QgsEditorWidgetWrapper::constraintFailureReason() const
{

View File

@ -27,7 +27,7 @@ class QgsField;
#include "qgswidgetwrapper.h"
#include "qgis_gui.h"
#include "qgis_sip.h"
#include "qgsvectorlayerref.h"
/**
* \ingroup gui
@ -193,19 +193,6 @@ class GUI_EXPORT QgsEditorWidgetWrapper : public QgsWidgetWrapper
*/
bool isBlockingCommit() const;
/**
* Returns a list of weak layer references to other layers required by this widget.
* The default implementation returns an empty list.
*
* This method should be reimplemented by widgets that handle relations with other layers,
* (e.g. ValueRelation) and can be used by client code to warn the user about
* missing required dependencies or to add some resolution logic in order
* to load the missing dependency.
* \note not available in Python bindings
* \since QGIS 3.12
*/
virtual QList< QgsVectorLayerRef > layerDependencies() const SIP_SKIP;
/**
* Returns the reason why a constraint check has failed (or an empty string
* if constraint check was successful).

View File

@ -182,21 +182,6 @@ QStringList QgsRelationReferenceWidgetWrapper::additionalFields() const
return fields;
}
QList<QgsVectorLayerRef> QgsRelationReferenceWidgetWrapper::layerDependencies() const
{
QList<QgsVectorLayerRef> result;
if ( mWidget )
{
result.append(
QgsVectorLayerRef(
mWidget->referencedLayerId(),
mWidget->referencedLayerName(),
mWidget->referencedLayerDataSource(),
mWidget->referencedLayerProviderKey() ) );
}
return result;
}
void QgsRelationReferenceWidgetWrapper::updateValues( const QVariant &val, const QVariantList &additionalValues )
{
if ( !mWidget || ( !mIndeterminateState && val == value() && val.isNull() == value().isNull() ) )

View File

@ -19,6 +19,7 @@
#include "qgseditorwidgetwrapper.h"
#include "qgis_sip.h"
#include "qgis_gui.h"
#include "qgsvectorlayerref.h"
class QgsRelationReferenceWidget;
class QgsMapCanvas;
@ -69,7 +70,6 @@ class GUI_EXPORT QgsRelationReferenceWidgetWrapper : public QgsEditorWidgetWrapp
protected:
void updateConstraintWidgetStatus() override;
QList<QgsVectorLayerRef> layerDependencies() const override SIP_SKIP;
private:
void updateValues( const QVariant &val, const QVariantList &additionalValues = QVariantList() ) override;

View File

@ -452,21 +452,6 @@ void QgsValueRelationWidgetWrapper::setEnabled( bool enabled )
QgsEditorWidgetWrapper::setEnabled( enabled );
}
QList<QgsVectorLayerRef> QgsValueRelationWidgetWrapper::layerDependencies() const
{
QList<QgsVectorLayerRef> result;
const QString layerId { config().value( QStringLiteral( "Layer" ) ).toString() };
const QString layerName { config().value( QStringLiteral( "LayerName" ) ).toString() };
const QString providerName { config().value( QStringLiteral( "LayerProviderName" ) ).toString() };
const QString layerSource { config().value( QStringLiteral( "LayerSource" ) ).toString() };
if ( ! layerId.isEmpty() && ! layerName.isEmpty() && ! providerName.isEmpty() && ! layerSource.isEmpty() )
{
result.append( QgsVectorLayerRef( layerId, layerName, layerSource, providerName ) );
}
return result;
}
void QgsValueRelationWidgetWrapper::emitValueChangedInternal( const QString &value )
{
Q_NOWARN_DEPRECATED_PUSH

View File

@ -102,8 +102,6 @@ class GUI_EXPORT QgsValueRelationWidgetWrapper : public QgsEditorWidgetWrapper
*/
void setFeature( const QgsFeature &feature ) override;
QList<QgsVectorLayerRef> layerDependencies() const override;
private slots:
void emitValueChangedInternal( const QString &value );

View File

@ -503,24 +503,6 @@ void TestQgsRelationReferenceWidget::testDependencies()
QCOMPARE( w.referencedLayerDataSource(), mLayer2.publicSource() );
QCOMPARE( w.referencedLayerProviderKey(), mLayer2.providerType() );
// Test dependencies
QgsRelationReferenceWidget editor( new QWidget() );
QgsRelationReferenceWidgetWrapper ww( &mLayer1, 10, &editor, &canvas, nullptr, nullptr );
ww.setConfig(
{
{ QStringLiteral( "ReferencedLayerDataSource" ), mLayer2.publicSource() },
{ QStringLiteral( "ReferencedLayerProviderKey" ), mLayer2.providerType() },
{ QStringLiteral( "ReferencedLayerId" ), mLayer2.id() },
{ QStringLiteral( "ReferencedLayerName" ), mLayer2.name() },
} );
ww.initWidget( &editor );
const QList<QgsVectorLayerRef> dependencies = ww.layerDependencies();
QVERIFY( dependencies.count() == 1 );
const QgsVectorLayerRef dependency = dependencies.first();
QCOMPARE( dependency.layerId, mLayer2.id() );
QCOMPARE( dependency.name, mLayer2.name() );
QCOMPARE( dependency.provider, mLayer2.providerType() );
QCOMPARE( dependency.source, mLayer2.publicSource() );
}
QGSTEST_MAIN( TestQgsRelationReferenceWidget )