QGIS API Documentation  3.0.2-Girona (307d082)
qgseditformconfig.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgseditformconfig.cpp
3  ---------------------
4  begin : November 2015
5  copyright : (C) 2015 by Matthias Kuhn
6  email : matthias at opengis dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 #include "qgseditformconfig_p.h"
16 #include "qgseditformconfig.h"
17 #include "qgspathresolver.h"
18 #include "qgsproject.h"
19 #include "qgsreadwritecontext.h"
20 #include "qgsrelationmanager.h"
21 #include "qgslogger.h"
22 #include "qgsxmlutils.h"
23 
24 //#include "qgseditorwidgetregistry.h"
25 
27 {
28  qDeleteAll( mChildren );
29 }
30 
32  : d( new QgsEditFormConfigPrivate() )
33 {
34 }
35 
36 QVariantMap QgsEditFormConfig::widgetConfig( const QString &widgetName ) const
37 {
38  int fieldIndex = d->mFields.indexOf( widgetName );
39  if ( fieldIndex != -1 )
40  return d->mFields.at( fieldIndex ).editorWidgetSetup().config();
41  else
42  return d->mWidgetConfigs.value( widgetName );
43 }
44 
45 void QgsEditFormConfig::setFields( const QgsFields &fields )
46 {
47  d.detach();
48  d->mFields = fields;
49 
50  if ( !d->mConfiguredRootContainer )
51  {
52  d->mInvisibleRootContainer->clear();
53  for ( int i = 0; i < d->mFields.size(); ++i )
54  {
55  QgsAttributeEditorField *field = new QgsAttributeEditorField( d->mFields.at( i ).name(), i, d->mInvisibleRootContainer );
56  d->mInvisibleRootContainer->addChildElement( field );
57  }
58  }
59 }
60 
61 void QgsEditFormConfig::onRelationsLoaded()
62 {
63  QList<QgsAttributeEditorElement *> relations = d->mInvisibleRootContainer->findElements( QgsAttributeEditorElement::AeTypeRelation );
64 
65  Q_FOREACH ( QgsAttributeEditorElement *relElem, relations )
66  {
67  QgsAttributeEditorRelation *rel = dynamic_cast< QgsAttributeEditorRelation * >( relElem );
68  if ( !rel )
69  continue;
70 
71  rel->init( QgsProject::instance()->relationManager() );
72  }
73 }
74 
75 bool QgsEditFormConfig::setWidgetConfig( const QString &widgetName, const QVariantMap &config )
76 {
77  if ( d->mFields.indexOf( widgetName ) != -1 )
78  {
79  QgsDebugMsg( "Trying to set a widget config for a field on QgsEditFormConfig. Use layer->setEditorWidgetSetup() instead." );
80  return false;
81  }
82 
83  d.detach();
84  d->mWidgetConfigs[widgetName] = config;
85  return true;
86 }
87 
88 bool QgsEditFormConfig::removeWidgetConfig( const QString &widgetName )
89 {
90  d.detach();
91  return d->mWidgetConfigs.remove( widgetName ) != 0;
92 }
93 
95  : d( o.d )
96 {
97 }
98 
100 {}
101 
103 {
104  d = o.d;
105  return *this;
106 }
107 
109 {
110  return d == o.d;
111 }
112 
114 {
115  d.detach();
116  d->mInvisibleRootContainer->addChildElement( data );
117 }
118 
119 QList<QgsAttributeEditorElement *> QgsEditFormConfig::tabs() const
120 {
121  return d->mInvisibleRootContainer->children();
122 }
123 
125 {
126  d.detach();
127  d->mInvisibleRootContainer->clear();
128 }
129 
131 {
132  return d->mInvisibleRootContainer;
133 }
134 
136 {
137  return d->mEditorLayout;
138 }
139 
141 {
142  d.detach();
143  d->mEditorLayout = editorLayout;
144 
145  if ( editorLayout == TabLayout )
146  d->mConfiguredRootContainer = true;
147 }
148 
150 {
151  return d->mUiFormPath;
152 }
153 
154 void QgsEditFormConfig::setUiForm( const QString &ui )
155 {
156  if ( ui.isEmpty() || ui.isNull() )
157  {
159  }
160  else
161  {
163  }
164  d->mUiFormPath = ui;
165 }
166 
167 bool QgsEditFormConfig::readOnly( int idx ) const
168 {
169  if ( idx >= 0 && idx < d->mFields.count() )
170  {
171  if ( d->mFields.fieldOrigin( idx ) == QgsFields::OriginJoin
172  || d->mFields.fieldOrigin( idx ) == QgsFields::OriginExpression )
173  return true;
174  return !d->mFieldEditables.value( d->mFields.at( idx ).name(), true );
175  }
176  else
177  return false;
178 }
179 
180 bool QgsEditFormConfig::labelOnTop( int idx ) const
181 {
182  if ( idx >= 0 && idx < d->mFields.count() )
183  return d->mLabelOnTop.value( d->mFields.at( idx ).name(), false );
184  else
185  return false;
186 }
187 
189 {
190  if ( idx >= 0 && idx < d->mFields.count() )
191  {
192  d.detach();
193  d->mFieldEditables[ d->mFields.at( idx ).name()] = !readOnly;
194  }
195 }
196 
197 void QgsEditFormConfig::setLabelOnTop( int idx, bool onTop )
198 {
199  if ( idx >= 0 && idx < d->mFields.count() )
200  {
201  d.detach();
202  d->mLabelOnTop[ d->mFields.at( idx ).name()] = onTop;
203  }
204 }
205 
207 {
208  return d->mInitFunction;
209 }
210 
211 void QgsEditFormConfig::setInitFunction( const QString &function )
212 {
213  d.detach();
214  d->mInitFunction = function;
215 }
216 
218 {
219  return d->mInitCode;
220 }
221 
222 void QgsEditFormConfig::setInitCode( const QString &code )
223 {
224  d.detach();
225  d->mInitCode = code;
226 }
227 
229 {
230  return d->mInitFilePath;
231 }
232 
233 void QgsEditFormConfig::setInitFilePath( const QString &filePath )
234 {
235  d.detach();
236  d->mInitFilePath = filePath;
237 }
238 
240 {
241  return d->mInitCodeSource;
242 }
243 
245 {
246  d.detach();
247  d->mInitCodeSource = initCodeSource;
248 }
249 
251 {
252  return d->mSuppressForm;
253 }
254 
256 {
257  d.detach();
258  d->mSuppressForm = s;
259 }
260 
261 void QgsEditFormConfig::readXml( const QDomNode &node, const QgsReadWriteContext &context )
262 {
263  d.detach();
264 
265  QDomNode editFormNode = node.namedItem( QStringLiteral( "editform" ) );
266  if ( !editFormNode.isNull() )
267  {
268  QDomElement e = editFormNode.toElement();
269  d->mUiFormPath = context.pathResolver().readPath( e.text() );
270  }
271 
272  QDomNode editFormInitNode = node.namedItem( QStringLiteral( "editforminit" ) );
273  if ( !editFormInitNode.isNull() )
274  {
275  d->mInitFunction = editFormInitNode.toElement().text();
276  }
277 
278  QDomNode editFormInitCodeSourceNode = node.namedItem( QStringLiteral( "editforminitcodesource" ) );
279  if ( !editFormInitCodeSourceNode.isNull() && !editFormInitCodeSourceNode.toElement().text().isEmpty() )
280  {
281  setInitCodeSource( static_cast< QgsEditFormConfig::PythonInitCodeSource >( editFormInitCodeSourceNode.toElement().text().toInt() ) );
282  }
283 
284  QDomNode editFormInitCodeNode = node.namedItem( QStringLiteral( "editforminitcode" ) );
285  if ( !editFormInitCodeNode.isNull() )
286  {
287  setInitCode( editFormInitCodeNode.toElement().text() );
288  }
289 
290  // Temporary < 2.12 b/w compatibility "dot" support patch
291  // \see: https://github.com/qgis/QGIS/pull/2498
292  // For b/w compatibility, check if there's a dot in the function name
293  // and if yes, transform it in an import statement for the module
294  // and set the PythonInitCodeSource to CodeSourceDialog
295  int dotPos = d->mInitFunction.lastIndexOf( '.' );
296  if ( dotPos >= 0 ) // It's a module
297  {
299  setInitCode( QStringLiteral( "from %1 import %2\n" ).arg( d->mInitFunction.left( dotPos ), d->mInitFunction.mid( dotPos + 1 ) ) );
300  setInitFunction( d->mInitFunction.mid( dotPos + 1 ) );
301  }
302 
303  QDomNode editFormInitFilePathNode = node.namedItem( QStringLiteral( "editforminitfilepath" ) );
304  if ( !editFormInitFilePathNode.isNull() && !editFormInitFilePathNode.toElement().text().isEmpty() )
305  {
306  setInitFilePath( context.pathResolver().readPath( editFormInitFilePathNode.toElement().text() ) );
307  }
308 
309  QDomNode fFSuppNode = node.namedItem( QStringLiteral( "featformsuppress" ) );
310  if ( fFSuppNode.isNull() )
311  {
312  d->mSuppressForm = QgsEditFormConfig::SuppressDefault;
313  }
314  else
315  {
316  QDomElement e = fFSuppNode.toElement();
317  d->mSuppressForm = static_cast< QgsEditFormConfig::FeatureFormSuppress >( e.text().toInt() );
318  }
319 
320  // tab display
321  QDomNode editorLayoutNode = node.namedItem( QStringLiteral( "editorlayout" ) );
322  if ( editorLayoutNode.isNull() )
323  {
324  d->mEditorLayout = QgsEditFormConfig::GeneratedLayout;
325  }
326  else
327  {
328  if ( editorLayoutNode.toElement().text() == QLatin1String( "uifilelayout" ) )
329  {
330  d->mEditorLayout = QgsEditFormConfig::UiFileLayout;
331  }
332  else if ( editorLayoutNode.toElement().text() == QLatin1String( "tablayout" ) )
333  {
334  d->mEditorLayout = QgsEditFormConfig::TabLayout;
335  }
336  else
337  {
338  d->mEditorLayout = QgsEditFormConfig::GeneratedLayout;
339  }
340  }
341 
342  d->mFieldEditables.clear();
343  QDomNodeList editableNodeList = node.namedItem( QStringLiteral( "editable" ) ).toElement().childNodes();
344  for ( int i = 0; i < editableNodeList.size(); ++i )
345  {
346  QDomElement editableElement = editableNodeList.at( i ).toElement();
347  d->mFieldEditables.insert( editableElement.attribute( QStringLiteral( "name" ) ), static_cast< bool >( editableElement.attribute( QStringLiteral( "editable" ) ).toInt() ) );
348  }
349 
350  d->mLabelOnTop.clear();
351  QDomNodeList labelOnTopNodeList = node.namedItem( QStringLiteral( "labelOnTop" ) ).toElement().childNodes();
352  for ( int i = 0; i < labelOnTopNodeList.size(); ++i )
353  {
354  QDomElement labelOnTopElement = labelOnTopNodeList.at( i ).toElement();
355  d->mLabelOnTop.insert( labelOnTopElement.attribute( QStringLiteral( "name" ) ), static_cast< bool >( labelOnTopElement.attribute( QStringLiteral( "labelOnTop" ) ).toInt() ) );
356  }
357 
358  QDomNodeList widgetsNodeList = node.namedItem( QStringLiteral( "widgets" ) ).toElement().childNodes();
359 
360  for ( int i = 0; i < widgetsNodeList.size(); ++i )
361  {
362  QDomElement widgetElement = widgetsNodeList.at( i ).toElement();
363  QVariant config = QgsXmlUtils::readVariant( widgetElement.firstChildElement( QStringLiteral( "config" ) ) );
364 
365  d->mWidgetConfigs[widgetElement.attribute( QStringLiteral( "name" ) )] = config.toMap();
366  }
367 
368  // tabs and groups display info
369  QDomNode attributeEditorFormNode = node.namedItem( QStringLiteral( "attributeEditorForm" ) );
370  if ( !attributeEditorFormNode.isNull() )
371  {
372  QDomNodeList attributeEditorFormNodeList = attributeEditorFormNode.toElement().childNodes();
373 
374  if ( attributeEditorFormNodeList.size() )
375  {
376  d->mConfiguredRootContainer = true;
377  clearTabs();
378 
379  for ( int i = 0; i < attributeEditorFormNodeList.size(); i++ )
380  {
381  QDomElement elem = attributeEditorFormNodeList.at( i ).toElement();
382 
383  QgsAttributeEditorElement *attributeEditorWidget = attributeEditorElementFromDomElement( elem, nullptr );
384  addTab( attributeEditorWidget );
385  }
386 
387  onRelationsLoaded();
388  }
389  }
390 }
391 
392 void QgsEditFormConfig::writeXml( QDomNode &node, const QgsReadWriteContext &context ) const
393 {
394  QDomDocument doc( node.ownerDocument() );
395 
396  QDomElement efField = doc.createElement( QStringLiteral( "editform" ) );
397  QDomText efText = doc.createTextNode( context.pathResolver().writePath( uiForm() ) );
398  efField.appendChild( efText );
399  node.appendChild( efField );
400 
401  QDomElement efiField = doc.createElement( QStringLiteral( "editforminit" ) );
402  if ( !initFunction().isEmpty() )
403  efiField.appendChild( doc.createTextNode( initFunction() ) );
404  node.appendChild( efiField );
405 
406  QDomElement eficsField = doc.createElement( QStringLiteral( "editforminitcodesource" ) );
407  eficsField.appendChild( doc.createTextNode( QString::number( initCodeSource() ) ) );
408  node.appendChild( eficsField );
409 
410  QDomElement efifpField = doc.createElement( QStringLiteral( "editforminitfilepath" ) );
411  efifpField.appendChild( doc.createTextNode( context.pathResolver().writePath( initFilePath() ) ) );
412  node.appendChild( efifpField );
413 
414  QDomElement eficField = doc.createElement( QStringLiteral( "editforminitcode" ) );
415  eficField.appendChild( doc.createCDATASection( initCode() ) );
416  node.appendChild( eficField );
417 
418  QDomElement fFSuppElem = doc.createElement( QStringLiteral( "featformsuppress" ) );
419  QDomText fFSuppText = doc.createTextNode( QString::number( suppress() ) );
420  fFSuppElem.appendChild( fFSuppText );
421  node.appendChild( fFSuppElem );
422 
423  // tab display
424  QDomElement editorLayoutElem = doc.createElement( QStringLiteral( "editorlayout" ) );
425  switch ( layout() )
426  {
428  editorLayoutElem.appendChild( doc.createTextNode( QStringLiteral( "uifilelayout" ) ) );
429  break;
430 
432  editorLayoutElem.appendChild( doc.createTextNode( QStringLiteral( "tablayout" ) ) );
433  break;
434 
436  default:
437  editorLayoutElem.appendChild( doc.createTextNode( QStringLiteral( "generatedlayout" ) ) );
438  break;
439  }
440 
441  node.appendChild( editorLayoutElem );
442 
443  // tabs and groups of edit form
444  if ( !tabs().empty() && d->mConfiguredRootContainer )
445  {
446  QDomElement tabsElem = doc.createElement( QStringLiteral( "attributeEditorForm" ) );
447 
448  QDomElement rootElem = d->mInvisibleRootContainer->toDomElement( doc );
449  QDomNodeList elemList = rootElem.childNodes();
450 
451  while ( !elemList.isEmpty() )
452  {
453  tabsElem.appendChild( elemList.at( 0 ) );
454  }
455 
456  node.appendChild( tabsElem );
457  }
458 
459  QDomElement editableElem = doc.createElement( QStringLiteral( "editable" ) );
460  for ( auto editIt = d->mFieldEditables.constBegin(); editIt != d->mFieldEditables.constEnd(); ++editIt )
461  {
462  QDomElement fieldElem = doc.createElement( QStringLiteral( "field" ) );
463  fieldElem.setAttribute( QStringLiteral( "name" ), editIt.key() );
464  fieldElem.setAttribute( QStringLiteral( "editable" ), editIt.value() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
465  editableElem.appendChild( fieldElem );
466  }
467  node.appendChild( editableElem );
468 
469  QDomElement labelOnTopElem = doc.createElement( QStringLiteral( "labelOnTop" ) );
470  for ( auto labelOnTopIt = d->mLabelOnTop.constBegin(); labelOnTopIt != d->mLabelOnTop.constEnd(); ++labelOnTopIt )
471  {
472  QDomElement fieldElem = doc.createElement( QStringLiteral( "field" ) );
473  fieldElem.setAttribute( QStringLiteral( "name" ), labelOnTopIt.key() );
474  fieldElem.setAttribute( QStringLiteral( "labelOnTop" ), labelOnTopIt.value() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
475  labelOnTopElem.appendChild( fieldElem );
476  }
477  node.appendChild( labelOnTopElem );
478 
479  QDomElement widgetsElem = doc.createElement( QStringLiteral( "widgets" ) );
480 
481  QMap<QString, QVariantMap >::ConstIterator configIt( d->mWidgetConfigs.constBegin() );
482 
483  while ( configIt != d->mWidgetConfigs.constEnd() )
484  {
485  QDomElement widgetElem = doc.createElement( QStringLiteral( "widget" ) );
486  widgetElem.setAttribute( QStringLiteral( "name" ), configIt.key() );
487  // widgetElem.setAttribute( "notNull", );
488 
489  QDomElement configElem = QgsXmlUtils::writeVariant( configIt.value(), doc );
490  configElem.setTagName( QStringLiteral( "config" ) );
491  widgetElem.appendChild( configElem );
492  widgetsElem.appendChild( widgetElem );
493  ++configIt;
494  }
495 
496  node.appendChild( widgetsElem );
497 
499 }
500 
502 {
503  QgsAttributeEditorElement *newElement = nullptr;
504 
505  if ( elem.tagName() == QLatin1String( "attributeEditorContainer" ) )
506  {
507  QgsAttributeEditorContainer *container = new QgsAttributeEditorContainer( elem.attribute( QStringLiteral( "name" ) ), parent );
508  bool ok;
509  int cc = elem.attribute( QStringLiteral( "columnCount" ) ).toInt( &ok );
510  if ( !ok )
511  cc = 0;
512  container->setColumnCount( cc );
513 
514  bool isGroupBox = elem.attribute( QStringLiteral( "groupBox" ) ).toInt( &ok );
515  if ( ok )
516  container->setIsGroupBox( isGroupBox );
517  else
518  container->setIsGroupBox( parent );
519 
520  bool visibilityExpressionEnabled = elem.attribute( QStringLiteral( "visibilityExpressionEnabled" ) ).toInt( &ok );
521  QgsOptionalExpression visibilityExpression;
522  if ( ok )
523  {
524  visibilityExpression.setEnabled( visibilityExpressionEnabled );
525  visibilityExpression.setData( QgsExpression( elem.attribute( QStringLiteral( "visibilityExpression" ) ) ) );
526  }
527  container->setVisibilityExpression( visibilityExpression );
528 
529  QDomNodeList childNodeList = elem.childNodes();
530 
531  for ( int i = 0; i < childNodeList.size(); i++ )
532  {
533  QDomElement childElem = childNodeList.at( i ).toElement();
534  QgsAttributeEditorElement *myElem = attributeEditorElementFromDomElement( childElem, container );
535  if ( myElem )
536  container->addChildElement( myElem );
537  }
538 
539  newElement = container;
540  }
541  else if ( elem.tagName() == QLatin1String( "attributeEditorField" ) )
542  {
543  QString name = elem.attribute( QStringLiteral( "name" ) );
544  int idx = d->mFields.lookupField( name );
545  newElement = new QgsAttributeEditorField( name, idx, parent );
546  }
547  else if ( elem.tagName() == QLatin1String( "attributeEditorRelation" ) )
548  {
549  // At this time, the relations are not loaded
550  // So we only grab the id and delegate the rest to onRelationsLoaded()
551  QString name = elem.attribute( QStringLiteral( "name" ) );
552  QgsAttributeEditorRelation *relElement = new QgsAttributeEditorRelation( name, elem.attribute( QStringLiteral( "relation" ), QStringLiteral( "[None]" ) ), parent );
553  relElement->setShowLinkButton( elem.attribute( QStringLiteral( "showLinkButton" ), QStringLiteral( "1" ) ).toInt() );
554  relElement->setShowUnlinkButton( elem.attribute( QStringLiteral( "showUnlinkButton" ), QStringLiteral( "1" ) ).toInt() );
555  newElement = relElement;
556  }
557 
558  if ( newElement )
559  {
560  if ( elem.hasAttribute( QStringLiteral( "showLabel" ) ) )
561  newElement->setShowLabel( elem.attribute( QStringLiteral( "showLabel" ) ).toInt() );
562  else
563  newElement->setShowLabel( true );
564  }
565 
566  return newElement;
567 }
568 
570 {
571  return mColumnCount;
572 }
573 
575 {
576  mColumnCount = columnCount;
577 }
578 
580 {
581  QgsAttributeEditorContainer *element = new QgsAttributeEditorContainer( name(), parent );
582 
583  Q_FOREACH ( QgsAttributeEditorElement *child, children() )
584  {
585  element->addChildElement( child->clone( element ) );
586  }
587  element->mIsGroupBox = mIsGroupBox;
588  element->mColumnCount = mColumnCount;
589  element->mVisibilityExpression = mVisibilityExpression;
590 
591  return element;
592 }
593 
594 void QgsAttributeEditorContainer::saveConfiguration( QDomElement &elem ) const
595 {
596  elem.setAttribute( QStringLiteral( "columnCount" ), mColumnCount );
597  elem.setAttribute( QStringLiteral( "groupBox" ), mIsGroupBox ? 1 : 0 );
598  elem.setAttribute( QStringLiteral( "visibilityExpressionEnabled" ), mVisibilityExpression.enabled() ? 1 : 0 );
599  elem.setAttribute( QStringLiteral( "visibilityExpression" ), mVisibilityExpression->expression() );
600 
601  Q_FOREACH ( QgsAttributeEditorElement *child, mChildren )
602  {
603  QDomDocument doc = elem.ownerDocument();
604  elem.appendChild( child->toDomElement( doc ) );
605  }
606 }
607 
608 QString QgsAttributeEditorContainer::typeIdentifier() const
609 {
610  return QStringLiteral( "attributeEditorContainer" );
611 }
The class is used as a container of context for various read/write operations on other objects...
Use the Python code provided in the dialog.
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...
Definition: qgsfields.h:50
This is an abstract base class for any elements of a drag and drop form.
EditorLayout
The different types to layout the attribute editor.
void setInitFilePath(const QString &filePath)
Set Python external file path for edit form initialization.
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...
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QList< QgsAttributeEditorElement *> tabs() const
Returns a list of tabs for EditorLayout::TabLayout obtained from the invisible root container...
Use a layout with tabs and group boxes. Needs to be configured.
Container of fields for a vector layer.
Definition: qgsfields.h:42
QVariantMap widgetConfig(const QString &widgetName) const
Get the configuration for the editor widget with the given name.
This element will load a field&#39;s widget onto the form.
QDomElement toDomElement(QDomDocument &doc) const
Get the XML Dom element to save this element.
This element will load a relation editor onto the form.
void setInitFunction(const QString &function)
Set Python function for edit form initialization.
PythonInitCodeSource initCodeSource() const
Return Python code source for edit form initialization (if it shall be loaded from a file...
void setColumnCount(int columnCount)
Set the number of columns in this group.
Use the application-wide setting.
void setLabelOnTop(int idx, bool onTop)
If this is set to true, the widget at the given index will receive its label on the previous line whi...
QgsEditFormConfig()
Create a new edit form config.
void setData(const T &data)
Set the payload data.
Definition: qgsoptional.h:129
An expression with an additional enabled flag.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
void setShowLabel(bool showLabel)
Controls if this element should be labeled with a title (field, relation or groupname).
void setLayout(EditorLayout editorLayout)
Set the active layout style for the attribute editor for this layer.
void addTab(QgsAttributeEditorElement *data)
Adds a new element to the invisible root container in the layout.
FeatureFormSuppress
Types of feature form suppression after feature creation.
void setInitCode(const QString &code)
Set Python code for edit form initialization.
void clearTabs()
Clears all the tabs for the attribute editor form with EditorLayout::TabLayout.
QgsAttributeEditorContainer * invisibleRootContainer()
Get the invisible root container for the drag and drop designer form (EditorLayout::TabLayout).
EditorLayout layout() const
Get the active layout style for the attribute editor for this layer.
void setSuppress(FeatureFormSuppress s)
Set type of feature form pop-up suppression after feature creation (overrides app setting) ...
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.
void writeXml(QDomNode &node, const QgsReadWriteContext &context) const
Write XML information Serialize on project save.
QString initCode() const
Get Python code for edit form initialization.
bool operator==(const QgsEditFormConfig &o)
FeatureFormSuppress suppress() const
Type of feature form pop-up suppression after feature creation (overrides app setting) ...
QgsEditFormConfig & operator=(const QgsEditFormConfig &o)
void setUiForm(const QString &ui)
Set path to the .ui form.
void setInitCodeSource(PythonInitCodeSource initCodeSource)
Set if Python code shall be used for edit form initialization and its origin.
Autogenerate a simple tabular layout for the form.
void setReadOnly(int idx, bool readOnly=true)
If set to false, the widget at the given index will be read-only.
virtual void setIsGroupBox(bool isGroupBox)
Determines if this container is rendered as collapsible group box or tab in a tabwidget.
Load a .ui file for the layout. Needs to be configured.
int columnCount() const
Get the number of columns in this group.
void readXml(const QDomNode &node, const QgsReadWriteContext &context)
Read XML information Deserialize on project load.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:383
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.
bool setWidgetConfig(const QString &widgetName, const QVariantMap &config)
Set the editor widget config for a widget which is not for a simple field.
virtual void addChildElement(QgsAttributeEditorElement *element)
Add a child element to this container.
bool readOnly(int idx) const
This returns true if the field is manually set to read only or if the field does not support editing ...
bool removeWidgetConfig(const QString &widgetName)
Remove the configuration for the editor widget with the given name.
bool labelOnTop(int idx) const
If this returns true, the widget at the given index will receive its label on the previous line while...
void setEnabled(bool enabled)
Set if this optional is enabled.
Definition: qgsoptional.h:99
virtual QgsAttributeEditorElement * clone(QgsAttributeEditorElement *parent) const =0
Returns a clone of this element.
Field is calculated from an expression.
Definition: qgsfields.h:52
QgsAttributeEditorElement * attributeEditorElementFromDomElement(QDomElement &elem, QgsAttributeEditorElement *parent)
Deserialize drag and drop designer elements.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
QString initFunction() const
Get Python function for edit form initialization.
PythonInitCodeSource
The Python init code source options.
QgsAttributeEditorElement * clone(QgsAttributeEditorElement *parent) const override
Creates a deep copy of this element.
QString uiForm() const
Get path to the .ui form. Only meaningful with EditorLayout::UiFileLayout.
QString initFilePath() const
Get Python external file path for edit form initialization.