42#include "moc_qgsrelationeditorwidget.cpp"
44using namespace Qt::StringLiterals;
56 if ( mRequest.acceptFeature( layer->
getFeature( fid ) ) )
57 mSelectedFeatureIds << fid;
62const QgsFeatureIds &QgsFilteredSelectionManager::selectedFeatureIds()
const
66 return mSelectedFeatureIds;
69int QgsFilteredSelectionManager::selectedFeatureCount()
71 return mSelectedFeatureIds.count();
74void QgsFilteredSelectionManager::onSelectionChanged(
const QgsFeatureIds &selected,
const QgsFeatureIds &deselected,
bool clearAndSelect )
79 mSelectedFeatureIds.clear();
83 for (
const auto fid : deselected )
84 mSelectedFeatureIds.remove( fid );
87 for (
const auto fid : selected )
88 if ( mRequest.acceptFeature( layer()->getFeature( fid ) ) )
89 mSelectedFeatureIds << fid;
91 lselected.remove( fid );
93 emit selectionChanged( lselected, deselected, clearAndSelect );
101 , mShowFirstFeature(
config.value( u
"show_first_feature"_s, true ).toBool() )
102 , mAllowAddChildFeatureWithNoGeometry(
config.value( u
"allow_add_child_feature_with_no_geometry"_s, false ).toBool() )
103 , mFilterExpression(
config.value( u
"filter_expression"_s ).toString() )
105 QVBoxLayout *rootLayout =
new QVBoxLayout(
this );
106 rootLayout->setContentsMargins( 0, 9, 0, 0 );
109 QHBoxLayout *buttonLayout =
new QHBoxLayout();
110 buttonLayout->setContentsMargins( 0, 0, 0, 0 );
112 mToggleEditingButton =
new QToolButton(
this );
113 mToggleEditingButton->setObjectName( u
"mToggleEditingButton"_s );
115 mToggleEditingButton->setText( tr(
"Toggle Editing" ) );
116 mToggleEditingButton->setEnabled(
false );
117 mToggleEditingButton->setCheckable(
true );
118 mToggleEditingButton->setToolTip( tr(
"Toggle editing mode for child layer" ) );
119 buttonLayout->addWidget( mToggleEditingButton );
121 mSaveEditsButton =
new QToolButton(
this );
123 mSaveEditsButton->setText( tr(
"Save Child Layer Edits" ) );
124 mSaveEditsButton->setToolTip( tr(
"Save child layer edits" ) );
125 mSaveEditsButton->setEnabled(
true );
126 buttonLayout->addWidget( mSaveEditsButton );
128 mAddFeatureGeometryButton =
new QToolButton(
this );
129 mAddFeatureGeometryButton->setObjectName( u
"mAddFeatureGeometryButton"_s );
130 buttonLayout->addWidget( mAddFeatureGeometryButton );
132 mAddFeatureButton =
new QToolButton(
this );
134 mAddFeatureButton->setText( tr(
"Add Child Feature" ) );
135 mAddFeatureButton->setToolTip( tr(
"Add child feature" ) );
136 mAddFeatureButton->setObjectName( u
"mAddFeatureButton"_s );
137 buttonLayout->addWidget( mAddFeatureButton );
139 mDuplicateFeatureButton =
new QToolButton(
this );
141 mDuplicateFeatureButton->setText( tr(
"Duplicate Child Feature(s)" ) );
142 mDuplicateFeatureButton->setToolTip( tr(
"Duplicate selected child feature(s)" ) );
143 mDuplicateFeatureButton->setObjectName( u
"mDuplicateFeatureButton"_s );
144 buttonLayout->addWidget( mDuplicateFeatureButton );
146 mDeleteFeatureButton =
new QToolButton(
this );
148 mDeleteFeatureButton->setText( tr(
"Delete Child Feature(s)" ) );
149 mDeleteFeatureButton->setToolTip( tr(
"Delete selected child feature(s)" ) );
150 mDeleteFeatureButton->setObjectName( u
"mDeleteFeatureButton"_s );
151 buttonLayout->addWidget( mDeleteFeatureButton );
153 mLinkFeatureButton =
new QToolButton(
this );
155 mLinkFeatureButton->setText( tr(
"Link Existing Feature(s)" ) );
156 mLinkFeatureButton->setToolTip( tr(
"Link existing child feature(s)" ) );
157 mLinkFeatureButton->setObjectName( u
"mLinkFeatureButton"_s );
158 buttonLayout->addWidget( mLinkFeatureButton );
160 mUnlinkFeatureButton =
new QToolButton(
this );
162 mUnlinkFeatureButton->setText( tr(
"Unlink Feature(s)" ) );
163 mUnlinkFeatureButton->setToolTip( tr(
"Unlink selected child feature(s)" ) );
164 mUnlinkFeatureButton->setObjectName( u
"mUnlinkFeatureButton"_s );
165 buttonLayout->addWidget( mUnlinkFeatureButton );
167 mZoomToFeatureButton =
new QToolButton(
this );
169 mZoomToFeatureButton->setText( tr(
"Zoom To Feature(s)" ) );
170 mZoomToFeatureButton->setToolTip( tr(
"Zoom to selected child feature(s)" ) );
171 mZoomToFeatureButton->setObjectName( u
"mZoomToFeatureButton"_s );
172 buttonLayout->addWidget( mZoomToFeatureButton );
174 buttonLayout->addItem(
new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
176 mFormViewButton =
new QToolButton(
this );
177 mFormViewButton->setText( tr(
"Form View" ) );
178 mFormViewButton->setToolTip( tr(
"Switch to form view" ) );
180 mFormViewButton->setCheckable(
true );
182 buttonLayout->addWidget( mFormViewButton );
184 mTableViewButton =
new QToolButton(
this );
185 mTableViewButton->setText( tr(
"Table View" ) );
186 mTableViewButton->setToolTip( tr(
"Switch to table view" ) );
188 mTableViewButton->setCheckable(
true );
190 buttonLayout->addWidget( mTableViewButton );
192 mViewModeButtonGroup =
new QButtonGroup(
this );
196 mMultiEditInfoLabel =
new QLabel(
this );
197 buttonLayout->addWidget( mMultiEditInfoLabel );
200 rootLayout->addLayout( buttonLayout );
203 mStackedWidget =
new QStackedWidget(
this );
207 mDualView->setView( mViewMode );
211 mMultiEditStackedWidgetPage =
new QWidget(
this );
213 QVBoxLayout *vBoxLayout =
new QVBoxLayout();
214 vBoxLayout->setContentsMargins( 0, 0, 0, 0 );
216 mMultiEditTreeWidget =
new QTreeWidget(
this );
217 mMultiEditTreeWidget->setHeaderHidden(
true );
218 mMultiEditTreeWidget->setSelectionMode( QTreeWidget::ExtendedSelection );
219 vBoxLayout->addWidget( mMultiEditTreeWidget );
221 mMultiEditStackedWidgetPage->setLayout( vBoxLayout );
223 mStackedWidget->addWidget( mMultiEditStackedWidgetPage );
225 mStackedWidget->addWidget( mDualView );
227 rootLayout->addWidget( mStackedWidget );
230 connect( mToggleEditingButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::toggleEditing );
232 connect( mAddFeatureButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::addFeature );
233 connect( mAddFeatureGeometryButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::addFeatureGeometry );
236 connect( mLinkFeatureButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::linkFeature );
239 connect( mMultiEditTreeWidget, &QTreeWidget::itemSelectionChanged,
this, &QgsRelationEditorWidget::multiEditItemSelectionChanged );
244 setLayout( rootLayout );
257 mDualView->init( layer,
mEditorContext.mapCanvas(), request, ctx,
true, mShowFirstFeature );
258 mFeatureSelectionMgr =
new QgsFilteredSelectionManager( layer, request, mDualView );
259 mDualView->setFeatureSelectionManager( mFeatureSelectionMgr );
268 text = tr(
"Add Point Child Feature" );
273 text = tr(
"Add Line Child Feature" );
278 text = tr(
"Add Polygon Child Feature" );
281 mAddFeatureGeometryButton->setIcon( icon );
282 mAddFeatureGeometryButton->setText( text );
283 mAddFeatureGeometryButton->setToolTip( text );
295 mMapToolDigitize->setButton( mAddFeatureGeometryButton );
303 mDualView->setView( mode );
307void QgsRelationEditorWidget::updateButtons()
309 bool toggleEditingButtonEnabled =
false;
311 bool canAddGeometry =
false;
312 bool canRemove =
false;
313 bool canEdit =
false;
314 bool canLink =
false;
315 bool canUnlink =
false;
316 bool spatial =
false;
332 toggleEditingButtonEnabled |=
mNmRelation.referencedLayer()->supportsEditing();
333 canAdd =
mNmRelation.referencedLayer()->isEditable();
334 canAddGeometry =
mNmRelation.referencedLayer()->isEditable();
335 canRemove =
mNmRelation.referencedLayer()->isEditable();
336 canEdit =
mNmRelation.referencedLayer()->isEditable();
337 spatial =
mNmRelation.referencedLayer()->isSpatial();
340 const bool selectionNotEmpty = mFeatureSelectionMgr ? mFeatureSelectionMgr->selectedFeatureCount() :
false;
343 const bool multieditLinkedChildSelected = !selectedChildFeatureIds().isEmpty();
345 canAddGeometry =
false;
347 canRemove = canRemove && multieditLinkedChildSelected;
351 canUnlink = canUnlink && multieditLinkedChildSelected;
355 canRemove = canRemove && selectionNotEmpty;
356 canUnlink = canUnlink && selectionNotEmpty;
359 mToggleEditingButton->setEnabled( toggleEditingButtonEnabled );
360 mAddFeatureButton->setEnabled( canAdd );
361 mAddFeatureGeometryButton->setEnabled( canAddGeometry );
362 mDuplicateFeatureButton->setEnabled( canEdit && selectionNotEmpty );
363 mLinkFeatureButton->setEnabled( canLink );
364 mDeleteFeatureButton->setEnabled( canRemove );
365 mUnlinkFeatureButton->setEnabled( canUnlink );
366 mZoomToFeatureButton->setEnabled( selectionNotEmpty );
367 mToggleEditingButton->setChecked( canEdit );
368 mSaveEditsButton->setEnabled( canEdit || canLink || canUnlink );
382void QgsRelationEditorWidget::addFeature()
389 mMultiEditTreeWidget->blockSignals(
true );
390 mMultiEdit1NJustAddedIds = addedFeatures;
391 QTreeWidgetItemIterator treeWidgetItemIterator( mMultiEditTreeWidget );
392 while ( *treeWidgetItemIterator )
394 if ( ( *treeWidgetItemIterator )->data( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ) ).toInt() !=
static_cast<int>( MultiEditFeatureType::Child ) )
396 ++treeWidgetItemIterator;
400 if ( addedFeatures.contains( ( *treeWidgetItemIterator )->data( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt() ) )
401 ( *treeWidgetItemIterator )->setSelected(
true );
403 ++treeWidgetItemIterator;
405 mMultiEditTreeWidget->blockSignals(
false );
411void QgsRelationEditorWidget::addFeatureGeometry()
415 QgsLogger::warning( tr(
"Adding a geometry feature is not supported in multiple edit mode" ) );
419 QgsVectorLayer *layer =
nullptr;
425 mMapToolDigitize->setLayer( layer );
428 if ( window()->objectName() !=
"QgisApp"_L1 )
430 window()->setVisible(
false );
432 setMapTool( mMapToolDigitize );
442 const QString title = tr(
"Create child feature for parent %1 \"%2\"" ).arg(
mRelation.referencedLayer()->name(), displayString );
443 const QString msg = tr(
"Digitize the geometry for the new feature on layer %1. Press <ESC> to cancel." )
444 .arg( layer->
name() );
446 lMainMessageBar->pushItem( mMessageBarItem );
450void QgsRelationEditorWidget::onDigitizingCompleted(
const QgsFeature &feature )
453 digitizingFinished();
456void QgsRelationEditorWidget::multiEditItemSelectionChanged()
458 const QList<QTreeWidgetItem *> selectedItems = mMultiEditTreeWidget->selectedItems();
462 if ( selectedItems.size() == 1
463 && mMultiEditPreviousSelectedItems.size() <= 1 )
465 if ( selectedItems.first()->data( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ) ).toInt() ==
static_cast<int>( MultiEditFeatureType::Child ) )
467 mMultiEditTreeWidget->blockSignals(
true );
469 const QgsFeatureId featureIdSelectedItem = selectedItems.first()->data( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt();
471 QTreeWidgetItemIterator treeWidgetItemIterator( mMultiEditTreeWidget );
472 while ( *treeWidgetItemIterator )
474 if ( ( *treeWidgetItemIterator )->data( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ) ).toInt() !=
static_cast<int>( MultiEditFeatureType::Child ) )
476 ++treeWidgetItemIterator;
480 const QgsFeatureId featureIdCurrentItem = ( *treeWidgetItemIterator )->data( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt();
483 if ( featureIdSelectedItem == featureIdCurrentItem )
484 ( *treeWidgetItemIterator )->setSelected(
true );
488 if ( !mMultiEdit1NJustAddedIds.contains( featureIdSelectedItem ) )
491 if ( mMultiEdit1NJustAddedIds.contains( featureIdCurrentItem ) )
492 ( *treeWidgetItemIterator )->setSelected(
true );
495 ++treeWidgetItemIterator;
497 mMultiEditTreeWidget->blockSignals(
false );
500 mMultiEditPreviousSelectedItems = selectedItems;
504void QgsRelationEditorWidget::linkFeature()
509void QgsRelationEditorWidget::toggleEditing(
bool state )
527 updateUiSingleEdit();
532 mButtonsVisibility = buttons;
539 if ( mLinkFeatureButton->isVisible() )
541 if ( mUnlinkFeatureButton->isVisible() )
543 if ( mSaveEditsButton->isVisible() )
545 if ( mAddFeatureButton->isVisible() )
547 if ( mDuplicateFeatureButton->isVisible() )
549 if ( mDeleteFeatureButton->isVisible() )
551 if ( mZoomToFeatureButton->isVisible() )
558 mDualView->parentFormValueChanged( attribute, newValue );
565 QAction *qAction =
nullptr;
570 connect( qAction, &QAction::triggered,
this, [
this, fid]() {
deleteFeature( fid ); } );
576 connect( qAction, &QAction::triggered,
this, [
this, fid]() {
unlinkFeature( fid ); } );
581void QgsRelationEditorWidget::setMapTool(
QgsMapTool *mapTool )
586 mapCanvas->window()->raise();
587 mapCanvas->activateWindow();
588 mapCanvas->setFocus();
592void QgsRelationEditorWidget::unsetMapTool()
602QgsFeatureIds QgsRelationEditorWidget::selectedChildFeatureIds()
const
607 for ( QTreeWidgetItem *treeWidgetItem : mMultiEditTreeWidget->selectedItems() )
609 if (
static_cast<MultiEditFeatureType
>( treeWidgetItem->data( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ) ).toInt() ) != MultiEditFeatureType::Child )
612 featureIds.insert( treeWidgetItem->data( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toLongLong() );
616 else if ( mFeatureSelectionMgr )
618 return mFeatureSelectionMgr->selectedFeatureIds();
626void QgsRelationEditorWidget::updateUiSingleEdit()
628 mFormViewButton->setVisible(
true );
629 mTableViewButton->setVisible(
true );
630 mMultiEditInfoLabel->setVisible(
false );
632 mStackedWidget->setCurrentWidget( mDualView );
635 QgsVectorLayer *layer =
nullptr;
639 QgsFeatureRequest nmRequest;
641 QgsFeatureIterator it =
mRelation.referencingLayer()->getFeatures( request );
646 QString filter =
mNmRelation.getReferencedFeatureRequest( fet ).filterExpression()->expression();
647 filters << filter.prepend(
'(' ).append(
')' );
650 QString reducedExpression;
660 request = std::move( nmRequest );
672 if ( !mDualView->masterModel() || layer != mDualView->masterModel()->layer() )
674 initDualView( layer, request );
678 mFeatureSelectionMgr =
new QgsFilteredSelectionManager( layer, request, mDualView );
679 mDualView->setFeatureSelectionManager( mFeatureSelectionMgr );
682 mDualView->setRequest( request );
683 mDualView->masterModel()->loadLayer();
689void QgsRelationEditorWidget::updateUiMultiEdit()
691 mFormViewButton->setVisible(
false );
692 mTableViewButton->setVisible(
false );
693 mMultiEditInfoLabel->setVisible(
true );
695 mStackedWidget->setCurrentWidget( mMultiEditStackedWidgetPage );
697 QList<QTreeWidgetItem *> parentTreeWidgetItems;
700 QMultiMap<QTreeWidgetItem *, QgsFeatureId> multimapChildFeatures;
702 mMultiEditTreeWidget->clear();
703 for (
const QgsFeature &featureParent : std::as_const(
mFeatureList ) )
705 QTreeWidgetItem *treeWidgetItem = createMultiEditTreeWidgetItem( featureParent,
mRelation.referencedLayer(), MultiEditFeatureType::Parent );
708 treeWidgetItem->setFlags( Qt::ItemIsEnabled );
710 parentTreeWidgetItems.append( treeWidgetItem );
714 QgsFeatureIterator featureIterator =
mRelation.referencingLayer()->getFeatures( request );
715 QgsFeature featureChild;
716 while ( featureIterator.
nextFeature( featureChild ) )
720 const QgsFeatureRequest requestFinalChild =
mNmRelation.getReferencedFeatureRequest( featureChild );
721 QgsFeatureIterator featureIteratorFinalChild =
mNmRelation.referencedLayer()->getFeatures( requestFinalChild );
722 QgsFeature featureChildChild;
723 while ( featureIteratorFinalChild.
nextFeature( featureChildChild ) )
725 QTreeWidgetItem *treeWidgetItemChild = createMultiEditTreeWidgetItem( featureChildChild,
mNmRelation.referencedLayer(), MultiEditFeatureType::Child );
727 treeWidgetItem->addChild( treeWidgetItemChild );
729 featureIdsMixedValues.insert( featureChildChild.
id() );
730 multimapChildFeatures.insert( treeWidgetItem, featureChildChild.
id() );
735 QTreeWidgetItem *treeWidgetItemChild = createMultiEditTreeWidgetItem( featureChild,
mRelation.referencingLayer(), MultiEditFeatureType::Child );
736 treeWidgetItem->addChild( treeWidgetItemChild );
738 featureIdsMixedValues.insert( featureChild.
id() );
742 mMultiEditTreeWidget->addTopLevelItem( treeWidgetItem );
743 treeWidgetItem->setExpanded(
true );
759 QgsFeatureIds::iterator iterator = featureIdsMixedValues.begin();
760 while ( iterator != featureIdsMixedValues.end() )
762 bool mixedValues =
false;
763 for ( QTreeWidgetItem *parentTreeWidgetItem : parentTreeWidgetItems )
765 if ( !multimapChildFeatures.values( parentTreeWidgetItem ).contains( *iterator ) )
774 iterator = featureIdsMixedValues.erase( iterator );
783 if ( featureIdsMixedValues.isEmpty() )
786 mMultiEditInfoLabel->setPixmap( icon.pixmap( mMultiEditInfoLabel->height(), mMultiEditInfoLabel->height() ) );
787 mMultiEditInfoLabel->setToolTip( tr(
"All features in selection have equal relations" ) );
792 mMultiEditInfoLabel->setPixmap( icon.pixmap( mMultiEditInfoLabel->height(), mMultiEditInfoLabel->height() ) );
793 mMultiEditInfoLabel->setToolTip( tr(
"Some features in selection have different relations" ) );
796 QFont fontItalic = mMultiEditTreeWidget->font();
797 fontItalic.setItalic(
true );
798 for ( QTreeWidgetItem *parentTreeWidgetItem : parentTreeWidgetItems )
800 for (
int childIndex = 0; childIndex < parentTreeWidgetItem->childCount(); ++childIndex )
802 QTreeWidgetItem *childItem = parentTreeWidgetItem->child( childIndex );
803 const QgsFeatureId featureIdCurrentItem = childItem->data( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt();
804 if ( featureIdsMixedValues.contains( featureIdCurrentItem ) )
805 childItem->setFont( 0, fontItalic );
811QTreeWidgetItem *QgsRelationEditorWidget::createMultiEditTreeWidgetItem(
const QgsFeature &feature,
QgsVectorLayer *layer, MultiEditFeatureType type )
813 QTreeWidgetItem *treeWidgetItem =
new QTreeWidgetItem();
816 treeWidgetItem->setData( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ),
static_cast<int>( type ) );
817 treeWidgetItem->setData( 0,
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ),
feature.id() );
818 return treeWidgetItem;
821void QgsRelationEditorWidget::onDigitizingCanceled()
823 digitizingFinished();
826void QgsRelationEditorWidget::digitizingFinished()
828 window()->setVisible(
true );
830 window()->activateWindow();
834void QgsRelationEditorWidget::mapToolDeactivated()
840 mMessageBarItem =
nullptr;
845 return QVariantMap( { {
"buttons",
qgsFlagValueToKeys(
visibleButtons() ) }, {
"show_first_feature", mShowFirstFeature }, {
"allow_add_child_feature_with_no_geometry", mAllowAddChildFeatureWithNoGeometry }, {
"filter_expression", mFilterExpression } } );
851 mShowFirstFeature =
config.value( u
"show_first_feature"_s,
true ).toBool();
852 mAllowAddChildFeatureWithNoGeometry =
config.value( u
"allow_add_child_feature_with_no_geometry"_s,
false ).toBool();
853 mFilterExpression =
config.value( u
"filter_expression"_s ).toString();
859 Q_UNUSED( newRelation );
860 Q_UNUSED( newFeature );
884 initDualView(
mRelation.referencingLayer(), myRequest );
889 Q_UNUSED( newRelation );
890 Q_UNUSED( newNmRelation );
924 return mFeatureSelectionMgr;
929 const QgsFeatureIds selectedFids = selectedChildFeatureIds();
945 const QgsFeatureIds selectedFids = selectedChildFeatureIds();
957 mFeatureSelectionMgr->selectedFeatureIds()
971 filterExpressionLabel->setEnabled( mRelationShowLinkCheckBox->isChecked() );
972 mEditExpression->setEnabled( mRelationShowLinkCheckBox->isChecked() );
973 mFilterExpression->setEnabled( mRelationShowLinkCheckBox->isChecked() );
974 connect( mRelationShowLinkCheckBox, &QCheckBox::toggled, filterExpressionLabel, &QLabel::setEnabled );
975 connect( mRelationShowLinkCheckBox, &QCheckBox::toggled, mEditExpression, &QToolButton::setEnabled );
976 connect( mRelationShowLinkCheckBox, &QCheckBox::toggled, mFilterExpression, &QTextEdit::setEnabled );
979 mAllowAddChildFeatureWithNoGeometry->setEnabled( mRelationShowAddChildCheckBox->isChecked() );
980 connect( mRelationShowAddChildCheckBox, &QCheckBox::toggled, mAllowAddChildFeatureWithNoGeometry, &QCheckBox::setEnabled );
999 dlg.setWindowTitle( tr(
"Edit Filter Expression of Target Layer" ) );
1001 if ( dlg.exec() == QDialog::Accepted )
1020 {
"show_first_feature", mShowFirstFeature->isChecked() },
1021 {
"allow_add_child_feature_with_no_geometry", mAllowAddChildFeatureWithNoGeometry->isChecked() },
1022 {
"filter_expression", mFilterExpression->toPlainText() }
1038 mShowFirstFeature->setChecked(
config.value( u
"show_first_feature"_s,
true ).toBool() );
1039 mAllowAddChildFeatureWithNoGeometry->setChecked(
config.value( u
"allow_add_child_feature_with_no_geometry"_s,
false ).toBool() );
1040 mFilterExpression->setPlainText(
config.value( u
"filter_expression"_s ).toString() );
1054 return u
"relation_editor"_s;
1059 return QObject::tr(
"Relation Editor" );
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Contains context information for attribute editor widgets.
QgsMapCanvas * mapCanvas() const
Returns the associated map canvas (e.g.
QgsAdvancedDigitizingDockWidget * cadDockWidget() const
Returns the associated CAD dock widget (e.g.
void setParentFormFeature(const QgsFeature &feature)
Sets the feature of the currently edited parent form.
This widget is used to show the attributes of a set of features of a QgsVectorLayer.
void showContextMenuExternally(QgsActionMenu *menu, QgsFeatureId fid)
Emitted when selecting context menu on the feature list to create the context menu individually.
ViewMode
The view modes, in which this widget can present information.
@ AttributeTable
Shows the features and attributes in a table layout.
@ AttributeEditor
Show a list of the features, where one can be chosen and the according attribute dialog will be prese...
A generic dialog for building expression strings.
QgsExpressionBuilderWidget * expressionBuilder()
The builder widget that is used by the dialog.
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...
static bool attemptReduceToInClause(const QStringList &expressions, QString &result)
Attempts to reduce a list of expressions to a single "field IN (val1, val2, ... )" type expression.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Is an interface class to abstract feature selection handling.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
static QIcon iconForLayer(const QgsMapLayer *layer)
Returns the icon corresponding to a specified map layer.
static void warning(const QString &msg)
Goes to qWarning.
Map canvas is a class for displaying all GIS data types on a canvas.
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
void setMapTool(QgsMapTool *mapTool, bool clean=false)
Sets the map tool currently being used on the canvas.
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
void editingStarted()
Emitted when editing on this layer has started.
static QgsMessageBarItem * createMessage(const QString &text, QWidget *parent=nullptr)
Creates message bar item widget containing a message text to be displayed on the bar.
Represents a relationship between two vector layers.
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
Manages vector layer selections.
static QString getFeatureDisplayString(const QgsVectorLayer *layer, const QgsFeature &feature)
Returns a descriptive string for a feature, suitable for displaying to the user.
Represents a vector layer which manages a vector based dataset.
bool isEditable() const final
Returns true if the provider is in editing mode.
bool isSpatial() const final
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsFlagValueToKeys(const T &value, bool *returnOk=nullptr)
Returns the value for the given keys of a flag.
T qgsFlagKeysToValue(const QString &keys, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given keys of a flag.
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features