16#include <QDomDocument> 
   20#include <QInputDialog> 
   23#include <QStandardItem> 
   40    QWidget *parent, Qt::WindowFlags fl )
 
   41  : QDialog( parent, fl )
 
   45  connect( btnEqual, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnEqual_clicked );
 
   46  connect( btnLessThan, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnLessThan_clicked );
 
   47  connect( btnGreaterThan, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnGreaterThan_clicked );
 
   48  connect( btnLike, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnLike_clicked );
 
   49  connect( btnILike, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnILike_clicked );
 
   50  connect( btnPct, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnPct_clicked );
 
   51  connect( btnIn, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnIn_clicked );
 
   52  connect( btnNotIn, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnNotIn_clicked );
 
   53  connect( lstFields, &QListView::doubleClicked, 
this, &QgsSearchQueryBuilder::lstFields_doubleClicked );
 
   54  connect( lstValues, &QListView::doubleClicked, 
this, &QgsSearchQueryBuilder::lstValues_doubleClicked );
 
   55  connect( btnLessEqual, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnLessEqual_clicked );
 
   56  connect( btnGreaterEqual, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnGreaterEqual_clicked );
 
   57  connect( btnNotEqual, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnNotEqual_clicked );
 
   58  connect( btnAnd, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnAnd_clicked );
 
   59  connect( btnNot, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnNot_clicked );
 
   60  connect( btnOr, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnOr_clicked );
 
   61  connect( btnGetAllValues, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnGetAllValues_clicked );
 
   62  connect( btnSampleValues, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnSampleValues_clicked );
 
   64  connect( buttonBox, &QDialogButtonBox::helpRequested, 
this, &QgsSearchQueryBuilder::showHelp );
 
   66  setWindowTitle( tr( 
"Search Query Builder" ) );
 
   68  QPushButton *pbn = 
new QPushButton( tr( 
"&Test" ) );
 
   69  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
   70  connect( pbn, &QAbstractButton::clicked, 
this, &QgsSearchQueryBuilder::btnTest_clicked );
 
   72  pbn = 
new QPushButton( tr( 
"&Clear" ) );
 
   73  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
   74  connect( pbn, &QAbstractButton::clicked, 
this, &QgsSearchQueryBuilder::btnClear_clicked );
 
   76  pbn = 
new QPushButton( tr( 
"&Save…" ) );
 
   77  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
   78  pbn->setToolTip( tr( 
"Save query to an xml file" ) );
 
   81  pbn = 
new QPushButton( tr( 
"&Load…" ) );
 
   82  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
   83  pbn->setToolTip( tr( 
"Load query from xml file" ) );
 
   87    lblDataUri->setText( layer->
name() );
 
   91void QgsSearchQueryBuilder::populateFields()
 
   97  for ( 
int idx = 0; idx < fields.
count(); ++idx )
 
   99    const QString fieldName = fields.
at( idx ).
name();
 
  100    mFieldMap[fieldName] = idx;
 
  101    QStandardItem *myItem = 
new QStandardItem( fieldName );
 
  102    myItem->setEditable( 
false );
 
  103    mModelFields->insertRow( mModelFields->rowCount(), myItem );
 
  107void QgsSearchQueryBuilder::setupListViews()
 
  110  mModelFields = 
new QStandardItemModel();
 
  111  mModelValues = 
new QStandardItemModel();
 
  112  lstFields->setModel( mModelFields );
 
  113  lstValues->setModel( mModelValues );
 
  115  lstFields->setViewMode( QListView::ListMode );
 
  116  lstValues->setViewMode( QListView::ListMode );
 
  117  lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
 
  118  lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
 
  120  lstFields->setUniformItemSizes( 
true );
 
  121  lstValues->setUniformItemSizes( 
true );
 
  124void QgsSearchQueryBuilder::getFieldValues( 
int limit )
 
  131  mModelValues->clear();
 
  134  const QString fieldName = mModelFields->data( lstFields->currentIndex() ).toString();
 
  135  const int fieldIndex = mFieldMap[fieldName];
 
  137  const bool numeric = ( 
field.
type() == QVariant::Int || 
field.
type() == QVariant::Double );
 
  143  attrs.append( fieldIndex );
 
  147  lstValues->setCursor( Qt::WaitCursor );
 
  149  mModelValues->blockSignals( 
true );
 
  150  lstValues->setUpdatesEnabled( 
false );
 
  153  QSet<QString> insertedValues;
 
  156          ( limit == 0 || mModelValues->rowCount() != limit ) )
 
  158    value = feat.
attribute( fieldIndex ).toString();
 
  163      value = 
'\'' + value.replace( 
'\'', QLatin1String( 
"''" ) ) + 
'\'';
 
  167    if ( !insertedValues.contains( value ) )
 
  169      QStandardItem *myItem = 
new QStandardItem( value );
 
  170      myItem->setEditable( 
false );
 
  171      mModelValues->insertRow( mModelValues->rowCount(), myItem );
 
  172      insertedValues.insert( value );
 
  176  mModelValues->blockSignals( 
false );
 
  177  lstValues->setUpdatesEnabled( 
true );
 
  179  mModelValues->sort( 0 );
 
  180  lstValues->setCursor( Qt::ArrowCursor );
 
  183void QgsSearchQueryBuilder::btnSampleValues_clicked()
 
  185  getFieldValues( 25 );
 
  188void QgsSearchQueryBuilder::btnGetAllValues_clicked()
 
  193void QgsSearchQueryBuilder::btnTest_clicked()
 
  195  const long count = countRecords( mTxtSql->text() );
 
  201  QMessageBox::information( 
this, tr( 
"Test Query" ), tr( 
"Found %n matching feature(s).", 
"test result", count ) );
 
  205long QgsSearchQueryBuilder::countRecords( 
const QString &searchString )
 
  208  if ( search.hasParserError() )
 
  210    QMessageBox::critical( 
this, tr( 
"Query Result" ), search.parserErrorString() );
 
  217  const bool fetchGeom = search.needsGeometry();
 
  224  if ( !search.prepare( &context ) )
 
  226    QMessageBox::critical( 
this, tr( 
"Query Result" ), search.evalErrorString() );
 
  230  QApplication::setOverrideCursor( Qt::WaitCursor );
 
  236    context.setFeature( feat );
 
  237    const QVariant value = search.evaluate( &context );
 
  238    if ( value.toInt() != 0 )
 
  244    if ( search.hasEvalError() )
 
  248  QApplication::restoreOverrideCursor();
 
  250  if ( search.hasEvalError() )
 
  252    QMessageBox::critical( 
this, tr( 
"Query Result" ), search.evalErrorString() );
 
  260void QgsSearchQueryBuilder::btnOk_clicked()
 
  263  if ( mTxtSql->text().trimmed().length() > 0 )
 
  270  const long numRecs = countRecords( mTxtSql->text() );
 
  275  else if ( numRecs == 0 )
 
  277    QMessageBox::warning( 
this, tr( 
"Query Result" ), tr( 
"The query you specified results in zero records being returned." ) );
 
  286void QgsSearchQueryBuilder::btnEqual_clicked()
 
  288  mTxtSql->insertText( QStringLiteral( 
" = " ) );
 
  291void QgsSearchQueryBuilder::btnLessThan_clicked()
 
  293  mTxtSql->insertText( QStringLiteral( 
" < " ) );
 
  296void QgsSearchQueryBuilder::btnGreaterThan_clicked()
 
  298  mTxtSql->insertText( QStringLiteral( 
" > " ) );
 
  301void QgsSearchQueryBuilder::btnPct_clicked()
 
  303  mTxtSql->insertText( QStringLiteral( 
"%" ) );
 
  306void QgsSearchQueryBuilder::btnIn_clicked()
 
  308  mTxtSql->insertText( QStringLiteral( 
" IN " ) );
 
  311void QgsSearchQueryBuilder::btnNotIn_clicked()
 
  313  mTxtSql->insertText( QStringLiteral( 
" NOT IN " ) );
 
  316void QgsSearchQueryBuilder::btnLike_clicked()
 
  318  mTxtSql->insertText( QStringLiteral( 
" LIKE " ) );
 
  323  return mTxtSql->text();
 
  331void QgsSearchQueryBuilder::lstFields_doubleClicked( 
const QModelIndex &index )
 
  336void QgsSearchQueryBuilder::lstValues_doubleClicked( 
const QModelIndex &index )
 
  338  mTxtSql->insertText( mModelValues->data( index ).toString() );
 
  341void QgsSearchQueryBuilder::btnLessEqual_clicked()
 
  343  mTxtSql->insertText( QStringLiteral( 
" <= " ) );
 
  346void QgsSearchQueryBuilder::btnGreaterEqual_clicked()
 
  348  mTxtSql->insertText( QStringLiteral( 
" >= " ) );
 
  351void QgsSearchQueryBuilder::btnNotEqual_clicked()
 
  353  mTxtSql->insertText( QStringLiteral( 
" != " ) );
 
  356void QgsSearchQueryBuilder::btnAnd_clicked()
 
  358  mTxtSql->insertText( QStringLiteral( 
" AND " ) );
 
  361void QgsSearchQueryBuilder::btnNot_clicked()
 
  363  mTxtSql->insertText( QStringLiteral( 
" NOT " ) );
 
  366void QgsSearchQueryBuilder::btnOr_clicked()
 
  368  mTxtSql->insertText( QStringLiteral( 
" OR " ) );
 
  371void QgsSearchQueryBuilder::btnClear_clicked()
 
  376void QgsSearchQueryBuilder::btnILike_clicked()
 
  378  mTxtSql->insertText( QStringLiteral( 
" ILIKE " ) );
 
  392    mTxtSql->insertText( query );
 
  396void QgsSearchQueryBuilder::showHelp()
 
  398  QgsHelp::openHelp( QStringLiteral( 
"working_with_vector/vector_properties.html#query-builder" ) );
 
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)
 
This class wraps a request for features to a vector layer (or directly its vector data provider).
 
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
 
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
 
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
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.
 
int count() const
Returns number of items.
 
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.
 
QgsFields fields() const FINAL
Returns the list of fields of this layer.
 
QList< int > QgsAttributeList