Skip to content

Commit

Permalink
form_mode for qmlwidgetwrapper expression
Browse files Browse the repository at this point in the history
  • Loading branch information
signedav committed Sep 10, 2018
1 parent a5fc391 commit d80ad3d
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 15 deletions.
5 changes: 3 additions & 2 deletions python/core/auto_generated/qgsexpressioncontext.sip.in
Expand Up @@ -765,10 +765,11 @@ For instance, QGIS version numbers and variables specified through QGIS options.
.. seealso:: :py:func:`setGlobalVariable`
%End

static QgsExpressionContextScope *formScope( const QgsFeature &formFeature = QgsFeature( ) ) /Factory/;
static QgsExpressionContextScope *formScope( const QgsFeature &formFeature = QgsFeature( ), const QString &formMode = QString() ) /Factory/;
%Docstring
Creates a new scope which contains functions and variables from the current attribute form/table feature.
Creates a new scope which contains functions and variables from the current attribute form/table ``feature``.
The variables and values in this scope will reflect the current state of the form/row being edited.
The ``formMode`` (SingleEditMode etc.) is passed as text

.. versionadded:: 3.2
%End
Expand Down
Expand Up @@ -165,6 +165,15 @@ that any pending changes should be pushed to the edit buffer or they
might be lost.

.. versionadded:: 3.2
%End

signals:

void contextChanged();
%Docstring
Signal when QgsAttributeEditorContext mContext changed after the widget wrapper has already been intialized

.. versionadded:: 3.4
%End

protected:
Expand Down
Expand Up @@ -50,6 +50,8 @@ writes the ``qmlCode`` into a temporary file

public slots:

void setQmlContext();

virtual void setFeature( const QgsFeature &feature );


Expand Down
32 changes: 32 additions & 0 deletions python/gui/auto_generated/qgsattributeeditorcontext.sip.in
Expand Up @@ -24,6 +24,16 @@ showing an embedded form due to relations)
%End
public:

enum Mode
{
SingleEditMode,
AddFeatureMode,
MultiEditMode,
SearchMode,
AggregateSearchMode,
IdentifyMode
};

enum RelationMode
{
Undefined,
Expand Down Expand Up @@ -198,9 +208,31 @@ Set current ``feature`` for the currently edited form or table row
.. versionadded:: 3.2
%End

Mode attributeFormMode() const;
%Docstring
Returns current attributeFormMode

.. versionadded:: 3.4
%End

void setAttributeFormMode( const Mode attributeFormMode );
%Docstring
Set ``attributeFormMode`` for the edited form

.. versionadded:: 3.4
%End

QString attributeFormModeString() const;
%Docstring
Returns the context as string

.. versionadded:: 3.4
%End


};


/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
3 changes: 3 additions & 0 deletions src/core/expression/qgsexpression.cpp
Expand Up @@ -791,6 +791,9 @@ void QgsExpression::initVariableHelp()
//form context variable
sVariableHelpTexts.insert( QStringLiteral( "current_geometry" ), QCoreApplication::translate( "current_geometry", "Represents the geometry of the feature currently being edited in the form or the table row. Can be used in a form/row context to filter the related features." ) );
sVariableHelpTexts.insert( QStringLiteral( "current_feature" ), QCoreApplication::translate( "current_feature", "Represents the feature currently being edited in the form or the table row. Can be used in a form/row context to filter the related features." ) );

//form variable
sVariableHelpTexts.insert( QStringLiteral( "form_mode" ), QCoreApplication::translate( "form_mode", "What the form is used for, like AddFeatureMode, SingleEditModem, MultiEditMode, SearchMode, AggregateSearchMode or IdentifyMode as string." ) );
}

QString QgsExpression::variableHelpText( const QString &variableName )
Expand Down
3 changes: 2 additions & 1 deletion src/core/qgsexpressioncontext.cpp
Expand Up @@ -790,12 +790,13 @@ class GetProcessingParameterValue : public QgsScopedExpressionFunction
///@endcond


QgsExpressionContextScope *QgsExpressionContextUtils::formScope( const QgsFeature &formFeature )
QgsExpressionContextScope *QgsExpressionContextUtils::formScope( const QgsFeature &formFeature, const QString &formMode )
{
QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Form" ) );
scope->addFunction( QStringLiteral( "current_value" ), new GetCurrentFormFieldValue( ) );
scope->setVariable( QStringLiteral( "current_geometry" ), formFeature.geometry( ), true );
scope->setVariable( QStringLiteral( "current_feature" ), formFeature, true );
scope->setVariable( QStringLiteral( "form_mode" ), formMode, true );
return scope;
}

Expand Down
5 changes: 3 additions & 2 deletions src/core/qgsexpressioncontext.h
Expand Up @@ -740,11 +740,12 @@ class CORE_EXPORT QgsExpressionContextUtils
static QgsExpressionContextScope *globalScope() SIP_FACTORY;

/**
* Creates a new scope which contains functions and variables from the current attribute form/table feature.
* Creates a new scope which contains functions and variables from the current attribute form/table \a feature.
* The variables and values in this scope will reflect the current state of the form/row being edited.
* The \a formMode (SingleEditMode etc.) is passed as text
* \since QGIS 3.2
*/
static QgsExpressionContextScope *formScope( const QgsFeature &formFeature = QgsFeature( ) ) SIP_FACTORY;
static QgsExpressionContextScope *formScope( const QgsFeature &formFeature = QgsFeature( ), const QString &formMode = QString() ) SIP_FACTORY;

/**
* Sets a global context variable. This variable will be contained within scopes retrieved via
Expand Down
1 change: 1 addition & 0 deletions src/gui/editorwidgets/core/qgswidgetwrapper.cpp
Expand Up @@ -66,6 +66,7 @@ void QgsWidgetWrapper::setConfig( const QVariantMap &config )
void QgsWidgetWrapper::setContext( const QgsAttributeEditorContext &context )
{
mContext = context;
emit contextChanged();
}

QVariant QgsWidgetWrapper::config( const QString &key, const QVariant &defaultVal ) const
Expand Down
9 changes: 9 additions & 0 deletions src/gui/editorwidgets/core/qgswidgetwrapper.h
Expand Up @@ -202,6 +202,15 @@ class GUI_EXPORT QgsWidgetWrapper : public QObject
*/
void notifyAboutToSave();

signals:

/**
* Signal when QgsAttributeEditorContext mContext changed after the widget wrapper has already been intialized
*
* \since QGIS 3.4
*/
void contextChanged();

protected:

/**
Expand Down
26 changes: 16 additions & 10 deletions src/gui/editorwidgets/qgsqmlwidgetwrapper.cpp
Expand Up @@ -23,7 +23,7 @@
QgsQmlWidgetWrapper::QgsQmlWidgetWrapper( QgsVectorLayer *layer, QWidget *editor, QWidget *parent )
: QgsWidgetWrapper( layer, editor, parent )
{

connect( this, &QgsWidgetWrapper::contextChanged, this, &QgsQmlWidgetWrapper::setQmlContext );
}

bool QgsQmlWidgetWrapper::valid() const
Expand Down Expand Up @@ -66,7 +66,6 @@ void QgsQmlWidgetWrapper::reinitWidget( )
initWidget( mWidget );
}


void QgsQmlWidgetWrapper::setQmlCode( const QString &qmlCode )
{
if ( !mQmlFile.open() )
Expand All @@ -81,24 +80,31 @@ void QgsQmlWidgetWrapper::setQmlCode( const QString &qmlCode )
mQmlFile.close();
}

void QgsQmlWidgetWrapper::setFeature( const QgsFeature &feature )
void QgsQmlWidgetWrapper::setQmlContext( )
{
if ( !mWidget )
return;

QgsExpressionContext context = layer()->createExpressionContext();
context << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::layerScope( layer() );

context.setFeature( feature );
QgsExpressionContext expressionContext = layer()->createExpressionContext();
expressionContext << QgsExpressionContextUtils::formScope( mFeature, context().attributeFormModeString() );
expressionContext.setFeature( mFeature );

QmlExpression *qmlExpression = new QmlExpression();
qmlExpression->setExpressionContext( context );
qmlExpression->setExpressionContext( expressionContext );

mWidget->rootContext()->setContextProperty( "expression", qmlExpression );
}

void QgsQmlWidgetWrapper::setFeature( const QgsFeature &feature )
{
if ( !mWidget )
return;

mFeature = feature;

setQmlContext();
}

///@cond PRIVATE
void QmlExpression::setExpressionContext( const QgsExpressionContext &context )
{
Expand Down
3 changes: 3 additions & 0 deletions src/gui/editorwidgets/qgsqmlwidgetwrapper.h
Expand Up @@ -55,11 +55,14 @@ class GUI_EXPORT QgsQmlWidgetWrapper : public QgsWidgetWrapper

public slots:

void setQmlContext();

void setFeature( const QgsFeature &feature ) override;

private:
QTemporaryFile mQmlFile;
QQuickWidget *mWidget = nullptr;
QgsFeature mFeature;
};


Expand Down
49 changes: 49 additions & 0 deletions src/gui/qgsattributeeditorcontext.h
Expand Up @@ -38,6 +38,18 @@ class GUI_EXPORT QgsAttributeEditorContext
{
public:

//! Form modes
enum Mode
{
SingleEditMode, //!< Single edit mode, for editing a single feature
AddFeatureMode, /*!< Add feature mode, for setting attributes for a new feature. In this mode the dialog will be editable even with an invalid feature and
will add a new feature when the form is accepted. */
MultiEditMode, //!< Multi edit mode, for editing fields of multiple features at once
SearchMode, //!< Form values are used for searching/filtering the layer
AggregateSearchMode, //!< Form is in aggregate search mode, show each widget in this mode \since QGIS 3.0
IdentifyMode //!< Identify the feature \since QGIS 3.0
};

/**
* Determines in which direction a relation was resolved.
*/
Expand Down Expand Up @@ -204,6 +216,41 @@ class GUI_EXPORT QgsAttributeEditorContext
*/
void setFormFeature( const QgsFeature &feature ) { mFormFeature = feature ; }

/**
* Returns current attributeFormMode
* \since QGIS 3.4
*/
Mode attributeFormMode() const { return mAttributeFormMode; }

/**
* Set \a attributeFormMode for the edited form
* \since QGIS 3.4
*/
void setAttributeFormMode( const Mode attributeFormMode ) { mAttributeFormMode = attributeFormMode; }

/**
* Returns the context as string
* \since QGIS 3.4
*/
QString attributeFormModeString() const
{
switch ( mAttributeFormMode )
{
case SingleEditMode:
return QStringLiteral( "SingleEditMode" );
case AddFeatureMode:
return QStringLiteral( "AddFeatureMode" );
case MultiEditMode:
return QStringLiteral( "MultiEditMode" );
case SearchMode:
return QStringLiteral( "SearchMode" );
case AggregateSearchMode:
return QStringLiteral( "AggregateSearchMode" );
case IdentifyMode:
return QStringLiteral( "IdentifyMode" );
}
}


private:
const QgsAttributeEditorContext *mParentContext = nullptr;
Expand All @@ -217,6 +264,8 @@ class GUI_EXPORT QgsAttributeEditorContext
QgsFeature mFormFeature;
FormMode mFormMode = Embed;
bool mAllowCustomUi = true;
Mode mAttributeFormMode = QgsAttributeEditorContext::SingleEditMode;
};

#endif // QGSATTRIBUTEEDITORCONTEXT_H

8 changes: 8 additions & 0 deletions src/gui/qgsattributeform.cpp
Expand Up @@ -183,6 +183,13 @@ void QgsAttributeForm::setMode( QgsAttributeForm::Mode mode )
break;
}
}
//update all form editor widget modes to match
for ( QgsWidgetWrapper *w : qgis::as_const( mWidgets ) )
{
QgsAttributeEditorContext newContext = w->context();
newContext.setAttributeFormMode( ( QgsAttributeEditorContext::Mode )mode );
w->setContext( newContext );
}

bool relationWidgetsVisible = ( mMode != QgsAttributeForm::MultiEditMode && mMode != QgsAttributeForm::AggregateSearchMode );
for ( QgsAttributeFormRelationEditorWidget *w : findChildren< QgsAttributeFormRelationEditorWidget * >() )
Expand Down Expand Up @@ -1777,6 +1784,7 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt
QgsQmlWidgetWrapper *qmlWrapper = new QgsQmlWidgetWrapper( mLayer, nullptr, this );
qmlWrapper->setQmlCode( elementDef->qmlCode() );
qmlWrapper->setConfig( mLayer->editFormConfig().widgetConfig( elementDef->name() ) );
context.setAttributeFormMode( ( QgsAttributeEditorContext::Mode ) mode() );
qmlWrapper->setContext( context );

mWidgets.append( qmlWrapper );
Expand Down

0 comments on commit d80ad3d

Please sign in to comment.