diff --git a/images/images.qrc b/images/images.qrc
index 1a82ba76185..0231feb7df6 100644
--- a/images/images.qrc
+++ b/images/images.qrc
@@ -596,6 +596,7 @@
themes/default/mIconAms.svg
themes/default/mActionAddAmsLayer.svg
themes/default/mActionAddAfsLayer.svg
+ themes/default/mIconFormSelect.svg
qgis_tips/symbol_levels.png
diff --git a/images/themes/default/mIconFormSelect.svg b/images/themes/default/mIconFormSelect.svg
new file mode 100644
index 00000000000..228fa9bf293
--- /dev/null
+++ b/images/themes/default/mIconFormSelect.svg
@@ -0,0 +1,148 @@
+
+
+
+
diff --git a/python/gui/qgsattributeform.sip b/python/gui/qgsattributeform.sip
index 61272409678..5259941b8ef 100644
--- a/python/gui/qgsattributeform.sip
+++ b/python/gui/qgsattributeform.sip
@@ -125,6 +125,13 @@ class QgsAttributeForm : QWidget
*/
void setMultiEditFeatureIds( const QgsFeatureIds& fids );
+ /** Sets the message bar to display feedback from the form in. This is used in the search/filter
+ * mode to display the count of selected features.
+ * @param messageBar target message bar
+ * @note added in QGIS 2.16
+ */
+ void setMessageBar( QgsMessageBar* messageBar );
+
signals:
/**
* Notifies about changes of attributes
@@ -161,6 +168,11 @@ class QgsAttributeForm : QWidget
*/
void modeChanged( QgsAttributeForm::Mode mode );
+ /** Emitted when the user selects the close option from the form's button bar.
+ * @note added in QGIS 2.16
+ */
+ void closed();
+
public slots:
/**
* Call this to change the content of a given attribute. Will update the editor(s) related to this field.
diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index 6e68b411e04..60ad8dd2193 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -113,6 +113,7 @@ SET(QGIS_APP_SRCS
qgsrasterlayerproperties.cpp
qgsrelationmanagerdialog.cpp
qgsrelationadddlg.cpp
+ qgsselectbyformdialog.cpp
qgsstatisticalsummarydockwidget.cpp
qgstextannotationdialog.cpp
qgssnappingdialog.cpp
@@ -287,6 +288,7 @@ SET (QGIS_APP_MOC_HDRS
qgsrasterlayerproperties.h
qgsrelationmanagerdialog.h
qgsrelationadddlg.h
+ qgsselectbyformdialog.h
qgssnappingdialog.h
qgssponsors.h
qgsstatisticalsummarydockwidget.h
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp
index 62c3af2ddea..f546d8ba5f9 100644
--- a/src/app/qgisapp.cpp
+++ b/src/app/qgisapp.cpp
@@ -210,6 +210,7 @@
#include "qgsrectangle.h"
#include "qgsscalevisibilitydialog.h"
#include "qgsgroupwmsdatadialog.h"
+#include "qgsselectbyformdialog.h"
#include "qgsshortcutsmanager.h"
#include "qgssinglebandgrayrenderer.h"
#include "qgssnappingdialog.h"
@@ -1514,6 +1515,7 @@ void QgisApp::createActions()
connect( mActionSelectAll, SIGNAL( triggered() ), this, SLOT( selectAll() ) );
connect( mActionInvertSelection, SIGNAL( triggered() ), this, SLOT( invertSelection() ) );
connect( mActionSelectByExpression, SIGNAL( triggered() ), this, SLOT( selectByExpression() ) );
+ connect( mActionSelectByForm, SIGNAL( triggered() ), this, SLOT( selectByForm() ) );
connect( mActionIdentify, SIGNAL( triggered() ), this, SLOT( identify() ) );
connect( mActionFeatureAction, SIGNAL( triggered() ), this, SLOT( doFeatureAction() ) );
connect( mActionMeasure, SIGNAL( triggered() ), this, SLOT( measure() ) );
@@ -1988,7 +1990,7 @@ void QgisApp::createToolBars()
QToolButton *bt = new QToolButton( mAttributesToolBar );
bt->setPopupMode( QToolButton::MenuButtonPopup );
QList selectActions;
- selectActions << mActionSelectByExpression << mActionSelectAll
+ selectActions << mActionSelectByExpression << mActionSelectByForm << mActionSelectAll
<< mActionInvertSelection;
bt->addActions( selectActions );
bt->setDefaultAction( mActionSelectByExpression );
@@ -2550,6 +2552,7 @@ void QgisApp::setTheme( const QString& theThemeName )
mActionSelectAll->setIcon( QgsApplication::getThemeIcon( "/mActionSelectAll.svg" ) );
mActionInvertSelection->setIcon( QgsApplication::getThemeIcon( "/mActionInvertSelection.svg" ) );
mActionSelectByExpression->setIcon( QgsApplication::getThemeIcon( "/mIconExpressionSelect.svg" ) );
+ mActionSelectByForm->setIcon( QgsApplication::getThemeIcon( "/mIconFormSelect.svg" ) );
mActionOpenTable->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.svg" ) );
mActionOpenFieldCalc->setIcon( QgsApplication::getThemeIcon( "/mActionCalculateField.png" ) );
mActionMeasure->setIcon( QgsApplication::getThemeIcon( "/mActionMeasure.png" ) );
@@ -7211,6 +7214,34 @@ void QgisApp::selectByExpression()
dlg->show();
}
+void QgisApp::selectByForm()
+{
+ QgsVectorLayer *vlayer = qobject_cast( mMapCanvas->currentLayer() );
+ if ( !vlayer )
+ {
+ messageBar()->pushMessage(
+ tr( "No active vector layer" ),
+ tr( "To select features, choose a vector layer in the legend" ),
+ QgsMessageBar::INFO,
+ messageTimeout() );
+ return;
+ }
+ QgsDistanceArea myDa;
+
+ myDa.setSourceCrs( vlayer->crs().srsid() );
+ myDa.setEllipsoidalMode( mMapCanvas->mapSettings().hasCrsTransformEnabled() );
+ myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
+
+ QgsAttributeEditorContext context;
+ context.setDistanceArea( myDa );
+ context.setVectorLayerTools( mVectorLayerTools );
+
+ QgsSelectByFormDialog* dlg = new QgsSelectByFormDialog( vlayer, context, this );
+ dlg->setMessageBar( messageBar() );
+ dlg->setAttribute( Qt::WA_DeleteOnClose );
+ dlg->show();
+}
+
void QgisApp::addRing()
{
mMapCanvas->setMapTool( mMapTools.mAddRing );
@@ -10315,6 +10346,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionSelectRadius->setEnabled( false );
mActionIdentify->setEnabled( QSettings().value( "/Map/identifyMode", 0 ).toInt() != 0 );
mActionSelectByExpression->setEnabled( false );
+ mActionSelectByForm->setEnabled( false );
mActionLabeling->setEnabled( false );
mActionOpenTable->setEnabled( false );
mActionSelectAll->setEnabled( false );
@@ -10419,6 +10451,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionSelectRadius->setEnabled( true );
mActionIdentify->setEnabled( true );
mActionSelectByExpression->setEnabled( true );
+ mActionSelectByForm->setEnabled( true );
mActionOpenTable->setEnabled( true );
mActionSelectAll->setEnabled( true );
mActionInvertSelection->setEnabled( true );
@@ -10606,6 +10639,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionSelectAll->setEnabled( false );
mActionInvertSelection->setEnabled( false );
mActionSelectByExpression->setEnabled( false );
+ mActionSelectByForm->setEnabled( false );
mActionOpenFieldCalc->setEnabled( false );
mActionToggleEditing->setEnabled( false );
mActionToggleEditing->setChecked( false );
diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h
index 171214d34d1..5c65e7c463b 100644
--- a/src/app/qgisapp.h
+++ b/src/app/qgisapp.h
@@ -1089,6 +1089,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! select features by expression
void selectByExpression();
+ //! select features by form
+ void selectByForm();
+
//! refresh map canvas
void refreshMapCanvas();
diff --git a/src/app/qgsselectbyformdialog.cpp b/src/app/qgsselectbyformdialog.cpp
new file mode 100644
index 00000000000..2f43b840c95
--- /dev/null
+++ b/src/app/qgsselectbyformdialog.cpp
@@ -0,0 +1,54 @@
+/***************************************************************************
+ qgsselectbyformdialog.cpp
+ ------------------------
+ Date : June 2016
+ Copyright : (C) 2016 nyall Dawson
+ Email : nyall dot dawson at gmail dot com
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsselectbyformdialog.h"
+#include "qgsattributeform.h"
+#include
+#include
+
+QgsSelectByFormDialog::QgsSelectByFormDialog( QgsVectorLayer* layer, const QgsAttributeEditorContext& context, QWidget* parent, Qt::WindowFlags fl )
+ : QDialog( parent, fl )
+{
+ QgsAttributeEditorContext dlgContext = context;
+ dlgContext.setFormMode( QgsAttributeEditorContext::StandaloneDialog );
+
+ mForm = new QgsAttributeForm( layer, QgsFeature(), dlgContext, this );
+ mForm->setMode( QgsAttributeForm::SearchMode );
+
+ QVBoxLayout* vLayout = new QVBoxLayout();
+ vLayout->setMargin( 0 );
+ vLayout->setContentsMargins( 0, 0, 0, 0 );
+ setLayout( vLayout );
+
+ vLayout->addWidget( mForm );
+
+ connect( mForm, SIGNAL( closed() ), this, SLOT( close() ) );
+
+ QSettings settings;
+ restoreGeometry( settings.value( "/Windows/SelectByForm/geometry" ).toByteArray() );
+
+ setWindowTitle( tr( "Select matching features" ) );
+}
+
+QgsSelectByFormDialog::~QgsSelectByFormDialog()
+{
+ QSettings settings;
+ settings.setValue( "/Windows/SelectByForm/geometry", saveGeometry() );
+}
+
+void QgsSelectByFormDialog::setMessageBar( QgsMessageBar* messageBar )
+{
+ mForm->setMessageBar( messageBar );
+}
diff --git a/src/app/qgsselectbyformdialog.h b/src/app/qgsselectbyformdialog.h
new file mode 100644
index 00000000000..787af3a25eb
--- /dev/null
+++ b/src/app/qgsselectbyformdialog.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ qgsselectbyformdialog.h
+ ----------------------
+ Date : June 2016
+ Copyright : (C) 2016 nyall Dawson
+ Email : nyall dot dawson at gmail dot com
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSSELECTBYFORMDIALOG_H
+#define QGSSELECTBYFORMDIALOG_H
+
+#include
+#include "qgsattributeeditorcontext.h"
+
+class QgsAttributeForm;
+class QgsMessageBar;
+class QgsVectorLayer;
+
+/** \ingroup app
+ * \class QgsSelectByFormDialog
+ * A dialog for selecting features from a layer, using a form based off the layer's editor widgets.
+ * @note introduced in QGIS 2.16
+ */
+
+class APP_EXPORT QgsSelectByFormDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+
+ /** Constructor for QgsSelectByFormDialog
+ * @param layer vector layer to select from
+ * @param context editor context
+ * @param parent parent widget
+ * @param fl window flags
+ */
+ QgsSelectByFormDialog( QgsVectorLayer* layer,
+ const QgsAttributeEditorContext& context = QgsAttributeEditorContext(),
+ QWidget* parent = nullptr, Qt::WindowFlags fl = nullptr );
+
+ ~QgsSelectByFormDialog();
+
+ /** Sets the message bar to display feedback from the form in. This is used in the search/filter
+ * mode to display the count of selected features.
+ * @param messageBar target message bar
+ * @note added in QGIS 2.16
+ */
+ void setMessageBar( QgsMessageBar* messageBar );
+
+ private:
+
+ QgsAttributeForm* mForm;
+
+};
+
+
+#endif // QGSSELECTBYFORMDIALOG_H
diff --git a/src/gui/qgsattributeform.cpp b/src/gui/qgsattributeform.cpp
index e739386146f..a806484b901 100644
--- a/src/gui/qgsattributeform.cpp
+++ b/src/gui/qgsattributeform.cpp
@@ -51,6 +51,7 @@ QgsAttributeForm::QgsAttributeForm( QgsVectorLayer* vl, const QgsFeature &featur
: QWidget( parent )
, mLayer( vl )
, mMessageBar( nullptr )
+ , mOwnsMessageBar( true )
, mMultiEditUnsavedMessageBarItem( nullptr )
, mMultiEditMessageBarItem( nullptr )
, mInvalidConstraintMessage( nullptr )
@@ -1296,7 +1297,7 @@ void QgsAttributeForm::init()
else
{
QPushButton* closeButton = new QPushButton( tr( "Close" ), mSearchButtonBox );
- connect( closeButton, SIGNAL( clicked( bool ) ), this, SLOT( close() ) );
+ connect( closeButton, SIGNAL( clicked( bool ) ), this, SIGNAL( closed() ) );
closeButton->setShortcut( Qt::Key_Escape );
boxLayout->addWidget( closeButton );
}
@@ -1804,6 +1805,14 @@ void QgsAttributeForm::setMultiEditFeatureIds( const QgsFeatureIds& fids )
mIsSettingMultiEditFeatures = false;
}
+void QgsAttributeForm::setMessageBar( QgsMessageBar* messageBar )
+{
+ if ( mOwnsMessageBar )
+ delete mMessageBar;
+ mOwnsMessageBar = false;
+ mMessageBar = messageBar;
+}
+
int QgsAttributeForm::messageTimeout()
{
QSettings settings;
diff --git a/src/gui/qgsattributeform.h b/src/gui/qgsattributeform.h
index f9a94577a2c..ed3013b03b7 100644
--- a/src/gui/qgsattributeform.h
+++ b/src/gui/qgsattributeform.h
@@ -147,6 +147,13 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
*/
void setMultiEditFeatureIds( const QgsFeatureIds& fids );
+ /** Sets the message bar to display feedback from the form in. This is used in the search/filter
+ * mode to display the count of selected features.
+ * @param messageBar target message bar
+ * @note added in QGIS 2.16
+ */
+ void setMessageBar( QgsMessageBar* messageBar );
+
signals:
/**
* Notifies about changes of attributes
@@ -183,6 +190,11 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
*/
void modeChanged( QgsAttributeForm::Mode mode );
+ /** Emitted when the user selects the close option from the form's button bar.
+ * @note added in QGIS 2.16
+ */
+ void closed();
+
public slots:
/**
* Call this to change the content of a given attribute. Will update the editor(s) related to this field.
@@ -317,6 +329,7 @@ class GUI_EXPORT QgsAttributeForm : public QWidget
QgsVectorLayer* mLayer;
QgsFeature mFeature;
QgsMessageBar* mMessageBar;
+ bool mOwnsMessageBar;
QgsMessageBarItem* mMultiEditUnsavedMessageBarItem;
QgsMessageBarItem* mMultiEditMessageBarItem;
QLabel* mInvalidConstraintMessage;
diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui
index 43cb0032d8e..e863d598373 100644
--- a/src/ui/qgisapp.ui
+++ b/src/ui/qgisapp.ui
@@ -71,6 +71,7 @@
+
@@ -2502,7 +2503,7 @@ Acts on currently active editable layer
Modify the Attributes of all Selected Features Simultaneously
-
+
:/images/themes/default/mActionAddAmsLayer.svg:/images/themes/default/mActionAddAmsLayer.svg
@@ -2526,6 +2527,21 @@ Acts on currently active editable layer
Add ArcGIS FeatureServer Layer
+
+
+
+ :/images/themes/default/mIconFormSelect.svg:/images/themes/default/mIconFormSelect.svg
+
+
+ Select Features by Form...
+
+
+ Select Features By Form
+
+
+ F3
+
+