mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-16 00:03:12 -04:00
Contextmenu with individual actions
Individual actions in the contextmenu of the attributetable and the relationeditorwidget. It's unlink and delete feature in the relationeditorwidget. It's delete feature in the attributetable (form view)
This commit is contained in:
parent
9e704ebceb
commit
2eaf4de2ca
@ -245,6 +245,14 @@ Is emitted when a filter expression is set using the view.
|
|||||||
Emitted when the form changes mode.
|
Emitted when the form changes mode.
|
||||||
|
|
||||||
:param mode: new mode
|
:param mode: new mode
|
||||||
|
%End
|
||||||
|
|
||||||
|
void showContextMenuExternally( QgsActionMenu *menu, const QgsFeatureId fid );
|
||||||
|
%Docstring
|
||||||
|
Emitted when selecting context menu on the feature list to create the context menu individually
|
||||||
|
|
||||||
|
:param menu: context menu
|
||||||
|
:param fid: feature id of the selected feature
|
||||||
%End
|
%End
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -128,6 +128,14 @@ Is emitted, whenever the display expression is successfully changed
|
|||||||
%End
|
%End
|
||||||
|
|
||||||
|
|
||||||
|
void willShowContextMenu( QgsActionMenu *menu, const QModelIndex &atIndex );
|
||||||
|
%Docstring
|
||||||
|
Is emitted, when the context menu is created to add the specific actions to it
|
||||||
|
|
||||||
|
:param menu: is the already created context menu
|
||||||
|
:param atIndex: is the position of the current feature in the model
|
||||||
|
%End
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void setEditSelection( const QgsFeatureIds &fids );
|
void setEditSelection( const QgsFeatureIds &fids );
|
||||||
|
@ -105,6 +105,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QgsAttr
|
|||||||
connect( mMainView, &QgsDualView::currentChanged, this, &QgsAttributeTableDialog::mMainView_currentChanged );
|
connect( mMainView, &QgsDualView::currentChanged, this, &QgsAttributeTableDialog::mMainView_currentChanged );
|
||||||
connect( mActionAddFeature, &QAction::triggered, this, &QgsAttributeTableDialog::mActionAddFeature_triggered );
|
connect( mActionAddFeature, &QAction::triggered, this, &QgsAttributeTableDialog::mActionAddFeature_triggered );
|
||||||
connect( mActionExpressionSelect, &QAction::triggered, this, &QgsAttributeTableDialog::mActionExpressionSelect_triggered );
|
connect( mActionExpressionSelect, &QAction::triggered, this, &QgsAttributeTableDialog::mActionExpressionSelect_triggered );
|
||||||
|
connect( mMainView, &QgsDualView::showContextMenuExternally, this, &QgsAttributeTableDialog::showContextMenu );
|
||||||
|
|
||||||
Q_FOREACH ( const QgsField &field, mLayer->fields() )
|
Q_FOREACH ( const QgsField &field, mLayer->fields() )
|
||||||
{
|
{
|
||||||
@ -1042,6 +1043,21 @@ void QgsAttributeTableDialog::setFilterExpression( const QString &filterString,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QgsAttributeTableDialog::deleteFeature( const QgsFeatureId fid )
|
||||||
|
{
|
||||||
|
QgsDebugMsg( QString( "Delete %1" ).arg( fid ) );
|
||||||
|
mLayer->deleteFeature( fid );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsAttributeTableDialog::showContextMenu( QgsActionMenu *menu, const QgsFeatureId fid )
|
||||||
|
{
|
||||||
|
if ( mLayer->isEditable() )
|
||||||
|
{
|
||||||
|
QAction *qAction = menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDeleteSelected.svg" ) ), tr( "Delete feature" ) );
|
||||||
|
connect( qAction, &QAction::triggered, this, [this, fid]() { deleteFeature( fid ); } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// QgsAttributeTableDock
|
// QgsAttributeTableDock
|
||||||
//
|
//
|
||||||
|
@ -219,6 +219,7 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
|
|||||||
void updateFieldFromExpressionSelected();
|
void updateFieldFromExpressionSelected();
|
||||||
void viewModeChanged( QgsAttributeForm::Mode mode );
|
void viewModeChanged( QgsAttributeForm::Mode mode );
|
||||||
void formFilterSet( const QString &filter, QgsAttributeForm::FilterType type );
|
void formFilterSet( const QString &filter, QgsAttributeForm::FilterType type );
|
||||||
|
void showContextMenu( QgsActionMenu *menu, const QgsFeatureId fid );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMenu *mMenuActions = nullptr;
|
QMenu *mMenuActions = nullptr;
|
||||||
@ -236,6 +237,7 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
|
|||||||
QgsAttributeEditorContext mEditorContext;
|
QgsAttributeEditorContext mEditorContext;
|
||||||
|
|
||||||
void updateMultiEditButtonState();
|
void updateMultiEditButtonState();
|
||||||
|
void deleteFeature( const QgsFeatureId fid );
|
||||||
|
|
||||||
friend class TestQgsAttributeTable;
|
friend class TestQgsAttributeTable;
|
||||||
};
|
};
|
||||||
|
@ -74,6 +74,7 @@ void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const Qg
|
|||||||
mTableView->horizontalHeader()->setContextMenuPolicy( Qt::CustomContextMenu );
|
mTableView->horizontalHeader()->setContextMenuPolicy( Qt::CustomContextMenu );
|
||||||
connect( mTableView->horizontalHeader(), &QHeaderView::customContextMenuRequested, this, &QgsDualView::showViewHeaderMenu );
|
connect( mTableView->horizontalHeader(), &QHeaderView::customContextMenuRequested, this, &QgsDualView::showViewHeaderMenu );
|
||||||
connect( mTableView, &QgsAttributeTableView::columnResized, this, &QgsDualView::tableColumnResized );
|
connect( mTableView, &QgsAttributeTableView::columnResized, this, &QgsDualView::tableColumnResized );
|
||||||
|
connect( mFeatureList, &QgsFeatureListView::willShowContextMenu, this, &QgsDualView::widgetWillShowContextMenu );
|
||||||
|
|
||||||
initLayerCache( !( request.flags() & QgsFeatureRequest::NoGeometry ) || !request.filterRect().isNull() );
|
initLayerCache( !( request.flags() & QgsFeatureRequest::NoGeometry ) || !request.filterRect().isNull() );
|
||||||
initModels( mapCanvas, request, loadFeatures );
|
initModels( mapCanvas, request, loadFeatures );
|
||||||
@ -401,7 +402,6 @@ void QgsDualView::insertRecentlyUsedDisplayExpression( const QString &expression
|
|||||||
mLastDisplayExpressionAction = previewAction;
|
mLastDisplayExpressionAction = previewAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QgsDualView::mFeatureList_aboutToChangeEditSelection( bool &ok )
|
void QgsDualView::mFeatureList_aboutToChangeEditSelection( bool &ok )
|
||||||
{
|
{
|
||||||
if ( mLayer->isEditable() && !mAttributeForm->save() )
|
if ( mLayer->isEditable() && !mAttributeForm->save() )
|
||||||
@ -543,7 +543,6 @@ void QgsDualView::viewWillShowContextMenu( QMenu *menu, const QModelIndex &atInd
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QModelIndex sourceIndex = mFilterModel->mapToSource( atIndex );
|
QModelIndex sourceIndex = mFilterModel->mapToSource( atIndex );
|
||||||
|
|
||||||
QAction *copyContentAction = new QAction( tr( "Copy cell content" ), this );
|
QAction *copyContentAction = new QAction( tr( "Copy cell content" ), this );
|
||||||
@ -608,6 +607,13 @@ void QgsDualView::viewWillShowContextMenu( QMenu *menu, const QModelIndex &atInd
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QgsDualView::widgetWillShowContextMenu( QgsActionMenu *menu, const QModelIndex &atIndex )
|
||||||
|
{
|
||||||
|
emit showContextMenuExternally( menu, mFilterModel->rowToId( atIndex ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void QgsDualView::showViewHeaderMenu( QPoint point )
|
void QgsDualView::showViewHeaderMenu( QPoint point )
|
||||||
{
|
{
|
||||||
int col = mTableView->columnAt( point.x() );
|
int col = mTableView->columnAt( point.x() );
|
||||||
|
@ -269,6 +269,13 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
|
|||||||
*/
|
*/
|
||||||
void formModeChanged( QgsAttributeForm::Mode mode );
|
void formModeChanged( QgsAttributeForm::Mode mode );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when selecting context menu on the feature list to create the context menu individually
|
||||||
|
* \param menu context menu
|
||||||
|
* \param fid feature id of the selected feature
|
||||||
|
*/
|
||||||
|
void showContextMenuExternally( QgsActionMenu *menu, const QgsFeatureId fid );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void hideEvent( QHideEvent *event ) override;
|
void hideEvent( QHideEvent *event ) override;
|
||||||
|
|
||||||
@ -289,6 +296,8 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
|
|||||||
|
|
||||||
void viewWillShowContextMenu( QMenu *menu, const QModelIndex &atIndex );
|
void viewWillShowContextMenu( QMenu *menu, const QModelIndex &atIndex );
|
||||||
|
|
||||||
|
void widgetWillShowContextMenu( QgsActionMenu *menu, const QModelIndex &atIndex );
|
||||||
|
|
||||||
void showViewHeaderMenu( QPoint point );
|
void showViewHeaderMenu( QPoint point );
|
||||||
|
|
||||||
void organizeColumns();
|
void organizeColumns();
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
#include "qgsactionmenu.h"
|
|
||||||
#include "qgsattributetabledelegate.h"
|
#include "qgsattributetabledelegate.h"
|
||||||
#include "qgsattributetablefiltermodel.h"
|
#include "qgsattributetablefiltermodel.h"
|
||||||
#include "qgsattributetablemodel.h"
|
#include "qgsattributetablemodel.h"
|
||||||
@ -302,6 +301,9 @@ void QgsFeatureListView::contextMenuEvent( QContextMenuEvent *event )
|
|||||||
QgsFeature feature = mModel->data( index, QgsFeatureListModel::FeatureRole ).value<QgsFeature>();
|
QgsFeature feature = mModel->data( index, QgsFeatureListModel::FeatureRole ).value<QgsFeature>();
|
||||||
|
|
||||||
QgsActionMenu *menu = new QgsActionMenu( mModel->layerCache()->layer(), feature, QStringLiteral( "Feature" ), this );
|
QgsActionMenu *menu = new QgsActionMenu( mModel->layerCache()->layer(), feature, QStringLiteral( "Feature" ), this );
|
||||||
|
|
||||||
|
emit willShowContextMenu( menu, index );
|
||||||
|
|
||||||
menu->exec( event->globalPos() );
|
menu->exec( event->globalPos() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "qgis_sip.h"
|
#include "qgis_sip.h"
|
||||||
#include "qgis.h"
|
#include "qgis.h"
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
#include "qgsactionmenu.h"
|
||||||
|
|
||||||
#include "qgsfeature.h" // For QgsFeatureIds
|
#include "qgsfeature.h" // For QgsFeatureIds
|
||||||
#include "qgis_gui.h"
|
#include "qgis_gui.h"
|
||||||
@ -146,6 +147,13 @@ class GUI_EXPORT QgsFeatureListView : public QListView
|
|||||||
//! \note not available in Python bindings
|
//! \note not available in Python bindings
|
||||||
void aboutToChangeEditSelection( bool &ok ) SIP_SKIP;
|
void aboutToChangeEditSelection( bool &ok ) SIP_SKIP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is emitted, when the context menu is created to add the specific actions to it
|
||||||
|
* \param menu is the already created context menu
|
||||||
|
* \param atIndex is the position of the current feature in the model
|
||||||
|
*/
|
||||||
|
void willShowContextMenu( QgsActionMenu *menu, const QModelIndex &atIndex );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,6 +199,7 @@ class GUI_EXPORT QgsFeatureListView : public QListView
|
|||||||
bool mEditSelectionDrag = false; // Is set to true when the user initiated a left button click over an edit button and still keeps pressing //!< TODO
|
bool mEditSelectionDrag = false; // Is set to true when the user initiated a left button click over an edit button and still keeps pressing //!< TODO
|
||||||
int mRowAnchor = 0;
|
int mRowAnchor = 0;
|
||||||
QItemSelectionModel::SelectionFlags mCtrlDragSelectionFlag;
|
QItemSelectionModel::SelectionFlags mCtrlDragSelectionFlag;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -138,11 +138,13 @@ QgsRelationEditorWidget::QgsRelationEditorWidget( QWidget *parent )
|
|||||||
connect( mSaveEditsButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::saveEdits );
|
connect( mSaveEditsButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::saveEdits );
|
||||||
connect( mAddFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::addFeature );
|
connect( mAddFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::addFeature );
|
||||||
connect( mDuplicateFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::duplicateFeature );
|
connect( mDuplicateFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::duplicateFeature );
|
||||||
connect( mDeleteFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::deleteFeature );
|
connect( mDeleteFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::deleteSelectedFeatures );
|
||||||
connect( mLinkFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::linkFeature );
|
connect( mLinkFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::linkFeature );
|
||||||
connect( mUnlinkFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::unlinkFeature );
|
connect( mUnlinkFeatureButton, &QAbstractButton::clicked, this, &QgsRelationEditorWidget::unlinkSelectedFeatures );
|
||||||
connect( mFeatureSelectionMgr, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsRelationEditorWidget::updateButtons );
|
connect( mFeatureSelectionMgr, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsRelationEditorWidget::updateButtons );
|
||||||
|
|
||||||
|
connect( mDualView, &QgsDualView::showContextMenuExternally, this, &QgsRelationEditorWidget::showContextMenu );
|
||||||
|
|
||||||
// Set initial state for add/remove etc. buttons
|
// Set initial state for add/remove etc. buttons
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
@ -447,27 +449,55 @@ void QgsRelationEditorWidget::duplicateFeature()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsRelationEditorWidget::deleteFeature()
|
void QgsRelationEditorWidget::deleteFeature( const QgsFeatureId featureid )
|
||||||
|
{
|
||||||
|
QgsFeatureIds featureids;
|
||||||
|
|
||||||
|
featureids << featureid;
|
||||||
|
|
||||||
|
deleteFeatures( featureids );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsRelationEditorWidget::deleteSelectedFeatures( )
|
||||||
|
{
|
||||||
|
deleteFeatures( mFeatureSelectionMgr->selectedFeatureIds() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsRelationEditorWidget::deleteFeatures( const QgsFeatureIds &featureids )
|
||||||
{
|
{
|
||||||
QgsVectorLayer *layer = nullptr;
|
QgsVectorLayer *layer = nullptr;
|
||||||
|
|
||||||
if ( mNmRelation.isValid() )
|
if ( mNmRelation.isValid() )
|
||||||
// So far we expect the database to take care of cleaning up the linking table or restricting
|
|
||||||
// TODO: add more options for the behavior here
|
|
||||||
layer = mNmRelation.referencedLayer();
|
layer = mNmRelation.referencedLayer();
|
||||||
else
|
else
|
||||||
layer = mRelation.referencingLayer();
|
layer = mRelation.referencingLayer();
|
||||||
QgsDebugMsg( QString( "Delete %1" ).arg( mFeatureSelectionMgr->selectedFeatureIds().size() ) );
|
|
||||||
layer->deleteFeatures( mFeatureSelectionMgr->selectedFeatureIds() );
|
QgsDebugMsg( QString( "Delete %1" ).arg( featureids.size() ) );
|
||||||
|
layer->deleteFeatures( featureids );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsRelationEditorWidget::unlinkFeature()
|
|
||||||
|
void QgsRelationEditorWidget::unlinkFeature( const QgsFeatureId featureid )
|
||||||
|
{
|
||||||
|
QgsFeatureIds featureids;
|
||||||
|
|
||||||
|
featureids << featureid;
|
||||||
|
|
||||||
|
unlinkFeatures( featureids );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsRelationEditorWidget::unlinkSelectedFeatures( )
|
||||||
|
{
|
||||||
|
unlinkFeatures( mFeatureSelectionMgr->selectedFeatureIds() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsRelationEditorWidget::unlinkFeatures( const QgsFeatureIds &featureids )
|
||||||
{
|
{
|
||||||
if ( mNmRelation.isValid() )
|
if ( mNmRelation.isValid() )
|
||||||
{
|
{
|
||||||
QgsFeatureIterator selectedIterator = mNmRelation.referencedLayer()->getFeatures(
|
QgsFeatureIterator selectedIterator = mNmRelation.referencedLayer()->getFeatures(
|
||||||
QgsFeatureRequest()
|
QgsFeatureRequest()
|
||||||
.setFilterFids( mFeatureSelectionMgr->selectedFeatureIds() )
|
.setFilterFids( featureids )
|
||||||
.setSubsetOfAttributes( mNmRelation.referencedFields() ) );
|
.setSubsetOfAttributes( mNmRelation.referencedFields() ) );
|
||||||
|
|
||||||
QgsFeature f;
|
QgsFeature f;
|
||||||
@ -514,7 +544,7 @@ void QgsRelationEditorWidget::unlinkFeature()
|
|||||||
keyFields.insert( idx, fld );
|
keyFields.insert( idx, fld );
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH ( QgsFeatureId fid, mFeatureSelectionMgr->selectedFeatureIds() )
|
Q_FOREACH ( QgsFeatureId fid, featureids )
|
||||||
{
|
{
|
||||||
QMapIterator<int, QgsField> it( keyFields );
|
QMapIterator<int, QgsField> it( keyFields );
|
||||||
while ( it.hasNext() )
|
while ( it.hasNext() )
|
||||||
@ -630,3 +660,17 @@ void QgsRelationEditorWidget::setShowLabel( bool showLabel )
|
|||||||
else
|
else
|
||||||
setTitle( QString() );
|
setTitle( QString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsRelationEditorWidget::showContextMenu( QgsActionMenu *menu, const QgsFeatureId fid )
|
||||||
|
{
|
||||||
|
if ( mRelation.referencingLayer()->isEditable() )
|
||||||
|
{
|
||||||
|
QAction *qAction = nullptr;
|
||||||
|
|
||||||
|
qAction = menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionDeleteSelected.svg" ) ), tr( "Delete feature" ) );
|
||||||
|
connect( qAction, &QAction::triggered, this, [this, fid]() { deleteFeature( fid ); } );
|
||||||
|
|
||||||
|
qAction = menu->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUnlink.svg" ) ), tr( "Unlink feature" ) );
|
||||||
|
connect( qAction, &QAction::triggered, this, [this, fid]() { unlinkFeature( fid ); } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -148,11 +148,14 @@ class GUI_EXPORT QgsRelationEditorWidget : public QgsCollapsibleGroupBox
|
|||||||
void addFeature();
|
void addFeature();
|
||||||
void duplicateFeature();
|
void duplicateFeature();
|
||||||
void linkFeature();
|
void linkFeature();
|
||||||
void deleteFeature();
|
void deleteFeature( const QgsFeatureId featureid = QgsFeatureId() );
|
||||||
void unlinkFeature();
|
void deleteSelectedFeatures();
|
||||||
|
void unlinkFeature( const QgsFeatureId featureid = QgsFeatureId() );
|
||||||
|
void unlinkSelectedFeatures();
|
||||||
void saveEdits();
|
void saveEdits();
|
||||||
void toggleEditing( bool state );
|
void toggleEditing( bool state );
|
||||||
void onCollapsedStateChanged( bool collapsed );
|
void onCollapsedStateChanged( bool collapsed );
|
||||||
|
void showContextMenu( QgsActionMenu *menu, const QgsFeatureId fid );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateUi();
|
void updateUi();
|
||||||
@ -179,6 +182,20 @@ class GUI_EXPORT QgsRelationEditorWidget : public QgsCollapsibleGroupBox
|
|||||||
|
|
||||||
bool mShowLabel = true;
|
bool mShowLabel = true;
|
||||||
bool mVisible = false;
|
bool mVisible = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the features
|
||||||
|
* \param featureids features to delete
|
||||||
|
* \since QGIS 3.00
|
||||||
|
*/
|
||||||
|
void deleteFeatures( const QgsFeatureIds &featureids );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlinks the features
|
||||||
|
* \param featureids features to unlink
|
||||||
|
* \since QGIS 3.00
|
||||||
|
*/
|
||||||
|
void unlinkFeatures( const QgsFeatureIds &featureids );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QGSRELATIONEDITOR_H
|
#endif // QGSRELATIONEDITOR_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user