30 qDeleteAll( mChildren );
34 : d( new QgsEditFormConfigPrivate() )
40 int fieldIndex = d->mFields.indexOf( widgetName );
41 if ( fieldIndex != -1 )
42 return d->mFields.at( fieldIndex ).editorWidgetSetup().config();
44 return d->mWidgetConfigs.value( widgetName );
47 void QgsEditFormConfig::setFields(
const QgsFields &fields )
52 if ( !d->mConfiguredRootContainer )
54 d->mInvisibleRootContainer->clear();
55 for (
int i = 0; i < d->mFields.size(); ++i )
58 d->mInvisibleRootContainer->addChildElement( field );
63 void QgsEditFormConfig::onRelationsLoaded()
79 if ( d->mFields.indexOf( widgetName ) != -1 )
81 QgsDebugMsg( QStringLiteral(
"Trying to set a widget config for a field on QgsEditFormConfig. Use layer->setEditorWidgetSetup() instead." ) );
86 d->mWidgetConfigs[widgetName] = config;
93 return d->mWidgetConfigs.remove( widgetName ) != 0;
118 d->mInvisibleRootContainer->addChildElement( data );
123 return d->mInvisibleRootContainer->children();
129 d->mInvisibleRootContainer->clear();
134 return d->mInvisibleRootContainer;
139 return d->mEditorLayout;
145 d->mEditorLayout = editorLayout;
148 d->mConfiguredRootContainer =
true;
153 return d->mUiFormPath;
158 if ( !ui.isEmpty() && !QUrl::fromUserInput( ui ).isLocalFile() )
177 if ( idx >= 0 && idx < d->mFields.count() )
182 return !d->mFieldEditables.value( d->mFields.at( idx ).name(), true );
190 if ( idx >= 0 && idx < d->mFields.count() )
191 return d->mLabelOnTop.value( d->mFields.at( idx ).name(), false );
198 if ( idx >= 0 && idx < d->mFields.count() )
201 d->mFieldEditables[ d->mFields.at( idx ).name()] = !
readOnly;
207 if ( idx >= 0 && idx < d->mFields.count() )
210 d->mLabelOnTop[ d->mFields.at( idx ).name()] = onTop;
216 return d->mInitFunction;
222 d->mInitFunction =
function;
238 return d->mInitFilePath;
244 d->mInitFilePath = filePath;
249 return d->mInitCodeSource;
260 return d->mSuppressForm;
266 d->mSuppressForm = s;
275 QDomNode editFormNode = node.namedItem( QStringLiteral(
"editform" ) );
276 if ( !editFormNode.isNull() )
278 QDomElement e = editFormNode.toElement();
279 const bool tolerantRemoteUrls = e.hasAttribute( QStringLiteral(
"tolerant" ) );
280 if ( !e.text().isEmpty() )
286 const bool localFile = QFileInfo::exists( uiFormPath );
287 if ( localFile || tolerantRemoteUrls || uiFormPath.startsWith( QLatin1String(
"http" ) ) )
292 QDomNode editFormInitNode = node.namedItem( QStringLiteral(
"editforminit" ) );
293 if ( !editFormInitNode.isNull() )
295 d->mInitFunction = editFormInitNode.toElement().text();
298 QDomNode editFormInitCodeSourceNode = node.namedItem( QStringLiteral(
"editforminitcodesource" ) );
299 if ( !editFormInitCodeSourceNode.isNull() && !editFormInitCodeSourceNode.toElement().text().isEmpty() )
301 setInitCodeSource( static_cast< QgsEditFormConfig::PythonInitCodeSource >( editFormInitCodeSourceNode.toElement().text().toInt() ) );
304 QDomNode editFormInitCodeNode = node.namedItem( QStringLiteral(
"editforminitcode" ) );
305 if ( !editFormInitCodeNode.isNull() )
307 setInitCode( editFormInitCodeNode.toElement().text() );
315 int dotPos = d->mInitFunction.lastIndexOf(
'.' );
319 setInitCode( QStringLiteral(
"from %1 import %2\n" ).arg( d->mInitFunction.left( dotPos ), d->mInitFunction.mid( dotPos + 1 ) ) );
323 QDomNode editFormInitFilePathNode = node.namedItem( QStringLiteral(
"editforminitfilepath" ) );
324 if ( !editFormInitFilePathNode.isNull() && !editFormInitFilePathNode.toElement().text().isEmpty() )
329 QDomNode fFSuppNode = node.namedItem( QStringLiteral(
"featformsuppress" ) );
330 if ( fFSuppNode.isNull() )
336 QDomElement e = fFSuppNode.toElement();
341 QDomNode editorLayoutNode = node.namedItem( QStringLiteral(
"editorlayout" ) );
342 if ( editorLayoutNode.isNull() )
348 if ( editorLayoutNode.toElement().text() == QLatin1String(
"uifilelayout" ) )
352 else if ( editorLayoutNode.toElement().text() == QLatin1String(
"tablayout" ) )
362 d->mFieldEditables.clear();
363 QDomNodeList editableNodeList = node.namedItem( QStringLiteral(
"editable" ) ).toElement().childNodes();
364 for (
int i = 0; i < editableNodeList.size(); ++i )
366 QDomElement editableElement = editableNodeList.at( i ).toElement();
367 d->mFieldEditables.insert( editableElement.attribute( QStringLiteral(
"name" ) ),
static_cast< bool >( editableElement.attribute( QStringLiteral(
"editable" ) ).toInt() ) );
370 d->mLabelOnTop.clear();
371 QDomNodeList labelOnTopNodeList = node.namedItem( QStringLiteral(
"labelOnTop" ) ).toElement().childNodes();
372 for (
int i = 0; i < labelOnTopNodeList.size(); ++i )
374 QDomElement labelOnTopElement = labelOnTopNodeList.at( i ).toElement();
375 d->mLabelOnTop.insert( labelOnTopElement.attribute( QStringLiteral(
"name" ) ),
static_cast< bool >( labelOnTopElement.attribute( QStringLiteral(
"labelOnTop" ) ).toInt() ) );
378 QDomNodeList widgetsNodeList = node.namedItem( QStringLiteral(
"widgets" ) ).toElement().childNodes();
380 for (
int i = 0; i < widgetsNodeList.size(); ++i )
382 QDomElement widgetElement = widgetsNodeList.at( i ).toElement();
385 d->mWidgetConfigs[widgetElement.attribute( QStringLiteral(
"name" ) )] = config.toMap();
389 QDomNode attributeEditorFormNode = node.namedItem( QStringLiteral(
"attributeEditorForm" ) );
390 if ( !attributeEditorFormNode.isNull() )
392 QDomNodeList attributeEditorFormNodeList = attributeEditorFormNode.toElement().childNodes();
394 if ( attributeEditorFormNodeList.size() )
396 d->mConfiguredRootContainer =
true;
399 for (
int i = 0; i < attributeEditorFormNodeList.size(); i++ )
401 QDomElement elem = attributeEditorFormNodeList.at( i ).toElement();
404 addTab( attributeEditorWidget );
414 QDomDocument doc( node.ownerDocument() );
416 QDomElement efField = doc.createElement( QStringLiteral(
"editform" ) );
417 efField.setAttribute( QStringLiteral(
"tolerant" ), QStringLiteral(
"1" ) );
419 efField.appendChild( efText );
420 node.appendChild( efField );
422 QDomElement efiField = doc.createElement( QStringLiteral(
"editforminit" ) );
424 efiField.appendChild( doc.createTextNode(
initFunction() ) );
425 node.appendChild( efiField );
427 QDomElement eficsField = doc.createElement( QStringLiteral(
"editforminitcodesource" ) );
428 eficsField.appendChild( doc.createTextNode( QString::number(
initCodeSource() ) ) );
429 node.appendChild( eficsField );
431 QDomElement efifpField = doc.createElement( QStringLiteral(
"editforminitfilepath" ) );
433 node.appendChild( efifpField );
435 QDomElement eficField = doc.createElement( QStringLiteral(
"editforminitcode" ) );
436 eficField.appendChild( doc.createCDATASection(
initCode() ) );
437 node.appendChild( eficField );
439 QDomElement fFSuppElem = doc.createElement( QStringLiteral(
"featformsuppress" ) );
440 QDomText fFSuppText = doc.createTextNode( QString::number(
suppress() ) );
441 fFSuppElem.appendChild( fFSuppText );
442 node.appendChild( fFSuppElem );
445 QDomElement editorLayoutElem = doc.createElement( QStringLiteral(
"editorlayout" ) );
449 editorLayoutElem.appendChild( doc.createTextNode( QStringLiteral(
"uifilelayout" ) ) );
453 editorLayoutElem.appendChild( doc.createTextNode( QStringLiteral(
"tablayout" ) ) );
458 editorLayoutElem.appendChild( doc.createTextNode( QStringLiteral(
"generatedlayout" ) ) );
462 node.appendChild( editorLayoutElem );
465 if ( !
tabs().empty() && d->mConfiguredRootContainer )
467 QDomElement tabsElem = doc.createElement( QStringLiteral(
"attributeEditorForm" ) );
469 QDomElement rootElem = d->mInvisibleRootContainer->toDomElement( doc );
470 QDomNodeList elemList = rootElem.childNodes();
472 while ( !elemList.isEmpty() )
474 tabsElem.appendChild( elemList.at( 0 ) );
477 node.appendChild( tabsElem );
480 QDomElement editableElem = doc.createElement( QStringLiteral(
"editable" ) );
481 for (
auto editIt = d->mFieldEditables.constBegin(); editIt != d->mFieldEditables.constEnd(); ++editIt )
483 QDomElement fieldElem = doc.createElement( QStringLiteral(
"field" ) );
484 fieldElem.setAttribute( QStringLiteral(
"name" ), editIt.key() );
485 fieldElem.setAttribute( QStringLiteral(
"editable" ), editIt.value() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
486 editableElem.appendChild( fieldElem );
488 node.appendChild( editableElem );
490 QDomElement labelOnTopElem = doc.createElement( QStringLiteral(
"labelOnTop" ) );
491 for (
auto labelOnTopIt = d->mLabelOnTop.constBegin(); labelOnTopIt != d->mLabelOnTop.constEnd(); ++labelOnTopIt )
493 QDomElement fieldElem = doc.createElement( QStringLiteral(
"field" ) );
494 fieldElem.setAttribute( QStringLiteral(
"name" ), labelOnTopIt.key() );
495 fieldElem.setAttribute( QStringLiteral(
"labelOnTop" ), labelOnTopIt.value() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
496 labelOnTopElem.appendChild( fieldElem );
498 node.appendChild( labelOnTopElem );
500 QDomElement widgetsElem = doc.createElement( QStringLiteral(
"widgets" ) );
502 QMap<QString, QVariantMap >::ConstIterator configIt( d->mWidgetConfigs.constBegin() );
504 while ( configIt != d->mWidgetConfigs.constEnd() )
506 QDomElement widgetElem = doc.createElement( QStringLiteral(
"widget" ) );
507 widgetElem.setAttribute( QStringLiteral(
"name" ), configIt.key() );
511 configElem.setTagName( QStringLiteral(
"config" ) );
512 widgetElem.appendChild( configElem );
513 widgetsElem.appendChild( widgetElem );
517 node.appendChild( widgetsElem );
526 if ( elem.tagName() == QLatin1String(
"attributeEditorContainer" ) )
530 int cc = elem.attribute( QStringLiteral(
"columnCount" ) ).toInt( &ok );
535 bool isGroupBox = elem.attribute( QStringLiteral(
"groupBox" ) ).toInt( &ok );
541 bool visibilityExpressionEnabled = elem.attribute( QStringLiteral(
"visibilityExpressionEnabled" ) ).toInt( &ok );
545 visibilityExpression.
setEnabled( visibilityExpressionEnabled );
546 visibilityExpression.
setData(
QgsExpression( elem.attribute( QStringLiteral(
"visibilityExpression" ) ) ) );
550 QDomNodeList childNodeList = elem.childNodes();
552 for (
int i = 0; i < childNodeList.size(); i++ )
554 QDomElement childElem = childNodeList.at( i ).toElement();
560 newElement = container;
562 else if ( elem.tagName() == QLatin1String(
"attributeEditorField" ) )
564 QString name = elem.attribute( QStringLiteral(
"name" ) );
565 int idx = d->mFields.lookupField( name );
568 else if ( elem.tagName() == QLatin1String(
"attributeEditorRelation" ) )
573 relElement->
setShowLinkButton( elem.attribute( QStringLiteral(
"showLinkButton" ), QStringLiteral(
"1" ) ).toInt() );
574 relElement->
setShowUnlinkButton( elem.attribute( QStringLiteral(
"showUnlinkButton" ), QStringLiteral(
"1" ) ).toInt() );
575 newElement = relElement;
577 else if ( elem.tagName() == QLatin1String(
"attributeEditorQmlElement" ) )
581 newElement = qmlElement;
586 if ( elem.hasAttribute( QStringLiteral(
"showLabel" ) ) )
587 newElement->
setShowLabel( elem.attribute( QStringLiteral(
"showLabel" ) ).toInt() );
602 mColumnCount = columnCount;
609 const auto childElements = children();
615 element->mIsGroupBox = mIsGroupBox;
616 element->mColumnCount = mColumnCount;
617 element->mVisibilityExpression = mVisibilityExpression;
622 void QgsAttributeEditorContainer::saveConfiguration( QDomElement &elem )
const 624 elem.setAttribute( QStringLiteral(
"columnCount" ), mColumnCount );
625 elem.setAttribute( QStringLiteral(
"groupBox" ), mIsGroupBox ? 1 : 0 );
626 elem.setAttribute( QStringLiteral(
"visibilityExpressionEnabled" ), mVisibilityExpression.enabled() ? 1 : 0 );
627 elem.setAttribute( QStringLiteral(
"visibilityExpression" ), mVisibilityExpression->expression() );
631 QDomDocument doc = elem.ownerDocument();
636 QString QgsAttributeEditorContainer::typeIdentifier()
const 638 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.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
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
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...
QDomElement toDomElement(QDomDocument &doc) const
Gets the XML Dom element to save this element.
This element will load a relation editor onto the form.
void setColumnCount(int columnCount)
Set the number of columns in this group.
const QgsProjectTranslator * projectTranslator() const
Returns the project translator.
void setQmlCode(const QString &qmlCode)
The QML code that will be represented within this widget.
void setData(const T &data)
Set the payload data.
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).
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.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
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...
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
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.