40 #include <QHBoxLayout>
42 #include <QMessageBox>
43 #include <QPushButton>
55 if ( mRequest.acceptFeature( layer->
getFeature( fid ) ) )
56 mSelectedFeatureIds << fid;
61 const QgsFeatureIds &QgsFilteredSelectionManager::selectedFeatureIds()
const
65 return mSelectedFeatureIds;
68 int QgsFilteredSelectionManager::selectedFeatureCount()
70 return mSelectedFeatureIds.count();
73 void QgsFilteredSelectionManager::onSelectionChanged(
const QgsFeatureIds &selected,
const QgsFeatureIds &deselected,
bool clearAndSelect )
78 mSelectedFeatureIds.clear();
82 for (
const auto fid : deselected )
83 mSelectedFeatureIds.remove( fid );
86 for (
const auto fid : selected )
87 if ( mRequest.acceptFeature( layer()->getFeature( fid ) ) )
88 mSelectedFeatureIds << fid;
90 lselected.remove( fid );
92 emit selectionChanged( lselected, deselected, clearAndSelect );
100 , mShowFirstFeature( config.value( QStringLiteral(
"show_first_feature" ), true ).toBool() )
102 QVBoxLayout *rootLayout =
new QVBoxLayout(
this );
103 rootLayout->setContentsMargins( 0, 9, 0, 0 );
106 QHBoxLayout *buttonLayout =
new QHBoxLayout();
107 buttonLayout->setContentsMargins( 0, 0, 0, 0 );
109 mToggleEditingButton =
new QToolButton(
this );
110 mToggleEditingButton->setObjectName( QStringLiteral(
"mToggleEditingButton" ) );
112 mToggleEditingButton->setText( tr(
"Toggle Editing" ) );
113 mToggleEditingButton->setEnabled(
false );
114 mToggleEditingButton->setCheckable(
true );
115 mToggleEditingButton->setToolTip( tr(
"Toggle editing mode for child layer" ) );
116 buttonLayout->addWidget( mToggleEditingButton );
118 mSaveEditsButton =
new QToolButton(
this );
120 mSaveEditsButton->setText( tr(
"Save Child Layer Edits" ) );
121 mSaveEditsButton->setToolTip( tr(
"Save child layer edits" ) );
122 mSaveEditsButton->setEnabled(
true );
123 buttonLayout->addWidget( mSaveEditsButton );
125 mAddFeatureGeometryButton =
new QToolButton(
this );
126 mAddFeatureGeometryButton->setObjectName( QStringLiteral(
"mAddFeatureGeometryButton" ) );
127 buttonLayout->addWidget( mAddFeatureGeometryButton );
129 mAddFeatureButton =
new QToolButton(
this );
131 mAddFeatureButton->setText( tr(
"Add Child Feature" ) );
132 mAddFeatureButton->setToolTip( tr(
"Add child feature" ) );
133 mAddFeatureButton->setObjectName( QStringLiteral(
"mAddFeatureButton" ) );
134 buttonLayout->addWidget( mAddFeatureButton );
136 mDuplicateFeatureButton =
new QToolButton(
this );
138 mDuplicateFeatureButton->setText( tr(
"Duplicate Child Feature" ) );
139 mDuplicateFeatureButton->setToolTip( tr(
"Duplicate selected child feature" ) );
140 mDuplicateFeatureButton->setObjectName( QStringLiteral(
"mDuplicateFeatureButton" ) );
141 buttonLayout->addWidget( mDuplicateFeatureButton );
143 mDeleteFeatureButton =
new QToolButton(
this );
145 mDeleteFeatureButton->setText( tr(
"Delete Child Feature" ) );
146 mDeleteFeatureButton->setToolTip( tr(
"Delete selected child feature" ) );
147 mDeleteFeatureButton->setObjectName( QStringLiteral(
"mDeleteFeatureButton" ) );
148 buttonLayout->addWidget( mDeleteFeatureButton );
150 mLinkFeatureButton =
new QToolButton(
this );
152 mLinkFeatureButton->setText( tr(
"Link Existing Features" ) );
153 mLinkFeatureButton->setToolTip( tr(
"Link existing child features" ) );
154 mLinkFeatureButton->setObjectName( QStringLiteral(
"mLinkFeatureButton" ) );
155 buttonLayout->addWidget( mLinkFeatureButton );
157 mUnlinkFeatureButton =
new QToolButton(
this );
159 mUnlinkFeatureButton->setText( tr(
"Unlink Feature" ) );
160 mUnlinkFeatureButton->setToolTip( tr(
"Unlink selected child feature" ) );
161 mUnlinkFeatureButton->setObjectName( QStringLiteral(
"mUnlinkFeatureButton" ) );
162 buttonLayout->addWidget( mUnlinkFeatureButton );
164 mZoomToFeatureButton =
new QToolButton(
this );
166 mZoomToFeatureButton->setText( tr(
"Zoom To Feature" ) );
167 mZoomToFeatureButton->setToolTip( tr(
"Zoom to selected child feature" ) );
168 mZoomToFeatureButton->setObjectName( QStringLiteral(
"mZoomToFeatureButton" ) );
169 buttonLayout->addWidget( mZoomToFeatureButton );
171 buttonLayout->addItem(
new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
173 mFormViewButton =
new QToolButton(
this );
174 mFormViewButton->setText( tr(
"Form View" ) );
175 mFormViewButton->setToolTip( tr(
"Switch to form view" ) );
177 mFormViewButton->setCheckable(
true );
179 buttonLayout->addWidget( mFormViewButton );
181 mTableViewButton =
new QToolButton(
this );
182 mTableViewButton->setText( tr(
"Table View" ) );
183 mTableViewButton->setToolTip( tr(
"Switch to table view" ) );
185 mTableViewButton->setCheckable(
true );
187 buttonLayout->addWidget( mTableViewButton );
189 mViewModeButtonGroup =
new QButtonGroup(
this );
194 rootLayout->addLayout( buttonLayout );
197 QGridLayout *relationLayout =
new QGridLayout();
198 relationLayout->setContentsMargins( 0, 0, 0, 0 );
200 mDualView->
setView( mViewMode );
202 relationLayout->addWidget( mDualView );
203 rootLayout->addLayout( relationLayout );
205 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
206 connect( mViewModeButtonGroup,
static_cast<void ( QButtonGroup::* )(
int )
>( &QButtonGroup::buttonClicked ),
209 connect( mViewModeButtonGroup, &QButtonGroup::idClicked,
212 connect( mToggleEditingButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::toggleEditing );
214 connect( mAddFeatureButton, &QAbstractButton::clicked,
this, [
this]() {
addFeature(); } );
215 connect( mAddFeatureGeometryButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::addFeatureGeometry );
225 setLayout( rootLayout );
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 Child Feature" );
256 mAddFeatureGeometryButton->setIcon( icon );
257 mAddFeatureGeometryButton->setText( text );
258 mAddFeatureGeometryButton->setToolTip( text );
270 mMapToolDigitize->
setButton( mAddFeatureGeometryButton );
282 void QgsRelationEditorWidget::updateButtons()
284 bool toggleEditingButtonEnabled =
false;
285 bool editable =
false;
286 bool linkable =
false;
287 bool spatial =
false;
288 const bool selectionNotEmpty = mFeatureSelectionMgr ? mFeatureSelectionMgr->
selectedFeatureCount() :
false;
305 mToggleEditingButton->setEnabled( toggleEditingButtonEnabled );
306 mAddFeatureButton->setEnabled( editable );
307 mAddFeatureGeometryButton->setEnabled( editable );
308 mDuplicateFeatureButton->setEnabled( editable && selectionNotEmpty );
309 mLinkFeatureButton->setEnabled( linkable );
310 mDeleteFeatureButton->setEnabled( editable && selectionNotEmpty );
311 mUnlinkFeatureButton->setEnabled( linkable && selectionNotEmpty );
312 mZoomToFeatureButton->setEnabled( selectionNotEmpty );
313 mToggleEditingButton->setChecked( editable );
314 mSaveEditsButton->setEnabled( editable || linkable );
318 mLinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Link ) );
319 mUnlinkFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
320 mSaveEditsButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) && !
mLayerInSameTransactionGroup );
321 mAddFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
323 mDuplicateFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
324 mDeleteFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
325 mZoomToFeatureButton->setVisible( mButtonsVisibility.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) &&
mEditorContext.
mapCanvas() && spatial );
328 void QgsRelationEditorWidget::addFeatureGeometry()
336 mMapToolDigitize->
setLayer( layer );
339 window()->setVisible(
false );
340 setMapTool( mMapToolDigitize );
350 const QString msg = tr(
"Digitize the geometry for the new feature on layer %1. Press <ESC> to cancel." )
351 .arg( layer->
name() );
353 lMainMessageBar->pushItem( mMessageBarItem );
358 void QgsRelationEditorWidget::onDigitizingCompleted(
const QgsFeature &feature )
365 void QgsRelationEditorWidget::toggleEditing(
bool state )
391 filters << filter.prepend(
'(' ).append(
')' );
407 mButtonsVisibility = buttons;
414 if ( mLinkFeatureButton->isVisible() )
415 buttons |= Button::Link;
416 if ( mUnlinkFeatureButton->isVisible() )
417 buttons |= Button::Unlink;
418 if ( mSaveEditsButton->isVisible() )
419 buttons |= Button::SaveChildEdits;
420 if ( mAddFeatureButton->isVisible() )
421 buttons |= Button::AddChildFeature;
422 if ( mDuplicateFeatureButton->isVisible() )
423 buttons |= Button::DuplicateChildFeature;
424 if ( mDeleteFeatureButton->isVisible() )
425 buttons |= Button::DeleteChildFeature;
426 if ( mZoomToFeatureButton->isVisible() )
427 buttons |= Button::ZoomToChildFeature;
440 QAction *qAction =
nullptr;
443 connect( qAction, &QAction::triggered,
this, [
this, fid]() {
deleteFeature( fid ); } );
446 connect( qAction, &QAction::triggered,
this, [
this, fid]() {
unlinkFeature( fid ); } );
450 void QgsRelationEditorWidget::setMapTool(
QgsMapTool *mapTool )
455 mapCanvas->window()->raise();
456 mapCanvas->activateWindow();
457 mapCanvas->setFocus();
461 void QgsRelationEditorWidget::unsetMapTool()
472 void QgsRelationEditorWidget::onKeyPressed( QKeyEvent *e )
474 if ( e->key() == Qt::Key_Escape )
480 void QgsRelationEditorWidget::mapToolDeactivated()
482 window()->setVisible(
true );
484 window()->activateWindow();
490 mMessageBarItem =
nullptr;
496 {
"show_first_feature", mShowFirstFeature}} );
501 mButtonsVisibility =
qgsFlagKeysToValue(
config.value( QStringLiteral(
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
502 mShowFirstFeature =
config.value( QStringLiteral(
"show_first_feature" ),
true ).toBool();
508 Q_UNUSED( newRelation );
509 Q_UNUSED( newFeature );
537 Q_UNUSED( newRelation );
538 Q_UNUSED( newNmRelation );
572 return mFeatureSelectionMgr;
619 QgsRelationEditorWidget::Buttons buttons;
620 buttons.setFlag( QgsRelationEditorWidget::Button::Link, mRelationShowLinkCheckBox->isChecked() );
621 buttons.setFlag( QgsRelationEditorWidget::Button::Unlink, mRelationShowUnlinkCheckBox->isChecked() );
622 buttons.setFlag( QgsRelationEditorWidget::Button::AddChildFeature, mRelationShowAddChildCheckBox->isChecked() );
623 buttons.setFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature, mRelationShowDuplicateChildFeatureCheckBox->isChecked() );
624 buttons.setFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature, mRelationShowZoomToFeatureCheckBox->isChecked() );
625 buttons.setFlag( QgsRelationEditorWidget::Button::DeleteChildFeature, mRelationDeleteChildFeatureCheckBox->isChecked() );
626 buttons.setFlag( QgsRelationEditorWidget::Button::SaveChildEdits, mRelationShowSaveChildEditsCheckBox->isChecked() );
631 {
"show_first_feature", mShowFirstFeature->isChecked()}
637 const QgsRelationEditorWidget::Buttons buttons =
qgsFlagKeysToValue(
config.value( QStringLiteral(
"buttons" ) ).toString(), QgsRelationEditorWidget::Button::AllButtons );
639 mRelationShowLinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Link ) );
640 mRelationShowUnlinkCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::Unlink ) );
641 mRelationShowAddChildCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::AddChildFeature ) );
642 mRelationShowDuplicateChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DuplicateChildFeature ) );
643 mRelationShowZoomToFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::ZoomToChildFeature ) );
644 mRelationDeleteChildFeatureCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::DeleteChildFeature ) );
645 mRelationShowSaveChildEditsCheckBox->setChecked( buttons.testFlag( QgsRelationEditorWidget::Button::SaveChildEdits ) );
646 mShowFirstFeature->setChecked(
config.value( QStringLiteral(
"show_first_feature" ),
true ).toBool() );
661 return QStringLiteral(
"relation_editor" );
666 return QObject::tr(
"Relation Editor" );
void reset(T *p=nullptr)
Will reset the managed pointer to p.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
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.
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 init(QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request=QgsFeatureRequest(), const QgsAttributeEditorContext &context=QgsAttributeEditorContext(), bool loadFeatures=true, bool showFirstFeature=true)
Has to be called to initialize the dual view.
void parentFormValueChanged(const QString &attribute, const QVariant &value)
Called in embedded forms when an attribute value in the parent form has changed.
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 unique ID, geometry and a list of field...
bool isValid() const
Returns the validity of this feature.
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.
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
void editingStarted()
Emitted when editing on this layer has started.
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...
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.
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.
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.
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