26 #include <QMessageBox>
28 #include <QPushButton>
33 QWidget *parent, Qt::WindowFlags fl )
34 : QDialog( parent, fl )
35 , mPreviousFieldRow( -1 )
40 connect( btnEqual, &QPushButton::clicked,
this, &QgsQueryBuilder::btnEqual_clicked );
41 connect( btnLessThan, &QPushButton::clicked,
this, &QgsQueryBuilder::btnLessThan_clicked );
42 connect( btnGreaterThan, &QPushButton::clicked,
this, &QgsQueryBuilder::btnGreaterThan_clicked );
43 connect( btnPct, &QPushButton::clicked,
this, &QgsQueryBuilder::btnPct_clicked );
44 connect( btnIn, &QPushButton::clicked,
this, &QgsQueryBuilder::btnIn_clicked );
45 connect( btnNotIn, &QPushButton::clicked,
this, &QgsQueryBuilder::btnNotIn_clicked );
46 connect( btnLike, &QPushButton::clicked,
this, &QgsQueryBuilder::btnLike_clicked );
47 connect( btnILike, &QPushButton::clicked,
this, &QgsQueryBuilder::btnILike_clicked );
48 connect( lstFields, &QListView::clicked,
this, &QgsQueryBuilder::lstFields_clicked );
49 connect( lstFields, &QListView::doubleClicked,
this, &QgsQueryBuilder::lstFields_doubleClicked );
50 connect( lstValues, &QListView::doubleClicked,
this, &QgsQueryBuilder::lstValues_doubleClicked );
51 connect( btnLessEqual, &QPushButton::clicked,
this, &QgsQueryBuilder::btnLessEqual_clicked );
52 connect( btnGreaterEqual, &QPushButton::clicked,
this, &QgsQueryBuilder::btnGreaterEqual_clicked );
53 connect( btnNotEqual, &QPushButton::clicked,
this, &QgsQueryBuilder::btnNotEqual_clicked );
54 connect( btnAnd, &QPushButton::clicked,
this, &QgsQueryBuilder::btnAnd_clicked );
55 connect( btnNot, &QPushButton::clicked,
this, &QgsQueryBuilder::btnNot_clicked );
56 connect( btnOr, &QPushButton::clicked,
this, &QgsQueryBuilder::btnOr_clicked );
57 connect( btnGetAllValues, &QPushButton::clicked,
this, &QgsQueryBuilder::btnGetAllValues_clicked );
58 connect( btnSampleValues, &QPushButton::clicked,
this, &QgsQueryBuilder::btnSampleValues_clicked );
59 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsQueryBuilder::showHelp );
61 QPushButton *pbn =
new QPushButton( tr(
"&Test" ) );
62 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
65 pbn =
new QPushButton( tr(
"&Clear" ) );
66 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
73 mUseUnfilteredLayer->setDisabled( mLayer->
subsetString().isEmpty() );
75 lblDataUri->setText( tr(
"Set provider filter on %1" ).arg( layer->
name() ) );
76 txtSQL->setText( mOrigSubsetString );
78 mFilterLineEdit->setShowSearchIcon(
true );
79 mFilterLineEdit->setPlaceholderText( tr(
"Search…" ) );
80 connect( mFilterLineEdit, &QgsFilterLineEdit::textChanged,
this, &QgsQueryBuilder::onTextChanged );
88 QDialog::showEvent( event );
91 void QgsQueryBuilder::populateFields()
94 txtSQL->setFields( fields );
95 for (
int idx = 0; idx < fields.
count(); ++idx )
103 myItem->setData( idx );
104 myItem->setEditable(
false );
105 mModelFields->insertRow( mModelFields->rowCount(), myItem );
109 setupLstFieldsModel();
112 void QgsQueryBuilder::setupLstFieldsModel()
114 lstFields->setModel( mModelFields );
117 void QgsQueryBuilder::setupGuiViews()
120 mModelFields =
new QStandardItemModel();
121 mModelValues =
new QStandardItemModel();
122 mProxyValues =
new QSortFilterProxyModel();
123 mProxyValues->setSourceModel( mModelValues );
125 lstFields->setViewMode( QListView::ListMode );
126 lstValues->setViewMode( QListView::ListMode );
127 lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
128 lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
130 lstFields->setUniformItemSizes(
true );
131 lstValues->setUniformItemSizes(
true );
133 lstFields->setAlternatingRowColors(
true );
134 lstValues->setAlternatingRowColors(
true );
135 lstValues->setModel( mProxyValues );
138 void QgsQueryBuilder::fillValues(
int idx,
int limit )
141 mModelValues->clear();
144 QList<QVariant> values = qgis::setToList( mLayer->
uniqueValues( idx, limit ) );
145 std::sort( values.begin(), values.end() );
149 QgsDebugMsg( QStringLiteral(
"nullValue: %1" ).arg( nullValue ) );
151 const auto constValues = values;
152 for (
const QVariant &var : constValues )
157 else if ( var.type() == QVariant::Date && mLayer->
providerType() == QLatin1String(
"ogr" ) && mLayer->
storageType() == QLatin1String(
"ESRI Shapefile" ) )
158 value = var.toDate().toString( QStringLiteral(
"yyyy/MM/dd" ) );
160 value = var.toString();
162 QStandardItem *myItem =
new QStandardItem( value );
163 myItem->setEditable(
false );
164 myItem->setData( var, Qt::UserRole + 1 );
165 mModelValues->insertRow( mModelValues->rowCount(), myItem );
166 QgsDebugMsg( QStringLiteral(
"Value is null: %1\nvalue: %2" ).arg( var.isNull() ).arg( var.isNull() ? nullValue : var.toString() ) );
170 void QgsQueryBuilder::btnSampleValues_clicked()
172 lstValues->setCursor( Qt::WaitCursor );
175 if ( mUseUnfilteredLayer->isChecked() && !prevSubsetString.isEmpty() )
181 fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), 25 );
188 lstValues->setCursor( Qt::ArrowCursor );
191 void QgsQueryBuilder::btnGetAllValues_clicked()
193 lstValues->setCursor( Qt::WaitCursor );
196 if ( mUseUnfilteredLayer->isChecked() && !prevSubsetString.isEmpty() )
202 fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), -1 );
209 lstValues->setCursor( Qt::ArrowCursor );
220 mUseUnfilteredLayer->setDisabled( mLayer->
subsetString().isEmpty() );
224 if ( featureCount < 0 )
226 QMessageBox::warning(
this,
227 tr(
"Query Result" ),
228 tr(
"An error occurred when executing the query, please check the expression syntax." ) );
232 QMessageBox::information(
this,
233 tr(
"Query Result" ),
234 tr(
"The where clause returned %n row(s).",
"returned test rows", featureCount ) );
239 QMessageBox::warning(
this,
240 tr(
"Query Result" ),
241 tr(
"An error occurred when executing the query." )
242 + tr(
"\nThe data provider said:\n%1" ).arg( mLayer->
dataProvider()->
errors().join( QStringLiteral(
"\n" ) ) ) );
247 QMessageBox::warning(
this,
248 tr(
"Query Result" ),
249 tr(
"An error occurred when executing the query." ) );
255 if ( txtSQL->text() != mOrigSubsetString )
262 QMessageBox::warning(
this,
263 tr(
"Query Result" ),
264 tr(
"An error occurred when executing the query." )
265 + tr(
"\nThe data provider said:\n%1" ).arg( mLayer->
dataProvider()->
errors().join( QStringLiteral(
"\n" ) ) ) );
270 QMessageBox::warning(
this, tr(
"Query Result" ), tr(
"Error in query. The subset string could not be set." ) );
288 void QgsQueryBuilder::btnEqual_clicked()
290 txtSQL->insertText( QStringLiteral(
" = " ) );
294 void QgsQueryBuilder::btnLessThan_clicked()
296 txtSQL->insertText( QStringLiteral(
" < " ) );
300 void QgsQueryBuilder::btnGreaterThan_clicked()
302 txtSQL->insertText( QStringLiteral(
" > " ) );
306 void QgsQueryBuilder::btnPct_clicked()
308 txtSQL->insertText( QStringLiteral(
"%" ) );
312 void QgsQueryBuilder::btnIn_clicked()
314 txtSQL->insertText( QStringLiteral(
" IN " ) );
318 void QgsQueryBuilder::btnNotIn_clicked()
320 txtSQL->insertText( QStringLiteral(
" NOT IN " ) );
324 void QgsQueryBuilder::btnLike_clicked()
326 txtSQL->insertText( QStringLiteral(
" LIKE " ) );
332 return txtSQL->text();
337 txtSQL->setText( sqlStatement );
340 void QgsQueryBuilder::lstFields_clicked(
const QModelIndex &index )
342 if ( mPreviousFieldRow != index.row() )
344 mPreviousFieldRow = index.row();
346 btnSampleValues->setEnabled(
true );
347 btnGetAllValues->setEnabled(
true );
349 mModelValues->clear();
350 mFilterLineEdit->clear();
354 void QgsQueryBuilder::lstFields_doubleClicked(
const QModelIndex &index )
356 txtSQL->insertText(
'\"' + mLayer->
fields().
at( mModelFields->data( index, Qt::UserRole + 1 ).toInt() ).
name() +
'\"' );
360 void QgsQueryBuilder::lstValues_doubleClicked(
const QModelIndex &index )
362 QVariant value = index.data( Qt::UserRole + 1 );
363 if ( value.isNull() )
364 txtSQL->insertText( QStringLiteral(
"NULL" ) );
365 else if ( value.type() == QVariant::Date && mLayer->
providerType() == QLatin1String(
"ogr" ) && mLayer->
storageType() == QLatin1String(
"ESRI Shapefile" ) )
366 txtSQL->insertText(
'\'' + value.toDate().toString( QStringLiteral(
"yyyy/MM/dd" ) ) +
'\'' );
367 else if ( value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong || value.type() == QVariant::Bool )
368 txtSQL->insertText( value.toString() );
370 txtSQL->insertText(
'\'' + value.toString().replace(
'\'', QLatin1String(
"''" ) ) +
'\'' );
375 void QgsQueryBuilder::btnLessEqual_clicked()
377 txtSQL->insertText( QStringLiteral(
" <= " ) );
381 void QgsQueryBuilder::btnGreaterEqual_clicked()
383 txtSQL->insertText( QStringLiteral(
" >= " ) );
387 void QgsQueryBuilder::btnNotEqual_clicked()
389 txtSQL->insertText( QStringLiteral(
" != " ) );
393 void QgsQueryBuilder::btnAnd_clicked()
395 txtSQL->insertText( QStringLiteral(
" AND " ) );
399 void QgsQueryBuilder::btnNot_clicked()
401 txtSQL->insertText( QStringLiteral(
" NOT " ) );
405 void QgsQueryBuilder::btnOr_clicked()
407 txtSQL->insertText( QStringLiteral(
" OR " ) );
411 void QgsQueryBuilder::onTextChanged(
const QString &text )
413 mProxyValues->setFilterCaseSensitivity( Qt::CaseInsensitive );
414 mProxyValues->setFilterWildcard( text );
421 mUseUnfilteredLayer->setDisabled(
true );
424 void QgsQueryBuilder::btnILike_clicked()
426 txtSQL->insertText( QStringLiteral(
" ILIKE " ) );
432 lblDataUri->setText( uri );
435 void QgsQueryBuilder::showHelp()
437 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/vector_properties.html#query-builder" ) );