mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-15 00:02:52 -04:00
Merge pull request #55146 from nirvn/qml_responsive
[editor widgets] Fix QML editor widget not responsive to attribute changes
This commit is contained in:
commit
0ce0b78295
@ -7,6 +7,7 @@
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
class QgsQmlWidgetWrapper : QgsWidgetWrapper
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "qgswebframe.h"
|
||||
#include "qgsvaluerelationfieldformatter.h"
|
||||
#include "qgsattributeform.h"
|
||||
|
||||
#include <QScreen>
|
||||
|
||||
QgsHtmlWidgetWrapper::QgsHtmlWidgetWrapper( QgsVectorLayer *layer, QWidget *editor, QWidget *parent )
|
||||
@ -34,7 +35,6 @@ bool QgsHtmlWidgetWrapper::valid() const
|
||||
|
||||
QWidget *QgsHtmlWidgetWrapper::createWidget( QWidget *parent )
|
||||
{
|
||||
|
||||
QgsAttributeForm *form = qobject_cast<QgsAttributeForm *>( parent );
|
||||
|
||||
if ( form )
|
||||
@ -44,9 +44,7 @@ QWidget *QgsHtmlWidgetWrapper::createWidget( QWidget *parent )
|
||||
{
|
||||
if ( attributeChanged )
|
||||
{
|
||||
const thread_local QRegularExpression expRe { QStringLiteral( R"re(expression.evaluate\s*\(\s*"(.*)"\))re" ), QRegularExpression::PatternOption::MultilineOption | QRegularExpression::PatternOption::DotMatchesEverythingOption };
|
||||
const QRegularExpressionMatch match { expRe.match( mHtmlCode ) };
|
||||
if ( match.hasMatch() && QgsValueRelationFieldFormatter::expressionRequiresFormScope( match.captured( 1 ) ) )
|
||||
if ( mRequiresFormScope )
|
||||
{
|
||||
mFormFeature.setAttribute( attribute, newValue );
|
||||
setHtmlContext();
|
||||
@ -121,6 +119,18 @@ void QgsHtmlWidgetWrapper::checkGeometryNeeds()
|
||||
void QgsHtmlWidgetWrapper::setHtmlCode( const QString &htmlCode )
|
||||
{
|
||||
mHtmlCode = htmlCode;
|
||||
|
||||
bool ok = false;
|
||||
const thread_local QRegularExpression expRe( QStringLiteral( R"re(expression.evaluate\s*\(\s*"(.*)"\))re" ), QRegularExpression::PatternOption::MultilineOption | QRegularExpression::PatternOption::DotMatchesEverythingOption );
|
||||
QRegularExpressionMatchIterator matchIt = expRe.globalMatch( mHtmlCode );
|
||||
while ( !ok && matchIt.hasNext() )
|
||||
{
|
||||
const QRegularExpressionMatch match = matchIt.next();
|
||||
const QgsExpression exp = match.captured( 1 );
|
||||
ok = QgsValueRelationFieldFormatter::expressionRequiresFormScope( exp );
|
||||
}
|
||||
mRequiresFormScope = ok;
|
||||
|
||||
checkGeometryNeeds();
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,7 @@ class GUI_EXPORT QgsHtmlWidgetWrapper : public QgsWidgetWrapper
|
||||
QgsFeature mFeature;
|
||||
bool mNeedsGeometry = false;
|
||||
QgsFeature mFormFeature;
|
||||
bool mRequiresFormScope = false;
|
||||
|
||||
friend class TestQgsHtmlWidgetWrapper;
|
||||
};
|
||||
|
@ -13,12 +13,13 @@
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsqmlwidgetwrapper.h"
|
||||
#include "qgsattributeform.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsexpressioncontextutils.h"
|
||||
#include "qgsvaluerelationfieldformatter.h"
|
||||
|
||||
#include <QtQuickWidgets/QQuickWidget>
|
||||
#include <QQuickWidget>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlEngine>
|
||||
#include <QUrl>
|
||||
@ -36,6 +37,24 @@ bool QgsQmlWidgetWrapper::valid() const
|
||||
|
||||
QWidget *QgsQmlWidgetWrapper::createWidget( QWidget *parent )
|
||||
{
|
||||
QgsAttributeForm *form = qobject_cast<QgsAttributeForm *>( parent );
|
||||
|
||||
if ( form )
|
||||
{
|
||||
mFormFeature = form->feature();
|
||||
connect( form, &QgsAttributeForm::widgetValueChanged, this, [ = ]( const QString & attribute, const QVariant & newValue, bool attributeChanged )
|
||||
{
|
||||
if ( attributeChanged )
|
||||
{
|
||||
if ( mRequiresFormScope )
|
||||
{
|
||||
mFormFeature.setAttribute( attribute, newValue );
|
||||
setQmlContext();
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
return new QQuickWidget( parent );
|
||||
}
|
||||
|
||||
@ -71,6 +90,24 @@ void QgsQmlWidgetWrapper::reinitWidget( )
|
||||
|
||||
void QgsQmlWidgetWrapper::setQmlCode( const QString &qmlCode )
|
||||
{
|
||||
if ( mQmlCode == qmlCode )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mQmlCode = qmlCode;
|
||||
|
||||
bool ok = false;
|
||||
const thread_local QRegularExpression expRe( QStringLiteral( R"re(expression.evaluate\s*\(\s*"(.*)"\))re" ), QRegularExpression::PatternOption::MultilineOption | QRegularExpression::PatternOption::DotMatchesEverythingOption );
|
||||
QRegularExpressionMatchIterator matchIt = expRe.globalMatch( mQmlCode );
|
||||
while ( !ok && matchIt.hasNext() )
|
||||
{
|
||||
const QRegularExpressionMatch match = matchIt.next();
|
||||
const QgsExpression exp = match.captured( 1 );
|
||||
ok = QgsValueRelationFieldFormatter::expressionRequiresFormScope( exp );
|
||||
}
|
||||
mRequiresFormScope = ok;
|
||||
|
||||
if ( !mQmlFile.open() )
|
||||
{
|
||||
QgsMessageLog::logMessage( tr( "Failed to open temporary QML file" ) );
|
||||
@ -78,7 +115,7 @@ void QgsQmlWidgetWrapper::setQmlCode( const QString &qmlCode )
|
||||
}
|
||||
|
||||
mQmlFile.resize( 0 );
|
||||
mQmlFile.write( qmlCode.toUtf8() );
|
||||
mQmlFile.write( mQmlCode.toUtf8() );
|
||||
|
||||
mQmlFile.close();
|
||||
}
|
||||
@ -90,7 +127,12 @@ void QgsQmlWidgetWrapper::setQmlContext( )
|
||||
|
||||
const QgsAttributeEditorContext attributecontext = context();
|
||||
QgsExpressionContext expressionContext = layer()->createExpressionContext();
|
||||
expressionContext << QgsExpressionContextUtils::formScope( mFeature, attributecontext.attributeFormModeString() );
|
||||
expressionContext << QgsExpressionContextUtils::formScope( mFormFeature, attributecontext.attributeFormModeString() );
|
||||
if ( attributecontext.parentFormFeature().isValid() )
|
||||
{
|
||||
expressionContext << QgsExpressionContextUtils::parentFormScope( attributecontext.parentFormFeature() );
|
||||
}
|
||||
|
||||
expressionContext.setFeature( mFeature );
|
||||
|
||||
QmlExpression *qmlExpression = new QmlExpression();
|
||||
@ -105,6 +147,7 @@ void QgsQmlWidgetWrapper::setFeature( const QgsFeature &feature )
|
||||
return;
|
||||
|
||||
mFeature = feature;
|
||||
mFormFeature = feature;
|
||||
|
||||
setQmlContext();
|
||||
}
|
||||
|
@ -19,7 +19,8 @@
|
||||
#include "qgswidgetwrapper.h"
|
||||
#include "qgis_sip.h"
|
||||
#include "qgis_gui.h"
|
||||
#include <QtQuickWidgets/QQuickWidget>
|
||||
|
||||
#include <QQuickWidget>
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
@ -62,8 +63,11 @@ class GUI_EXPORT QgsQmlWidgetWrapper : public QgsWidgetWrapper
|
||||
|
||||
private:
|
||||
QTemporaryFile mQmlFile;
|
||||
QString mQmlCode;
|
||||
QQuickWidget *mWidget = nullptr;
|
||||
QgsFeature mFeature;
|
||||
QgsFeature mFormFeature;
|
||||
bool mRequiresFormScope = false;
|
||||
};
|
||||
|
||||
|
||||
|
@ -42,17 +42,7 @@ QWidget *QgsTextWidgetWrapper::createWidget( QWidget *parent )
|
||||
{
|
||||
if ( attributeChanged )
|
||||
{
|
||||
bool ok { false };
|
||||
const thread_local QRegularExpression sRegEx{ QStringLiteral( "\\[%(.*?)%\\]" ), QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption };
|
||||
QRegularExpressionMatchIterator matchIt { sRegEx.globalMatch( mText ) };
|
||||
while ( !ok && matchIt.hasNext() )
|
||||
{
|
||||
const QRegularExpressionMatch match { matchIt.next() };
|
||||
const QgsExpression exp { match.captured( 1 ) };
|
||||
ok = QgsValueRelationFieldFormatter::expressionRequiresFormScope( exp );
|
||||
}
|
||||
|
||||
if ( ok )
|
||||
if ( mRequiresFormScope )
|
||||
{
|
||||
mFormFeature.setAttribute( attribute, newValue );
|
||||
updateTextContext();
|
||||
@ -99,6 +89,18 @@ void QgsTextWidgetWrapper::reinitWidget( )
|
||||
void QgsTextWidgetWrapper::setText( const QString &text )
|
||||
{
|
||||
mText = text;
|
||||
|
||||
bool ok = false;
|
||||
const thread_local QRegularExpression sRegEx( QStringLiteral( "\\[%(.*?)%\\]" ), QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption );
|
||||
QRegularExpressionMatchIterator matchIt = sRegEx.globalMatch( mText );
|
||||
while ( !ok && matchIt.hasNext() )
|
||||
{
|
||||
const QRegularExpressionMatch match = matchIt.next();
|
||||
const QgsExpression exp = match.captured( 1 );
|
||||
ok = QgsValueRelationFieldFormatter::expressionRequiresFormScope( exp );
|
||||
}
|
||||
mRequiresFormScope = ok;
|
||||
|
||||
reinitWidget();
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,7 @@ class GUI_EXPORT QgsTextWidgetWrapper : public QgsWidgetWrapper
|
||||
QLabel *mWidget = nullptr;
|
||||
QgsFeature mFeature;
|
||||
QgsFeature mFormFeature;
|
||||
bool mRequiresFormScope = false;
|
||||
QgsExpressionContext mTextContext;
|
||||
bool mNeedsGeometry = false;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user