16#include <QDomDocument>
20#include <QInputDialog>
23#include <QStandardItem>
30#include "moc_qgssearchquerybuilder.cpp"
39 QWidget *parent, Qt::WindowFlags fl )
40 : QDialog( parent, fl )
44 connect( btnEqual, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnEqual_clicked );
45 connect( btnLessThan, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnLessThan_clicked );
46 connect( btnGreaterThan, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnGreaterThan_clicked );
47 connect( btnLike, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnLike_clicked );
48 connect( btnILike, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnILike_clicked );
49 connect( btnPct, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnPct_clicked );
50 connect( btnIn, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnIn_clicked );
51 connect( btnNotIn, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnNotIn_clicked );
52 connect( lstFields, &QListView::doubleClicked,
this, &QgsSearchQueryBuilder::lstFields_doubleClicked );
53 connect( lstValues, &QListView::doubleClicked,
this, &QgsSearchQueryBuilder::lstValues_doubleClicked );
54 connect( btnLessEqual, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnLessEqual_clicked );
55 connect( btnGreaterEqual, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnGreaterEqual_clicked );
56 connect( btnNotEqual, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnNotEqual_clicked );
57 connect( btnAnd, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnAnd_clicked );
58 connect( btnNot, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnNot_clicked );
59 connect( btnOr, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnOr_clicked );
60 connect( btnGetAllValues, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnGetAllValues_clicked );
61 connect( btnSampleValues, &QPushButton::clicked,
this, &QgsSearchQueryBuilder::btnSampleValues_clicked );
63 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsSearchQueryBuilder::showHelp );
65 setWindowTitle( tr(
"Search Query Builder" ) );
67 QPushButton *pbn =
new QPushButton( tr(
"&Test" ) );
68 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
69 connect( pbn, &QAbstractButton::clicked,
this, &QgsSearchQueryBuilder::btnTest_clicked );
71 pbn =
new QPushButton( tr(
"&Clear" ) );
72 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
73 connect( pbn, &QAbstractButton::clicked,
this, &QgsSearchQueryBuilder::btnClear_clicked );
75 pbn =
new QPushButton( tr(
"&Save…" ) );
76 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
77 pbn->setToolTip( tr(
"Save query to an xml file" ) );
80 pbn =
new QPushButton( tr(
"&Load…" ) );
81 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
82 pbn->setToolTip( tr(
"Load query from xml file" ) );
86 lblDataUri->setText( layer->
name() );
90void QgsSearchQueryBuilder::populateFields()
96 for (
int idx = 0; idx < fields.
count(); ++idx )
98 const QString fieldName = fields.
at( idx ).
name();
99 mFieldMap[fieldName] = idx;
100 QStandardItem *myItem =
new QStandardItem( fieldName );
101 myItem->setEditable(
false );
102 mModelFields->insertRow( mModelFields->rowCount(), myItem );
106void QgsSearchQueryBuilder::setupListViews()
109 mModelFields =
new QStandardItemModel();
110 mModelValues =
new QStandardItemModel();
111 lstFields->setModel( mModelFields );
112 lstValues->setModel( mModelValues );
114 lstFields->setViewMode( QListView::ListMode );
115 lstValues->setViewMode( QListView::ListMode );
116 lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
117 lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
119 lstFields->setUniformItemSizes(
true );
120 lstValues->setUniformItemSizes(
true );
123void QgsSearchQueryBuilder::getFieldValues(
int limit )
130 mModelValues->clear();
133 const QString fieldName = mModelFields->data( lstFields->currentIndex() ).toString();
134 const int fieldIndex = mFieldMap[fieldName];
136 const bool numeric = ( field.
type() == QMetaType::Type::Int || field.
type() == QMetaType::Type::Double );
142 attrs.append( fieldIndex );
146 lstValues->setCursor( Qt::WaitCursor );
148 mModelValues->blockSignals(
true );
149 lstValues->setUpdatesEnabled(
false );
152 QSet<QString> insertedValues;
155 ( limit == 0 || mModelValues->rowCount() != limit ) )
157 value = feat.
attribute( fieldIndex ).toString();
162 value =
'\'' + value.replace(
'\'', QLatin1String(
"''" ) ) +
'\'';
166 if ( !insertedValues.contains( value ) )
168 QStandardItem *myItem =
new QStandardItem( value );
169 myItem->setEditable(
false );
170 mModelValues->insertRow( mModelValues->rowCount(), myItem );
171 insertedValues.insert( value );
175 mModelValues->blockSignals(
false );
176 lstValues->setUpdatesEnabled(
true );
178 mModelValues->sort( 0 );
179 lstValues->setCursor( Qt::ArrowCursor );
182void QgsSearchQueryBuilder::btnSampleValues_clicked()
184 getFieldValues( 25 );
187void QgsSearchQueryBuilder::btnGetAllValues_clicked()
192void QgsSearchQueryBuilder::btnTest_clicked()
194 const long count = countRecords( mTxtSql->text() );
200 QMessageBox::information(
this, tr(
"Test Query" ), tr(
"Found %n matching feature(s).",
"test result", count ) );
204long QgsSearchQueryBuilder::countRecords(
const QString &searchString )
207 if ( search.hasParserError() )
209 QMessageBox::critical(
this, tr(
"Query Result" ), search.parserErrorString() );
216 const bool fetchGeom = search.needsGeometry();
223 if ( !search.prepare( &context ) )
225 QMessageBox::critical(
this, tr(
"Query Result" ), search.evalErrorString() );
229 QApplication::setOverrideCursor( Qt::WaitCursor );
235 context.setFeature( feat );
236 const QVariant value = search.evaluate( &context );
237 if ( value.toInt() != 0 )
243 if ( search.hasEvalError() )
247 QApplication::restoreOverrideCursor();
249 if ( search.hasEvalError() )
251 QMessageBox::critical(
this, tr(
"Query Result" ), search.evalErrorString() );
259void QgsSearchQueryBuilder::btnOk_clicked()
262 if ( mTxtSql->text().trimmed().length() > 0 )
269 const long numRecs = countRecords( mTxtSql->text() );
274 else if ( numRecs == 0 )
276 QMessageBox::warning(
this, tr(
"Query Result" ), tr(
"The query you specified results in zero records being returned." ) );
285void QgsSearchQueryBuilder::btnEqual_clicked()
287 mTxtSql->insertText( QStringLiteral(
" = " ) );
290void QgsSearchQueryBuilder::btnLessThan_clicked()
292 mTxtSql->insertText( QStringLiteral(
" < " ) );
295void QgsSearchQueryBuilder::btnGreaterThan_clicked()
297 mTxtSql->insertText( QStringLiteral(
" > " ) );
300void QgsSearchQueryBuilder::btnPct_clicked()
302 mTxtSql->insertText( QStringLiteral(
"%" ) );
305void QgsSearchQueryBuilder::btnIn_clicked()
307 mTxtSql->insertText( QStringLiteral(
" IN " ) );
310void QgsSearchQueryBuilder::btnNotIn_clicked()
312 mTxtSql->insertText( QStringLiteral(
" NOT IN " ) );
315void QgsSearchQueryBuilder::btnLike_clicked()
317 mTxtSql->insertText( QStringLiteral(
" LIKE " ) );
322 return mTxtSql->text();
330void QgsSearchQueryBuilder::lstFields_doubleClicked(
const QModelIndex &index )
335void QgsSearchQueryBuilder::lstValues_doubleClicked(
const QModelIndex &index )
337 mTxtSql->insertText( mModelValues->data( index ).toString() );
340void QgsSearchQueryBuilder::btnLessEqual_clicked()
342 mTxtSql->insertText( QStringLiteral(
" <= " ) );
345void QgsSearchQueryBuilder::btnGreaterEqual_clicked()
347 mTxtSql->insertText( QStringLiteral(
" >= " ) );
350void QgsSearchQueryBuilder::btnNotEqual_clicked()
352 mTxtSql->insertText( QStringLiteral(
" != " ) );
355void QgsSearchQueryBuilder::btnAnd_clicked()
357 mTxtSql->insertText( QStringLiteral(
" AND " ) );
360void QgsSearchQueryBuilder::btnNot_clicked()
362 mTxtSql->insertText( QStringLiteral(
" NOT " ) );
365void QgsSearchQueryBuilder::btnOr_clicked()
367 mTxtSql->insertText( QStringLiteral(
" OR " ) );
370void QgsSearchQueryBuilder::btnClear_clicked()
375void QgsSearchQueryBuilder::btnILike_clicked()
377 mTxtSql->insertText( QStringLiteral(
" ILIKE " ) );
391 mTxtSql->insertText( query );
395void QgsSearchQueryBuilder::showHelp()
397 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#query-builder" ) );
The Qgis class provides global constants for use throughout the application.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ NoFlags
No flags are set.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Class for parsing and evaluation of expressions (formerly called "search strings").
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
static bool loadQueryFromFile(QString &subset)
Load query from the XML file.
static bool saveQueryToFile(const QString &subset)
Save query to the XML file.
QgsSearchQueryBuilder(QgsVectorLayer *layer, QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
Constructor - takes pointer to vector layer as a parameter.
void setSearchString(const QString &searchString)
change search string shown in text field
QString searchString()
returns newly created search string
Represents a vector layer which manages a vector based data sets.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QList< int > QgsAttributeList