29 qDeleteAll( mChildren );
33 : d( new QgsEditFormConfigPrivate() )
39 int fieldIndex = d->mFields.indexOf( widgetName );
40 if ( fieldIndex != -1 )
41 return d->mFields.at( fieldIndex ).editorWidgetSetup().config();
43 return d->mWidgetConfigs.value( widgetName );
46 void QgsEditFormConfig::setFields(
const QgsFields &fields )
51 if ( !d->mConfiguredRootContainer )
53 d->mInvisibleRootContainer->clear();
54 for (
int i = 0; i < d->mFields.size(); ++i )
57 d->mInvisibleRootContainer->addChildElement( field );
62 void QgsEditFormConfig::onRelationsLoaded()
78 if ( d->mFields.indexOf( widgetName ) != -1 )
80 QgsDebugMsg( QStringLiteral(
"Trying to set a widget config for a field on QgsEditFormConfig. Use layer->setEditorWidgetSetup() instead." ) );
85 d->mWidgetConfigs[widgetName] = config;
92 return d->mWidgetConfigs.remove( widgetName ) != 0;
117 d->mInvisibleRootContainer->addChildElement( data );
122 return d->mInvisibleRootContainer->children();
128 d->mInvisibleRootContainer->clear();
133 return d->mInvisibleRootContainer;
138 return d->mEditorLayout;
144 d->mEditorLayout = editorLayout;
147 d->mConfiguredRootContainer =
true;
152 return d->mUiFormPath;
157 if ( !ui.isEmpty() && !QUrl::fromUserInput( ui ).isLocalFile() )
176 if ( idx >= 0 && idx < d->mFields.count() )
181 return !d->mFieldEditables.value( d->mFields.at( idx ).name(), true );
189 if ( idx >= 0 && idx < d->mFields.count() )
190 return d->mLabelOnTop.value( d->mFields.at( idx ).name(), false );
197 if ( idx >= 0 && idx < d->mFields.count() )
200 d->mFieldEditables[ d->mFields.at( idx ).name()] = !
readOnly;
206 if ( idx >= 0 && idx < d->mFields.count() )
209 d->mLabelOnTop[ d->mFields.at( idx ).name()] = onTop;
215 return d->mInitFunction;
221 d->mInitFunction =
function;
237 return d->mInitFilePath;
243 d->mInitFilePath = filePath;
248 return d->mInitCodeSource;
259 return d->mSuppressForm;
265 d->mSuppressForm = s;
274 QDomNode editFormNode = node.namedItem( QStringLiteral(
"editform" ) );
275 if ( !editFormNode.isNull() )
277 QDomElement e = editFormNode.toElement();
278 const bool tolerantRemoteUrls = e.hasAttribute( QStringLiteral(
"tolerant" ) );
279 if ( !e.text().isEmpty() )
285 const bool localFile = QFileInfo::exists( uiFormPath );
286 if ( localFile || tolerantRemoteUrls || uiFormPath.startsWith( QLatin1String(
"http" ) ) )
291 QDomNode editFormInitNode = node.namedItem( QStringLiteral(
"editforminit" ) );
292 if ( !editFormInitNode.isNull() )
294 d->mInitFunction = editFormInitNode.toElement().text();
297 QDomNode editFormInitCodeSourceNode = node.namedItem( QStringLiteral(
"editforminitcodesource" ) );
298 if ( !editFormInitCodeSourceNode.isNull() && !editFormInitCodeSourceNode.toElement().text().isEmpty() )
300 setInitCodeSource( static_cast< QgsEditFormConfig::PythonInitCodeSource >( editFormInitCodeSourceNode.toElement().text().toInt() ) );
303 QDomNode editFormInitCodeNode = node.namedItem( QStringLiteral(
"editforminitcode" ) );
304 if ( !editFormInitCodeNode.isNull() )
306 setInitCode( editFormInitCodeNode.toElement().text() );
314 int dotPos = d->mInitFunction.lastIndexOf(
'.' );
318 setInitCode( QStringLiteral(
"from %1 import %2\n" ).arg( d->mInitFunction.left( dotPos ), d->mInitFunction.mid( dotPos + 1 ) ) );
322 QDomNode editFormInitFilePathNode = node.namedItem( QStringLiteral(
"editforminitfilepath" ) );
323 if ( !editFormInitFilePathNode.isNull() && !editFormInitFilePathNode.toElement().text().isEmpty() )
328 QDomNode fFSuppNode = node.namedItem( QStringLiteral(
"featformsuppress" ) );
329 if ( fFSuppNode.isNull() )
335 QDomElement e = fFSuppNode.toElement();
340 QDomNode editorLayoutNode = node.namedItem( QStringLiteral(
"editorlayout" ) );
341 if ( editorLayoutNode.isNull() )
347 if ( editorLayoutNode.toElement().text() == QLatin1String(
"uifilelayout" ) )
351 else if ( editorLayoutNode.toElement().text() == QLatin1String(
"tablayout" ) )
361 d->mFieldEditables.clear();
362 QDomNodeList editableNodeList = node.namedItem( QStringLiteral(
"editable" ) ).toElement().childNodes();
363 for (
int i = 0; i < editableNodeList.size(); ++i )
365 QDomElement editableElement = editableNodeList.at( i ).toElement();
366 d->mFieldEditables.insert( editableElement.attribute( QStringLiteral(
"name" ) ),
static_cast< bool >( editableElement.attribute( QStringLiteral(
"editable" ) ).toInt() ) );
369 d->mLabelOnTop.clear();
370 QDomNodeList labelOnTopNodeList = node.namedItem( QStringLiteral(
"labelOnTop" ) ).toElement().childNodes();
371 for (
int i = 0; i < labelOnTopNodeList.size(); ++i )
373 QDomElement labelOnTopElement = labelOnTopNodeList.at( i ).toElement();
374 d->mLabelOnTop.insert( labelOnTopElement.attribute( QStringLiteral(
"name" ) ),
static_cast< bool >( labelOnTopElement.attribute( QStringLiteral(
"labelOnTop" ) ).toInt() ) );
377 QDomNodeList widgetsNodeList = node.namedItem( QStringLiteral(
"widgets" ) ).toElement().childNodes();
379 for (
int i = 0; i < widgetsNodeList.size(); ++i )
381 QDomElement widgetElement = widgetsNodeList.at( i ).toElement();
384 d->mWidgetConfigs[widgetElement.attribute( QStringLiteral(
"name" ) )] = config.toMap();
388 QDomNode attributeEditorFormNode = node.namedItem( QStringLiteral(
"attributeEditorForm" ) );
389 if ( !attributeEditorFormNode.isNull() )
391 QDomNodeList attributeEditorFormNodeList = attributeEditorFormNode.toElement().childNodes();
393 if ( attributeEditorFormNodeList.size() )
395 d->mConfiguredRootContainer =
true;
398 for (
int i = 0; i < attributeEditorFormNodeList.size(); i++ )
400 QDomElement elem = attributeEditorFormNodeList.at( i ).toElement();
403 addTab( attributeEditorWidget );
413 QDomDocument doc( node.ownerDocument() );
415 QDomElement efField = doc.createElement( QStringLiteral(
"editform" ) );
416 efField.setAttribute( QStringLiteral(
"tolerant" ), QStringLiteral(
"1" ) );
418 efField.appendChild( efText );
419 node.appendChild( efField );
421 QDomElement efiField = doc.createElement( QStringLiteral(
"editforminit" ) );
423 efiField.appendChild( doc.createTextNode(
initFunction() ) );
424 node.appendChild( efiField );
426 QDomElement eficsField = doc.createElement( QStringLiteral(
"editforminitcodesource" ) );
427 eficsField.appendChild( doc.createTextNode( QString::number(
initCodeSource() ) ) );
428 node.appendChild( eficsField );
430 QDomElement efifpField = doc.createElement( QStringLiteral(
"editforminitfilepath" ) );
432 node.appendChild( efifpField );
434 QDomElement eficField = doc.createElement( QStringLiteral(
"editforminitcode" ) );
435 eficField.appendChild( doc.createCDATASection(
initCode() ) );
436 node.appendChild( eficField );
438 QDomElement fFSuppElem = doc.createElement( QStringLiteral(
"featformsuppress" ) );
439 QDomText fFSuppText = doc.createTextNode( QString::number(
suppress() ) );
440 fFSuppElem.appendChild( fFSuppText );
441 node.appendChild( fFSuppElem );
444 QDomElement editorLayoutElem = doc.createElement( QStringLiteral(
"editorlayout" ) );
448 editorLayoutElem.appendChild( doc.createTextNode( QStringLiteral(
"uifilelayout" ) ) );
452 editorLayoutElem.appendChild( doc.createTextNode( QStringLiteral(
"tablayout" ) ) );
457 editorLayoutElem.appendChild( doc.createTextNode( QStringLiteral(
"generatedlayout" ) ) );
461 node.appendChild( editorLayoutElem );
464 if ( !
tabs().empty() && d->mConfiguredRootContainer )
466 QDomElement tabsElem = doc.createElement( QStringLiteral(
"attributeEditorForm" ) );
468 QDomElement rootElem = d->mInvisibleRootContainer->toDomElement( doc );
469 QDomNodeList elemList = rootElem.childNodes();
471 while ( !elemList.isEmpty() )
473 tabsElem.appendChild( elemList.at( 0 ) );
476 node.appendChild( tabsElem );
479 QDomElement editableElem = doc.createElement( QStringLiteral(
"editable" ) );
480 for (
auto editIt = d->mFieldEditables.constBegin(); editIt != d->mFieldEditables.constEnd(); ++editIt )
482 QDomElement fieldElem = doc.createElement( QStringLiteral(
"field" ) );
483 fieldElem.setAttribute( QStringLiteral(
"name" ), editIt.key() );
484 fieldElem.setAttribute( QStringLiteral(
"editable" ), editIt.value() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
485 editableElem.appendChild( fieldElem );
487 node.appendChild( editableElem );
489 QDomElement labelOnTopElem = doc.createElement( QStringLiteral(
"labelOnTop" ) );
490 for (
auto labelOnTopIt = d->mLabelOnTop.constBegin(); labelOnTopIt != d->mLabelOnTop.constEnd(); ++labelOnTopIt )
492 QDomElement fieldElem = doc.createElement( QStringLiteral(
"field" ) );
493 fieldElem.setAttribute( QStringLiteral(
"name" ), labelOnTopIt.key() );
494 fieldElem.setAttribute( QStringLiteral(
"labelOnTop" ), labelOnTopIt.value() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
495 labelOnTopElem.appendChild( fieldElem );
497 node.appendChild( labelOnTopElem );
499 QDomElement widgetsElem = doc.createElement( QStringLiteral(
"widgets" ) );
501 QMap<QString, QVariantMap >::ConstIterator configIt( d->mWidgetConfigs.constBegin() );
503 while ( configIt != d->mWidgetConfigs.constEnd() )
505 QDomElement widgetElem = doc.createElement( QStringLiteral(
"widget" ) );
506 widgetElem.setAttribute( QStringLiteral(
"name" ), configIt.key() );
510 configElem.setTagName( QStringLiteral(
"config" ) );
511 widgetElem.appendChild( configElem );
512 widgetsElem.appendChild( widgetElem );
516 node.appendChild( widgetsElem );
525 if ( elem.tagName() == QLatin1String(
"attributeEditorContainer" ) )
529 int cc = elem.attribute( QStringLiteral(
"columnCount" ) ).toInt( &ok );
534 bool isGroupBox = elem.attribute( QStringLiteral(
"groupBox" ) ).toInt( &ok );
540 bool visibilityExpressionEnabled = elem.attribute( QStringLiteral(
"visibilityExpressionEnabled" ) ).toInt( &ok );
544 visibilityExpression.
setEnabled( visibilityExpressionEnabled );
545 visibilityExpression.
setData(
QgsExpression( elem.attribute( QStringLiteral(
"visibilityExpression" ) ) ) );
549 QDomNodeList childNodeList = elem.childNodes();
551 for (
int i = 0; i < childNodeList.size(); i++ )
553 QDomElement childElem = childNodeList.at( i ).toElement();
559 newElement = container;
561 else if ( elem.tagName() == QLatin1String(
"attributeEditorField" ) )
563 QString name = elem.attribute( QStringLiteral(
"name" ) );
564 int idx = d->mFields.lookupField( name );
567 else if ( elem.tagName() == QLatin1String(
"attributeEditorRelation" ) )
572 relElement->
setShowLinkButton( elem.attribute( QStringLiteral(
"showLinkButton" ), QStringLiteral(
"1" ) ).toInt() );
573 relElement->
setShowUnlinkButton( elem.attribute( QStringLiteral(
"showUnlinkButton" ), QStringLiteral(
"1" ) ).toInt() );
574 newElement = relElement;
576 else if ( elem.tagName() == QLatin1String(
"attributeEditorQmlElement" ) )
580 newElement = qmlElement;
585 if ( elem.hasAttribute( QStringLiteral(
"showLabel" ) ) )
586 newElement->
setShowLabel( elem.attribute( QStringLiteral(
"showLabel" ) ).toInt() );
601 mColumnCount = columnCount;
608 const auto childElements = children();
614 element->mIsGroupBox = mIsGroupBox;
615 element->mColumnCount = mColumnCount;
616 element->mVisibilityExpression = mVisibilityExpression;
621 void QgsAttributeEditorContainer::saveConfiguration( QDomElement &elem )
const 623 elem.setAttribute( QStringLiteral(
"columnCount" ), mColumnCount );
624 elem.setAttribute( QStringLiteral(
"groupBox" ), mIsGroupBox ? 1 : 0 );
625 elem.setAttribute( QStringLiteral(
"visibilityExpressionEnabled" ), mVisibilityExpression.enabled() ? 1 : 0 );
626 elem.setAttribute( QStringLiteral(
"visibilityExpression" ), mVisibilityExpression->expression() );
630 QDomDocument doc = elem.ownerDocument();
635 QString QgsAttributeEditorContainer::typeIdentifier()
const 637 return QStringLiteral(
"attributeEditorContainer" );
Class for parsing and evaluation of expressions (formerly called "search strings").
The class is used as a container of context for various read/write operations on other objects...
An attribute editor widget that will represent arbitrary QML code.
bool init(QgsRelationManager *relManager)
Initializes the relation from the id.
Field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
This is an abstract base class for any elements of a drag and drop form.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
MAYBE_UNUSED NODISCARD QgsReadWriteContextCategoryPopper enterCategory(const QString &category, const QString &details=QString())
Push a category to the stack.
void setVisibilityExpression(const QgsOptionalExpression &visibilityExpression)
The visibility expression is used in the attribute form to show or hide this container based on an ex...
~QgsAttributeEditorContainer() override
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
The download will start immediately, not need to run QgsFecthedContent::download() ...
Container of fields for a vector layer.
This element will load a field's widget onto the form.
Allows entering a context category and takes care of leaving this category on deletion of the class...
This element will load a relation editor onto the form.
void setColumnCount(int columnCount)
Set the number of columns in this group.
void setQmlCode(const QString &qmlCode)
The QML code that will be represented within this widget.
void setData(const T &data)
Set the payload data.
QDomElement toDomElement(QDomDocument &doc) const
Gets the XML Dom element to save this element.
An expression with an additional enabled flag.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
void setShowLabel(bool showLabel)
Controls if this element should be labeled with a title (field, relation or groupname).
const QgsProjectTranslator * projectTranslator() const
Returns the project translator.
virtual QString translate(const QString &context, const QString &sourceText, const char *disambiguation=nullptr, int n=-1) const =0
The derived translate() translates with QTranslator and qm file the sourceText.
void setShowLinkButton(bool showLinkButton)
Determines if the "link feature" button should be shown.
void setShowUnlinkButton(bool showUnlinkButton)
Determines if the "unlink feature" button should be shown.
virtual void setIsGroupBox(bool isGroupBox)
Determines if this container is rendered as collapsible group box or tab in a tabwidget.
int columnCount() const
Gets the number of columns in this group.
static QgsProject * instance()
Returns the QgsProject singleton instance.
static QgsNetworkContentFetcherRegistry * networkContentFetcherRegistry()
Returns the application's network content registry used for fetching temporary files during QGIS sess...
This is a container for attribute editors, used to group them visually in the attribute form if it is...
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
const QgsFetchedContent * fetch(const QString &url, FetchingMode fetchingMode=DownloadLater)
Initialize a download for the given URL.
virtual void addChildElement(QgsAttributeEditorElement *element)
Add a child element to this container.
void setEnabled(bool enabled)
Set if this optional is enabled.
Field is calculated from an expression.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
QgsAttributeEditorElement * clone(QgsAttributeEditorElement *parent) const override
Creates a deep copy of this element.