@@ -215,19 +215,32 @@ class MatchCollectingFilter : public QgsPointLocator::MatchFilter
215
215
/* *
216
216
* Keeps the best match from a selected feature so that we can possibly use it with higher priority.
217
217
* If we do not encounter any selected feature within tolerance, we use the best match as usual.
218
+ *
219
+ * There are two kinds of "selected" features... if we have a "locked" feature in vertex tool,
220
+ * we get a non-null QgsSelectedFeature which has feature's layer and feature id. In such case we
221
+ * only allow matches from that feature. The other kind is if some features within layer are
222
+ * in the layer's list of selected features - in that case we accept any match from those features
223
+ * (but only if we do not have "locked" feature)
218
224
*/
219
225
class SelectedMatchFilter : public QgsPointLocator ::MatchFilter
220
226
{
221
227
public:
222
- explicit SelectedMatchFilter ( double tol )
223
- : mTolerance( tol ) {}
228
+ explicit SelectedMatchFilter ( double tol, QgsSelectedFeature *selectedFeature )
229
+ : mTolerance( tol )
230
+ , mSelectedFeature( selectedFeature ) {}
224
231
225
232
bool acceptMatch ( const QgsPointLocator::Match &match ) override
226
233
{
227
- if ( match.distance () <= mTolerance && match.layer () && match. layer ()-> selectedFeatureIds (). contains ( match. featureId () ) )
234
+ if ( match.distance () <= mTolerance && match.layer () )
228
235
{
229
- if ( !mBestSelectedMatch .isValid () || match.distance () < mBestSelectedMatch .distance () )
230
- mBestSelectedMatch = match;
236
+ // option 1: we have "locked" feature - we consider just a match from that feature
237
+ // option 2: we do not have "locked" feature - we consider matches from any selected feature
238
+ if ( ( mSelectedFeature && mSelectedFeature ->layer () == match.layer () && mSelectedFeature ->featureId () == match.featureId () )
239
+ || ( !mSelectedFeature && match.layer ()->selectedFeatureIds ().contains ( match.featureId () ) ) )
240
+ {
241
+ if ( !mBestSelectedMatch .isValid () || match.distance () < mBestSelectedMatch .distance () )
242
+ mBestSelectedMatch = match;
243
+ }
231
244
}
232
245
return true ;
233
246
}
@@ -237,6 +250,7 @@ class SelectedMatchFilter : public QgsPointLocator::MatchFilter
237
250
238
251
private:
239
252
double mTolerance ;
253
+ QgsSelectedFeature *mSelectedFeature ; // not null in case of selected (locked) feature
240
254
QgsPointLocator::Match mBestSelectedMatch ;
241
255
};
242
256
@@ -740,7 +754,7 @@ QgsPointLocator::Match QgsVertexTool::snapToEditableLayer( QgsMapMouseEvent *e )
740
754
}
741
755
742
756
snapUtils->setConfig ( config );
743
- SelectedMatchFilter filter ( tol );
757
+ SelectedMatchFilter filter ( tol, mSelectedFeature . get () );
744
758
m = snapUtils->snapToMap ( mapPoint, &filter );
745
759
746
760
// we give priority to snap matches that are from selected features
@@ -767,7 +781,7 @@ QgsPointLocator::Match QgsVertexTool::snapToEditableLayer( QgsMapMouseEvent *e )
767
781
}
768
782
769
783
snapUtils->setConfig ( config );
770
- SelectedMatchFilter filter ( tol );
784
+ SelectedMatchFilter filter ( tol, mSelectedFeature . get () );
771
785
m = snapUtils->snapToMap ( mapPoint, &filter );
772
786
773
787
// we give priority to snap matches that are from selected features
0 commit comments