1414 ***************************************************************************/
1515
1616#include " qgsexpressionselectiondialog.h"
17+
1718#include " qgsapplication.h"
1819#include " qgsexpression.h"
20+ #include " qgsgeometry.h"
21+ #include " qgsmessagebar.h"
1922#include " qgsvectorlayer.h"
2023
2124#include < QSettings>
2225
2326QgsExpressionSelectionDialog::QgsExpressionSelectionDialog ( QgsVectorLayer* layer, const QString& startText, QWidget* parent )
2427 : QDialog( parent )
2528 , mLayer( layer )
29+ , mMessageBar( nullptr )
30+ , mMapCanvas( nullptr )
2631{
2732 setupUi ( this );
2833
@@ -50,6 +55,9 @@ QgsExpressionSelectionDialog::QgsExpressionSelectionDialog( QgsVectorLayer* laye
5055 << QgsExpressionContextUtils::layerScope ( mLayer );
5156 mExpressionBuilder ->setExpressionContext ( context );
5257
58+ // by default, zoom to features is hidden, shown only if canvas is set
59+ mButtonZoomToFeatures ->setVisible ( false );
60+
5361 QSettings settings;
5462 restoreGeometry ( settings.value ( QStringLiteral ( " /Windows/ExpressionSelectionDialog/geometry" ) ).toByteArray () );
5563}
@@ -75,6 +83,17 @@ void QgsExpressionSelectionDialog::setGeomCalculator( const QgsDistanceArea & da
7583 mExpressionBuilder ->setGeomCalculator ( da );
7684}
7785
86+ void QgsExpressionSelectionDialog::setMessageBar ( QgsMessageBar* messageBar )
87+ {
88+ mMessageBar = messageBar;
89+ }
90+
91+ void QgsExpressionSelectionDialog::setMapCanvas ( QgsMapCanvas* canvas )
92+ {
93+ mMapCanvas = canvas;
94+ mButtonZoomToFeatures ->setVisible ( true );
95+ }
96+
7897void QgsExpressionSelectionDialog::on_mActionSelect_triggered ()
7998{
8099 mLayer ->selectByExpression ( mExpressionBuilder ->expressionText (),
@@ -103,6 +122,63 @@ void QgsExpressionSelectionDialog::on_mActionRemoveFromSelection_triggered()
103122 saveRecent ();
104123}
105124
125+ void QgsExpressionSelectionDialog::on_mButtonZoomToFeatures_clicked ()
126+ {
127+ if ( mExpressionBuilder ->expressionText ().isEmpty () || !mMapCanvas )
128+ return ;
129+
130+ QgsFeatureIds ids;
131+
132+ QgsExpressionContext context;
133+ context << QgsExpressionContextUtils::globalScope ()
134+ << QgsExpressionContextUtils::projectScope ()
135+ << QgsExpressionContextUtils::layerScope ( mLayer );
136+
137+ QgsFeatureRequest request = QgsFeatureRequest ().setFilterExpression ( mExpressionBuilder ->expressionText () )
138+ .setExpressionContext ( context )
139+ .setSubsetOfAttributes ( QgsAttributeList () );
140+
141+ QgsFeatureIterator features = mLayer ->getFeatures ( request );
142+
143+ QgsRectangle bbox;
144+ bbox.setMinimal ();
145+ QgsFeature feat;
146+ int featureCount = 0 ;
147+ while ( features.nextFeature ( feat ) )
148+ {
149+ QgsGeometry geom = feat.geometry ();
150+ if ( geom.isEmpty () || geom.geometry ()->isEmpty () )
151+ continue ;
152+
153+ QgsRectangle r = mMapCanvas ->mapSettings ().layerExtentToOutputExtent ( mLayer , geom.boundingBox () );
154+ bbox.combineExtentWith ( r );
155+ featureCount++;
156+ }
157+ features.close ();
158+
159+ QSettings settings;
160+ int timeout = settings.value ( QStringLiteral ( " /qgis/messageTimeout" ), 5 ).toInt ();
161+ if ( featureCount > 0 )
162+ {
163+ mMapCanvas ->zoomToFeatureExtent ( bbox );
164+ if ( mMessageBar )
165+ {
166+ mMessageBar ->pushMessage ( QString (),
167+ tr ( " Zoomed to %n matching feature(s)" , " number of matching features" , featureCount ),
168+ QgsMessageBar::INFO ,
169+ timeout );
170+ }
171+ }
172+ else if ( mMessageBar )
173+ {
174+ mMessageBar ->pushMessage ( QString (),
175+ tr ( " No matching features found" ),
176+ QgsMessageBar::INFO ,
177+ timeout );
178+ }
179+ saveRecent ();
180+ }
181+
106182void QgsExpressionSelectionDialog::closeEvent ( QCloseEvent *closeEvent )
107183{
108184 QDialog::closeEvent ( closeEvent );
0 commit comments