Merge pull request #51525 from elpaso/widgets-editable-data-defined

[Feature] Data defined form widget editable state.
This commit is contained in:
Alessandro Pasotti 2023-01-23 16:09:55 +01:00 committed by GitHub
commit c9608029f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 114 additions and 32 deletions

View File

@ -75,6 +75,7 @@ Constructor for TabData
NoProperty, NoProperty,
AllProperties, AllProperties,
Alias, Alias,
Editable,
}; };
QgsEditFormConfig( const QgsEditFormConfig &o ); QgsEditFormConfig( const QgsEditFormConfig &o );

View File

@ -113,6 +113,7 @@ class CORE_EXPORT QgsEditFormConfig
NoProperty = 0, //!< No property NoProperty = 0, //!< No property
AllProperties = 1, //!< All properties for item AllProperties = 1, //!< All properties for item
Alias = 2, //!< Alias Alias = 2, //!< Alias
Editable = 3, //!< Editable state \since QGIS 3.30
}; };
/** /**

View File

@ -64,6 +64,12 @@ class QgsEditFormConfigPrivate : public QSharedData
QObject::tr( "Alias" ), QObject::tr( "Alias" ),
QgsPropertyDefinition::String ) QgsPropertyDefinition::String )
}, },
{
QgsEditFormConfig::DataDefinedProperty::Editable,
QgsPropertyDefinition( "dataDefinedEditable",
QObject::tr( "Editable" ),
QgsPropertyDefinition::Boolean )
},
}; };
return sPropertyDefinitions; return sPropertyDefinitions;
}; };

View File

@ -74,7 +74,16 @@ QgsAttributeTypeDialog::QgsAttributeTypeDialog( QgsVectorLayer *vl, int fieldIdx
mExpressionWidget->registerExpressionContextGenerator( this ); mExpressionWidget->registerExpressionContextGenerator( this );
mExpressionWidget->setLayer( mLayer ); mExpressionWidget->setLayer( mLayer );
mEditableExpressionButton->registerExpressionContextGenerator( this );
mEditableExpressionButton->init( QgsEditFormConfig::DataDefinedProperty::Editable, mDataDefinedProperties.property( QgsEditFormConfig::DataDefinedProperty::Editable ), vl->editFormConfig().propertyDefinitions(), vl );
mEditableExpressionButton->registerLinkedWidget( isFieldEditableCheckBox );
connect( mEditableExpressionButton, &QgsPropertyOverrideButton::changed, this, [ = ]
{
mDataDefinedProperties.setProperty( QgsEditFormConfig::DataDefinedProperty::Editable, mEditableExpressionButton->toProperty() );
} );
mAliasExpressionButton->registerExpressionContextGenerator( this ); mAliasExpressionButton->registerExpressionContextGenerator( this );
mAliasExpressionButton->init( QgsEditFormConfig::DataDefinedProperty::Alias, mDataDefinedProperties.property( QgsEditFormConfig::DataDefinedProperty::Alias ), vl->editFormConfig().propertyDefinitions(), vl );
connect( mAliasExpressionButton, &QgsPropertyOverrideButton::changed, this, [ = ] connect( mAliasExpressionButton, &QgsPropertyOverrideButton::changed, this, [ = ]
{ {
mDataDefinedProperties.setProperty( QgsEditFormConfig::DataDefinedProperty::Alias, mAliasExpressionButton->toProperty() ); mDataDefinedProperties.setProperty( QgsEditFormConfig::DataDefinedProperty::Alias, mAliasExpressionButton->toProperty() );
@ -321,6 +330,7 @@ QgsExpressionContext QgsAttributeTypeDialog::createExpressionContext() const
<< QgsExpressionContextUtils::globalScope() << QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() ) << QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::layerScope( mLayer ) << QgsExpressionContextUtils::layerScope( mLayer )
<< QgsExpressionContextUtils::formScope( )
<< QgsExpressionContextUtils::mapToolCaptureScope( QList<QgsPointLocator::Match>() ); << QgsExpressionContextUtils::mapToolCaptureScope( QList<QgsPointLocator::Match>() );
return context; return context;
@ -372,6 +382,10 @@ void QgsAttributeTypeDialog::setDataDefinedProperties( const QgsPropertyCollecti
{ {
mAliasExpressionButton->setToProperty( properties.property( QgsEditFormConfig::DataDefinedProperty::Alias ) ); mAliasExpressionButton->setToProperty( properties.property( QgsEditFormConfig::DataDefinedProperty::Alias ) );
} }
if ( properties.hasProperty( QgsEditFormConfig::DataDefinedProperty::Editable ) )
{
mEditableExpressionButton->setToProperty( properties.property( QgsEditFormConfig::DataDefinedProperty::Editable ) );
}
} }
void QgsAttributeTypeDialog::setComment( const QString &comment ) void QgsAttributeTypeDialog::setComment( const QString &comment )

View File

@ -99,6 +99,7 @@ QgsAttributeForm::QgsAttributeForm( QgsVectorLayer *vl, const QgsFeature &featur
updateContainersVisibility(); updateContainersVisibility();
updateLabels(); updateLabels();
updateEditableState();
} }
@ -1051,8 +1052,9 @@ void QgsAttributeForm::onAttributeChanged( const QVariant &value, const QVariant
mAlreadyUpdatedFields.removeAll( eww->fieldIdx() ); mAlreadyUpdatedFields.removeAll( eww->fieldIdx() );
} }
// Updates expression controlled labels // Updates expression controlled labels and editable state
updateLabels(); updateLabels();
updateEditableState();
// Update other widgets pointing to the same field // Update other widgets pointing to the same field
const QList<QgsAttributeFormEditorWidget *> formEditorWidgets = mFormEditorWidgets.values( eww->fieldIdx() ); const QList<QgsAttributeFormEditorWidget *> formEditorWidgets = mFormEditorWidgets.values( eww->fieldIdx() );
@ -1196,6 +1198,29 @@ void QgsAttributeForm::updateLabels()
} }
} }
void QgsAttributeForm::updateEditableState()
{
if ( ! mEditableDataDefinedProperties.isEmpty() )
{
QgsFeature currentFeature;
if ( currentFormValuesFeature( currentFeature ) )
{
QgsExpressionContext context = createExpressionContext( currentFeature );
for ( auto it = mEditableDataDefinedProperties.constBegin() ; it != mEditableDataDefinedProperties.constEnd(); ++it )
{
QWidget *w { it.key() };
bool ok;
const bool isEditable { it->valueAsBool( context, true, &ok ) };
if ( ok )
{
w->setEnabled( isEditable );
}
}
}
}
}
bool QgsAttributeForm::currentFormValuesFeature( QgsFeature &feature ) bool QgsAttributeForm::currentFormValuesFeature( QgsFeature &feature )
{ {
bool rc = true; bool rc = true;
@ -1784,11 +1809,19 @@ void QgsAttributeForm::init()
if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( QgsEditFormConfig::DataDefinedProperty::Alias ) ) if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( QgsEditFormConfig::DataDefinedProperty::Alias ) )
{ {
const QgsProperty property { mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).property( QgsEditFormConfig::DataDefinedProperty::Alias ) }; const QgsProperty property { mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).property( QgsEditFormConfig::DataDefinedProperty::Alias ) };
if ( property.isActive() && ! property.expressionString().isEmpty() ) if ( property.isActive() )
{ {
mLabelDataDefinedProperties[ label ] = property; mLabelDataDefinedProperties[ label ] = property;
} }
} }
if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( QgsEditFormConfig::DataDefinedProperty::Editable ) )
{
const QgsProperty property { mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).property( QgsEditFormConfig::DataDefinedProperty::Editable ) };
if ( property.isActive() )
{
mEditableDataDefinedProperties[ widgetInfo.widget ] = property;
}
}
} }
} }
} }
@ -1867,7 +1900,7 @@ void QgsAttributeForm::init()
if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( QgsEditFormConfig::DataDefinedProperty::Alias ) ) if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( QgsEditFormConfig::DataDefinedProperty::Alias ) )
{ {
const QgsProperty property { mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).property( QgsEditFormConfig::DataDefinedProperty::Alias ) }; const QgsProperty property { mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).property( QgsEditFormConfig::DataDefinedProperty::Alias ) };
if ( property.isActive() && ! property.expressionString().isEmpty() ) if ( property.isActive() )
{ {
mLabelDataDefinedProperties[ label ] = property; mLabelDataDefinedProperties[ label ] = property;
} }
@ -1885,6 +1918,15 @@ void QgsAttributeForm::init()
formWidget->createSearchWidgetWrappers( mContext ); formWidget->createSearchWidgetWrappers( mContext );
label->setBuddy( eww->widget() ); label->setBuddy( eww->widget() );
if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( QgsEditFormConfig::DataDefinedProperty::Editable ) )
{
const QgsProperty property { mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).property( QgsEditFormConfig::DataDefinedProperty::Editable ) };
if ( property.isActive() )
{
mEditableDataDefinedProperties[ formWidget ] = property;
}
}
} }
else else
{ {
@ -2397,11 +2439,19 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt
if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( QgsEditFormConfig::DataDefinedProperty::Alias ) ) if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( QgsEditFormConfig::DataDefinedProperty::Alias ) )
{ {
const QgsProperty property { mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).property( QgsEditFormConfig::DataDefinedProperty::Alias ) }; const QgsProperty property { mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).property( QgsEditFormConfig::DataDefinedProperty::Alias ) };
if ( property.isActive() && ! property.expressionString().isEmpty() ) if ( property.isActive() )
{ {
mLabelDataDefinedProperties[ mypLabel ] = property; mLabelDataDefinedProperties[ mypLabel ] = property;
} }
} }
if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( QgsEditFormConfig::DataDefinedProperty::Editable ) )
{
const QgsProperty property { mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).property( QgsEditFormConfig::DataDefinedProperty::Editable ) };
if ( property.isActive() )
{
mEditableDataDefinedProperties[ widgetInfo.widget ] = property;
}
}
} }
} }

View File

@ -448,6 +448,7 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
void updateContainersVisibility(); void updateContainersVisibility();
void updateConstraint( const QgsFeature &ft, QgsEditorWidgetWrapper *eww ); void updateConstraint( const QgsFeature &ft, QgsEditorWidgetWrapper *eww );
void updateLabels(); void updateLabels();
void updateEditableState();
bool currentFormValuesFeature( QgsFeature &feature ); bool currentFormValuesFeature( QgsFeature &feature );
bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions ) const; bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions ) const;
bool currentFormValidHardConstraints( QStringList &invalidFields, QStringList &descriptions ) const; bool currentFormValidHardConstraints( QStringList &invalidFields, QStringList &descriptions ) const;
@ -473,6 +474,7 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
QList< QgsAttributeFormWidget *> mFormWidgets; QList< QgsAttributeFormWidget *> mFormWidgets;
QMap<const QgsVectorLayerJoinInfo *, QgsFeature> mJoinedFeatures; QMap<const QgsVectorLayerJoinInfo *, QgsFeature> mJoinedFeatures;
QMap<QLabel *, QgsProperty> mLabelDataDefinedProperties; QMap<QLabel *, QgsProperty> mLabelDataDefinedProperties;
QMap<QWidget *, QgsProperty> mEditableDataDefinedProperties;
bool mValuesInitialized = false; bool mValuesInitialized = false;
bool mDirty = false; bool mDirty = false;
bool mIsSettingFeature = false; bool mIsSettingFeature = false;

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>752</width> <width>1033</width>
<height>620</height> <height>880</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -19,14 +19,11 @@
<property name="title"> <property name="title">
<string>General</string> <string>General</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0" columnstretch="0,0,1,0,0"> <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0" columnstretch="0,0,1,0,0,0">
<item row="2" column="1"> <item row="2" column="3">
<widget class="QCheckBox" name="reuseLastValuesCheckBox"> <widget class="QCheckBox" name="labelOnTopCheckBox">
<property name="toolTip">
<string>If checked, then the most recent value entered for this field will be remembered and reused when creating a new feature.</string>
</property>
<property name="text"> <property name="text">
<string>Reuse last entered value</string> <string>Label on top</string>
</property> </property>
<property name="checked"> <property name="checked">
<bool>false</bool> <bool>false</bool>
@ -40,13 +37,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="1" column="2" colspan="3">
<widget class="QCheckBox" name="labelOnTopCheckBox"> <widget class="QLabel" name="laComment">
<property name="text"> <property name="text">
<string>Label on top</string> <string/>
</property> </property>
<property name="checked"> <property name="wordWrap">
<bool>false</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
@ -60,6 +57,26 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="5">
<widget class="QgsPropertyOverrideButton" name="mAliasExpressionButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="reuseLastValuesCheckBox">
<property name="toolTip">
<string>If checked, then the most recent value entered for this field will be remembered and reused when creating a new feature.</string>
</property>
<property name="text">
<string>Reuse last entered value</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_9"> <widget class="QLabel" name="label_9">
<property name="text"> <property name="text">
@ -67,23 +84,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="4"> <item row="0" column="2" colspan="3">
<widget class="QgsPropertyOverrideButton" name="mAliasExpressionButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QLineEdit" name="mAlias"/> <widget class="QLineEdit" name="mAlias"/>
</item> </item>
<item row="1" column="1" colspan="3"> <item row="2" column="1">
<widget class="QLabel" name="laComment"> <widget class="QgsPropertyOverrideButton" name="mEditableExpressionButton">
<property name="text"> <property name="text">
<string/> <string>...</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
@ -330,6 +337,7 @@
</tabstops> </tabstops>
<resources> <resources>
<include location="../../../images/images.qrc"/> <include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>