41 #include <QHBoxLayout> 
   43 #include <QMessageBox> 
   44 #include <QPushButton> 
   45 #include <QTreeWidget> 
   57     if ( mRequest.acceptFeature( layer->
getFeature( fid ) ) )
 
   58       mSelectedFeatureIds << fid;
 
   63 const QgsFeatureIds &QgsFilteredSelectionManager::selectedFeatureIds()
 const 
   67   return mSelectedFeatureIds;
 
   70 int QgsFilteredSelectionManager::selectedFeatureCount()
 
   72   return mSelectedFeatureIds.count();
 
   75 void QgsFilteredSelectionManager::onSelectionChanged( 
const QgsFeatureIds &selected, 
const QgsFeatureIds &deselected, 
bool clearAndSelect )
 
   80     mSelectedFeatureIds.clear();
 
   84     for ( 
const auto fid : deselected )
 
   85       mSelectedFeatureIds.remove( fid );
 
   88   for ( 
const auto fid : selected )
 
   89     if ( mRequest.acceptFeature( layer()->getFeature( fid ) ) )
 
   90       mSelectedFeatureIds << fid;
 
   92       lselected.remove( fid );
 
   94   emit selectionChanged( lselected, deselected, clearAndSelect );
 
  102   , mShowFirstFeature( config.value( QStringLiteral( 
"show_first_feature" ), true ).toBool() )
 
  104   QVBoxLayout *rootLayout = 
new QVBoxLayout( 
this );
 
  105   rootLayout->setContentsMargins( 0, 9, 0, 0 );
 
  108   QHBoxLayout *buttonLayout = 
new QHBoxLayout();
 
  109   buttonLayout->setContentsMargins( 0, 0, 0, 0 );
 
  111   mToggleEditingButton = 
new QToolButton( 
this );
 
  112   mToggleEditingButton->setObjectName( QStringLiteral( 
"mToggleEditingButton" ) );
 
  114   mToggleEditingButton->setText( tr( 
"Toggle Editing" ) );
 
  115   mToggleEditingButton->setEnabled( 
false );
 
  116   mToggleEditingButton->setCheckable( 
true );
 
  117   mToggleEditingButton->setToolTip( tr( 
"Toggle editing mode for child layer" ) );
 
  118   buttonLayout->addWidget( mToggleEditingButton );
 
  120   mSaveEditsButton = 
new QToolButton( 
this );
 
  122   mSaveEditsButton->setText( tr( 
"Save Child Layer Edits" ) );
 
  123   mSaveEditsButton->setToolTip( tr( 
"Save child layer edits" ) );
 
  124   mSaveEditsButton->setEnabled( 
true );
 
  125   buttonLayout->addWidget( mSaveEditsButton );
 
  127   mAddFeatureGeometryButton = 
new QToolButton( 
this );
 
  128   mAddFeatureGeometryButton->setObjectName( QStringLiteral( 
"mAddFeatureGeometryButton" ) );
 
  129   buttonLayout->addWidget( mAddFeatureGeometryButton );
 
  131   mAddFeatureButton = 
new QToolButton( 
this );
 
  133   mAddFeatureButton->setText( tr( 
"Add Child Feature" ) );
 
  134   mAddFeatureButton->setToolTip( tr( 
"Add child feature" ) );
 
  135   mAddFeatureButton->setObjectName( QStringLiteral( 
"mAddFeatureButton" ) );
 
  136   buttonLayout->addWidget( mAddFeatureButton );
 
  138   mDuplicateFeatureButton = 
new QToolButton( 
this );
 
  140   mDuplicateFeatureButton->setText( tr( 
"Duplicate Child Feature(s)" ) );
 
  141   mDuplicateFeatureButton->setToolTip( tr( 
"Duplicate selected child feature(s)" ) );
 
  142   mDuplicateFeatureButton->setObjectName( QStringLiteral( 
"mDuplicateFeatureButton" ) );
 
  143   buttonLayout->addWidget( mDuplicateFeatureButton );
 
  145   mDeleteFeatureButton = 
new QToolButton( 
this );
 
  147   mDeleteFeatureButton->setText( tr( 
"Delete Child Feature(s)" ) );
 
  148   mDeleteFeatureButton->setToolTip( tr( 
"Delete selected child feature(s)" ) );
 
  149   mDeleteFeatureButton->setObjectName( QStringLiteral( 
"mDeleteFeatureButton" ) );
 
  150   buttonLayout->addWidget( mDeleteFeatureButton );
 
  152   mLinkFeatureButton = 
new QToolButton( 
this );
 
  154   mLinkFeatureButton->setText( tr( 
"Link Existing Feature(s)" ) );
 
  155   mLinkFeatureButton->setToolTip( tr( 
"Link existing child feature(s)" ) );
 
  156   mLinkFeatureButton->setObjectName( QStringLiteral( 
"mLinkFeatureButton" ) );
 
  157   buttonLayout->addWidget( mLinkFeatureButton );
 
  159   mUnlinkFeatureButton = 
new QToolButton( 
this );
 
  161   mUnlinkFeatureButton->setText( tr( 
"Unlink Feature(s)" ) );
 
  162   mUnlinkFeatureButton->setToolTip( tr( 
"Unlink selected child feature(s)" ) );
 
  163   mUnlinkFeatureButton->setObjectName( QStringLiteral( 
"mUnlinkFeatureButton" ) );
 
  164   buttonLayout->addWidget( mUnlinkFeatureButton );
 
  166   mZoomToFeatureButton = 
new QToolButton( 
this );
 
  168   mZoomToFeatureButton->setText( tr( 
"Zoom To Feature(s)" ) );
 
  169   mZoomToFeatureButton->setToolTip( tr( 
"Zoom to selected child feature(s)" ) );
 
  170   mZoomToFeatureButton->setObjectName( QStringLiteral( 
"mZoomToFeatureButton" ) );
 
  171   buttonLayout->addWidget( mZoomToFeatureButton );
 
  173   buttonLayout->addItem( 
new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
 
  175   mFormViewButton = 
new QToolButton( 
this );
 
  176   mFormViewButton->setText( tr( 
"Form View" ) );
 
  177   mFormViewButton->setToolTip( tr( 
"Switch to form view" ) );
 
  179   mFormViewButton->setCheckable( 
true );
 
  181   buttonLayout->addWidget( mFormViewButton );
 
  183   mTableViewButton = 
new QToolButton( 
this );
 
  184   mTableViewButton->setText( tr( 
"Table View" ) );
 
  185   mTableViewButton->setToolTip( tr( 
"Switch to table view" ) );
 
  187   mTableViewButton->setCheckable( 
true );
 
  189   buttonLayout->addWidget( mTableViewButton );
 
  191   mViewModeButtonGroup = 
new QButtonGroup( 
this );
 
  195   mMultiEditInfoLabel = 
new QLabel( 
this );
 
  196   buttonLayout->addWidget( mMultiEditInfoLabel );
 
  199   rootLayout->addLayout( buttonLayout );
 
  202   mStackedWidget = 
new QStackedWidget( 
this );
 
  206   mDualView->
setView( mViewMode );
 
  210   mMultiEditStackedWidgetPage = 
new QWidget( 
this );
 
  212     QVBoxLayout *vBoxLayout = 
new QVBoxLayout();
 
  213     vBoxLayout->setContentsMargins( 0, 0, 0, 0 );
 
  215     mMultiEditTreeWidget = 
new QTreeWidget( 
this );
 
  216     mMultiEditTreeWidget->setHeaderHidden( 
true );
 
  217     mMultiEditTreeWidget->setSelectionMode( QTreeWidget::ExtendedSelection );
 
  218     vBoxLayout->addWidget( mMultiEditTreeWidget );
 
  220     mMultiEditStackedWidgetPage->setLayout( vBoxLayout );
 
  222   mStackedWidget->addWidget( mMultiEditStackedWidgetPage );
 
  224   mStackedWidget->addWidget( mDualView );
 
  226   rootLayout->addWidget( mStackedWidget );
 
  228 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
  229   connect( mViewModeButtonGroup, 
static_cast<void ( QButtonGroup::* )( 
int )
>( &QButtonGroup::buttonClicked ),
 
  232   connect( mViewModeButtonGroup, &QButtonGroup::idClicked,
 
  235   connect( mToggleEditingButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::toggleEditing );
 
  237   connect( mAddFeatureButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::addFeature );
 
  238   connect( mAddFeatureGeometryButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::addFeatureGeometry );
 
  244   connect( mMultiEditTreeWidget, &QTreeWidget::itemSelectionChanged, 
this, &QgsRelationEditorWidget::multiEditItemSelectionChanged );
 
  249   setLayout( rootLayout );
 
  263   mFeatureSelectionMgr = 
new QgsFilteredSelectionManager( layer, request, mDualView );
 
  273     text = tr( 
"Add Point Child Feature" );
 
  278     text = tr( 
"Add Line Child Feature" );
 
  283     text = tr( 
"Add Polygon Child Feature" );
 
  286   mAddFeatureGeometryButton->setIcon( icon );
 
  287   mAddFeatureGeometryButton->setText( text );
 
  288   mAddFeatureGeometryButton->setToolTip( text );
 
  300     mMapToolDigitize->
setButton( mAddFeatureGeometryButton );
 
  312 void QgsRelationEditorWidget::updateButtons()
 
  314   bool toggleEditingButtonEnabled = 
false;
 
  316   bool canAddGeometry = 
false;
 
  317   bool canRemove = 
false;
 
  318   bool canEdit = 
false;
 
  319   bool canLink = 
false;
 
  320   bool canUnlink = 
false;
 
  321   bool spatial = 
false;
 
  345   const bool selectionNotEmpty = mFeatureSelectionMgr ? mFeatureSelectionMgr->
selectedFeatureCount() : 
false;
 
  348     const bool multieditLinkedChildSelected = ! selectedChildFeatureIds().isEmpty();
 
  350     canAddGeometry = 
false;
 
  352     canRemove = canRemove && multieditLinkedChildSelected;
 
  356     canUnlink = canUnlink && multieditLinkedChildSelected;
 
  360     canRemove = canRemove && selectionNotEmpty;
 
  361     canUnlink = canUnlink && selectionNotEmpty;
 
  364   mToggleEditingButton->setEnabled( toggleEditingButtonEnabled );
 
  365   mAddFeatureButton->setEnabled( canAdd );
 
  366   mAddFeatureGeometryButton->setEnabled( canAddGeometry );
 
  367   mDuplicateFeatureButton->setEnabled( canEdit && selectionNotEmpty );
 
  368   mLinkFeatureButton->setEnabled( canLink );
 
  369   mDeleteFeatureButton->setEnabled( canRemove );
 
  370   mUnlinkFeatureButton->setEnabled( canUnlink );
 
  371   mZoomToFeatureButton->setEnabled( selectionNotEmpty );
 
  372   mToggleEditingButton->setChecked( canEdit );
 
  373   mSaveEditsButton->setEnabled( canEdit || canLink || canUnlink );
 
  377   mLinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Link ) );
 
  378   mUnlinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
 
  379   mSaveEditsButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) && !
mLayerInSameTransactionGroup );
 
  380   mAddFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
 
  382   mDuplicateFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
 
  383   mDeleteFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
 
  384   mZoomToFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) && 
mEditorContext.
mapCanvas() && spatial );
 
  387 void QgsRelationEditorWidget::addFeature()
 
  394   mMultiEditTreeWidget->blockSignals( 
true );
 
  395   mMultiEdit1NJustAddedIds = addedFeatures;
 
  396   QTreeWidgetItemIterator treeWidgetItemIterator( mMultiEditTreeWidget );
 
  397   while ( *treeWidgetItemIterator )
 
  399     if ( ( *treeWidgetItemIterator )->data( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ) ).toInt() != 
static_cast<int>( MultiEditFeatureType::Child ) )
 
  401       ++treeWidgetItemIterator;
 
  405     if ( addedFeatures.contains( ( *treeWidgetItemIterator )->data( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt() ) )
 
  406       ( *treeWidgetItemIterator )->setSelected( 
true );
 
  408     ++treeWidgetItemIterator;
 
  410   mMultiEditTreeWidget->blockSignals( 
false );
 
  416 void QgsRelationEditorWidget::addFeatureGeometry()
 
  420     QgsLogger::warning( tr( 
"Adding a geometry feature is not supported in multiple edit mode" ) );
 
  430   mMapToolDigitize->
setLayer( layer );
 
  433   if ( window()->objectName() != QLatin1String( 
"QgisApp" ) )
 
  435     window()->setVisible( 
false );
 
  437   setMapTool( mMapToolDigitize );
 
  447     const QString msg = tr( 
"Digitize the geometry for the new feature on layer %1. Press <ESC> to cancel." )
 
  448                         .arg( layer->
name() );
 
  450     lMainMessageBar->pushItem( mMessageBarItem );
 
  454 void QgsRelationEditorWidget::onDigitizingCompleted( 
const QgsFeature &feature )
 
  461 void QgsRelationEditorWidget::multiEditItemSelectionChanged()
 
  463   const QList<QTreeWidgetItem *> selectedItems = mMultiEditTreeWidget->selectedItems();
 
  467   if ( selectedItems.size() == 1
 
  468        && mMultiEditPreviousSelectedItems.size() <= 1 )
 
  470     if ( selectedItems.first()->data( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ) ).toInt() == 
static_cast<int>( MultiEditFeatureType::Child ) )
 
  472       mMultiEditTreeWidget->blockSignals( 
true );
 
  474       const QgsFeatureId featureIdSelectedItem = selectedItems.first()->data( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt();
 
  476       QTreeWidgetItemIterator treeWidgetItemIterator( mMultiEditTreeWidget );
 
  477       while ( *treeWidgetItemIterator )
 
  479         if ( ( *treeWidgetItemIterator )->data( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ) ).toInt() != 
static_cast<int>( MultiEditFeatureType::Child ) )
 
  481           ++treeWidgetItemIterator;
 
  485         const QgsFeatureId featureIdCurrentItem = ( *treeWidgetItemIterator )->data( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt();
 
  488           if ( featureIdSelectedItem == featureIdCurrentItem )
 
  489             ( *treeWidgetItemIterator )->setSelected( 
true );
 
  493           if ( ! mMultiEdit1NJustAddedIds.contains( featureIdSelectedItem ) )
 
  496           if ( mMultiEdit1NJustAddedIds.contains( featureIdCurrentItem ) )
 
  497             ( *treeWidgetItemIterator )->setSelected( 
true );
 
  500         ++treeWidgetItemIterator;
 
  502       mMultiEditTreeWidget->blockSignals( 
false );
 
  505   mMultiEditPreviousSelectedItems = selectedItems;
 
  509 void QgsRelationEditorWidget::toggleEditing( 
bool state )
 
  527     updateUiSingleEdit();
 
  532   mButtonsVisibility = buttons;
 
  539   if ( mLinkFeatureButton->isVisible() )
 
  540     buttons |= Button::Link;
 
  541   if ( mUnlinkFeatureButton->isVisible() )
 
  542     buttons |= Button::Unlink;
 
  543   if ( mSaveEditsButton->isVisible() )
 
  544     buttons |= Button::SaveChildEdits;
 
  545   if ( mAddFeatureButton->isVisible() )
 
  546     buttons |= Button::AddChildFeature;
 
  547   if ( mDuplicateFeatureButton->isVisible() )
 
  548     buttons |= Button::DuplicateChildFeature;
 
  549   if ( mDeleteFeatureButton->isVisible() )
 
  550     buttons |= Button::DeleteChildFeature;
 
  551   if ( mZoomToFeatureButton->isVisible() )
 
  552     buttons |= Button::ZoomToChildFeature;
 
  565     QAction *qAction = 
nullptr;
 
  568     connect( qAction, &QAction::triggered, 
this, [
this, fid]() { 
deleteFeature( fid ); } );
 
  571     connect( qAction, &QAction::triggered, 
this, [
this, fid]() { 
unlinkFeature( fid ); } );
 
  575 void QgsRelationEditorWidget::setMapTool( 
QgsMapTool *mapTool )
 
  580   mapCanvas->window()->raise();
 
  581   mapCanvas->activateWindow();
 
  582   mapCanvas->setFocus();
 
  586 void QgsRelationEditorWidget::unsetMapTool()
 
  597 QgsFeatureIds QgsRelationEditorWidget::selectedChildFeatureIds()
 const 
  602     for ( QTreeWidgetItem *treeWidgetItem : mMultiEditTreeWidget->selectedItems() )
 
  604       if ( 
static_cast<MultiEditFeatureType
>( treeWidgetItem->data( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ) ).toInt() ) != MultiEditFeatureType::Child )
 
  607       featureIds.insert( treeWidgetItem->data( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toLongLong() );
 
  615 void QgsRelationEditorWidget::updateUiSingleEdit()
 
  617   mFormViewButton->setVisible( 
true );
 
  618   mTableViewButton->setVisible( 
true );
 
  619   mMultiEditInfoLabel->setVisible( 
false );
 
  621   mStackedWidget->setCurrentWidget( mDualView );
 
  634       filters << filter.prepend( 
'(' ).append( 
')' );
 
  648 void QgsRelationEditorWidget::updateUiMultiEdit()
 
  650   mFormViewButton->setVisible( 
false );
 
  651   mTableViewButton->setVisible( 
false );
 
  652   mMultiEditInfoLabel->setVisible( 
true );
 
  654   mStackedWidget->setCurrentWidget( mMultiEditStackedWidgetPage ) ;
 
  656   QList<QTreeWidgetItem *> parentTreeWidgetItems;
 
  659   QMultiMap<QTreeWidgetItem *, QgsFeatureId> multimapChildFeatures;
 
  661   mMultiEditTreeWidget->clear();
 
  664     QTreeWidgetItem *treeWidgetItem = createMultiEditTreeWidgetItem( featureParent, 
mRelation.
referencedLayer(), MultiEditFeatureType::Parent );
 
  667     treeWidgetItem->setFlags( Qt::ItemIsEnabled );
 
  669     parentTreeWidgetItems.append( treeWidgetItem );
 
  675     while ( featureIterator.
nextFeature( featureChild ) )
 
  682         while ( featureIteratorFinalChild.
nextFeature( featureChildChild ) )
 
  684           QTreeWidgetItem *treeWidgetItemChild = createMultiEditTreeWidgetItem( featureChildChild, 
mNmRelation.
referencedLayer(), MultiEditFeatureType::Child );
 
  686           treeWidgetItem->addChild( treeWidgetItemChild );
 
  688           featureIdsMixedValues.insert( featureChildChild.
id() );
 
  689           multimapChildFeatures.insert( treeWidgetItem, featureChildChild.
id() );
 
  694         QTreeWidgetItem *treeWidgetItemChild = createMultiEditTreeWidgetItem( featureChild, 
mRelation.
referencingLayer(), MultiEditFeatureType::Child );
 
  695         treeWidgetItem->addChild( treeWidgetItemChild );
 
  697         featureIdsMixedValues.insert( featureChild.
id() );
 
  701     mMultiEditTreeWidget->addTopLevelItem( treeWidgetItem );
 
  702     treeWidgetItem->setExpanded( 
true );
 
  718     QgsFeatureIds::iterator iterator = featureIdsMixedValues.begin();
 
  719     while ( iterator != featureIdsMixedValues.end() )
 
  721       bool mixedValues = 
false;
 
  722       for ( QTreeWidgetItem *parentTreeWidgetItem : parentTreeWidgetItems )
 
  724         if ( ! multimapChildFeatures.values( parentTreeWidgetItem ).contains( *iterator ) )
 
  733         iterator = featureIdsMixedValues.erase( iterator );
 
  742   if ( featureIdsMixedValues.isEmpty() )
 
  745     mMultiEditInfoLabel->setPixmap( icon.pixmap( mMultiEditInfoLabel->height(),
 
  746                                     mMultiEditInfoLabel->height() ) );
 
  747     mMultiEditInfoLabel->setToolTip( tr( 
"All features in selection have equal relations" ) );
 
  752     mMultiEditInfoLabel->setPixmap( icon.pixmap( mMultiEditInfoLabel->height(),
 
  753                                     mMultiEditInfoLabel->height() ) );
 
  754     mMultiEditInfoLabel->setToolTip( tr( 
"Some features in selection have different relations" ) );
 
  757     QFont fontItalic = mMultiEditTreeWidget->font();
 
  758     fontItalic.setItalic( 
true );
 
  759     for ( QTreeWidgetItem *parentTreeWidgetItem : parentTreeWidgetItems )
 
  761       for ( 
int childIndex = 0; childIndex < parentTreeWidgetItem->childCount(); ++childIndex )
 
  763         QTreeWidgetItem *childItem = parentTreeWidgetItem->child( childIndex );
 
  764         const QgsFeatureId featureIdCurrentItem = childItem->data( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ) ).toInt();
 
  765         if ( featureIdsMixedValues.contains( featureIdCurrentItem ) )
 
  766           childItem->setFont( 0, fontItalic );
 
  772 QTreeWidgetItem *QgsRelationEditorWidget::createMultiEditTreeWidgetItem( 
const QgsFeature &feature, 
QgsVectorLayer *layer, MultiEditFeatureType type )
 
  774   QTreeWidgetItem *treeWidgetItem = 
new QTreeWidgetItem();
 
  777   treeWidgetItem->setData( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), 
static_cast<int>( type ) );
 
  778   treeWidgetItem->setData( 0, 
static_cast<int>( MultiEditTreeWidgetRole::FeatureId ), 
feature.
id() );
 
  779   return treeWidgetItem;
 
  782 void QgsRelationEditorWidget::onKeyPressed( QKeyEvent *e )
 
  784   if ( e->key() == Qt::Key_Escape )
 
  786     window()->setVisible( 
true );
 
  788     window()->activateWindow();
 
  793 void QgsRelationEditorWidget::mapToolDeactivated()
 
  799   mMessageBarItem = 
nullptr;
 
  805     {
"show_first_feature", mShowFirstFeature}} );
 
  810   mButtonsVisibility = 
qgsFlagKeysToValue( 
config.value( QStringLiteral( 
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
 
  811   mShowFirstFeature = 
config.value( QStringLiteral( 
"show_first_feature" ), 
true ).toBool();
 
  817   Q_UNUSED( newRelation );
 
  818   Q_UNUSED( newFeature );
 
  847   Q_UNUSED( newRelation );
 
  848   Q_UNUSED( newNmRelation );
 
  882   return mFeatureSelectionMgr;
 
  887   const QgsFeatureIds selectedFids = selectedChildFeatureIds();
 
  903   const QgsFeatureIds selectedFids = selectedChildFeatureIds();
 
  930   QgsRelationEditorWidget::Buttons buttons;
 
  931   buttons.setFlag( QgsRelationEditorWidget::Button::Link, mRelationShowLinkCheckBox->isChecked() );
 
  932   buttons.setFlag( QgsRelationEditorWidget::Button::Unlink, mRelationShowUnlinkCheckBox->isChecked() );
 
  933   buttons.setFlag( QgsRelationEditorWidget::Button::AddChildFeature, mRelationShowAddChildCheckBox->isChecked() );
 
  934   buttons.setFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature, mRelationShowDuplicateChildFeatureCheckBox->isChecked() );
 
  935   buttons.setFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature, mRelationShowZoomToFeatureCheckBox->isChecked() );
 
  936   buttons.setFlag( QgsRelationEditorWidget::Button::DeleteChildFeature, mRelationDeleteChildFeatureCheckBox->isChecked() );
 
  937   buttons.setFlag( QgsRelationEditorWidget::Button::SaveChildEdits, mRelationShowSaveChildEditsCheckBox->isChecked() );
 
  942     {
"show_first_feature", mShowFirstFeature->isChecked()}
 
  948   const QgsRelationEditorWidget::Buttons buttons = 
qgsFlagKeysToValue( 
config.value( QStringLiteral( 
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
 
  950   mRelationShowLinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Link ) );
 
  951   mRelationShowUnlinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
 
  952   mRelationShowAddChildCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
 
  953   mRelationShowDuplicateChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
 
  954   mRelationShowZoomToFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) );
 
  955   mRelationDeleteChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
 
  956   mRelationShowSaveChildEditsCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) );
 
  957   mShowFirstFeature->setChecked( 
config.value( QStringLiteral( 
"show_first_feature" ), 
true ).toBool() );
 
  972   return QStringLiteral( 
"relation_editor" );
 
  977   return QObject::tr( 
"Relation Editor" );