22 #include <QMessageBox> 24 #include <QPushButton> 29 QWidget *parent, Qt::WindowFlags fl )
30 : QDialog( parent, fl )
31 , mPreviousFieldRow( -1 )
35 connect( btnEqual, &QPushButton::clicked,
this, &QgsQueryBuilder::btnEqual_clicked );
36 connect( btnLessThan, &QPushButton::clicked,
this, &QgsQueryBuilder::btnLessThan_clicked );
37 connect( btnGreaterThan, &QPushButton::clicked,
this, &QgsQueryBuilder::btnGreaterThan_clicked );
38 connect( btnPct, &QPushButton::clicked,
this, &QgsQueryBuilder::btnPct_clicked );
39 connect( btnIn, &QPushButton::clicked,
this, &QgsQueryBuilder::btnIn_clicked );
40 connect( btnNotIn, &QPushButton::clicked,
this, &QgsQueryBuilder::btnNotIn_clicked );
41 connect( btnLike, &QPushButton::clicked,
this, &QgsQueryBuilder::btnLike_clicked );
42 connect( btnILike, &QPushButton::clicked,
this, &QgsQueryBuilder::btnILike_clicked );
43 connect( lstFields, &QListView::clicked,
this, &QgsQueryBuilder::lstFields_clicked );
44 connect( lstFields, &QListView::doubleClicked,
this, &QgsQueryBuilder::lstFields_doubleClicked );
45 connect( lstValues, &QListView::doubleClicked,
this, &QgsQueryBuilder::lstValues_doubleClicked );
46 connect( btnLessEqual, &QPushButton::clicked,
this, &QgsQueryBuilder::btnLessEqual_clicked );
47 connect( btnGreaterEqual, &QPushButton::clicked,
this, &QgsQueryBuilder::btnGreaterEqual_clicked );
48 connect( btnNotEqual, &QPushButton::clicked,
this, &QgsQueryBuilder::btnNotEqual_clicked );
49 connect( btnAnd, &QPushButton::clicked,
this, &QgsQueryBuilder::btnAnd_clicked );
50 connect( btnNot, &QPushButton::clicked,
this, &QgsQueryBuilder::btnNot_clicked );
51 connect( btnOr, &QPushButton::clicked,
this, &QgsQueryBuilder::btnOr_clicked );
52 connect( btnGetAllValues, &QPushButton::clicked,
this, &QgsQueryBuilder::btnGetAllValues_clicked );
53 connect( btnSampleValues, &QPushButton::clicked,
this, &QgsQueryBuilder::btnSampleValues_clicked );
54 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsQueryBuilder::showHelp );
57 restoreGeometry( settings.
value( QStringLiteral(
"Windows/QueryBuilder/geometry" ) ).toByteArray() );
59 QPushButton *pbn =
new QPushButton( tr(
"&Test" ) );
60 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
63 pbn =
new QPushButton( tr(
"&Clear" ) );
64 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
71 mUseUnfilteredLayer->setDisabled( mLayer->
subsetString().isEmpty() );
73 lblDataUri->setText( tr(
"Set provider filter on %1" ).arg( layer->
name() ) );
74 txtSQL->setText( mOrigSubsetString );
88 QDialog::showEvent( event );
91 void QgsQueryBuilder::populateFields()
94 for (
int idx = 0; idx < fields.
count(); ++idx )
101 QStandardItem *myItem =
new QStandardItem( fields.
at( idx ).
name() );
102 myItem->setData( idx );
103 myItem->setEditable(
false );
104 mModelFields->insertRow( mModelFields->rowCount(), myItem );
108 setupLstFieldsModel();
111 void QgsQueryBuilder::setupLstFieldsModel()
113 lstFields->setModel( mModelFields );
116 void QgsQueryBuilder::setupGuiViews()
119 mModelFields =
new QStandardItemModel();
120 mModelValues =
new QStandardItemModel();
122 lstFields->setViewMode( QListView::ListMode );
123 lstValues->setViewMode( QListView::ListMode );
124 lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
125 lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
127 lstFields->setUniformItemSizes(
true );
128 lstValues->setUniformItemSizes(
true );
130 lstFields->setAlternatingRowColors(
true );
131 lstValues->setAlternatingRowColors(
true );
134 void QgsQueryBuilder::fillValues(
int idx,
int limit )
137 mModelValues->clear();
140 QList<QVariant> values = mLayer->
uniqueValues( idx, limit ).toList();
141 std::sort( values.begin(), values.end() );
145 QgsDebugMsg( QString(
"nullValue: %1" ).arg( nullValue ) );
147 Q_FOREACH (
const QVariant &var, values )
152 else if ( var.type() == QVariant::Date && mLayer->
providerType() == QLatin1String(
"ogr" ) && mLayer->
storageType() == QLatin1String(
"ESRI Shapefile" ) )
153 value = var.toDate().toString( QStringLiteral(
"yyyy/MM/dd" ) );
155 value = var.toString();
157 QStandardItem *myItem =
new QStandardItem( value );
158 myItem->setEditable(
false );
159 myItem->setData( var, Qt::UserRole + 1 );
160 mModelValues->insertRow( mModelValues->rowCount(), myItem );
161 QgsDebugMsg( QString(
"Value is null: %1\nvalue: %2" ).arg( var.isNull() ).arg( var.isNull() ? nullValue : var.toString() ) );
165 void QgsQueryBuilder::btnSampleValues_clicked()
167 lstValues->setCursor( Qt::WaitCursor );
170 if ( mUseUnfilteredLayer->isChecked() && !prevSubsetString.isEmpty() )
176 QStandardItemModel *tmp =
new QStandardItemModel();
177 lstValues->setModel( tmp );
179 fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), 25 );
180 lstValues->setModel( mModelValues );
189 lstValues->setCursor( Qt::ArrowCursor );
192 void QgsQueryBuilder::btnGetAllValues_clicked()
194 lstValues->setCursor( Qt::WaitCursor );
197 if ( mUseUnfilteredLayer->isChecked() && !prevSubsetString.isEmpty() )
203 QStandardItemModel *tmp =
new QStandardItemModel();
204 lstValues->setModel( tmp );
206 fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), -1 );
207 lstValues->setModel( mModelValues );
216 lstValues->setCursor( Qt::ArrowCursor );
227 mUseUnfilteredLayer->setDisabled( mLayer->
subsetString().isEmpty() );
229 QMessageBox::information(
this,
230 tr(
"Query Result" ),
231 tr(
"The where clause returned %n row(s).",
"returned test rows", mLayer->
featureCount() ) );
235 QMessageBox::warning(
this,
236 tr(
"Query Result" ),
237 tr(
"An error occurred when executing the query." )
238 + tr(
"\nThe data provider said:\n%1" ).arg( mLayer->
dataProvider()->
errors().join( QStringLiteral(
"\n" ) ) ) );
243 QMessageBox::warning(
this,
244 tr(
"Query Result" ),
245 tr(
"An error occurred when executing the query." ) );
256 QMessageBox::warning(
this,
257 tr(
"Query Result" ),
258 tr(
"An error occurred when executing the query." )
259 + tr(
"\nThe data provider said:\n%1" ).arg( mLayer->
dataProvider()->
errors().join( QStringLiteral(
"\n" ) ) ) );
264 QMessageBox::warning(
this, tr(
"Query Result" ), tr(
"Error in query. The subset string could not be set." ) );
281 void QgsQueryBuilder::btnEqual_clicked()
283 txtSQL->insertText( QStringLiteral(
" = " ) );
287 void QgsQueryBuilder::btnLessThan_clicked()
289 txtSQL->insertText( QStringLiteral(
" < " ) );
293 void QgsQueryBuilder::btnGreaterThan_clicked()
295 txtSQL->insertText( QStringLiteral(
" > " ) );
299 void QgsQueryBuilder::btnPct_clicked()
301 txtSQL->insertText( QStringLiteral(
"%" ) );
305 void QgsQueryBuilder::btnIn_clicked()
307 txtSQL->insertText( QStringLiteral(
" IN " ) );
311 void QgsQueryBuilder::btnNotIn_clicked()
313 txtSQL->insertText( QStringLiteral(
" NOT IN " ) );
317 void QgsQueryBuilder::btnLike_clicked()
319 txtSQL->insertText( QStringLiteral(
" LIKE " ) );
325 return txtSQL->text();
330 txtSQL->setText( sqlStatement );
333 void QgsQueryBuilder::lstFields_clicked(
const QModelIndex &index )
335 if ( mPreviousFieldRow != index.row() )
337 mPreviousFieldRow = index.row();
339 btnSampleValues->setEnabled(
true );
340 btnGetAllValues->setEnabled(
true );
342 mModelValues->clear();
346 void QgsQueryBuilder::lstFields_doubleClicked(
const QModelIndex &index )
348 txtSQL->insertText(
'\"' + mLayer->
fields().
at( mModelFields->data( index, Qt::UserRole + 1 ).toInt() ).name() +
'\"' );
352 void QgsQueryBuilder::lstValues_doubleClicked(
const QModelIndex &index )
354 QVariant value = mModelValues->data( index, Qt::UserRole + 1 );
355 if ( value.isNull() )
356 txtSQL->insertText( QStringLiteral(
"NULL" ) );
357 else if ( value.type() == QVariant::Date && mLayer->
providerType() == QLatin1String(
"ogr" ) && mLayer->
storageType() == QLatin1String(
"ESRI Shapefile" ) )
358 txtSQL->insertText(
'\'' + value.toDate().toString( QStringLiteral(
"yyyy/MM/dd" ) ) +
'\'' );
359 else if ( value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong )
360 txtSQL->insertText( value.toString() );
362 txtSQL->insertText(
'\'' + value.toString().replace(
'\'', QLatin1String(
"''" ) ) +
'\'' );
367 void QgsQueryBuilder::btnLessEqual_clicked()
369 txtSQL->insertText( QStringLiteral(
" <= " ) );
373 void QgsQueryBuilder::btnGreaterEqual_clicked()
375 txtSQL->insertText( QStringLiteral(
" >= " ) );
379 void QgsQueryBuilder::btnNotEqual_clicked()
381 txtSQL->insertText( QStringLiteral(
" != " ) );
385 void QgsQueryBuilder::btnAnd_clicked()
387 txtSQL->insertText( QStringLiteral(
" AND " ) );
391 void QgsQueryBuilder::btnNot_clicked()
393 txtSQL->insertText( QStringLiteral(
" NOT " ) );
397 void QgsQueryBuilder::btnOr_clicked()
399 txtSQL->insertText( QStringLiteral(
" OR " ) );
407 mUseUnfilteredLayer->setDisabled(
true );
410 void QgsQueryBuilder::btnILike_clicked()
412 txtSQL->insertText( QStringLiteral(
" ILIKE " ) );
418 lblDataUri->setText( uri );
421 void QgsQueryBuilder::showHelp()
423 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#query-builder" ) );
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
void test()
Test the constructed sql statement to see if the vector layer data provider likes it...
This class is a composition of two QSettings instances:
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
Container of fields for a vector layer.
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const override
Calculates a list of unique values contained within an attribute in the layer.
Field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
int count() const
Return number of items.
~QgsQueryBuilder() override
QgsField at(int i) const
Get field at particular index (must be in range 0..N-1)
void saveGeometry(QWidget *widget, const QString &keyName)
Save the wigget geometry into settings.
bool restoreGeometry(QWidget *widget, const QString &keyName)
Restore the wigget geometry from settings.
void setValue(const QString &key, const QVariant &value, const QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
void setSql(const QString &sqlStatement)
QgsFields fields() const override
Returns the list of fields of this layer.
long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QStringList errors() const
Get recorded errors.
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
void clearErrors()
Clear recorded errors.
QgsQueryBuilder(QgsVectorLayer *layer, QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
This constructor is used when the query builder is called from the vector layer properties dialog...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key.
void setDatasourceDescription(const QString &uri)
bool hasErrors() const
Provider has errors to report.
virtual QString subsetString() const
Get the string (typically sql) used to define a subset of the layer.
QgsVectorDataProvider * dataProvider() override
Returns the layer's data provider.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
virtual bool setSubsetString(const QString &subset)
Set the string (typically sql) used to define a subset of the layer.
QString providerType() const
Return the provider type for this layer.
Represents a vector layer which manages a vector based data sets.
void showEvent(QShowEvent *event) override