Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #51525 from elpaso/widgets-editable-data-defined
[Feature] Data defined form widget editable state.
  • Loading branch information
elpaso committed Jan 23, 2023
2 parents 3f0c51d + bb86f47 commit c960802
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 31 deletions.
Expand Up @@ -75,6 +75,7 @@ Constructor for TabData
NoProperty,
AllProperties,
Alias,
Editable,
};

QgsEditFormConfig( const QgsEditFormConfig &o );
Expand Down
1 change: 1 addition & 0 deletions src/core/editform/qgseditformconfig.h
Expand Up @@ -113,6 +113,7 @@ class CORE_EXPORT QgsEditFormConfig
NoProperty = 0, //!< No property
AllProperties = 1, //!< All properties for item
Alias = 2, //!< Alias
Editable = 3, //!< Editable state \since QGIS 3.30
};

/**
Expand Down
6 changes: 6 additions & 0 deletions src/core/editform/qgseditformconfig_p.h
Expand Up @@ -64,6 +64,12 @@ class QgsEditFormConfigPrivate : public QSharedData
QObject::tr( "Alias" ),
QgsPropertyDefinition::String )
},
{
QgsEditFormConfig::DataDefinedProperty::Editable,
QgsPropertyDefinition( "dataDefinedEditable",
QObject::tr( "Editable" ),
QgsPropertyDefinition::Boolean )
},
};
return sPropertyDefinitions;
};
Expand Down
14 changes: 14 additions & 0 deletions src/gui/attributeformconfig/qgsattributetypedialog.cpp
Expand Up @@ -74,7 +74,16 @@ QgsAttributeTypeDialog::QgsAttributeTypeDialog( QgsVectorLayer *vl, int fieldIdx
mExpressionWidget->registerExpressionContextGenerator( this );
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->init( QgsEditFormConfig::DataDefinedProperty::Alias, mDataDefinedProperties.property( QgsEditFormConfig::DataDefinedProperty::Alias ), vl->editFormConfig().propertyDefinitions(), vl );
connect( mAliasExpressionButton, &QgsPropertyOverrideButton::changed, this, [ = ]
{
mDataDefinedProperties.setProperty( QgsEditFormConfig::DataDefinedProperty::Alias, mAliasExpressionButton->toProperty() );
Expand Down Expand Up @@ -321,6 +330,7 @@ QgsExpressionContext QgsAttributeTypeDialog::createExpressionContext() const
<< QgsExpressionContextUtils::globalScope()
<< QgsExpressionContextUtils::projectScope( QgsProject::instance() )
<< QgsExpressionContextUtils::layerScope( mLayer )
<< QgsExpressionContextUtils::formScope( )
<< QgsExpressionContextUtils::mapToolCaptureScope( QList<QgsPointLocator::Match>() );

return context;
Expand Down Expand Up @@ -372,6 +382,10 @@ void QgsAttributeTypeDialog::setDataDefinedProperties( const QgsPropertyCollecti
{
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 )
Expand Down
58 changes: 54 additions & 4 deletions src/gui/qgsattributeform.cpp
Expand Up @@ -99,6 +99,7 @@ QgsAttributeForm::QgsAttributeForm( QgsVectorLayer *vl, const QgsFeature &featur

updateContainersVisibility();
updateLabels();
updateEditableState();

}

Expand Down Expand Up @@ -1051,8 +1052,9 @@ void QgsAttributeForm::onAttributeChanged( const QVariant &value, const QVariant
mAlreadyUpdatedFields.removeAll( eww->fieldIdx() );
}

// Updates expression controlled labels
// Updates expression controlled labels and editable state
updateLabels();
updateEditableState();

// Update other widgets pointing to the same field
const QList<QgsAttributeFormEditorWidget *> formEditorWidgets = mFormEditorWidgets.values( eww->fieldIdx() );
Expand Down Expand Up @@ -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 rc = true;
Expand Down Expand Up @@ -1784,11 +1809,19 @@ void QgsAttributeForm::init()
if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( 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;
}
}
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;
}
}
}
}
}
Expand Down Expand Up @@ -1867,7 +1900,7 @@ void QgsAttributeForm::init()
if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( 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;
}
Expand All @@ -1885,6 +1918,15 @@ void QgsAttributeForm::init()
formWidget->createSearchWidgetWrappers( mContext );

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
{
Expand Down Expand Up @@ -2397,11 +2439,19 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt
if ( mLayer->editFormConfig().dataDefinedFieldProperties( fieldName ).hasProperty( 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;
}
}
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;
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/gui/qgsattributeform.h
Expand Up @@ -448,6 +448,7 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
void updateContainersVisibility();
void updateConstraint( const QgsFeature &ft, QgsEditorWidgetWrapper *eww );
void updateLabels();
void updateEditableState();
bool currentFormValuesFeature( QgsFeature &feature );
bool currentFormValidConstraints( QStringList &invalidFields, QStringList &descriptions ) const;
bool currentFormValidHardConstraints( QStringList &invalidFields, QStringList &descriptions ) const;
Expand All @@ -473,6 +474,7 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
QList< QgsAttributeFormWidget *> mFormWidgets;
QMap<const QgsVectorLayerJoinInfo *, QgsFeature> mJoinedFeatures;
QMap<QLabel *, QgsProperty> mLabelDataDefinedProperties;
QMap<QWidget *, QgsProperty> mEditableDataDefinedProperties;
bool mValuesInitialized = false;
bool mDirty = false;
bool mIsSettingFeature = false;
Expand Down
62 changes: 35 additions & 27 deletions src/ui/attributeformconfig/qgsattributetypeedit.ui
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>752</width>
<height>620</height>
<width>1033</width>
<height>880</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -19,14 +19,11 @@
<property name="title">
<string>General</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0" columnstretch="0,0,1,0,0">
<item row="2" column="1">
<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>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0" columnstretch="0,0,1,0,0,0">
<item row="2" column="3">
<widget class="QCheckBox" name="labelOnTopCheckBox">
<property name="text">
<string>Reuse last entered value</string>
<string>Label on top</string>
</property>
<property name="checked">
<bool>false</bool>
Expand All @@ -40,13 +37,13 @@
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="labelOnTopCheckBox">
<item row="1" column="2" colspan="3">
<widget class="QLabel" name="laComment">
<property name="text">
<string>Label on top</string>
<string/>
</property>
<property name="checked">
<bool>false</bool>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
Expand All @@ -60,30 +57,40 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<item row="0" column="5">
<widget class="QgsPropertyOverrideButton" name="mAliasExpressionButton">
<property name="text">
<string>Alias</string>
<string>...</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QgsPropertyOverrideButton" name="mAliasExpressionButton">
<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>...</string>
<string>Reuse last entered value</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Alias</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<item row="0" column="2" colspan="3">
<widget class="QLineEdit" name="mAlias"/>
</item>
<item row="1" column="1" colspan="3">
<widget class="QLabel" name="laComment">
<item row="2" column="1">
<widget class="QgsPropertyOverrideButton" name="mEditableExpressionButton">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
<string>...</string>
</property>
</widget>
</item>
Expand Down Expand Up @@ -330,6 +337,7 @@
</tabstops>
<resources>
<include location="../../../images/images.qrc"/>
<include location="../../../images/images.qrc"/>
</resources>
<connections/>
</ui>

0 comments on commit c960802

Please sign in to comment.