mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[ui] select by form/expression harmonization and feature parity (#3912)
This commit is contained in:
parent
95ff9a1c4c
commit
efaf5ea926
@ -35,12 +35,18 @@ class QgsExpressionSelectionDialog : QDialog
|
||||
*/
|
||||
void setGeomCalculator( const QgsDistanceArea & da );
|
||||
|
||||
public slots:
|
||||
void on_mActionSelect_triggered();
|
||||
void on_mActionAddToSelection_triggered();
|
||||
void on_mActionRemoveFromSelection_triggered();
|
||||
void on_mActionSelectIntersect_triggered();
|
||||
void on_mPbnClose_clicked();
|
||||
/** Sets the message bar to display feedback from the dialog. This is used when zooming to
|
||||
* features to display the count of selected features.
|
||||
* @param messageBar target message bar
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
void setMessageBar( QgsMessageBar* messageBar );
|
||||
|
||||
/**
|
||||
* Sets a map canvas associated with the dialog.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
void setMapCanvas( QgsMapCanvas* canvas );
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -7496,6 +7496,8 @@ void QgisApp::selectByExpression()
|
||||
}
|
||||
|
||||
QgsExpressionSelectionDialog* dlg = new QgsExpressionSelectionDialog( vlayer, QString(), this );
|
||||
dlg->setMessageBar( messageBar() );
|
||||
dlg->setMapCanvas( mapCanvas() );
|
||||
dlg->setAttribute( Qt::WA_DeleteOnClose );
|
||||
dlg->show();
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ QString QgsSearchWidgetWrapper::toString( QgsSearchWidgetWrapper::FilterFlag fla
|
||||
case EqualTo:
|
||||
return QObject::tr( "Equal to (=)" );
|
||||
case NotEqualTo:
|
||||
return QObject::tr( "Not equal to" );
|
||||
return QObject::tr( "Not equal to (!=)" );
|
||||
case GreaterThan:
|
||||
return QObject::tr( "Greater than (>)" );
|
||||
case LessThan:
|
||||
|
@ -1328,21 +1328,27 @@ void QgsAttributeForm::init()
|
||||
QToolButton* selectButton = new QToolButton();
|
||||
selectButton->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
|
||||
selectButton->setText( tr( "&Select features" ) );
|
||||
selectButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFormSelect.svg" ) ) );
|
||||
selectButton->setPopupMode( QToolButton::MenuButtonPopup );
|
||||
selectButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
|
||||
connect( selectButton, &QToolButton::clicked, this, &QgsAttributeForm::searchSetSelection );
|
||||
QMenu* selectMenu = new QMenu( selectButton );
|
||||
QAction* selectAction = new QAction( tr( "Select features" ), selectMenu );
|
||||
selectAction->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFormSelect.svg" ) ) );
|
||||
connect( selectAction, &QAction::triggered, this, &QgsAttributeForm::searchSetSelection );
|
||||
selectMenu->addAction( selectAction );
|
||||
QAction* addSelectAction = new QAction( tr( "Add to current selection" ), selectMenu );
|
||||
addSelectAction->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelectAdd.svg" ) ) );
|
||||
connect( addSelectAction, &QAction::triggered, this, &QgsAttributeForm::searchAddToSelection );
|
||||
selectMenu->addAction( addSelectAction );
|
||||
QAction* filterSelectAction = new QAction( tr( "Filter current selection" ), selectMenu );
|
||||
connect( filterSelectAction, &QAction::triggered, this, &QgsAttributeForm::searchIntersectSelection );
|
||||
selectMenu->addAction( filterSelectAction );
|
||||
QAction* deselectAction = new QAction( tr( "Remove from current selection" ), selectMenu );
|
||||
deselectAction->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelectRemove.svg" ) ) );
|
||||
connect( deselectAction, &QAction::triggered, this, &QgsAttributeForm::searchRemoveFromSelection );
|
||||
selectMenu->addAction( deselectAction );
|
||||
QAction* filterSelectAction = new QAction( tr( "Filter current selection" ), selectMenu );
|
||||
filterSelectAction->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mIconSelectIntersect.svg" ) ) );
|
||||
connect( filterSelectAction, &QAction::triggered, this, &QgsAttributeForm::searchIntersectSelection );
|
||||
selectMenu->addAction( filterSelectAction );
|
||||
selectButton->setMenu( selectMenu );
|
||||
boxLayout->addWidget( selectButton );
|
||||
|
||||
|
@ -14,8 +14,11 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsexpressionselectiondialog.h"
|
||||
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsmessagebar.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include <QSettings>
|
||||
@ -23,6 +26,8 @@
|
||||
QgsExpressionSelectionDialog::QgsExpressionSelectionDialog( QgsVectorLayer* layer, const QString& startText, QWidget* parent )
|
||||
: QDialog( parent )
|
||||
, mLayer( layer )
|
||||
, mMessageBar( nullptr )
|
||||
, mMapCanvas( nullptr )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
@ -50,6 +55,9 @@ QgsExpressionSelectionDialog::QgsExpressionSelectionDialog( QgsVectorLayer* laye
|
||||
<< QgsExpressionContextUtils::layerScope( mLayer );
|
||||
mExpressionBuilder->setExpressionContext( context );
|
||||
|
||||
// by default, zoom to features is hidden, shown only if canvas is set
|
||||
mButtonZoomToFeatures->setVisible( false );
|
||||
|
||||
QSettings settings;
|
||||
restoreGeometry( settings.value( QStringLiteral( "/Windows/ExpressionSelectionDialog/geometry" ) ).toByteArray() );
|
||||
}
|
||||
@ -75,6 +83,17 @@ void QgsExpressionSelectionDialog::setGeomCalculator( const QgsDistanceArea & da
|
||||
mExpressionBuilder->setGeomCalculator( da );
|
||||
}
|
||||
|
||||
void QgsExpressionSelectionDialog::setMessageBar( QgsMessageBar* messageBar )
|
||||
{
|
||||
mMessageBar = messageBar;
|
||||
}
|
||||
|
||||
void QgsExpressionSelectionDialog::setMapCanvas( QgsMapCanvas* canvas )
|
||||
{
|
||||
mMapCanvas = canvas;
|
||||
mButtonZoomToFeatures->setVisible( true );
|
||||
}
|
||||
|
||||
void QgsExpressionSelectionDialog::on_mActionSelect_triggered()
|
||||
{
|
||||
mLayer->selectByExpression( mExpressionBuilder->expressionText(),
|
||||
@ -103,6 +122,63 @@ void QgsExpressionSelectionDialog::on_mActionRemoveFromSelection_triggered()
|
||||
saveRecent();
|
||||
}
|
||||
|
||||
void QgsExpressionSelectionDialog::on_mButtonZoomToFeatures_clicked()
|
||||
{
|
||||
if ( mExpressionBuilder->expressionText().isEmpty() || !mMapCanvas )
|
||||
return;
|
||||
|
||||
QgsFeatureIds ids;
|
||||
|
||||
QgsExpressionContext context;
|
||||
context << QgsExpressionContextUtils::globalScope()
|
||||
<< QgsExpressionContextUtils::projectScope()
|
||||
<< QgsExpressionContextUtils::layerScope( mLayer );
|
||||
|
||||
QgsFeatureRequest request = QgsFeatureRequest().setFilterExpression( mExpressionBuilder->expressionText() )
|
||||
.setExpressionContext( context )
|
||||
.setSubsetOfAttributes( QgsAttributeList() );
|
||||
|
||||
QgsFeatureIterator features = mLayer->getFeatures( request );
|
||||
|
||||
QgsRectangle bbox;
|
||||
bbox.setMinimal();
|
||||
QgsFeature feat;
|
||||
int featureCount = 0;
|
||||
while ( features.nextFeature( feat ) )
|
||||
{
|
||||
QgsGeometry geom = feat.geometry();
|
||||
if ( geom.isEmpty() || geom.geometry()->isEmpty() )
|
||||
continue;
|
||||
|
||||
QgsRectangle r = mMapCanvas->mapSettings().layerExtentToOutputExtent( mLayer, geom.boundingBox() );
|
||||
bbox.combineExtentWith( r );
|
||||
featureCount++;
|
||||
}
|
||||
features.close();
|
||||
|
||||
QSettings settings;
|
||||
int timeout = settings.value( QStringLiteral( "/qgis/messageTimeout" ), 5 ).toInt();
|
||||
if ( featureCount > 0 )
|
||||
{
|
||||
mMapCanvas->zoomToFeatureExtent( bbox );
|
||||
if ( mMessageBar )
|
||||
{
|
||||
mMessageBar->pushMessage( QString(),
|
||||
tr( "Zoomed to %n matching feature(s)", "number of matching features", featureCount ),
|
||||
QgsMessageBar::INFO,
|
||||
timeout );
|
||||
}
|
||||
}
|
||||
else if ( mMessageBar )
|
||||
{
|
||||
mMessageBar->pushMessage( QString(),
|
||||
tr( "No matching features found" ),
|
||||
QgsMessageBar::INFO,
|
||||
timeout );
|
||||
}
|
||||
saveRecent();
|
||||
}
|
||||
|
||||
void QgsExpressionSelectionDialog::closeEvent( QCloseEvent *closeEvent )
|
||||
{
|
||||
QDialog::closeEvent( closeEvent );
|
||||
|
@ -16,9 +16,13 @@
|
||||
#ifndef QGSEXPRESSIONSELECTIONDIALOG_H
|
||||
#define QGSEXPRESSIONSELECTIONDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_qgsexpressionselectiondialogbase.h"
|
||||
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsmessagebar.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
/** \ingroup gui
|
||||
* This class offers a dialog to change feature selections.
|
||||
* To do so, a QgsExpressionBuilderWidget is shown in a dialog.
|
||||
@ -62,11 +66,25 @@ class GUI_EXPORT QgsExpressionSelectionDialog : public QDialog, private Ui::QgsE
|
||||
*/
|
||||
void setGeomCalculator( const QgsDistanceArea & da );
|
||||
|
||||
public slots:
|
||||
/** Sets the message bar to display feedback from the dialog. This is used when zooming to
|
||||
* features to display the count of selected features.
|
||||
* @param messageBar target message bar
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
void setMessageBar( QgsMessageBar* messageBar );
|
||||
|
||||
/**
|
||||
* Sets a map canvas associated with the dialog.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
void setMapCanvas( QgsMapCanvas* canvas );
|
||||
|
||||
private slots:
|
||||
void on_mActionSelect_triggered();
|
||||
void on_mActionAddToSelection_triggered();
|
||||
void on_mActionRemoveFromSelection_triggered();
|
||||
void on_mActionSelectIntersect_triggered();
|
||||
void on_mButtonZoomToFeatures_clicked();
|
||||
void on_mPbnClose_clicked();
|
||||
|
||||
protected:
|
||||
@ -88,6 +106,8 @@ class GUI_EXPORT QgsExpressionSelectionDialog : public QDialog, private Ui::QgsE
|
||||
private:
|
||||
void saveRecent();
|
||||
QgsVectorLayer* mLayer;
|
||||
QgsMessageBar* mMessageBar;
|
||||
QgsMapCanvas* mMapCanvas;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -30,14 +30,14 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="mPbnClose">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="1" column="2">
|
||||
<widget class="QToolButton" name="mButtonSelect">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -56,28 +56,35 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QToolButton" name="mButtonZoomToFeatures">
|
||||
<property name="text">
|
||||
<string>Zoom to features</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QgsExpressionBuilderWidget" name="mExpressionBuilder" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="mActionSelect">
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
<string>Select features</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="mActionAddToSelection">
|
||||
<property name="text">
|
||||
<string>Add to selection</string>
|
||||
<string>Add to current selection</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="mActionRemoveFromSelection">
|
||||
<property name="text">
|
||||
<string>Remove from selection</string>
|
||||
<string>Remove from current selection</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="mActionSelectIntersect">
|
||||
<property name="text">
|
||||
<string>Select within selection</string>
|
||||
<string>Filter current selection</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
|
Loading…
x
Reference in New Issue
Block a user