QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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"
26 
27 
28 QgsExpressionSelectionDialog::QgsExpressionSelectionDialog( QgsVectorLayer *layer, const QString &startText, QWidget *parent )
29  : QDialog( parent )
30  , mLayer( layer )
31 
32 {
33  setupUi( this );
34 
36 
37  connect( mActionSelect, &QAction::triggered, this, &QgsExpressionSelectionDialog::mActionSelect_triggered );
38  connect( mActionAddToSelection, &QAction::triggered, this, &QgsExpressionSelectionDialog::mActionAddToSelection_triggered );
39  connect( mActionRemoveFromSelection, &QAction::triggered, this, &QgsExpressionSelectionDialog::mActionRemoveFromSelection_triggered );
40  connect( mActionSelectIntersect, &QAction::triggered, this, &QgsExpressionSelectionDialog::mActionSelectIntersect_triggered );
41  connect( mButtonZoomToFeatures, &QToolButton::clicked, this, &QgsExpressionSelectionDialog::mButtonZoomToFeatures_clicked );
42  connect( mPbnClose, &QPushButton::clicked, this, &QgsExpressionSelectionDialog::mPbnClose_clicked );
43 
44  setWindowTitle( QStringLiteral( "Select by Expression - %1" ).arg( layer->name() ) );
45 
46  mActionSelect->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconExpressionSelect.svg" ) ) );
47  mActionAddToSelection->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelectAdd.svg" ) ) );
48  mActionRemoveFromSelection->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelectRemove.svg" ) ) );
49  mActionSelectIntersect->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelectIntersect.svg" ) ) );
50 
51  mButtonSelect->addAction( mActionSelect );
52  mButtonSelect->addAction( mActionAddToSelection );
53  mButtonSelect->addAction( mActionRemoveFromSelection );
54  mButtonSelect->addAction( mActionSelectIntersect );
55  mButtonSelect->setDefaultAction( mActionSelect );
56 
57  mExpressionBuilder->setLayer( layer );
58  mExpressionBuilder->setExpressionText( startText );
59  mExpressionBuilder->loadFieldNames();
60  mExpressionBuilder->loadRecent( QStringLiteral( "Selection" ) );
61 
63  mExpressionBuilder->setExpressionContext( context );
64 
65  // by default, zoom to features is hidden, shown only if canvas is set
66  mButtonZoomToFeatures->setVisible( false );
67 
68  connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsExpressionSelectionDialog::showHelp );
69 }
70 
72 {
73  return mExpressionBuilder;
74 }
75 
77 {
78  mExpressionBuilder->setExpressionText( text );
79 }
80 
82 {
83  return mExpressionBuilder->expressionText();
84 }
85 
87 {
88  // Store in child widget only.
89  mExpressionBuilder->setGeomCalculator( da );
90 }
91 
93 {
94  mMessageBar = messageBar;
95 }
96 
98 {
99  mMapCanvas = canvas;
100  mButtonZoomToFeatures->setVisible( true );
101 }
102 
103 void QgsExpressionSelectionDialog::mActionSelect_triggered()
104 {
105  mLayer->selectByExpression( mExpressionBuilder->expressionText(),
107  pushSelectedFeaturesMessage();
108  saveRecent();
109 }
110 
111 void QgsExpressionSelectionDialog::mActionAddToSelection_triggered()
112 {
113  mLayer->selectByExpression( mExpressionBuilder->expressionText(),
115  pushSelectedFeaturesMessage();
116  saveRecent();
117 }
118 
119 void QgsExpressionSelectionDialog::mActionSelectIntersect_triggered()
120 {
121  mLayer->selectByExpression( mExpressionBuilder->expressionText(),
123  pushSelectedFeaturesMessage();
124  saveRecent();
125 }
126 
127 void QgsExpressionSelectionDialog::mActionRemoveFromSelection_triggered()
128 {
129  mLayer->selectByExpression( mExpressionBuilder->expressionText(),
131  pushSelectedFeaturesMessage();
132  saveRecent();
133 }
134 
135 void QgsExpressionSelectionDialog::pushSelectedFeaturesMessage()
136 {
137  if ( !mMessageBar )
138  return;
139 
140  const int timeout = QgsSettings().value( QStringLiteral( "qgis/messageTimeout" ), 5 ).toInt();
141  const int count = mLayer->selectedFeatureCount();
142  if ( count > 0 )
143  {
144  mMessageBar->pushMessage( QString(),
145  tr( "%1 matching %2 selected" ).arg( count )
146  .arg( count == 1 ? tr( "feature" ) : tr( "features" ) ),
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.
virtual bool isEmpty() const
Returns true if the geometry is empty.
A rectangle specified with double values.
Definition: qgsrectangle.h:40
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:150
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
QString expressionText()
Returns the current expression text.
void zoomToFeatureExtent(QgsRectangle &rect)
Zooms to feature extent.
Remove from current selection.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:45
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:106
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:74
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
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)...
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.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle...
Definition: qgsrectangle.h:358
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)
Select matching features using an expression.
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer&#39;s CRS to output CRS
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:98
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:35
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request.
QString name
Definition: qgsmaplayer.h:67
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.