diff --git a/python/core/auto_generated/fieldformatter/qgsrelationreferencefieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgsrelationreferencefieldformatter.sip.in index 65fa4ac8de3..6239a16d4ed 100644 --- a/python/core/auto_generated/fieldformatter/qgsrelationreferencefieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgsrelationreferencefieldformatter.sip.in @@ -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 layerDependencies( const QVariantMap &config ) const; + }; /************************************************************************ diff --git a/python/core/auto_generated/fieldformatter/qgsvaluerelationfieldformatter.sip.in b/python/core/auto_generated/fieldformatter/qgsvaluerelationfieldformatter.sip.in index 79d833eb6c9..37f849d2501 100644 --- a/python/core/auto_generated/fieldformatter/qgsvaluerelationfieldformatter.sip.in +++ b/python/core/auto_generated/fieldformatter/qgsvaluerelationfieldformatter.sip.in @@ -128,7 +128,7 @@ Returns the (possibly NULL) layer from the widget's ``config`` and ``project`` .. versionadded:: 3.8 %End - + virtual QList layerDependencies( const QVariantMap &config ) const; }; diff --git a/python/core/auto_generated/qgsfieldformatter.sip.in b/python/core/auto_generated/qgsfieldformatter.sip.in index f15911ad268..e283ccfba7b 100644 --- a/python/core/auto_generated/qgsfieldformatter.sip.in +++ b/python/core/auto_generated/qgsfieldformatter.sip.in @@ -85,6 +85,9 @@ make use of a cache if present. .. versionadded:: 3.0 %End + + + }; /************************************************************************ diff --git a/python/gui/auto_generated/editorwidgets/core/qgseditorwidgetwrapper.sip.in b/python/gui/auto_generated/editorwidgets/core/qgseditorwidgetwrapper.sip.in index f6684224092..9525d396696 100644 --- a/python/gui/auto_generated/editorwidgets/core/qgseditorwidgetwrapper.sip.in +++ b/python/gui/auto_generated/editorwidgets/core/qgseditorwidgetwrapper.sip.in @@ -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 diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 26a64fa6118..0020b8a149f 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -1998,13 +1998,11 @@ QList QgisApp::findBrokenWidgetDependencies( QgsVectorLayer * // Check for missing layer widget dependencies for ( int i = 0; i < vl->fields().count(); i++ ) { - std::unique_ptr 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( diff --git a/src/core/fieldformatter/qgsrelationreferencefieldformatter.cpp b/src/core/fieldformatter/qgsrelationreferencefieldformatter.cpp index 72e1169453e..f1576d5998e 100644 --- a/src/core/fieldformatter/qgsrelationreferencefieldformatter.cpp +++ b/src/core/fieldformatter/qgsrelationreferencefieldformatter.cpp @@ -160,3 +160,17 @@ QVariant QgsRelationReferenceFieldFormatter::createCache( QgsVectorLayer *layer, return QVariant::fromValue>( cache ); } + + +QList QgsRelationReferenceFieldFormatter::layerDependencies( const QVariantMap &config ) const +{ + + const QList result {{ + QgsVectorLayerRef( + config.value( QStringLiteral( "ReferencedLayerId" ) ).toString(), + config.value( QStringLiteral( "ReferencedLayerName" ) ).toString(), + config.value( QStringLiteral( "ReferencedLayerDataSource" ) ).toString(), + config.value( QStringLiteral( "ReferencedLayerProviderKey" ) ).toString() ) + }}; + return result; +} diff --git a/src/core/fieldformatter/qgsrelationreferencefieldformatter.h b/src/core/fieldformatter/qgsrelationreferencefieldformatter.h index edec95061d0..723ffcde24f 100644 --- a/src/core/fieldformatter/qgsrelationreferencefieldformatter.h +++ b/src/core/fieldformatter/qgsrelationreferencefieldformatter.h @@ -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 layerDependencies( const QVariantMap &config ) const override; }; #endif // QGSRELATIONREFERENCEFIELDKIT_H diff --git a/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp b/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp index d90805833c5..eecf9b54de9 100644 --- a/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp +++ b/src/core/fieldformatter/qgsvaluerelationfieldformatter.cpp @@ -168,6 +168,21 @@ QgsValueRelationFieldFormatter::ValueRelationCache QgsValueRelationFieldFormatte return cache; } + +QList QgsValueRelationFieldFormatter::layerDependencies( const QVariantMap &config ) const +{ + QList 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 ); } - diff --git a/src/core/fieldformatter/qgsvaluerelationfieldformatter.h b/src/core/fieldformatter/qgsvaluerelationfieldformatter.h index 0028ed00c5f..222bdb5ce78 100644 --- a/src/core/fieldformatter/qgsvaluerelationfieldformatter.h +++ b/src/core/fieldformatter/qgsvaluerelationfieldformatter.h @@ -125,8 +125,7 @@ class CORE_EXPORT QgsValueRelationFieldFormatter : public QgsFieldFormatter */ static QgsVectorLayer *resolveLayer( const QVariantMap &config, const QgsProject *project ); - - + QList layerDependencies( const QVariantMap &config ) const override; }; Q_DECLARE_METATYPE( QgsValueRelationFieldFormatter::ValueRelationCache ) diff --git a/src/core/qgsfieldformatter.cpp b/src/core/qgsfieldformatter.cpp index 383656f6216..6ff820fc08a 100644 --- a/src/core/qgsfieldformatter.cpp +++ b/src/core/qgsfieldformatter.cpp @@ -62,3 +62,9 @@ QVariant QgsFieldFormatter::createCache( QgsVectorLayer *layer, int fieldIndex, return QVariant(); } + +QList QgsFieldFormatter::layerDependencies( const QVariantMap &config ) const +{ + Q_UNUSED( config ) + return QList(); +} diff --git a/src/core/qgsfieldformatter.h b/src/core/qgsfieldformatter.h index b37185cb5b2..10cc8c25f8e 100644 --- a/src/core/qgsfieldformatter.h +++ b/src/core/qgsfieldformatter.h @@ -20,6 +20,7 @@ #include #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 diff --git a/src/core/qgsopenclutils.cpp b/src/core/qgsopenclutils.cpp index 003fdf0fc26..f00d90b92c2 100644 --- a/src/core/qgsopenclutils.cpp +++ b/src/core/qgsopenclutils.cpp @@ -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; } diff --git a/src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp b/src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp index f94cf7f163a..682f9c26a07 100644 --- a/src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp +++ b/src/gui/editorwidgets/core/qgseditorwidgetwrapper.cpp @@ -267,10 +267,6 @@ bool QgsEditorWidgetWrapper::isBlockingCommit() const return mIsBlockingCommit; } -QList QgsEditorWidgetWrapper::layerDependencies() const -{ - return QList(); -} QString QgsEditorWidgetWrapper::constraintFailureReason() const { diff --git a/src/gui/editorwidgets/core/qgseditorwidgetwrapper.h b/src/gui/editorwidgets/core/qgseditorwidgetwrapper.h index 178ddda0e1e..2df39fb0720 100644 --- a/src/gui/editorwidgets/core/qgseditorwidgetwrapper.h +++ b/src/gui/editorwidgets/core/qgseditorwidgetwrapper.h @@ -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). diff --git a/src/gui/editorwidgets/qgsrelationreferencewidgetwrapper.cpp b/src/gui/editorwidgets/qgsrelationreferencewidgetwrapper.cpp index a8ec2e2fc87..d94e3616f3e 100644 --- a/src/gui/editorwidgets/qgsrelationreferencewidgetwrapper.cpp +++ b/src/gui/editorwidgets/qgsrelationreferencewidgetwrapper.cpp @@ -182,21 +182,6 @@ QStringList QgsRelationReferenceWidgetWrapper::additionalFields() const return fields; } -QList QgsRelationReferenceWidgetWrapper::layerDependencies() const -{ - QList 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() ) ) diff --git a/src/gui/editorwidgets/qgsrelationreferencewidgetwrapper.h b/src/gui/editorwidgets/qgsrelationreferencewidgetwrapper.h index a23b7613ee1..8fcd79dcc5d 100644 --- a/src/gui/editorwidgets/qgsrelationreferencewidgetwrapper.h +++ b/src/gui/editorwidgets/qgsrelationreferencewidgetwrapper.h @@ -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 layerDependencies() const override SIP_SKIP; private: void updateValues( const QVariant &val, const QVariantList &additionalValues = QVariantList() ) override; diff --git a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp index e2af2f7581f..641e0e47bca 100644 --- a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp +++ b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp @@ -452,21 +452,6 @@ void QgsValueRelationWidgetWrapper::setEnabled( bool enabled ) QgsEditorWidgetWrapper::setEnabled( enabled ); } - -QList QgsValueRelationWidgetWrapper::layerDependencies() const -{ - QList 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 diff --git a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.h b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.h index a5e758f4ff8..3d94796801a 100644 --- a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.h +++ b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.h @@ -102,8 +102,6 @@ class GUI_EXPORT QgsValueRelationWidgetWrapper : public QgsEditorWidgetWrapper */ void setFeature( const QgsFeature &feature ) override; - QList layerDependencies() const override; - private slots: void emitValueChangedInternal( const QString &value ); diff --git a/tests/src/gui/testqgsrelationreferencewidget.cpp b/tests/src/gui/testqgsrelationreferencewidget.cpp index 5412a86660d..20b8c92ebbc 100644 --- a/tests/src/gui/testqgsrelationreferencewidget.cpp +++ b/tests/src/gui/testqgsrelationreferencewidget.cpp @@ -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 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 )