32 #include <QTextStream> 35 #include <QFormLayout> 36 #include <QGridLayout> 40 #include <QPushButton> 41 #include <QScrollArea> 43 #include <QMessageBox> 45 #include <QToolButton> 49 int QgsAttributeForm::sFormCounter = 0;
54 , mMessageBar( nullptr )
55 , mOwnsMessageBar( true )
56 , mMultiEditUnsavedMessageBarItem( nullptr )
57 , mMultiEditMessageBarItem( nullptr )
58 , mInvalidConstraintMessage( nullptr )
60 , mButtonBox( nullptr )
61 , mSearchButtonBox( nullptr )
62 , mFormNr( sFormCounter++ )
64 , mPreventFeatureRefresh( false )
65 , mIsSettingFeature( false )
66 , mIsSettingMultiEditFeatures( false )
67 , mUnsavedMultiEditChanges( false )
68 , mEditCommandMessage( tr(
"Attributes changed" ) )
69 , mMode( SingleEditMode )
75 connect( vl, SIGNAL( updatedFields() ),
this, SLOT( onUpdatedFields() ) );
76 connect( vl, SIGNAL( beforeAddingExpressionField(
QString ) ),
this, SLOT( preventFeatureRefresh() ) );
77 connect( vl, SIGNAL( beforeRemovingExpressionField(
int ) ),
this, SLOT( preventFeatureRefresh() ) );
78 connect( vl, SIGNAL( selectionChanged() ),
this, SLOT( layerSelectionChanged() ) );
81 updateAllConstaints();
87 qDeleteAll( mInterfaces );
96 connect( mLayer, SIGNAL( beforeModifiedCheck() ),
this, SLOT(
save() ) );
103 disconnect( mLayer, SIGNAL( beforeModifiedCheck() ),
this, SLOT(
save() ) );
114 mInterfaces.
append( iface );
130 if ( mUnsavedMultiEditChanges )
134 tr(
"Apply changes to edited features?" ), QMessageBox::Yes | QMessageBox::No );
135 if ( res == QMessageBox::Yes )
140 clearMultiEditMessages();
142 mUnsavedMultiEditChanges =
false;
148 connect( mLayer, SIGNAL( beforeModifiedCheck() ),
this, SLOT(
save() ) );
152 disconnect( mLayer, SIGNAL( beforeModifiedCheck() ),
this, SLOT(
save() ) );
192 synchronizeEnabledState();
197 resetMultiEdit(
false );
198 synchronizeEnabledState();
207 delete mInvalidConstraintMessage;
208 mInvalidConstraintMessage =
nullptr;
212 mTopMessageWidget->
hide();
230 if ( eww && eww->
field().
name() == field )
239 mIsSettingFeature =
true;
249 synchronizeEnabledState();
264 mIsSettingFeature =
false;
267 bool QgsAttributeForm::saveEdits()
270 bool changedLayer =
false;
276 bool doUpdate =
false;
297 bool changed = ( dstVar != srcVar && !dstVar.
isNull() && !srcVar.
isNull() )
299 if ( changed && srcVar.
isValid()
325 bool res = mLayer->
addFeature( updatedFeature );
344 for (
int i = 0; i < dst.
count(); ++i )
346 if (( dst.
at( i ) == src.
at( i ) && dst.
at( i ).isNull() == src.
at( i ).isNull() )
347 || !dst.
at( i ).isValid()
355 .arg( dst.
at( i ).toString(), dst.
at( i ).typeName() ).arg( dst.
at( i ).isNull() ).arg( dst.
at( i ).isValid() ) );
357 .arg( src.
at( i ).toString(), src.
at( i ).typeName() ).arg( src.
at( i ).isNull() ).arg( src.
at( i ).isValid() ) );
359 newValues[i] = dst.
at( i );
360 oldValues[i] = src.
at( i );
367 if ( success && n > 0 )
394 void QgsAttributeForm::resetMultiEdit(
bool promptToSave )
399 mUnsavedMultiEditChanges =
false;
403 void QgsAttributeForm::multiEditMessageClicked(
const QString& link )
405 clearMultiEditMessages();
406 resetMultiEdit( link ==
"#apply" );
409 void QgsAttributeForm::filterTriggered()
411 QString filter = createFilterExpression();
417 void QgsAttributeForm::filterAndTriggered()
419 QString filter = createFilterExpression();
428 void QgsAttributeForm::filterOrTriggered()
430 QString filter = createFilterExpression();
439 void QgsAttributeForm::pushSelectedFeaturesMessage()
445 tr(
"%1 matching %2 selected" ).arg( count )
446 .arg( count == 1 ?
tr(
"feature" ) :
tr(
"features" ) ),
453 tr(
"No matching features found" ),
461 QString filter = createFilterExpression();
466 pushSelectedFeaturesMessage();
471 void QgsAttributeForm::searchSetSelection()
476 void QgsAttributeForm::searchAddToSelection()
481 void QgsAttributeForm::searchRemoveFromSelection()
486 void QgsAttributeForm::searchIntersectSelection()
491 bool QgsAttributeForm::saveMultiEdits()
496 for ( ; wIt != mFormEditorWidgets.
constEnd(); ++ wIt )
514 if ( newAttributeValues.
isEmpty() )
523 tr(
"Edits will be applied to all selected features" ), QMessageBox::Ok | QMessageBox::Cancel );
524 if ( res != QMessageBox::Ok )
537 QgsAttributeMap::const_iterator aIt = newAttributeValues.
constBegin();
538 for ( ; aIt != newAttributeValues.
constEnd(); ++aIt )
544 clearMultiEditMessages();
558 mMessageBar->
pushItem( mMultiEditMessageBarItem );
582 success = saveEdits();
586 success = saveMultiEdits();
591 mUnsavedMultiEditChanges =
false;
612 void QgsAttributeForm::clearMultiEditMessages()
614 if ( mMultiEditUnsavedMessageBarItem )
617 mMessageBar->
popWidget( mMultiEditUnsavedMessageBarItem );
618 mMultiEditUnsavedMessageBarItem =
nullptr;
620 if ( mMultiEditMessageBarItem )
623 mMessageBar->
popWidget( mMultiEditMessageBarItem );
624 mMultiEditMessageBarItem =
nullptr;
628 QString QgsAttributeForm::createFilterExpression()
const 645 void QgsAttributeForm::onAttributeChanged(
const QVariant& value )
657 if ( !mIsSettingFeature )
665 if ( !mIsSettingMultiEditFeatures )
667 mUnsavedMultiEditChanges =
true;
669 QLabel *msgLabel =
new QLabel(
tr(
"Unsaved multiedit changes: <a href=\"#apply\">apply changes</a> or <a href=\"#reset\">reset changes</a>." ), mMessageBar );
670 msgLabel->
setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
671 msgLabel->
setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
672 connect( msgLabel, SIGNAL( linkActivated(
QString ) ),
this, SLOT( multiEditMessageClicked(
QString ) ) );
673 clearMultiEditMessages();
677 mMessageBar->
pushItem( mMultiEditUnsavedMessageBarItem );
700 #if QT_VERSION >= 0x050000 701 buddy->
setText(
QString(
"%1<font color=\"red\">❌</font>" ).arg( text ) );
703 buddy->
setText(
QString(
"%1<font color=\"red\">*</font>" ).arg( text ) );
709 #if QT_VERSION >= 0x050000 710 buddy->
setText(
QString(
"%1<font color=\"green\">✔</font>" ).arg( text ) );
712 buddy->
setText(
QString(
"%1<font color=\"green\">*</font>" ).arg( text ) );
718 updateConstraints( eww );
724 void QgsAttributeForm::updateAllConstaints()
730 updateConstraints( eww );
738 if ( currentFormFeature( ft ) )
745 constraintDependencies( eww, deps );
751 synchronizeEnabledState(
false );
756 Q_FOREACH ( ContainerInformation* info, mContainerInformationDependency.
value( eww->
field().
name() ) )
758 info->apply( &mExpressionContext );
798 void QgsAttributeForm::clearInvalidConstraintsMessage()
800 mTopMessageWidget->
hide();
801 mInvalidConstraintMessage->
clear();
804 void QgsAttributeForm::displayInvalidConstraintMessage(
const QStringList& f,
807 clearInvalidConstraintsMessage();
813 for (
int i = 0; i <
size; i++ )
814 descriptions +=
QString(
"<li>%1: <i>%2</i></li>" ).
arg( f[i] ).
arg( d[i] );
818 mInvalidConstraintMessage->
setText( msg );
819 mTopMessageWidget->
show();
822 void QgsAttributeForm::registerContainerInformation( QgsAttributeForm::ContainerInformation* info )
824 mContainerVisibilityInformation.
append( info );
825 Q_FOREACH (
const QString& col, info->expression.referencedColumns() )
827 mContainerInformationDependency[ col ].append( info );
831 bool QgsAttributeForm::currentFormValidConstraints(
QStringList &invalidFields,
846 descriptions.
append( desc );
856 void QgsAttributeForm::onAttributeAdded(
int idx )
858 mPreventFeatureRefresh =
false;
870 void QgsAttributeForm::onAttributeDeleted(
int idx )
872 mPreventFeatureRefresh =
false;
884 void QgsAttributeForm::onUpdatedFields()
886 mPreventFeatureRefresh =
false;
898 attrs[i].convert(
layer()->fields().at( i ).type() );
913 void QgsAttributeForm::onConstraintStatusChanged(
const QString& constraint,
923 QString tooltip =
tr(
"Description: " ) + description +
"\n" +
924 tr(
"Raw expression: " ) + constraint +
"\n" +
tr(
"Constraint: " ) + err;
935 buddy->
setText(
QString(
"%1<font color=\"red\">*</font>" ).arg( text ) );
940 buddy->
setText(
QString(
"%1<font color=\"green\">*</font>" ).arg( text ) );
959 if ( name != ewwName )
966 if ( name == colName )
977 void QgsAttributeForm::preventFeatureRefresh()
979 mPreventFeatureRefresh =
true;
996 void QgsAttributeForm::synchronizeEnabledState(
bool synchronizeWidgetWrapper )
998 bool isEditable = ( mFeature.
isValid()
1002 if ( synchronizeWidgetWrapper )
1006 bool fieldEditable =
true;
1015 ww->
setEnabled( isEditable && fieldEditable );
1020 clearInvalidConstraintsMessage();
1025 bool validConstraint = currentFormValidConstraints( invalidFields, descriptions );
1027 if ( ! validConstraint )
1028 displayInvalidConstraintMessage( invalidFields, descriptions );
1030 isEditable = isEditable & validConstraint;
1039 void QgsAttributeForm::init()
1044 QWidget* formWidget =
nullptr;
1046 bool buttonBoxVisible =
true;
1050 buttonBoxVisible = mButtonBox->
isVisible();
1052 mButtonBox =
nullptr;
1055 if ( mSearchButtonBox )
1057 delete mSearchButtonBox;
1058 mSearchButtonBox =
nullptr;
1061 qDeleteAll( mWidgets );
1064 while (
QWidget* w = this->findChild<QWidget*>() )
1074 mMessageBar->
setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
1077 mTopMessageWidget =
new QWidget();
1078 mTopMessageWidget->
hide();
1084 mInvalidConstraintMessage =
new QLabel(
this );
1086 mTopMessageWidget->
hide();
1098 mFormEditorWidgets.
clear();
1109 if ( file.open( QFile::ReadOnly ) )
1115 formWidget = loader.
load( &file,
this );
1120 mButtonBox = findChild<QDialogButtonBox*>();
1134 int columnCount = 1;
1141 if ( !containerDef )
1146 tabWidget =
nullptr;
1147 WidgetInfo widgetInfo = createWidgetFromDef( widgDef, formWidget, mLayer, mContext );
1148 layout->
addWidget( widgetInfo.widget, row, column, 1, 2 );
1149 registerContainerInformation(
new ContainerInformation( widgetInfo.widget, containerDef->
visibilityExpression().
data() ) );
1157 layout->
addWidget( tabWidget, row, column, 1, 2 );
1163 tabWidget->
addTab( tabPage, widgDef->
name() );
1167 registerContainerInformation(
new ContainerInformation( tabWidget, tabPage, containerDef->
visibilityExpression().
data() ) );
1172 WidgetInfo widgetInfo = createWidgetFromDef( widgDef, tabPage, mLayer, mContext );
1173 tabPageLayout->
addWidget( widgetInfo.widget );
1178 tabWidget =
nullptr;
1179 WidgetInfo widgetInfo = createWidgetFromDef( widgDef, container, mLayer, mContext );
1181 if ( columnCount > 1 && !widgetInfo.labelOnTop )
1183 label->
setAlignment( Qt::AlignRight | Qt::AlignVCenter );
1186 label->
setBuddy( widgetInfo.widget );
1188 if ( !widgetInfo.showLabel )
1191 label->
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
1193 layout->
addLayout( c, row, column, 1, 2 );
1196 else if ( widgetInfo.labelOnTop )
1199 label->
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
1202 layout->
addLayout( c, row, column, 1, 2 );
1207 layout->
addWidget( label, row, column++ );
1208 layout->
addWidget( widgetInfo.widget, row, column++ );
1212 if ( column >= columnCount * 2 )
1218 formWidget = container;
1225 formWidget =
new QWidget(
this );
1257 if ( widgetType ==
"Hidden" )
1272 mFormEditorWidgets.
insert( idx, formWidget );
1279 w =
new QLabel(
QString(
"<p style=\"color: red; font-style: italic;\">Failed to create widget with type '%1'</p>" ).arg( widgetType ) );
1287 addWidgetWrapper( eww );
1291 gridLayout->
addWidget( l, row++, 0, 1, 2 );
1292 gridLayout->
addWidget( w, row++, 0, 1, 2 );
1314 gridLayout->
addItem( spacerItem, row, 0 );
1322 mButtonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
1328 if ( !mSearchButtonBox )
1330 mSearchButtonBox =
new QWidget();
1334 mSearchButtonBox->
setLayout( boxLayout );
1343 selectButton->
setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
1344 selectButton->
setText(
tr(
"&Select features" ) );
1345 selectButton->
setPopupMode( QToolButton::MenuButtonPopup );
1346 connect( selectButton, SIGNAL( clicked(
bool ) ),
this, SLOT( searchSetSelection() ) );
1347 QMenu* selectMenu =
new QMenu( selectButton );
1348 QAction* selectAction =
new QAction(
tr(
"Select features" ), selectMenu );
1349 connect( selectAction, SIGNAL( triggered(
bool ) ),
this, SLOT( searchSetSelection() ) );
1351 QAction* addSelectAction =
new QAction(
tr(
"Add to current selection" ), selectMenu );
1352 connect( addSelectAction, SIGNAL( triggered(
bool ) ),
this, SLOT( searchAddToSelection() ) );
1353 selectMenu->
addAction( addSelectAction );
1354 QAction* filterSelectAction =
new QAction(
tr(
"Filter current selection" ), selectMenu );
1355 connect( filterSelectAction, SIGNAL( triggered(
bool ) ),
this, SLOT( searchIntersectSelection() ) );
1356 selectMenu->
addAction( filterSelectAction );
1357 QAction* deselectAction =
new QAction(
tr(
"Remove from current selection" ), selectMenu );
1358 connect( deselectAction, SIGNAL( triggered(
bool ) ),
this, SLOT( searchRemoveFromSelection() ) );
1359 selectMenu->
addAction( deselectAction );
1360 selectButton->
setMenu( selectMenu );
1366 filterButton->
setText(
tr(
"Filter features" ) );
1367 filterButton->
setPopupMode( QToolButton::MenuButtonPopup );
1368 filterButton->
setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
1369 connect( filterButton, SIGNAL( clicked(
bool ) ),
this, SLOT( filterTriggered() ) );
1370 QMenu* filterMenu =
new QMenu( filterButton );
1371 QAction* filterAndAction =
new QAction(
tr(
"Filter within (\"AND\")" ), filterMenu );
1372 connect( filterAndAction, SIGNAL( triggered(
bool ) ),
this, SLOT( filterAndTriggered() ) );
1373 filterMenu->
addAction( filterAndAction );
1374 QAction* filterOrAction =
new QAction(
tr(
"Extend filter (\"OR\")" ), filterMenu );
1375 connect( filterOrAction, SIGNAL( triggered(
bool ) ),
this, SLOT( filterOrTriggered() ) );
1376 filterMenu->
addAction( filterOrAction );
1377 filterButton->
setMenu( filterMenu );
1383 connect( closeButton, SIGNAL( clicked(
bool ) ),
this, SIGNAL(
closed() ) );
1394 connect( mButtonBox, SIGNAL( accepted() ),
this, SLOT(
accept() ) );
1397 connect( mLayer, SIGNAL( editingStarted() ),
this, SLOT( synchronizeEnabledState() ) );
1398 connect( mLayer, SIGNAL( editingStopped() ),
this, SLOT( synchronizeEnabledState() ) );
1413 void QgsAttributeForm::cleanPython()
1415 if ( !mPyFormVarName.
isNull() )
1417 QString expr =
QString(
"if locals().has_key('%1'): del %1\n" ).
arg( mPyFormVarName );
1422 void QgsAttributeForm::initPython()
1439 if ( ! initFilePath.
isEmpty() )
1441 QFile inputFile( initFilePath );
1443 if ( inputFile.
open( QFile::ReadOnly ) )
1488 static int sFormId = 0;
1489 mPyFormVarName =
QString(
"_qgis_featureform_%1_%2" ).
arg( mFormNr ).
arg( sFormId++ );
1491 QString form =
QString(
"%1 = sip.wrapinstance( %2, qgis.gui.QgsAttributeForm )" )
1492 .
arg( mPyFormVarName )
1493 .
arg((
unsigned long )
this );
1500 if ( numArgs ==
"3" )
1508 msgBox.
setText(
tr(
"The python init function (<code>%1</code>) does not accept three arguments as expected!<br>Please check the function name in the <b>Fields</b> tab of the layer properties." ).arg( initFunction ) );
1513 .arg( mPyFormVarName );
1514 QgsAttributeFormInterface* iface = QgsPythonRunner::evalToSipObject<QgsAttributeFormInterface*>( expr,
"QgsAttributeFormInterface" );
1524 msgBox.
setText(
tr(
"The python init function (<code>%1</code>) could not be found!<br>Please check the function name in the <b>Fields</b> tab of the layer properties." ).arg( initFunction ) );
1532 WidgetInfo newWidgetInfo;
1534 switch ( widgetDef->
type() )
1543 if ( fldIdx < vl->fields().count() && fldIdx >= 0 )
1550 mFormEditorWidgets.
insert( fldIdx, w );
1554 newWidgetInfo.widget = w;
1555 addWidgetWrapper( eww );
1557 newWidgetInfo.widget->setObjectName( mLayer->
fields().
at( fldIdx ).
name() );
1562 newWidgetInfo.showLabel = widgetDef->
showLabel();
1575 newWidgetInfo.widget = rww->
widget();
1580 newWidgetInfo.labelText = QString::null;
1581 newWidgetInfo.labelOnTop =
true;
1593 if ( columnCount <= 0 )
1602 myContainer = groupBox;
1603 newWidgetInfo.widget = myContainer;
1617 newWidgetInfo.widget = scrollArea;
1621 newWidgetInfo.
widget = myContainer;
1635 WidgetInfo widgetInfo = createWidgetFromDef( childDef, myContainer, vl, context );
1640 registerContainerInformation(
new ContainerInformation( widgetInfo.widget, containerDef->
visibilityExpression().
data() ) );
1643 if ( widgetInfo.labelText.isNull() )
1645 gbLayout->
addWidget( widgetInfo.widget, row, column, 1, 2 );
1651 if ( columnCount > 1 && !widgetInfo.labelOnTop )
1653 mypLabel->
setAlignment( Qt::AlignRight | Qt::AlignVCenter );
1656 mypLabel->
setBuddy( widgetInfo.widget );
1658 if ( widgetInfo.labelOnTop )
1661 mypLabel->
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
1664 gbLayout->
addLayout( c, row, column, 1, 2 );
1669 gbLayout->
addWidget( mypLabel, row, column++ );
1670 gbLayout->
addWidget( widgetInfo.widget, row, column++ );
1674 if ( column >= columnCount * 2 )
1681 spacer->
setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred );
1682 gbLayout->
addWidget( spacer, ++row, 0 );
1685 newWidgetInfo.labelText = QString::null;
1686 newWidgetInfo.labelOnTop =
true;
1691 QgsDebugMsg(
"Unknown attribute editor widget type encountered..." );
1695 newWidgetInfo.showLabel = widgetDef->
showLabel();
1697 return newWidgetInfo;
1719 void QgsAttributeForm::createWrappers()
1724 Q_FOREACH (
QWidget* myWidget, myWidgets )
1743 Q_FOREACH (
const QgsField& field, fields )
1752 addWidgetWrapper( eww );
1759 void QgsAttributeForm::afterWidgetInit()
1761 bool isFirstEww =
true;
1775 connect( eww, SIGNAL( valueChanged(
const QVariant& ) ),
this, SLOT( onAttributeChanged(
const QVariant& ) ) );
1785 Q_FOREACH (
QLabel* label, labels )
1787 if ( label->
buddy() )
1797 if ( e->
type() == QEvent::KeyPress )
1800 if ( keyEvent && keyEvent->
key() == Qt::Key_Escape )
1813 mixedValueFields.
clear();
1814 fieldSharedValues.
clear();
1820 for (
int i = 0; i < mLayer->
fields().
count(); ++i )
1822 if ( mixedValueFields.
contains( i ) )
1827 fieldSharedValues[i] = f.
attribute( i );
1833 fieldSharedValues.
remove( i );
1834 mixedValueFields.
insert( i );
1849 void QgsAttributeForm::layerSelectionChanged()
1859 resetMultiEdit(
true );
1866 mIsSettingMultiEditFeatures =
true;
1867 mMultiEditFeatureIds = fids;
1873 for ( ; wIt != mFormEditorWidgets.
constEnd(); ++ wIt )
1877 mIsSettingMultiEditFeatures =
false;
1886 scanForEqualAttributes( fit, mixedValueFields, fieldSharedValues );
1893 Q_FOREACH (
int field, mixedValueFields )
1897 w->initialize( firstFeature.
attribute( field ), true );
1901 for ( ; sharedValueIt != fieldSharedValues.
constEnd(); ++sharedValueIt )
1905 w->initialize( sharedValueIt.
value(), false );
1908 mIsSettingMultiEditFeatures =
false;
1913 if ( mOwnsMessageBar )
1915 mOwnsMessageBar =
false;
1916 mMessageBar = messageBar;
1919 int QgsAttributeForm::messageTimeout()
1922 return settings.
value(
"/qgis/messageTimeout", 5 ).
toInt();
1927 bool newVisibility = expression.evaluate( expressionContext ).toBool();
1933 tabWidget->setTabVisible( widget, newVisibility );
1937 widget->setVisible( newVisibility );
bool isValid() const
Returns the validity of this feature.
Class for parsing and evaluation of expressions (formerly called "search strings").
Wrapper for iterator of features from vector data provider or vector layer.
bool isValid() const
Returns the validity of this relation.
virtual QLayout * layout()
QString & append(QChar ch)
void setContentsMargins(int left, int top, int right, int bottom)
QgsAttributes attributes() const
Returns the feature's attributes.
int size() const
Return number of items.
This is an abstract base class for any elements of a drag and drop form.
bool enabled() const
Check if this optional is enabled.
void beginEditCommand(const QString &text)
Create edit command for undo/redo operations.
void append(const T &value)
Modify current selection to include only select features which match.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setFrameShape(Shape)
This class contains context information for attribute editor widgets.
QStringList referencedColumns() const
Get list of columns referenced by the expression.
QString & prepend(QChar ch)
static void warning(const QString &msg)
Goes to qWarning.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
const QgsRelation & relation() const
Get the id of the relation which shall be embedded.
const_iterator constBegin() const
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
const QObjectList & children() const
bool changeAttributeValues(QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues)
Changes attributes' values for a feature (but does not immediately commit the changes).
void insert(int i, const T &value)
A bar for displaying non-blocking messages to the user.
void setAlignment(QFlags< Qt::AlignmentFlag >)
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
This element will load a field's widget onto the form.
This element will load a relation editor onto the form.
Set selection, removing any existing selection.
QString join(const QString &separator) const
const_iterator insert(const T &value)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
bool addFeature(QgsFeature &feature, bool alsoUpdateExtent=true)
Adds a feature.
QgsRelationManager * relationManager() const
void setWorkingDirectory(const QDir &dir)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
void selectByExpression(const QString &expression, SelectBehaviour behaviour=SetSelection)
Select matching features using an expression.
int count() const
Return number of items.
QString tr(const char *sourceText, const char *disambiguation, int n)
AttributeEditorType type() const
The type of this element.
QString id() const
A (project-wide) unique id for this relation.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
QgsEditFormConfig * editFormConfig() const
Get the configuration of the form used to represent this vector layer.
QgsFields fields() const
Returns the list of fields of this layer.
void setBuddy(QWidget *buddy)
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
const char * name() const
void pushMessage(const QString &text, MessageLevel level=INFO, int duration=5)
convenience method for pushing a message to the bar
QVariantMap QgsEditorWidgetConfig
Holds a set of configuration parameters for a editor widget wrapper.
void append(const T &value)
bool showUnlinkButton() const
Determines if the "unlink feature" button should be shown.
const QgsFields * fields() const
Returns the field map associated with the feature.
QVariant property(const char *name) const
void setRowStretch(int row, int stretch)
const_iterator constEnd() const
void installEventFilter(QObject *filterObj)
int toInt(bool *ok) const
bool popWidget(QgsMessageBarItem *item)
Remove the passed widget from the bar (if previously added), then display the next one in the stack i...
QString displayName() const
Returns the name to use when displaying this field.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setObjectName(const QString &name)
void setText(const QString &text)
const_iterator constEnd() const
bool showLabel() const
Controls if this element should be labeled with a title (field, relation or groupname).
void triggerRepaint()
Will advice the map canvas (and any other interested party) that this layer requires to be repainted...
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void setOverrideCursor(const QCursor &cursor)
void destroyEditCommand()
Destroy active command and reverts all changes in it.
void restoreOverrideCursor()
QgsOptionalExpression visibilityExpression() const
An expression that controls the visibility of this container.
int idx() const
Return the index of the field.
Encapsulate a field in an attribute table or data source.
int remove(const Key &key)
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
void setMargin(int margin)
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
Q_DECL_DEPRECATED void setFields(const QgsFields *fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
Q_DECL_DEPRECATED bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &value, bool emitSignal)
Changes an attribute value (but does not commit it)
void endEditCommand()
Finish edit command and add it to undo/redo stack.
const T value(const Key &key) const
QgsFeatureId id() const
Get the feature ID for this feature.
static bool eval(const QString &command, QString &result)
Eval a python statement.
FormMode formMode() const
Returns the form mode.
const_iterator constBegin() const
bool contains(const T &value) const
void setFrameShadow(Shadow)
const QgsFeatureIds & selectedFeaturesIds() const
Return reference to identifiers of selected features.
void setValid(bool validity)
Sets the validity of the feature.
SelectBehaviour
Selection behaviour.
void addLayout(QLayout *layout, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
Q_DECL_DEPRECATED QString editFormInit() const
Get python function for edit form initialization.
Add selection to current selection.
const T & at(int i) const
QVariant value(const QString &key, const QVariant &defaultValue) const
const_iterator constBegin() const
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
void pushItem(QgsMessageBarItem *item)
Display a message item on the bar after hiding the currently visible one and putting it in a stack...
bool allowCustomUi() const
Returns true if the attribute editor should permit use of custom UI forms.
static bool run(const QString &command, const QString &messageOnError=QString())
Execute a python statement.
void addStretch(int stretch)
void setTitle(const QString &title)
This class manages a set of relations between layers.
int columnCount() const
Get the number of columns in this group.
void addItem(QLayoutItem *item, int row, int column, int rowSpan, int columnSpan, QFlags< Qt::AlignmentFlag > alignment)
static QgsProject * instance()
Returns the QgsProject singleton instance.
T data() const
Access the payload data.
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
int count(const T &value) const
This is a container for attribute editors, used to group them visually in the attribute form if it is...
QWidget * load(QIODevice *device, QWidget *parentWidget)
void setText(const QString &text)
QList< QgsAttributeEditorElement * > children() const
Get a list of the children elements of this container.
Remove from current selection.
bool setProperty(const char *name, const QVariant &value)
iterator insert(const Key &key, const T &value)
virtual bool isGroupBox() const
Returns if this container is going to be rendered as a group box.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
bool showLinkButton() const
Determines if the "link feature" button should be shown.
bool nextFeature(QgsFeature &f)
QgsRelation relation(const QString &id) const
Get access to a relation by its id.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
QString name() const
Return the name of this element.
int selectedFeatureCount()
The number of features that are selected in this layer.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString attributeDisplayName(int attributeIndex) const
Convenience function that returns the attribute alias if defined or the field name else...
Allows modification of attribute values.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
A form was embedded as a widget on another form.
void setContentsMargins(int left, int top, int right, int bottom)
const T value(const Key &key) const