16#include <QDomDocument> 
   20#include <QInputDialog> 
   23#include <QStandardItem> 
   30#include "moc_qgssearchquerybuilder.cpp" 
   39  : QDialog( parent, fl )
 
   43  connect( btnEqual, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnEqual_clicked );
 
   44  connect( btnLessThan, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnLessThan_clicked );
 
   45  connect( btnGreaterThan, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnGreaterThan_clicked );
 
   46  connect( btnLike, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnLike_clicked );
 
   47  connect( btnILike, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnILike_clicked );
 
   48  connect( btnPct, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnPct_clicked );
 
   49  connect( btnIn, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnIn_clicked );
 
   50  connect( btnNotIn, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnNotIn_clicked );
 
   51  connect( lstFields, &QListView::doubleClicked, 
this, &QgsSearchQueryBuilder::lstFields_doubleClicked );
 
   52  connect( lstValues, &QListView::doubleClicked, 
this, &QgsSearchQueryBuilder::lstValues_doubleClicked );
 
   53  connect( btnLessEqual, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnLessEqual_clicked );
 
   54  connect( btnGreaterEqual, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnGreaterEqual_clicked );
 
   55  connect( btnNotEqual, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnNotEqual_clicked );
 
   56  connect( btnAnd, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnAnd_clicked );
 
   57  connect( btnNot, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnNot_clicked );
 
   58  connect( btnOr, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnOr_clicked );
 
   59  connect( btnGetAllValues, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnGetAllValues_clicked );
 
   60  connect( btnSampleValues, &QPushButton::clicked, 
this, &QgsSearchQueryBuilder::btnSampleValues_clicked );
 
   62  connect( buttonBox, &QDialogButtonBox::helpRequested, 
this, &QgsSearchQueryBuilder::showHelp );
 
   64  setWindowTitle( tr( 
"Search Query Builder" ) );
 
   66  QPushButton *pbn = 
new QPushButton( tr( 
"&Test" ) );
 
   67  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
   68  connect( pbn, &QAbstractButton::clicked, 
this, &QgsSearchQueryBuilder::btnTest_clicked );
 
   70  pbn = 
new QPushButton( tr( 
"&Clear" ) );
 
   71  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
   72  connect( pbn, &QAbstractButton::clicked, 
this, &QgsSearchQueryBuilder::btnClear_clicked );
 
   74  pbn = 
new QPushButton( tr( 
"&Save…" ) );
 
   75  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
   76  pbn->setToolTip( tr( 
"Save query to an xml file" ) );
 
   79  pbn = 
new QPushButton( tr( 
"&Load…" ) );
 
   80  buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
 
   81  pbn->setToolTip( tr( 
"Load query from xml file" ) );
 
   85    lblDataUri->setText( layer->
name() );
 
 
   89void QgsSearchQueryBuilder::populateFields()
 
   95  for ( 
int idx = 0; idx < fields.
count(); ++idx )
 
   97    const QString fieldName = fields.
at( idx ).
name();
 
   98    mFieldMap[fieldName] = idx;
 
   99    QStandardItem *myItem = 
new QStandardItem( fieldName );
 
  100    myItem->setEditable( 
false );
 
  101    mModelFields->insertRow( mModelFields->rowCount(), myItem );
 
  105void QgsSearchQueryBuilder::setupListViews()
 
  108  mModelFields = 
new QStandardItemModel();
 
  109  mModelValues = 
new QStandardItemModel();
 
  110  lstFields->setModel( mModelFields );
 
  111  lstValues->setModel( mModelValues );
 
  113  lstFields->setViewMode( QListView::ListMode );
 
  114  lstValues->setViewMode( QListView::ListMode );
 
  115  lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
 
  116  lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
 
  118  lstFields->setUniformItemSizes( 
true );
 
  119  lstValues->setUniformItemSizes( 
true );
 
  122void QgsSearchQueryBuilder::getFieldValues( 
int limit )
 
  129  mModelValues->clear();
 
  132  const QString fieldName = mModelFields->data( lstFields->currentIndex() ).toString();
 
  133  const int fieldIndex = mFieldMap[fieldName];
 
  135  const bool numeric = ( field.
type() == QMetaType::Type::Int || field.
type() == QMetaType::Type::Double );
 
  141  attrs.append( fieldIndex );
 
  145  lstValues->setCursor( Qt::WaitCursor );
 
  147  mModelValues->blockSignals( 
true );
 
  148  lstValues->setUpdatesEnabled( 
false );
 
  151  QSet<QString> insertedValues;
 
  153  while ( fit.
nextFeature( feat ) && ( limit == 0 || mModelValues->rowCount() != limit ) )
 
  155    value = feat.
attribute( fieldIndex ).toString();
 
  160      value = 
'\'' + value.replace( 
'\'', QLatin1String( 
"''" ) ) + 
'\'';
 
  164    if ( !insertedValues.contains( value ) )
 
  166      QStandardItem *myItem = 
new QStandardItem( value );
 
  167      myItem->setEditable( 
false );
 
  168      mModelValues->insertRow( mModelValues->rowCount(), myItem );
 
  169      insertedValues.insert( value );
 
  173  mModelValues->blockSignals( 
false );
 
  174  lstValues->setUpdatesEnabled( 
true );
 
  176  mModelValues->sort( 0 );
 
  177  lstValues->setCursor( Qt::ArrowCursor );
 
  180void QgsSearchQueryBuilder::btnSampleValues_clicked()
 
  182  getFieldValues( 25 );
 
  185void QgsSearchQueryBuilder::btnGetAllValues_clicked()
 
  190void QgsSearchQueryBuilder::btnTest_clicked()
 
  192  const long count = countRecords( mTxtSql->text() );
 
  198  QMessageBox::information( 
this, tr( 
"Test Query" ), tr( 
"Found %n matching feature(s).", 
"test result", count ) );
 
  202long QgsSearchQueryBuilder::countRecords( 
const QString &searchString )
 
  205  if ( search.hasParserError() )
 
  207    QMessageBox::critical( 
this, tr( 
"Query Result" ), search.parserErrorString() );
 
  214  const bool fetchGeom = search.needsGeometry();
 
  221  if ( !search.prepare( &context ) )
 
  223    QMessageBox::critical( 
this, tr( 
"Query Result" ), search.evalErrorString() );
 
  227  QApplication::setOverrideCursor( Qt::WaitCursor );
 
  233    context.setFeature( feat );
 
  234    const QVariant value = search.evaluate( &context );
 
  235    if ( value.toInt() != 0 )
 
  241    if ( search.hasEvalError() )
 
  245  QApplication::restoreOverrideCursor();
 
  247  if ( search.hasEvalError() )
 
  249    QMessageBox::critical( 
this, tr( 
"Query Result" ), search.evalErrorString() );
 
  257void QgsSearchQueryBuilder::btnOk_clicked()
 
  260  if ( mTxtSql->text().trimmed().length() > 0 )
 
  267  const long numRecs = countRecords( mTxtSql->text() );
 
  272  else if ( numRecs == 0 )
 
  274    QMessageBox::warning( 
this, tr( 
"Query Result" ), tr( 
"The query you specified results in zero records being returned." ) );
 
  282void QgsSearchQueryBuilder::btnEqual_clicked()
 
  284  mTxtSql->insertText( QStringLiteral( 
" = " ) );
 
  287void QgsSearchQueryBuilder::btnLessThan_clicked()
 
  289  mTxtSql->insertText( QStringLiteral( 
" < " ) );
 
  292void QgsSearchQueryBuilder::btnGreaterThan_clicked()
 
  294  mTxtSql->insertText( QStringLiteral( 
" > " ) );
 
  297void QgsSearchQueryBuilder::btnPct_clicked()
 
  299  mTxtSql->insertText( QStringLiteral( 
"%" ) );
 
  302void QgsSearchQueryBuilder::btnIn_clicked()
 
  304  mTxtSql->insertText( QStringLiteral( 
" IN " ) );
 
  307void QgsSearchQueryBuilder::btnNotIn_clicked()
 
  309  mTxtSql->insertText( QStringLiteral( 
" NOT IN " ) );
 
  312void QgsSearchQueryBuilder::btnLike_clicked()
 
  314  mTxtSql->insertText( QStringLiteral( 
" LIKE " ) );
 
  319  return mTxtSql->text();
 
 
  327void QgsSearchQueryBuilder::lstFields_doubleClicked( 
const QModelIndex &index )
 
  332void QgsSearchQueryBuilder::lstValues_doubleClicked( 
const QModelIndex &index )
 
  334  mTxtSql->insertText( mModelValues->data( index ).toString() );
 
  337void QgsSearchQueryBuilder::btnLessEqual_clicked()
 
  339  mTxtSql->insertText( QStringLiteral( 
" <= " ) );
 
  342void QgsSearchQueryBuilder::btnGreaterEqual_clicked()
 
  344  mTxtSql->insertText( QStringLiteral( 
" >= " ) );
 
  347void QgsSearchQueryBuilder::btnNotEqual_clicked()
 
  349  mTxtSql->insertText( QStringLiteral( 
" != " ) );
 
  352void QgsSearchQueryBuilder::btnAnd_clicked()
 
  354  mTxtSql->insertText( QStringLiteral( 
" AND " ) );
 
  357void QgsSearchQueryBuilder::btnNot_clicked()
 
  359  mTxtSql->insertText( QStringLiteral( 
" NOT " ) );
 
  362void QgsSearchQueryBuilder::btnOr_clicked()
 
  364  mTxtSql->insertText( QStringLiteral( 
" OR " ) );
 
  367void QgsSearchQueryBuilder::btnClear_clicked()
 
  372void QgsSearchQueryBuilder::btnILike_clicked()
 
  374  mTxtSql->insertText( QStringLiteral( 
" ILIKE " ) );
 
  388    mTxtSql->insertText( query );
 
 
  392void QgsSearchQueryBuilder::showHelp()
 
  394  QgsHelp::openHelp( QStringLiteral( 
"working_with_vector/vector_properties.html#query-builder" ) );
 
Provides global constants and enumerations 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...
 
Handles 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.
 
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 dataset.
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
 
QList< int > QgsAttributeList