diff --git a/src/gui/attributetable/qgsvectorlayerselectionmanager.cpp b/src/gui/attributetable/qgsvectorlayerselectionmanager.cpp index 560f5a8b608..e9f4c28ffe2 100644 --- a/src/gui/attributetable/qgsvectorlayerselectionmanager.cpp +++ b/src/gui/attributetable/qgsvectorlayerselectionmanager.cpp @@ -21,7 +21,7 @@ QgsVectorLayerSelectionManager::QgsVectorLayerSelectionManager( QgsVectorLayer * : QgsIFeatureSelectionManager( parent ) , mLayer( layer ) { - connect( mLayer, &QgsVectorLayer::selectionChanged, this, &QgsVectorLayerSelectionManager::selectionChanged ); + connect( mLayer, &QgsVectorLayer::selectionChanged, this, &QgsVectorLayerSelectionManager::onSelectionChanged ); } int QgsVectorLayerSelectionManager::selectedFeatureCount() @@ -48,3 +48,13 @@ const QgsFeatureIds &QgsVectorLayerSelectionManager::selectedFeatureIds() const { return mLayer->selectedFeatureIds(); } + +QgsVectorLayer *QgsVectorLayerSelectionManager::layer() const +{ + return mLayer; +} + +void QgsVectorLayerSelectionManager::onSelectionChanged( const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect ) +{ + emit selectionChanged( selected, deselected, clearAndSelect ); +} diff --git a/src/gui/attributetable/qgsvectorlayerselectionmanager.h b/src/gui/attributetable/qgsvectorlayerselectionmanager.h index 8fcaec3bb8e..7c245e4d508 100644 --- a/src/gui/attributetable/qgsvectorlayerselectionmanager.h +++ b/src/gui/attributetable/qgsvectorlayerselectionmanager.h @@ -41,6 +41,10 @@ class GUI_EXPORT QgsVectorLayerSelectionManager : public QgsIFeatureSelectionMan void deselect( const QgsFeatureIds &ids ) override; void setSelectedFeatures( const QgsFeatureIds &ids ) override; const QgsFeatureIds &selectedFeatureIds() const override; + QgsVectorLayer *layer() const; + + protected slots: + virtual void onSelectionChanged( const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect ); private: QgsVectorLayer *mLayer = nullptr; diff --git a/src/gui/qgsrelationeditorwidget.cpp b/src/gui/qgsrelationeditorwidget.cpp index 555b28e4f63..fb5155992f0 100644 --- a/src/gui/qgsrelationeditorwidget.cpp +++ b/src/gui/qgsrelationeditorwidget.cpp @@ -36,6 +36,64 @@ #include #include +class QgsFilteredSelectionManager : public QgsVectorLayerSelectionManager +{ + public: + QgsFilteredSelectionManager( QgsVectorLayer *layer, const QgsFeatureRequest &request, QObject *parent = nullptr ) + : QgsVectorLayerSelectionManager( layer, parent ) + , mRequest( request ) + { + QgsFeature feature; + QgsFeatureIterator it = layer->getSelectedFeatures( mRequest ); + while ( it.nextFeature( feature ) ) + { + mSelectedFeatureIds << feature.id(); + } + + connect( layer, &QgsVectorLayer::selectionChanged, this, &QgsFilteredSelectionManager::onSelectionChanged ); + } + + const QgsFeatureIds &selectedFeatureIds() const override + { + return mSelectedFeatureIds; + } + + + int selectedFeatureCount() override + { + return mSelectedFeatureIds.count(); + } + + public slots: + + void onSelectionChanged( const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect ) override + { + QgsFeatureIds lselected = selected; + if ( clearAndSelect ) + { + mSelectedFeatureIds.clear(); + } + else + { + for ( auto fid : deselected ) + mSelectedFeatureIds.remove( fid ); + } + + for ( auto fid : selected ) + if ( mRequest.acceptFeature( layer()->getFeature( fid ) ) ) + mSelectedFeatureIds << fid; + else + lselected.remove( fid ); + + emit selectionChanged( lselected, deselected, clearAndSelect ); + } + + private: + + QgsFeatureRequest mRequest; + QgsFeatureIds mSelectedFeatureIds; +}; + QgsRelationEditorWidget::QgsRelationEditorWidget( QWidget *parent ) : QgsCollapsibleGroupBox( parent ) { @@ -203,7 +261,7 @@ void QgsRelationEditorWidget::setRelationFeature( const QgsRelation &relation, c void QgsRelationEditorWidget::initDualView( QgsVectorLayer *layer, const QgsFeatureRequest &request ) { mDualView->init( layer, nullptr, request, mEditorContext ); - mFeatureSelectionMgr = new QgsVectorLayerSelectionManager( layer, mDualView ); + mFeatureSelectionMgr = new QgsFilteredSelectionManager( layer, request, mDualView ); mDualView->setFeatureSelectionManager( mFeatureSelectionMgr ); connect( mFeatureSelectionMgr, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsRelationEditorWidget::updateButtons ); } diff --git a/tests/src/python/test_qgsrelationeditwidget.py b/tests/src/python/test_qgsrelationeditwidget.py index ae54725d8f2..f5fe3a142b2 100644 --- a/tests/src/python/test_qgsrelationeditwidget.py +++ b/tests/src/python/test_qgsrelationeditwidget.py @@ -255,6 +255,37 @@ class TestQgsRelationEditWidget(unittest.TestCase): self.assertEqual([2, 3], relation.referencingFields()) self.assertEqual([0, 1], relation.referencedFields()) + def test_selection(self): + + fbook = QgsFeature(self.vl_books.fields()) + fbook.setAttributes([self.vl_books.dataProvider().defaultValueClause(0), 'The Hitchhiker\'s Guide to the Galaxy', 'Sputnik Editions', 1961]) + self.vl_books.addFeature(fbook) + + flink = QgsFeature(self.vl_link_books_authors.fields()) + flink.setAttributes([fbook.id(), 5]) + self.vl_link_books_authors.addFeature(flink) + + self.createWrapper(self.vl_authors, '"name"=\'Douglas Adams\'') + + self.zoomToButton = self.widget.findChild(QToolButton, "mDeleteFeatureButton") + self.assertTrue(self.zoomToButton) + self.assertTrue(not self.zoomToButton.isEnabled()) + + selectionMgr = self.widget.featureSelectionManager() + self.assertTrue(selectionMgr) + + self.vl_books.select(fbook.id()) + self.assertEqual([fbook.id()], selectionMgr.selectedFeatureIds()) + self.assertTrue(self.zoomToButton.isEnabled()) + + selectionMgr.deselect([fbook.id()]) + self.assertEqual([], selectionMgr.selectedFeatureIds()) + self.assertTrue(not self.zoomToButton.isEnabled()) + + self.vl_books.select([1, fbook.id()]) + self.assertEqual([fbook.id()], selectionMgr.selectedFeatureIds()) + self.assertTrue(self.zoomToButton.isEnabled()) + def startTransaction(self): """ Start a new transaction and set all layers into transaction mode.