QGIS API Documentation  3.8.0-Zanzibar (11aff65)
qgsexpressionselectiondialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgisexpressionselectiondialog.cpp
3  --------------------------------------
4  Date : 24.1.2013
5  Copyright : (C) 2013 by Matthias kuhn
6  Email : matthias at opengis dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgsapplication.h"
19 #include "qgsexpression.h"
20 #include "qgsgeometry.h"
21 #include "qgsmapcanvas.h"
22 #include "qgsmessagebar.h"
23 #include "qgsvectorlayer.h"
24 #include "qgssettings.h"
25 #include "qgsgui.h"
27 
28 
29 QgsExpressionSelectionDialog::QgsExpressionSelectionDialog( QgsVectorLayer *layer, const QString &startText, QWidget *parent )
30  : QDialog( parent )
31  , mLayer( layer )
32 
33 {
34  setupUi( this );
35 
37 
38  connect( mActionSelect, &QAction::triggered, this, &QgsExpressionSelectionDialog::mActionSelect_triggered );
39  connect( mActionAddToSelection, &QAction::triggered, this, &QgsExpressionSelectionDialog::mActionAddToSelection_triggered );
40  connect( mActionRemoveFromSelection, &QAction::triggered, this, &QgsExpressionSelectionDialog::mActionRemoveFromSelection_triggered );
41  connect( mActionSelectIntersect, &QAction::triggered, this, &QgsExpressionSelectionDialog::mActionSelectIntersect_triggered );
42  connect( mButtonZoomToFeatures, &QToolButton::clicked, this, &QgsExpressionSelectionDialog::mButtonZoomToFeatures_clicked );
43  connect( mPbnClose, &QPushButton::clicked, this, &QgsExpressionSelectionDialog::mPbnClose_clicked );
44 
45  setWindowTitle( QStringLiteral( "Select by Expression - %1" ).arg( layer->name() ) );
46 
47  mActionSelect->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconExpressionSelect.svg" ) ) );
48  mActionAddToSelection->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelectAdd.svg" ) ) );
49  mActionRemoveFromSelection->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelectRemove.svg" ) ) );
50  mActionSelectIntersect->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelectIntersect.svg" ) ) );
51 
52  mButtonSelect->addAction( mActionSelect );
53  mButtonSelect->addAction( mActionAddToSelection );
54  mButtonSelect->addAction( mActionRemoveFromSelection );
55  mButtonSelect->addAction( mActionSelectIntersect );
56  mButtonSelect->setDefaultAction( mActionSelect );
57 
58  mExpressionBuilder->setLayer( layer );
59  mExpressionBuilder->setExpressionText( startText );
60  mExpressionBuilder->loadFieldNames();
61  mExpressionBuilder->loadRecent( QStringLiteral( "Selection" ) );
62 
64  mExpressionBuilder->setExpressionContext( context );
65 
66  // by default, zoom to features is hidden, shown only if canvas is set
67  mButtonZoomToFeatures->setVisible( false );
68 
69  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsExpressionSelectionDialog::showHelp );
70 }
71 
73 {
74  return mExpressionBuilder;
75 }
76 
78 {
79  mExpressionBuilder->setExpressionText( text );
80 }
81 
83 {
84  return mExpressionBuilder->expressionText();
85 }
86 
88 {
89  // Store in child widget only.
90  mExpressionBuilder->setGeomCalculator( da );
91 }
92 
94 {
95  mMessageBar = messageBar;
96 }
97 
99 {
100  mMapCanvas = canvas;
101  mButtonZoomToFeatures->setVisible( true );
102 }
103 
104 void QgsExpressionSelectionDialog::mActionSelect_triggered()
105 {
106  mLayer->selectByExpression( mExpressionBuilder->expressionText(),
108  pushSelectedFeaturesMessage();
109  saveRecent();
110 }
111 
112 void QgsExpressionSelectionDialog::mActionAddToSelection_triggered()
113 {
114  mLayer->selectByExpression( mExpressionBuilder->expressionText(),
116  pushSelectedFeaturesMessage();
117  saveRecent();
118 }
119 
120 void QgsExpressionSelectionDialog::mActionSelectIntersect_triggered()
121 {
122  mLayer->selectByExpression( mExpressionBuilder->expressionText(),
124  pushSelectedFeaturesMessage();
125  saveRecent();
126 }
127 
128 void QgsExpressionSelectionDialog::mActionRemoveFromSelection_triggered()
129 {
130  mLayer->selectByExpression( mExpressionBuilder->expressionText(),
132  pushSelectedFeaturesMessage();
133  saveRecent();
134 }
135 
136 void QgsExpressionSelectionDialog::pushSelectedFeaturesMessage()
137 {
138  if ( !mMessageBar )
139  return;
140 
141  const int timeout = QgsSettings().value( QStringLiteral( "qgis/messageTimeout" ), 5 ).toInt();
142  const int count = mLayer->selectedFeatureCount();
143  if ( count > 0 )
144  {
145  mMessageBar->pushMessage( QString(),
146  tr( "%n matching feature(s) selected", "matching features", count ),
147  Qgis::Info, timeout );
148  }
149  else
150  {
151  mMessageBar->pushMessage( QString(),
152  tr( "No matching features found" ),
153  Qgis::Warning, timeout );
154  }
155 }
156 
157 void QgsExpressionSelectionDialog::mButtonZoomToFeatures_clicked()
158 {
159  if ( mExpressionBuilder->expressionText().isEmpty() || !mMapCanvas )
160  return;
161 
163 
164  QgsFeatureRequest request = QgsFeatureRequest().setFilterExpression( mExpressionBuilder->expressionText() )
165  .setExpressionContext( context )
166  .setNoAttributes();
167 
168  QgsFeatureIterator features = mLayer->getFeatures( request );
169 
170  QgsRectangle bbox;
171  bbox.setMinimal();
172  QgsFeature feat;
173  int featureCount = 0;
174  while ( features.nextFeature( feat ) )
175  {
176  QgsGeometry geom = feat.geometry();
177  if ( geom.isNull() || geom.constGet()->isEmpty() )
178  continue;
179 
180  QgsRectangle r = mMapCanvas->mapSettings().layerExtentToOutputExtent( mLayer, geom.boundingBox() );
181  bbox.combineExtentWith( r );
182  featureCount++;
183  }
184  features.close();
185 
186  QgsSettings settings;
187  int timeout = settings.value( QStringLiteral( "qgis/messageTimeout" ), 5 ).toInt();
188  if ( featureCount > 0 )
189  {
190  mMapCanvas->zoomToFeatureExtent( bbox );
191  if ( mMessageBar )
192  {
193  mMessageBar->pushMessage( QString(),
194  tr( "Zoomed to %n matching feature(s)", "number of matching features", featureCount ),
195  Qgis::Info,
196  timeout );
197  }
198  }
199  else if ( mMessageBar )
200  {
201  mMessageBar->pushMessage( QString(),
202  tr( "No matching features found" ),
203  Qgis::Info,
204  timeout );
205  }
206  saveRecent();
207 }
208 
210 {
211  QDialog::closeEvent( closeEvent );
212 }
213 
214 void QgsExpressionSelectionDialog::mPbnClose_clicked()
215 {
216  close();
217 }
218 
220 {
221  QDialog::done( r );
222  close();
223 }
224 
225 void QgsExpressionSelectionDialog::saveRecent()
226 {
227  mExpressionBuilder->saveToRecent( QStringLiteral( "Selection" ) );
228 }
229 
230 void QgsExpressionSelectionDialog::showHelp()
231 {
232  QgsHelp::openHelp( QStringLiteral( "introduction/general_tools.html#automatic-selection" ) );
233 }
Wrapper for iterator of features from vector data provider or vector layer.
A rectangle specified with double values.
Definition: qgsrectangle.h:41
virtual bool isEmpty() const
Returns true if the geometry is empty.
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:151
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
QString expressionText()
Returns the current expression text.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
void zoomToFeatureExtent(QgsRectangle &rect)
Zooms to feature extent.
Remove from current selection.
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:45
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:111
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
QgsExpressionSelectionDialog(QgsVectorLayer *layer, const QString &startText=QString(), QWidget *parent=nullptr)
Creates a new selection dialog.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:73
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
void setGeomCalculator(const QgsDistanceArea &da)
Sets geometry calculator used in distance/area calculations.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void closeEvent(QCloseEvent *closeEvent) override
Implementation for closeEvent Saves the window geometry.
void done(int r) override
Implementation for done (default behavior when pressing esc) Calls close, so the window geometry gets...
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
void setMessageBar(QgsMessageBar *messageBar)
Sets the message bar to display feedback from the dialog.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::Info, int duration=5)
convenience method for pushing a message to the bar
Definition: qgsmessagebar.h:88
Add selection to current selection.
QgsExpressionBuilderWidget * expressionBuilder()
The builder widget that is used by the dialog.
void setExpressionText(const QString &text)
Sets the current expression text.
Set selection, removing any existing selection.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle...
Definition: qgsrectangle.h:359
A general purpose distance and area calculator, capable of performing ellipsoid based calculations...
Modify current selection to include only select features which match.
A reusable widget that can be used to build a expression string.
void selectByExpression(const QString &expression, SelectBehavior behavior=SetSelection)
Selects matching features using an expression.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:104
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QString name
Definition: qgsmaplayer.h:82
QgsGeometry geometry
Definition: qgsfeature.h:67
bool nextFeature(QgsFeature &f)
Represents a vector layer which manages a vector based data sets.
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas associated with the dialog.