23#include "qgsattributeformcontaineredit.h"
27#include "qgsattributetypedialog.h"
28#include "qgsattributewidgetedit.h"
42#include "moc_qgsattributesformproperties.cpp"
44using namespace Qt::StringLiterals;
46#ifdef ENABLE_MODELTEST
55 , mSourceFieldsProperties( sourceFieldsProperties )
68 QGridLayout *availableWidgetsWidgetLayout =
new QGridLayout;
71 availableWidgetsWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
72 mAvailableWidgetsWidget->setLayout( availableWidgetsWidgetLayout );
81 mAvailableWidgetsProxyModel->setAttributesFormSourceModel( mAvailableWidgetsModel );
82 mAvailableWidgetsProxyModel->setRecursiveFilteringEnabled(
true );
88#ifdef ENABLE_MODELTEST
89 new ModelTest( mAvailableWidgetsProxyModel,
this );
93 QGridLayout *formLayoutWidgetLayout =
new QGridLayout;
96 formLayoutWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
97 mFormLayoutWidget->setLayout( formLayoutWidgetLayout );
105 mFormLayoutProxyModel->setAttributesFormSourceModel( mFormLayoutModel );
106 mFormLayoutProxyModel->setRecursiveFilteringEnabled(
true );
112#ifdef ENABLE_MODELTEST
113 new ModelTest( mFormLayoutProxyModel,
this );
116 connect(
mAvailableWidgetsView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
117 connect(
mFormLayoutView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
119 connect(
mAvailableWidgetsView, &QWidget::customContextMenuRequested,
this, &QgsAttributesFormProperties::onContextMenuRequested );
121 connect( mAddContainerButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::addContainer );
122 connect( mRemoveLayoutItemButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::removeTabOrGroupButton );
123 connect( mInvertSelectionButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::onInvertSelectionButtonClicked );
124 connect( mShowAliasesButton, &QAbstractButton::toggled,
this, &QgsAttributesFormProperties::toggleShowAliases );
125 connect( mEditorLayoutComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged );
126 connect( pbnSelectEditForm, &QToolButton::clicked,
this, &QgsAttributesFormProperties::pbnSelectEditForm_clicked );
127 connect( mTbInitCode, &QPushButton::clicked,
this, &QgsAttributesFormProperties::mTbInitCode_clicked );
129 connect( mSearchLineEdit, &QgsFilterLineEdit::textChanged,
this, &QgsAttributesFormProperties::updateFilteredItems );
132 if ( !mBlockUpdates )
137 mAvailableWidgetsContextMenu =
new QMenu(
this );
138 mActionCopyWidgetConfiguration =
new QAction( tr(
"Copy widget configuration" ),
this );
139 mActionPasteWidgetConfiguration =
new QAction( tr(
"Paste widget configuration" ),
this );
141 connect( mActionCopyWidgetConfiguration, &QAction::triggered,
this, &QgsAttributesFormProperties::copyWidgetConfiguration );
142 connect( mActionPasteWidgetConfiguration, &QAction::triggered,
this, &QgsAttributesFormProperties::pasteWidgetConfiguration );
144 mAvailableWidgetsContextMenu->addAction( mActionCopyWidgetConfiguration );
145 mAvailableWidgetsContextMenu->addAction( mActionPasteWidgetConfiguration );
148 mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
149 gridLayout->addWidget( mMessageBar, 0, 0 );
153 splitter->setSizes( { widget->minimumSizeHint().width(), 600 } );
155 if ( mSourceFieldsProperties )
157 connect( mFormPreviewButton, &QAbstractButton::clicked,
this, &QgsAttributesFormProperties::previewForm );
161 mFormPreviewButton->setVisible(
false );
183 mAvailableWidgetsModel->populate();
192 mFormLayoutView->setSelectionBehavior( QAbstractItemView::SelectRows );
193 mFormLayoutView->setSelectionMode( QAbstractItemView::SelectionMode::ExtendedSelection );
195 mFormLayoutView->setDragDropMode( QAbstractItemView::DragDropMode::DragDrop );
199 mFormLayoutModel->populate();
218 mFormSuppressCmbBx->setCurrentIndex( mFormSuppressCmbBx->findData( QVariant::fromValue(
mLayer->editFormConfig().suppress() ) ) );
223 mAvailableWidgetsModel->populateLayerActions( actions );
235 mEditorLayoutComboBox->setCurrentIndex( mEditorLayoutComboBox->findData( QVariant::fromValue(
mLayer->editFormConfig().layout() ) ) );
237 mEditorLayoutComboBox_currentIndexChanged( mEditorLayoutComboBox->currentIndex() );
240 mEditFormLineEdit->setText( cfg.
uiForm() );
252 if ( mInitCode.isEmpty() )
254 mInitCode.append( tr(
"# -*- coding: utf-8 -*-\n\"\"\"\n"
255 "QGIS forms can have a Python function that is called when the form is\n"
258 "Use this function to add extra logic to your forms.\n"
260 "Enter the name of the function in the \"Python Init function\"\n"
262 "An example follows:\n"
264 "from qgis.PyQt.QtWidgets import QWidget\n\n"
265 "def my_form_open(dialog, layer, feature):\n"
266 " geom = feature.geometry()\n"
267 " control = dialog.findChild(QWidget, \"MyLineEdit\")\n" ) );
271void QgsAttributesFormProperties::loadAttributeTypeDialog()
282 if ( fieldIndex < 0 )
287 loadAttributeTypeDialogFromConfiguration( cfg );
290 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
334void QgsAttributesFormProperties::storeAttributeTypeDialog()
342 QgsAttributesFormData::FieldConfig cfg;
351 QgsFieldConstraints constraints;
394 const QString fieldName =
mLayer->fields().at( fieldIndex ).name();
396 QModelIndex index = mAvailableWidgetsModel->fieldModelIndex( fieldName );
397 if ( index.isValid() )
404 mFormLayoutModel->updateFieldConfigForFieldItems( fieldName, cfg );
410void QgsAttributesFormProperties::storeAttributeWidgetEdit()
419 storeAttributeWidgetEdit( index );
422void QgsAttributesFormProperties::storeAttributeWidgetEdit(
const QModelIndex &index )
427 if ( !index.isValid() )
435 QgsAttributesFormData::RelationEditorConfiguration config =
mAttributeWidgetEdit->updatedRelationConfiguration();
436 itemData.setRelationEditorConfiguration( config );
442void QgsAttributesFormProperties::loadAttributeWidgetEdit()
447 const QModelIndex currentIndex =
mFormLayoutView->firstSelectedIndex();
448 const QgsAttributesFormData::AttributeFormItemData itemData = currentIndex.data(
QgsAttributesFormModel::ItemDataRole ).value< QgsAttributesFormData::AttributeFormItemData >();
454 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
458void QgsAttributesFormProperties::loadInfoWidget(
const QString &infoText )
461 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
465void QgsAttributesFormProperties::storeAttributeContainerEdit()
473 const QModelIndex currentIndex =
mFormLayoutView->firstSelectedIndex();
474 storeAttributeContainerEdit( currentIndex );
477void QgsAttributesFormProperties::storeAttributeContainerEdit(
const QModelIndex &index )
482 if ( !index.isValid() )
486 QString containerName;
493void QgsAttributesFormProperties::loadAttributeContainerEdit()
498 const QModelIndex currentIndex =
mFormLayoutView->firstSelectedIndex();
499 const QgsAttributesFormData::AttributeFormItemData itemData = currentIndex.data(
QgsAttributesFormModel::ItemDataRole ).value< QgsAttributesFormData::AttributeFormItemData >();
506 mAttributeTypeFrame->layout()->setContentsMargins( 0, 0, 0, 0 );
510void QgsAttributesFormProperties::onAttributeSelectionChanged(
const QItemSelection &,
const QItemSelection & )
512 disconnect(
mFormLayoutView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
515 if (
mFormLayoutView->selectionModel()->selectedRows( 0 ).count() == 1 )
523 connect(
mFormLayoutView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsAttributesFormProperties::onFormLayoutSelectionChanged );
526void QgsAttributesFormProperties::onFormLayoutSelectionChanged(
const QItemSelection &,
const QItemSelection &deselected )
529 disconnect(
mAvailableWidgetsView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
531 if ( deselected.indexes().count() == 1 )
533 index = mFormLayoutProxyModel->mapToSource( deselected.indexes().at( 0 ) );
535 else if ( deselected.indexes().count() == 0 &&
mFormLayoutView->selectionModel()->selectedIndexes().count() == 2 )
542 connect(
mAvailableWidgetsView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &QgsAttributesFormProperties::onAttributeSelectionChanged );
551 storeAttributeWidgetEdit( deselectedFormLayoutIndex );
552 storeAttributeContainerEdit( deselectedFormLayoutIndex );
556 storeAttributeTypeDialog();
559 clearAttributeTypeFrame();
561 if ( emitter->selectionModel()->selectedRows( 0 ).count() != 1 )
563 receiver->clearSelection();
576 loadAttributeWidgetEdit();
580 loadInfoWidget( tr(
"This configuration is available in the Drag and Drop Designer" ) );
589 loadAttributeWidgetEdit();
591 loadAttributeTypeDialog();
596 receiver->clearSelection();
597 loadAttributeContainerEdit();
604 loadInfoWidget( action.
html() );
614 loadInfoWidget( tr(
"This configuration is available with double-click in the Drag and Drop Designer" ) );
618 loadInfoWidget( tr(
"This configuration is available with double-click in the Form Layout panel" ) );
620 receiver->clearSelection();
625 receiver->clearSelection();
632void QgsAttributesFormProperties::clearAttributeTypeFrame()
660void QgsAttributesFormProperties::onInvertSelectionButtonClicked(
bool checked )
663 for (
int i = 0; i < mFormLayoutProxyModel->rowCount(); ++i )
665 QModelIndex index = mFormLayoutProxyModel->index( i, 0 );
666 mFormLayoutView->selectionModel()->select( index, QItemSelectionModel::Toggle );
670void QgsAttributesFormProperties::toggleShowAliases(
bool checked )
673 mAvailableWidgetsModel->setShowAliases( checked );
674 mFormLayoutModel->setShowAliases( checked );
677void QgsAttributesFormProperties::addContainer()
679 QList<QgsAddAttributeFormContainerDialog::ContainerPair> existingContainerList = mFormLayoutModel->listOfContainers();
681 QModelIndex currentItem;
685 QgsAddAttributeFormContainerDialog dialog(
mLayer, existingContainerList, currentItem,
this );
687 if ( !dialog.exec() )
690 const QString name = dialog.name();
691 QModelIndex parentContainerItem = dialog.parentContainerItem();
693 mFormLayoutModel->addContainer( parentContainerItem, name, dialog.columnCount(), dialog.containerType() );
694 if ( parentContainerItem.isValid() )
698void QgsAttributesFormProperties::removeTabOrGroupButton()
704 const QModelIndexList items =
mFormLayoutView->selectionModel()->selectedRows();
708 const QModelIndex item = mFormLayoutProxyModel->mapToSource( items.at( 0 ) );
709 mFormLayoutModel->removeRow( item.row(), item.parent() );
713void QgsAttributesFormProperties::mEditorLayoutComboBox_currentIndexChanged(
int )
717 if ( selection.count() > 0 )
731 mFormLayoutWidget->setVisible(
false );
732 mTreeViewHorizontalSpacer->changeSize( 0, 20, QSizePolicy::Fixed, QSizePolicy::Fixed );
733 mUiFileFrame->setVisible(
false );
734 mAddContainerButton->setVisible(
false );
735 mRemoveLayoutItemButton->setVisible(
false );
736 mInvertSelectionButton->setVisible(
false );
738 setAvailableWidgetsIndicatorProvidersEnabled(
true );
739 setFormLayoutIndicatorProvidersEnabled(
false );
743 mFormLayoutWidget->setVisible(
true );
744 mTreeViewHorizontalSpacer->changeSize( 6, 20, QSizePolicy::Fixed, QSizePolicy::Fixed );
745 mUiFileFrame->setVisible(
false );
746 mAddContainerButton->setVisible(
true );
747 mRemoveLayoutItemButton->setVisible(
true );
748 mInvertSelectionButton->setVisible(
true );
750 setAvailableWidgetsIndicatorProvidersEnabled(
false );
751 setFormLayoutIndicatorProvidersEnabled(
true );
756 mFormLayoutWidget->setVisible(
false );
757 mTreeViewHorizontalSpacer->changeSize( 0, 20, QSizePolicy::Fixed, QSizePolicy::Fixed );
758 mUiFileFrame->setVisible(
true );
759 mAddContainerButton->setVisible(
false );
760 mRemoveLayoutItemButton->setVisible(
false );
761 mInvertSelectionButton->setVisible(
false );
763 setAvailableWidgetsIndicatorProvidersEnabled(
true );
764 setFormLayoutIndicatorProvidersEnabled(
false );
769 if ( selection.count() > 0 )
775void QgsAttributesFormProperties::mTbInitCode_clicked()
777 QgsAttributesFormInitCode attributesFormInitCode;
784 if ( !attributesFormInitCode.exec() )
787 mInitCodeSource = attributesFormInitCode.
codeSource();
788 mInitCode = attributesFormInitCode.
initCode();
793void QgsAttributesFormProperties::pbnSelectEditForm_clicked()
795 QgsSettings myQSettings;
796 const QString lastUsedDir = myQSettings.
value( u
"style/lastUIDir"_s, QDir::homePath() ).toString();
797 const QString uifilename = QFileDialog::getOpenFileName(
this, tr(
"Select edit form" ), lastUsedDir, tr(
"UI file" ) +
" (*.ui)" );
799 if ( uifilename.isNull() )
802 const QFileInfo fi( uifilename );
803 myQSettings.
setValue( u
"style/lastUIDir"_s, fi.path() );
804 mEditFormLineEdit->setText( uifilename );
809 storeAttributeWidgetEdit();
810 storeAttributeContainerEdit();
811 storeAttributeTypeDialog();
821void QgsAttributesFormProperties::applyToLayer(
QgsVectorLayer *layer )
826 const QModelIndex fieldContainer = mAvailableWidgetsModel->
fieldContainer();
829 for (
int i = 0; i < mAvailableWidgetsModel->
rowCount( fieldContainer ); i++ )
831 index = mAvailableWidgetsModel->
index( i, 0, fieldContainer );
890 for (
int t = 0; t < mFormLayoutModel->rowCount(); t++ )
892 QModelIndex index = mFormLayoutModel->index( t, 0 );
893 QgsAttributeEditorElement *editorElement { mFormLayoutModel->createAttributeEditorWidget( index,
nullptr ) };
895 editFormConfig.
addTab( editorElement );
898 editFormConfig.
setUiForm( mEditFormLineEdit->text() );
910 const QModelIndex relationContainer = mAvailableWidgetsModel->relationContainer();
912 for (
int i = 0; i < mAvailableWidgetsModel->rowCount( relationContainer ); i++ )
914 const QModelIndex relationIndex = mAvailableWidgetsModel->index( i, 0, relationContainer );
920 const QModelIndex layoutIndex = mFormLayoutModel->firstRecursiveMatchingModelIndex( indexType, indexId );
921 if ( layoutIndex.isValid() )
925 const QgsAttributesFormData::AttributeFormItemData tabIndexData = layoutIndex.data(
QgsAttributesFormModel::ItemDataRole ).value<QgsAttributesFormData::AttributeFormItemData>();
937void QgsAttributesFormProperties::updatedFields()
940 QMap<QString, QgsAttributesFormData::FieldConfig> fieldConfigs;
942 const QModelIndex fieldContainerBefore = mAvailableWidgetsModel->fieldContainer();
945 for (
int i = 0; i < mAvailableWidgetsModel->rowCount( fieldContainerBefore ); i++ )
947 index = mAvailableWidgetsModel->index( i, 0, fieldContainerBefore );
950 fieldConfigs[fieldName] = config;
955 const QModelIndex fieldContainerAfter = mAvailableWidgetsModel->fieldContainer();
957 for (
int i = 0; i < mAvailableWidgetsModel->rowCount( fieldContainerAfter ); i++ )
959 index = mAvailableWidgetsModel->index( i, 0, fieldContainerAfter );
962 if ( fieldConfigs.contains( fieldName ) )
970void QgsAttributesFormProperties::updateFilteredItems(
const QString &filterText )
972 const int availableWidgetsPreviousSelectionCount =
mAvailableWidgetsView->selectionModel()->selectedRows().count();
973 const int formLayoutPreviousSelectionCount =
mFormLayoutView->selectionModel()->selectedRows().count();
975 static_cast< QgsAttributesAvailableWidgetsView *
>(
mAvailableWidgetsView )->setFilterText( filterText );
978 static_cast< QgsAttributesFormLayoutView *
>(
mFormLayoutView )->setFilterText( filterText );
983 if ( !( availableWidgetsPreviousSelectionCount == 0 && formLayoutPreviousSelectionCount == 0 ) )
985 const int selectedAvailableWidgetItemCount =
mAvailableWidgetsView->selectionModel()->selectedRows().count();
986 const int selectedFormLayoutItemCount =
mFormLayoutView->selectionModel()->selectedRows().count();
988 if ( selectedAvailableWidgetItemCount == 0 && selectedFormLayoutItemCount == 0 )
991 clearAttributeTypeFrame();
996void QgsAttributesFormProperties::onContextMenuRequested( QPoint point )
1007 const QClipboard *clipboard = QApplication::clipboard();
1008 const QMimeData *mimeData = clipboard->mimeData();
1012 const bool pasteEnabled = mimeData->hasFormat( u
"application/x-qgsattributetabledesignerelementclipboard"_s );
1013 mActionPasteWidgetConfiguration->setEnabled( pasteEnabled );
1014 mAvailableWidgetsContextMenu->popup( globalPos );
1018void QgsAttributesFormProperties::copyWidgetConfiguration()
1030 const int fieldIndex =
mLayer->fields().indexOf( fieldName );
1032 if ( fieldIndex < 0 )
1035 const QgsField field =
mLayer->fields().field( fieldIndex );
1039 QDomElement documentElement = doc.createElement( u
"FormWidgetClipboard"_s );
1040 documentElement.setAttribute( u
"name"_s, field.
name() );
1045 QDomElement editWidgetElement = doc.createElement( u
"editWidget"_s );
1046 documentElement.appendChild( editWidgetElement );
1047 editWidgetElement.setAttribute( u
"type"_s, widgetSetup.
type() );
1048 QDomElement editWidgetConfigElement = doc.createElement( u
"config"_s );
1051 editWidgetElement.appendChild( editWidgetConfigElement );
1054 QDomElement splitPolicyElement = doc.createElement( u
"splitPolicy"_s );
1056 documentElement.appendChild( splitPolicyElement );
1059 QDomElement duplicatePolicyElement = doc.createElement( u
"duplicatePolicy"_s );
1061 documentElement.appendChild( duplicatePolicyElement );
1064 QDomElement mergePolicyElement = doc.createElement( u
"mergePolicy"_s );
1066 documentElement.appendChild( mergePolicyElement );
1069 QDomElement defaultElem = doc.createElement( u
"default"_s );
1072 documentElement.appendChild( defaultElem );
1075 QDomElement constraintElem = doc.createElement( u
"constraint"_s );
1080 documentElement.appendChild( constraintElem );
1083 QDomElement constraintExpressionElem = doc.createElement( u
"constraintExpression"_s );
1086 documentElement.appendChild( constraintExpressionElem );
1091 QDomElement widgetGeneralSettingsElem = doc.createElement( u
"widgetGeneralSettings"_s );
1092 widgetGeneralSettingsElem.setAttribute( u
"editable"_s,
mAttributeTypeDialog->fieldEditable() );
1093 widgetGeneralSettingsElem.setAttribute( u
"label_on_top"_s,
mAttributeTypeDialog->labelOnTop() );
1095 documentElement.appendChild( widgetGeneralSettingsElem );
1105 const QModelIndex indexLayout =
mFormLayoutView->firstSelectedIndex();
1108 QDomElement displayElement = doc.createElement( u
"widgetDisplay"_s );
1109 displayElement.setAttribute( u
"showLabel"_s, layoutData.showLabel() );
1110 displayElement.setAttribute( u
"horizontalStretch"_s, layoutData.horizontalStretch() );
1111 displayElement.setAttribute( u
"verticalStretch"_s, layoutData.verticalStretch() );
1112 displayElement.appendChild( layoutData.labelStyle().writeXml( doc ) );
1113 documentElement.appendChild( displayElement );
1116 doc.appendChild( documentElement );
1118 QMimeData *mimeData =
new QMimeData;
1119 mimeData->setData( u
"application/x-qgsattributetabledesignerelementclipboard"_s, doc.toByteArray() );
1120 QClipboard *clipboard = QApplication::clipboard();
1121 clipboard->setMimeData( mimeData );
1124void QgsAttributesFormProperties::pasteWidgetConfiguration()
1132 const int fieldIndex =
mLayer->fields().indexOf( fieldName );
1134 if ( fieldIndex < 0 )
1141 QClipboard *clipboard = QApplication::clipboard();
1142 const QMimeData *mimeData = clipboard->mimeData();
1146 if ( doc.setContent( mimeData->data( u
"application/x-qgsattributetabledesignerelementclipboard"_s ) ) )
1148 QgsReadWriteContext context;
1149 QDomElement docElem = doc.documentElement();
1150 if ( docElem.tagName() !=
"FormWidgetClipboard"_L1 )
1159 const QDomElement fieldWidgetElement = docElem.firstChildElement( u
"editWidget"_s );
1160 if ( !fieldWidgetElement.isNull() )
1162 const QString widgetType = fieldWidgetElement.attribute( u
"type"_s );
1168 const QDomElement configElement = fieldWidgetElement.firstChildElement( u
"config"_s );
1169 if ( !configElement.isNull() )
1171 const QDomElement optionsElem = configElement.childNodes().at( 0 ).toElement();
1179 mMessageBar->pushMessage( QString(), tr(
"Unable to paste widget configuration. The target field (%1) does not support the %2 widget type." ).arg( fieldName, widgetType ),
Qgis::MessageLevel::Warning );
1184 const QDomElement splitPolicyElement = docElem.firstChildElement( u
"splitPolicy"_s );
1185 if ( !splitPolicyElement.isNull() )
1192 const QDomElement duplicatePolicyElement = docElem.firstChildElement( u
"duplicatePolicy"_s );
1193 if ( !duplicatePolicyElement.isNull() )
1200 const QDomElement mergePolicyElement = docElem.firstChildElement( u
"mergePolicy"_s );
1201 if ( !mergePolicyElement.isNull() )
1208 const QDomElement defaultElement = docElem.firstChildElement( u
"default"_s );
1209 if ( !defaultElement.isNull() )
1218 const QDomElement constraintElement = docElem.firstChildElement( u
"constraint"_s );
1219 if ( !constraintElement.isNull() )
1221 const int intConstraints = constraintElement.attribute( u
"constraints"_s, u
"0"_s ).toInt();
1247 const int uniqueStrength = constraintElement.attribute( u
"unique_strength"_s, u
"1"_s ).toInt();
1248 const int notNullStrength = constraintElement.attribute( u
"notnull_strength"_s, u
"1"_s ).toInt();
1249 const int expStrength = constraintElement.attribute( u
"exp_strength"_s, u
"1"_s ).toInt();
1260 const QDomElement constraintExpressionElement = docElem.firstChildElement( u
"constraintExpression"_s );
1261 if ( !constraintExpressionElement.isNull() )
1263 QString expression = constraintExpressionElement.attribute( u
"exp"_s, QString() );
1264 QString description = constraintExpressionElement.attribute( u
"desc"_s, QString() );
1270 const QDomElement widgetGeneralSettingsElement = docElem.firstChildElement( u
"widgetGeneralSettings"_s );
1271 if ( !widgetGeneralSettingsElement.isNull() )
1273 const int editable = widgetGeneralSettingsElement.attribute( u
"editable"_s, u
"0"_s ).toInt();
1275 if ( widgetGeneralSettingsElement.hasAttribute( u
"reuse_last_values"_s ) )
1283 const int labelOnTop = widgetGeneralSettingsElement.attribute( u
"label_on_top"_s, u
"0"_s ).toInt();
1290 loadAttributeTypeDialogFromConfiguration( config );
1295 const QDomElement displayElement = docElem.firstChildElement( u
"widgetDisplay"_s );
1296 if ( !displayElement.isNull() )
1298 const int showLabel = displayElement.attribute( u
"showLabel"_s, u
"0"_s ).toInt();
1299 const int horizontalStretch = displayElement.attribute( u
"horizontalStretch"_s, u
"0"_s ).toInt();
1300 const int verticalStretch = displayElement.attribute( u
"verticalStretch"_s, u
"0"_s ).toInt();
1301 QgsAttributeEditorElement::LabelStyle style;
1302 style.
readXml( displayElement );
1314void QgsAttributesFormProperties::setAvailableWidgetsIndicatorProvidersEnabled(
bool enabled )
1317 if ( enabled && !mDefaultValueIndicatorProviderAvailableWidgets->isEnabled() )
1320 mDefaultValueIndicatorProviderAvailableWidgets->setEnabled( enabled );
1322 else if ( !enabled && mDefaultValueIndicatorProviderAvailableWidgets->isEnabled() )
1325 mDefaultValueIndicatorProviderAvailableWidgets->setEnabled( enabled );
1328 if ( enabled && !mConstraintIndicatorProviderAvailableWidgets->isEnabled() )
1331 mConstraintIndicatorProviderAvailableWidgets->setEnabled( enabled );
1333 else if ( !enabled && mConstraintIndicatorProviderAvailableWidgets->isEnabled() )
1336 mConstraintIndicatorProviderAvailableWidgets->setEnabled( enabled );
1340void QgsAttributesFormProperties::setFormLayoutIndicatorProvidersEnabled(
bool enabled )
1343 if ( enabled && !mDefaultValueIndicatorProviderFormLayout->isEnabled() )
1346 mDefaultValueIndicatorProviderFormLayout->setEnabled( enabled );
1348 else if ( !enabled && mDefaultValueIndicatorProviderFormLayout->isEnabled() )
1351 mDefaultValueIndicatorProviderFormLayout->setEnabled( enabled );
1354 if ( enabled && !mConstraintIndicatorProviderFormLayout->isEnabled() )
1357 mConstraintIndicatorProviderFormLayout->setEnabled( enabled );
1359 else if ( !enabled && mConstraintIndicatorProviderFormLayout->isEnabled() )
1362 mConstraintIndicatorProviderFormLayout->setEnabled( enabled );
1366void QgsAttributesFormProperties::previewForm()
1368 if ( !mSourceFieldsProperties )
1377 QList<QPair<QgsField, QString>> expressionFields;
1379 for (
int i = 0; i <
mLayer->fields().size(); i++ )
1383 expressionFields << qMakePair(
mLayer->fields().at( i ),
mLayer->expressionField( i ) );
1391 std::unique_ptr<QgsVectorLayer> vlayer;
1393 for (
const QPair<QgsField, QString> &expressionField : std::as_const( expressionFields ) )
1395 vlayer->addExpressionField( expressionField.second, expressionField.first );
1398 mSourceFieldsProperties->applyToLayer( vlayer.get() );
1399 applyToLayer( vlayer.get() );
1402 QgsAttributeDialog form( vlayer.get(), &feature,
false,
this,
true );
1406 projectDirtyBlocker.reset();
AttributeFormReuseLastValuePolicy
Attribute form policy for reusing last entered values.
@ AllowedDefaultOn
Reuse of last values allowed and enabled by default.
@ NotAllowed
Reuse of last values not allowed.
AttributeFormSuppression
Available form types for layout of the attribute form editor.
@ On
Always suppress feature form.
@ Default
Use the application-wide setting.
@ Off
Never suppress feature form.
AttributeFormLayout
Available form types for layout of the attribute form editor.
@ DragAndDrop
"Drag and drop" layout. Needs to be configured.
@ AutoGenerated
Autogenerate a simple tabular layout for the form.
@ UiFile
Load a .ui file for the layout. Needs to be configured.
FieldDomainMergePolicy
Merge policy for field domains.
@ DefaultValue
Use default field value.
@ Warning
Warning message.
FieldDomainSplitPolicy
Split policy for field domains.
@ Duplicate
Duplicate original value.
FieldDuplicatePolicy
Duplicate policy for fields.
@ Duplicate
Duplicate original value.
@ Expression
Field is calculated from an expression.
QString html() const
Returns an HTML table with the basic information about this action.
@ PreviewMode
Preview mode, for previewing attribute configurations.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
Provides field constraint indicators for attribute form views.
ConstraintStrength
Strength of constraints.
@ ConstraintStrengthSoft
User is warned if constraint is violated but feature can still be accepted.
@ ConstraintStrengthHard
Constraint must be honored before feature can be accepted.
void setConstraintStrength(Constraint constraint, ConstraintStrength strength)
Sets the strength of a constraint.
void setConstraintExpression(const QString &expression, const QString &description=QString())
Set the constraint expression for the field.
@ ConstraintOriginProvider
Constraint was set at data provider.
@ ConstraintOriginLayer
Constraint was set by layer.
ConstraintStrength constraintStrength(Constraint constraint) const
Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint is not pres...
ConstraintOrigin constraintOrigin(Constraint constraint) const
Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint is not present ...
QString constraintExpression() const
Returns the constraint expression for the field, if set.
@ ConstraintNotNull
Field may not be null.
@ ConstraintUnique
Field must have a unique value.
@ ConstraintExpression
Field has an expression constraint set. See constraintExpression().
void removeConstraint(Constraint constraint)
Removes a constraint from the field.
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
void setConstraint(Constraint constraint, ConstraintOrigin origin=ConstraintOriginLayer)
Sets a constraint on the field.
QFlags< Constraint > Constraints
Provides default value indicators for attribute form views.
Qgis::FieldDomainSplitPolicy splitPolicy() const
Returns the field's split policy, which indicates how field values should be handled during a split o...
Qgis::FieldDuplicatePolicy duplicatePolicy() const
Returns the field's duplicate policy, which indicates how field values should be handled during a dup...
QgsDefaultValue defaultValueDefinition
Qgis::FieldDomainMergePolicy mergePolicy() const
Returns the field's merge policy, which indicates how field values should be handled during a merge o...
QgsFieldConstraints constraints
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Q_INVOKABLE int indexOf(const QString &fieldName) const
Gets the field index from the field name.
static QgsEditorWidgetRegistry * editorWidgetRegistry()
Returns the global editor widget registry, used for managing all known edit widget factories.
static QgsVectorLayer * createMemoryLayer(const QString &name, const QgsFields &fields, Qgis::WkbType geometryType=Qgis::WkbType::NoGeometry, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem(), bool loadDefaultStyle=true) SIP_FACTORY
Creates a new memory layer using the specified parameters.
A bar for displaying non-blocking messages to the user.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
static QgsProject * instance()
Returns the QgsProject singleton instance.
int count() const
Returns the number of properties contained within the collection.
A boolean settings entry.
static const QgsSettingsEntryBool * settingsDigitizingDisableEnterAttributeValuesDialog
Settings entry digitizing disable enter attribute values dialog.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
A widget which displays information about vector layer fields, and allows some configuration of them.
static QgsFeature createFeature(const QgsVectorLayer *layer, const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap(), QgsExpressionContext *context=nullptr)
Creates a new feature ready for insertion into a layer.
Represents a vector layer which manages a vector based dataset.
void setFieldConstraint(int index, QgsFieldConstraints::Constraint constraint, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthHard)
Sets a constraint for a specified field index.
void removeFieldConstraint(int index, QgsFieldConstraints::Constraint constraint)
Removes a constraint for a specified field index.
void setFieldMergePolicy(int index, Qgis::FieldDomainMergePolicy policy)
Sets a merge policy for the field with the specified index.
void setDefaultValueDefinition(int index, const QgsDefaultValue &definition)
Sets the definition of the expression to use when calculating the default value for a field.
void setEditFormConfig(const QgsEditFormConfig &editFormConfig)
Sets the editFormConfig (configuration) of the form used to represent this vector layer.
void setEditorWidgetSetup(int index, const QgsEditorWidgetSetup &setup)
Sets the editor widget setup for the field at the specified index.
void setConstraintExpression(int index, const QString &expression, const QString &description=QString())
Sets the constraint expression for the specified field index.
void setFieldDuplicatePolicy(int index, Qgis::FieldDuplicatePolicy policy)
Sets a duplicate policy for the field with the specified index.
Q_INVOKABLE void setFieldAlias(int index, const QString &aliasString)
Sets an alias (a display name) for attributes to display in dialogs.
void updatedFields()
Emitted whenever the fields available from this layer have been changed.
QgsEditFormConfig editFormConfig
void setFieldSplitPolicy(int index, Qgis::FieldDomainSplitPolicy policy)
Sets a split policy for the field with the specified index.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
void readXml(const QDomNode &node)
Reads configuration from node.