39 #include <QHBoxLayout>
41 #include <QMessageBox>
42 #include <QPushButton>
54 if ( mRequest.acceptFeature( layer->
getFeature( fid ) ) )
55 mSelectedFeatureIds << fid;
60 const QgsFeatureIds &QgsFilteredSelectionManager::selectedFeatureIds()
const
64 return mSelectedFeatureIds;
67 int QgsFilteredSelectionManager::selectedFeatureCount()
69 return mSelectedFeatureIds.count();
72 void QgsFilteredSelectionManager::onSelectionChanged(
const QgsFeatureIds &selected,
const QgsFeatureIds &deselected,
bool clearAndSelect )
77 mSelectedFeatureIds.clear();
81 for (
auto fid : deselected )
82 mSelectedFeatureIds.remove( fid );
85 for (
auto fid : selected )
86 if ( mRequest.acceptFeature( layer()->getFeature( fid ) ) )
87 mSelectedFeatureIds << fid;
89 lselected.remove( fid );
91 emit selectionChanged( lselected, deselected, clearAndSelect );
100 QVBoxLayout *rootLayout =
new QVBoxLayout(
this );
101 rootLayout->setContentsMargins( 0, 0, 0, 0 );
104 rootLayout->addWidget( mRootCollapsibleGroupBox );
106 QVBoxLayout *topLayout =
new QVBoxLayout( mRootCollapsibleGroupBox );
107 topLayout->setContentsMargins( 0, 9, 0, 0 );
110 QHBoxLayout *buttonLayout =
new QHBoxLayout();
111 buttonLayout->setContentsMargins( 0, 0, 0, 0 );
113 mToggleEditingButton =
new QToolButton(
this );
114 mToggleEditingButton->setObjectName( QStringLiteral(
"mToggleEditingButton" ) );
116 mToggleEditingButton->setText( tr(
"Toggle Editing" ) );
117 mToggleEditingButton->setEnabled(
false );
118 mToggleEditingButton->setCheckable(
true );
119 mToggleEditingButton->setToolTip( tr(
"Toggle editing mode for child layer" ) );
120 buttonLayout->addWidget( mToggleEditingButton );
122 mSaveEditsButton =
new QToolButton(
this );
124 mSaveEditsButton->setText( tr(
"Save Child Layer Edits" ) );
125 mSaveEditsButton->setToolTip( tr(
"Save child layer edits" ) );
126 mSaveEditsButton->setEnabled(
true );
127 buttonLayout->addWidget( mSaveEditsButton );
129 mAddFeatureGeometryButton =
new QToolButton(
this );
130 mAddFeatureGeometryButton->setObjectName( QStringLiteral(
"mAddFeatureGeometryButton" ) );
131 buttonLayout->addWidget( mAddFeatureGeometryButton );
133 mAddFeatureButton =
new QToolButton(
this );
135 mAddFeatureButton->setText( tr(
"Add Child Feature" ) );
136 mAddFeatureButton->setToolTip( tr(
"Add child feature" ) );
137 mAddFeatureButton->setObjectName( QStringLiteral(
"mAddFeatureButton" ) );
138 buttonLayout->addWidget( mAddFeatureButton );
140 mDuplicateFeatureButton =
new QToolButton(
this );
142 mDuplicateFeatureButton->setText( tr(
"Duplicate Child Feature" ) );
143 mDuplicateFeatureButton->setToolTip( tr(
"Duplicate child feature" ) );
144 mDuplicateFeatureButton->setObjectName( QStringLiteral(
"mDuplicateFeatureButton" ) );
145 buttonLayout->addWidget( mDuplicateFeatureButton );
147 mDeleteFeatureButton =
new QToolButton(
this );
149 mDeleteFeatureButton->setText( tr(
"Delete Child Feature" ) );
150 mDeleteFeatureButton->setToolTip( tr(
"Delete child feature" ) );
151 mDeleteFeatureButton->setObjectName( QStringLiteral(
"mDeleteFeatureButton" ) );
152 buttonLayout->addWidget( mDeleteFeatureButton );
154 mLinkFeatureButton =
new QToolButton(
this );
156 mLinkFeatureButton->setText( tr(
"Link Existing Features" ) );
157 mLinkFeatureButton->setToolTip( tr(
"Link existing child features" ) );
158 mLinkFeatureButton->setObjectName( QStringLiteral(
"mLinkFeatureButton" ) );
159 buttonLayout->addWidget( mLinkFeatureButton );
161 mUnlinkFeatureButton =
new QToolButton(
this );
163 mUnlinkFeatureButton->setText( tr(
"Unlink Feature" ) );
164 mUnlinkFeatureButton->setToolTip( tr(
"Unlink child feature" ) );
165 mUnlinkFeatureButton->setObjectName( QStringLiteral(
"mUnlinkFeatureButton" ) );
166 buttonLayout->addWidget( mUnlinkFeatureButton );
168 mZoomToFeatureButton =
new QToolButton(
this );
170 mZoomToFeatureButton->setText( tr(
"Zoom To Feature" ) );
171 mZoomToFeatureButton->setToolTip( tr(
"Zoom to child feature" ) );
172 mZoomToFeatureButton->setObjectName( QStringLiteral(
"mZoomToFeatureButton" ) );
173 buttonLayout->addWidget( mZoomToFeatureButton );
175 buttonLayout->addItem(
new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
177 mFormViewButton =
new QToolButton(
this );
178 mFormViewButton->setText( tr(
"Form View" ) );
179 mFormViewButton->setToolTip( tr(
"Switch to form view" ) );
181 mFormViewButton->setCheckable(
true );
183 buttonLayout->addWidget( mFormViewButton );
185 mTableViewButton =
new QToolButton(
this );
186 mTableViewButton->setText( tr(
"Table View" ) );
187 mTableViewButton->setToolTip( tr(
"Switch to table view" ) );
189 mTableViewButton->setCheckable(
true );
191 buttonLayout->addWidget( mTableViewButton );
193 mViewModeButtonGroup =
new QButtonGroup(
this );
198 topLayout->addLayout( buttonLayout );
200 mRelationLayout =
new QGridLayout();
201 mRelationLayout->setContentsMargins( 0, 0, 0, 0 );
202 topLayout->addLayout( mRelationLayout );
205 mDualView->
setView( mViewMode );
207 mRelationLayout->addWidget( mDualView );
210 connect( mViewModeButtonGroup,
static_cast<void ( QButtonGroup::* )(
int )
>( &QButtonGroup::buttonClicked ),
212 connect( mToggleEditingButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::toggleEditing );
214 connect( mAddFeatureButton, &QAbstractButton::clicked,
this, [
this]() {
addFeature(); } );
215 connect( mAddFeatureGeometryButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::addFeatureGeometry );
233 mFeatureSelectionMgr =
new QgsFilteredSelectionManager( layer, request, mDualView );
243 text = tr(
"Add Point child Feature" );
248 text = tr(
"Add Line child Feature" );
253 text = tr(
"Add Polygon Feature" );
256 mAddFeatureGeometryButton->setIcon( icon );
257 mAddFeatureGeometryButton->setText( text );
258 mAddFeatureGeometryButton->setToolTip( text );
270 mMapToolDigitize->
setButton( mAddFeatureGeometryButton );
282 void QgsRelationEditorWidget::updateButtons()
284 bool editable =
false;
285 bool linkable =
false;
286 bool spatial =
false;
287 bool selectionNotEmpty = mFeatureSelectionMgr ? mFeatureSelectionMgr->
selectedFeatureCount() :
false;
302 mAddFeatureButton->setEnabled( editable );
303 mAddFeatureGeometryButton->setEnabled( editable );
304 mDuplicateFeatureButton->setEnabled( editable && selectionNotEmpty );
305 mLinkFeatureButton->setEnabled( linkable );
306 mDeleteFeatureButton->setEnabled( editable && selectionNotEmpty );
307 mUnlinkFeatureButton->setEnabled( linkable && selectionNotEmpty );
308 mZoomToFeatureButton->setEnabled( selectionNotEmpty );
309 mToggleEditingButton->setChecked( editable );
310 mSaveEditsButton->setEnabled( editable );
314 mLinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Link ) );
315 mUnlinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
316 mSaveEditsButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) && !
mLayerInSameTransactionGroup );
317 mAddFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
319 mDuplicateFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
320 mDeleteFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
321 mZoomToFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) &&
mEditorContext.
mapCanvas() && spatial );
324 void QgsRelationEditorWidget::addFeatureGeometry()
332 mMapToolDigitize->
setLayer( layer );
335 window()->setVisible(
false );
336 setMapTool( mMapToolDigitize );
346 QString msg = tr(
"Digitize the geometry for the new feature on layer %1. Press <ESC> to cancel." )
347 .arg( layer->
name() );
349 lMainMessageBar->pushItem( mMessageBarItem );
354 void QgsRelationEditorWidget::onDigitizingCompleted(
const QgsFeature &feature )
361 void QgsRelationEditorWidget::toggleEditing(
bool state )
368 void QgsRelationEditorWidget::onCollapsedStateChanged(
bool collapsed )
398 filters << filter.prepend(
'(' ).append(
')' );
416 mButtonsVisibility = buttons;
423 if ( mLinkFeatureButton->isVisible() )
424 buttons |= Button::Link;
425 if ( mUnlinkFeatureButton->isVisible() )
426 buttons |= Button::Unlink;
427 if ( mSaveEditsButton->isVisible() )
428 buttons |= Button::SaveChildEdits;
429 if ( mAddFeatureButton->isVisible() )
430 buttons |= Button::AddChildFeature;
431 if ( mDuplicateFeatureButton->isVisible() )
432 buttons |= Button::DuplicateChildFeature;
433 if ( mDeleteFeatureButton->isVisible() )
434 buttons |= Button::DeleteChildFeature;
435 if ( mZoomToFeatureButton->isVisible() )
436 buttons |= Button::ZoomToChildFeature;
449 QAction *qAction =
nullptr;
452 connect( qAction, &QAction::triggered,
this, [
this, fid]() {
deleteFeature( fid ); } );
455 connect( qAction, &QAction::triggered,
this, [
this, fid]() {
unlinkFeature( fid ); } );
459 void QgsRelationEditorWidget::setMapTool(
QgsMapTool *mapTool )
464 mapCanvas->window()->raise();
465 mapCanvas->activateWindow();
466 mapCanvas->setFocus();
470 void QgsRelationEditorWidget::unsetMapTool()
481 void QgsRelationEditorWidget::onKeyPressed( QKeyEvent *e )
483 if ( e->key() == Qt::Key_Escape )
489 void QgsRelationEditorWidget::mapToolDeactivated()
491 window()->setVisible(
true );
493 window()->activateWindow();
499 mMessageBarItem =
nullptr;
509 mButtonsVisibility =
qgsFlagKeysToValue(
config.value( QStringLiteral(
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
515 mRootCollapsibleGroupBox->setTitle( title );
520 Q_UNUSED( newRelation );
521 Q_UNUSED( newFeature );
532 mToggleEditingButton->setEnabled(
false );
542 if ( canChangeAttributes && !vl->
readOnly() )
544 mToggleEditingButton->setEnabled(
true );
549 mToggleEditingButton->setEnabled(
false );
565 Q_UNUSED( newRelation );
566 Q_UNUSED( newNmRelation );
597 if ( canChangeAttributes && !vl->
readOnly() )
599 mToggleEditingButton->setEnabled(
true );
603 mToggleEditingButton->setEnabled(
false );
611 return mFeatureSelectionMgr;
658 QgsRelationEditorWidget::Buttons buttons;
659 buttons.setFlag( QgsRelationEditorWidget::Button::Link, mRelationShowLinkCheckBox->isChecked() );
660 buttons.setFlag( QgsRelationEditorWidget::Button::Unlink, mRelationShowUnlinkCheckBox->isChecked() );
661 buttons.setFlag( QgsRelationEditorWidget::Button::AddChildFeature, mRelationShowAddChildCheckBox->isChecked() );
662 buttons.setFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature, mRelationShowDuplicateChildFeatureCheckBox->isChecked() );
663 buttons.setFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature, mRelationShowZoomToFeatureCheckBox->isChecked() );
664 buttons.setFlag( QgsRelationEditorWidget::Button::DeleteChildFeature, mRelationDeleteChildFeatureCheckBox->isChecked() );
665 buttons.setFlag( QgsRelationEditorWidget::Button::SaveChildEdits, mRelationShowSaveChildEditsCheckBox->isChecked() );
675 const QgsRelationEditorWidget::Buttons buttons =
qgsFlagKeysToValue(
config.value( QStringLiteral(
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
677 mRelationShowLinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Link ) );
678 mRelationShowUnlinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
679 mRelationShowAddChildCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
680 mRelationShowDuplicateChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
681 mRelationShowZoomToFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) );
682 mRelationDeleteChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
683 mRelationShowSaveChildEditsCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) );
698 return QStringLiteral(
"relation_editor" );
703 return QStringLiteral(
"Relation Editor" );
void reset(T *p=nullptr)
Will reset the managed pointer to p.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
This class contains context information for attribute editor widgets.
QgsMapCanvas * mapCanvas() const
Returns the associated map canvas (e.g.
QgsMessageBar * mainMessageBar()
Returns the main message bar.
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.
void collapsedStateChanged(bool collapsed)
Signal emitted when groupbox collapsed/expanded state is changed, and when first shown.
A groupbox that collapses/expands when toggled and can save its collapsed and checked states.
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...
void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
Set the feature selection model.
void parentFormValueChanged(const QString &attribute, const QVariant &value)
Called in embedded forms when an attribute value in the parent form has changed.
void init(QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request=QgsFeatureRequest(), const QgsAttributeEditorContext &context=QgsAttributeEditorContext(), bool loadFeatures=true)
Has to be called to initialize the dual view.
void setView(ViewMode view)
Change the current view mode.
QString expression() const
Returns the original, unmodified expression string.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsExpression * filterExpression() const
Returns the filter expression if set.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Is an interface class to abstract feature selection handling.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
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 keyPressed(QKeyEvent *e)
Emit key press event.
void setMapTool(QgsMapTool *mapTool, bool clean=false)
Sets the map tool currently being used on the canvas.
bool popWidget(QgsMessageBarItem *item)
Remove the specified item from the bar, and display the next most recent one in the stack.
static QgsMessageBarItem * createMessage(const QString &text, QWidget *parent=nullptr)
Creates message bar item widget containing a message text to be displayed on the bar.
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
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...
@ ChangeAttributeValues
Allows modification of attribute values.
virtual Q_INVOKABLE QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
int selectedFeatureCount() override
Returns the number of features that are selected in this layer.
const QgsFeatureIds & selectedFeatureIds() const override
Returns reference to identifiers of selected features.
static QString getFeatureDisplayString(const QgsVectorLayer *layer, const QgsFeature &feature)
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
void editingStarted()
Emitted when editing on this layer has started.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
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
T qgsFlagKeysToValue(const QString &keys, const T &defaultValue)
Returns the value corresponding to the given keys of a flag.
QString qgsFlagValueToKeys(const T &value)
Returns the value for the given keys of a flag.
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features