Attributes form properties: make sure layer actions list is up-to-date each time a user activates the Attributes Form tab in Layer Properties (fix #49502)

This commit is contained in:
Germán Carrillo 2025-04-08 13:06:35 -05:00
parent b0ddb95a4a
commit c16df35df8
5 changed files with 97 additions and 21 deletions

View File

@ -518,28 +518,8 @@ void QgsAttributesAvailableWidgetsModel::populate()
// Load form actions
auto itemActions = std::make_unique< QgsAttributesFormItem >( QgsAttributesFormData::WidgetType, QStringLiteral( "Actions" ), tr( "Actions" ) );
const QList<QgsAction> actions { mLayer->actions()->actions() };
for ( const auto &action : std::as_const( actions ) )
{
if ( action.isValid() && action.runable() && ( action.actionScopes().contains( QStringLiteral( "Feature" ) ) || action.actionScopes().contains( QStringLiteral( "Layer" ) ) ) )
{
const QString actionTitle { action.shortTitle().isEmpty() ? action.name() : action.shortTitle() };
QgsAttributesFormData::AttributeFormItemData itemData = QgsAttributesFormData::AttributeFormItemData();
itemData.setShowLabel( true );
auto itemAction = std::make_unique< QgsAttributesFormItem >();
itemAction->setData( ItemIdRole, action.id().toString() );
itemAction->setData( ItemTypeRole, QgsAttributesFormData::Action );
itemAction->setData( ItemNameRole, actionTitle );
itemAction->setData( ItemDataRole, itemData );
itemActions->addChild( std::move( itemAction ) );
}
}
mRootItem->addChild( std::move( itemActions ) );
populateActionItems();
// Other widgets
@ -570,6 +550,57 @@ void QgsAttributesAvailableWidgetsModel::populate()
endResetModel();
}
void QgsAttributesAvailableWidgetsModel::populateLayerActions()
{
QModelIndex actionsIndex = actionContainer();
QgsAttributesFormItem *itemActions = itemForIndex( actionsIndex );
beginRemoveRows( actionsIndex, 0, itemActions->childCount() );
itemActions->deleteChildren();
endRemoveRows();
int count = 0;
const QList<QgsAction> actions { mLayer->actions()->actions() };
for ( const auto &action : std::as_const( actions ) )
{
if ( action.isValid() && action.runable() && ( action.actionScopes().contains( QStringLiteral( "Feature" ) ) || action.actionScopes().contains( QStringLiteral( "Layer" ) ) ) )
{
count++;
}
}
beginInsertRows( actionsIndex, 0, count );
populateActionItems();
endInsertRows();
}
void QgsAttributesAvailableWidgetsModel::populateActionItems()
{
const QList<QgsAction> actions { mLayer->actions()->actions() };
QModelIndex actionsIndex = actionContainer();
QgsAttributesFormItem *itemActions = itemForIndex( actionsIndex );
for ( const auto &action : std::as_const( actions ) )
{
if ( action.isValid() && action.runable() && ( action.actionScopes().contains( QStringLiteral( "Feature" ) ) || action.actionScopes().contains( QStringLiteral( "Layer" ) ) ) )
{
const QString actionTitle { action.shortTitle().isEmpty() ? action.name() : action.shortTitle() };
QgsAttributesFormData::AttributeFormItemData itemData = QgsAttributesFormData::AttributeFormItemData();
itemData.setShowLabel( true );
auto itemAction = std::make_unique< QgsAttributesFormItem >();
itemAction->setData( ItemIdRole, action.id().toString() );
itemAction->setData( ItemTypeRole, QgsAttributesFormData::Action );
itemAction->setData( ItemNameRole, actionTitle );
itemAction->setData( ItemDataRole, itemData );
itemActions->addChild( std::move( itemAction ) );
}
}
}
QVariant QgsAttributesAvailableWidgetsModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() )
@ -729,6 +760,18 @@ QModelIndex QgsAttributesAvailableWidgetsModel::relationContainer() const
return QModelIndex();
}
QModelIndex QgsAttributesAvailableWidgetsModel::actionContainer() const
{
if ( mRootItem->childCount() > 2 )
{
const int row = 2;
QgsAttributesFormItem *item = mRootItem->child( row );
if ( item && item->name() == QLatin1String( "Actions" ) && item->type() == QgsAttributesFormData::WidgetType )
return createIndex( row, 0, item );
}
return QModelIndex();
}
QModelIndex QgsAttributesAvailableWidgetsModel::fieldModelIndex( const QString &fieldName ) const
{
if ( mRootItem->childCount() == 0 )

View File

@ -639,6 +639,13 @@ class GUI_EXPORT QgsAttributesAvailableWidgetsModel : public QgsAttributesFormMo
*/
QModelIndex relationContainer() const;
/**
* Returns the action container in this model, expected to be placed at the third top-level row.
*
* If there is no action container set, an invalid index is returned.
*/
QModelIndex actionContainer() const;
/**
* Returns the model index that corresponds to the field with the given \a fieldName.
*/
@ -646,6 +653,17 @@ class GUI_EXPORT QgsAttributesAvailableWidgetsModel : public QgsAttributesFormMo
public slots:
void populate() override;
/**
* Refresh layer actions in the model to keep an updated action list.
*/
void populateLayerActions();
private:
/**
* Refresh action items in the model.
*/
void populateActionItems();
};

View File

@ -165,6 +165,11 @@ void QgsAttributesFormProperties::initSuppressCombo()
mFormSuppressCmbBx->setCurrentIndex( mFormSuppressCmbBx->findData( QVariant::fromValue( mLayer->editFormConfig().suppress() ) ) );
}
void QgsAttributesFormProperties::initAvailableWidgetsActions()
{
mAvailableWidgetsModel->populateLayerActions();
}
QgsExpressionContext QgsAttributesFormProperties::createExpressionContext() const
{
QgsExpressionContext context;

View File

@ -94,6 +94,11 @@ class GUI_EXPORT QgsAttributesFormProperties : public QWidget, public QgsExpress
void initInitPython();
void initSuppressCombo();
/**
* Refresh layer actions in the Available Widgets view
*/
void initAvailableWidgetsActions();
QgsExpressionContext createExpressionContext() const override;
protected:

View File

@ -1589,6 +1589,11 @@ void QgsVectorLayerProperties::optionsStackedWidget_CurrentChanged( int index )
// store any edited attribute form field configuration to prevent loss of edits when adding/removing fields and/or joins
mAttributesFormPropertiesDialog->store();
}
else if ( index == mOptStackedWidget->indexOf( mOptsPage_AttributesForm ) )
{
// Refresh actions in Available Widgets panel
mAttributesFormPropertiesDialog->initAvailableWidgetsActions();
}
resizeAlltabs( index );
}