|
QGIS API Documentation
master-6227475
|
00001 /*************************************************************************** 00002 qgsquerybuilder.cpp - Query Builder 00003 -------------------------------------- 00004 Date : 2004-11-19 00005 Copyright : (C) 2004 by Gary E.Sherman 00006 Email : sherman at mrcc.com 00007 *************************************************************************** 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 ***************************************************************************/ 00015 #include "qgsquerybuilder.h" 00016 #include "qgslogger.h" 00017 #include <QListView> 00018 #include <QMessageBox> 00019 #include <QRegExp> 00020 #include <QPushButton> 00021 #include <QSettings> 00022 #include "qgsvectorlayer.h" 00023 #include "qgsvectordataprovider.h" 00024 00025 // constructor used when the query builder must make its own 00026 // connection to the database 00027 QgsQueryBuilder::QgsQueryBuilder( QgsVectorLayer *layer, 00028 QWidget *parent, Qt::WFlags fl ) 00029 : QDialog( parent, fl ) 00030 , mPreviousFieldRow( -1 ) 00031 , mLayer( layer ) 00032 { 00033 setupUi( this ); 00034 00035 QSettings settings; 00036 restoreGeometry( settings.value( "/Windows/QueryBuilder/geometry" ).toByteArray() ); 00037 00038 QPushButton *pbn = new QPushButton( tr( "&Test" ) ); 00039 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole ); 00040 connect( pbn, SIGNAL( clicked() ), this, SLOT( test() ) ); 00041 00042 pbn = new QPushButton( tr( "&Clear" ) ); 00043 buttonBox->addButton( pbn, QDialogButtonBox::ActionRole ); 00044 connect( pbn, SIGNAL( clicked() ), this, SLOT( clear() ) ); 00045 00046 setupGuiViews(); 00047 00048 mOrigSubsetString = layer->subsetString(); 00049 00050 mUseUnfilteredLayer->setDisabled( mLayer->subsetString().isEmpty() ); 00051 00052 lblDataUri->setText( layer->name() ); 00053 txtSQL->setText( mOrigSubsetString ); 00054 00055 populateFields(); 00056 } 00057 00058 QgsQueryBuilder::~QgsQueryBuilder() 00059 { 00060 QSettings settings; 00061 settings.setValue( "/Windows/QueryBuilder/geometry", saveGeometry() ); 00062 } 00063 00064 void QgsQueryBuilder::populateFields() 00065 { 00066 const QgsFields& fields = mLayer->pendingFields(); 00067 for ( int idx = 0; idx < fields.count(); ++idx ) 00068 { 00069 QStandardItem *myItem = new QStandardItem( fields[idx].name() ); 00070 myItem->setData( idx ); 00071 myItem->setEditable( false ); 00072 mModelFields->insertRow( mModelFields->rowCount(), myItem ); 00073 } 00074 00075 // All fields get ... setup 00076 setupLstFieldsModel(); 00077 } 00078 00079 void QgsQueryBuilder::setupLstFieldsModel() 00080 { 00081 lstFields->setModel( mModelFields ); 00082 } 00083 00084 void QgsQueryBuilder::setupGuiViews() 00085 { 00086 //Initialize the models 00087 mModelFields = new QStandardItemModel(); 00088 mModelValues = new QStandardItemModel(); 00089 // Modes 00090 lstFields->setViewMode( QListView::ListMode ); 00091 lstValues->setViewMode( QListView::ListMode ); 00092 lstFields->setSelectionBehavior( QAbstractItemView::SelectRows ); 00093 lstValues->setSelectionBehavior( QAbstractItemView::SelectRows ); 00094 // Performance tip since Qt 4.1 00095 lstFields->setUniformItemSizes( true ); 00096 lstValues->setUniformItemSizes( true ); 00097 // Colored rows 00098 lstFields->setAlternatingRowColors( true ); 00099 lstValues->setAlternatingRowColors( true ); 00100 } 00101 00102 void QgsQueryBuilder::fillValues( int idx, int limit ) 00103 { 00104 // clear the model 00105 mModelValues->clear(); 00106 00107 // determine the field type 00108 QList<QVariant> values; 00109 mLayer->uniqueValues( idx, values, limit ); 00110 00111 QSettings settings; 00112 QString nullValue = settings.value( "qgis/nullValue", "NULL" ).toString(); 00113 00114 QgsDebugMsg( QString( "nullValue: %1" ).arg( nullValue ) ); 00115 00116 for ( int i = 0; i < values.size(); i++ ) 00117 { 00118 QStandardItem *myItem = new QStandardItem( values[i].isNull() ? nullValue : values[i].toString() ); 00119 myItem->setEditable( false ); 00120 myItem->setData( values[i], Qt::UserRole + 1 ); 00121 mModelValues->insertRow( mModelValues->rowCount(), myItem ); 00122 QgsDebugMsg( QString( "Value is null: %1\nvalue: %2" ).arg( values[i].isNull() ).arg( values[i].isNull() ? nullValue : values[i].toString() ) ); 00123 } 00124 } 00125 00126 void QgsQueryBuilder::on_btnSampleValues_clicked() 00127 { 00128 lstValues->setCursor( Qt::WaitCursor ); 00129 00130 QString prevSubsetString = mLayer->subsetString(); 00131 if ( mUseUnfilteredLayer->isChecked() && !prevSubsetString.isEmpty() ) 00132 { 00133 mLayer->setSubsetString( "" ); 00134 } 00135 00136 //delete connection mModelValues and lstValues 00137 QStandardItemModel *tmp = new QStandardItemModel(); 00138 lstValues->setModel( tmp ); 00139 //Clear and fill the mModelValues 00140 fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), 25 ); 00141 lstValues->setModel( mModelValues ); 00142 //delete the tmp 00143 delete tmp; 00144 00145 if ( prevSubsetString != mLayer->subsetString() ) 00146 { 00147 mLayer->setSubsetString( prevSubsetString ); 00148 } 00149 00150 lstValues->setCursor( Qt::ArrowCursor ); 00151 } 00152 00153 void QgsQueryBuilder::on_btnGetAllValues_clicked() 00154 { 00155 lstValues->setCursor( Qt::WaitCursor ); 00156 00157 QString prevSubsetString = mLayer->subsetString(); 00158 if ( mUseUnfilteredLayer->isChecked() && !prevSubsetString.isEmpty() ) 00159 { 00160 mLayer->setSubsetString( "" ); 00161 } 00162 00163 //delete connection mModelValues and lstValues 00164 QStandardItemModel *tmp = new QStandardItemModel(); 00165 lstValues->setModel( tmp ); 00166 //Clear and fill the mModelValues 00167 fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), -1 ); 00168 lstValues->setModel( mModelValues ); 00169 //delete the tmp 00170 delete tmp; 00171 00172 if ( prevSubsetString != mLayer->subsetString() ) 00173 { 00174 mLayer->setSubsetString( prevSubsetString ); 00175 } 00176 00177 lstValues->setCursor( Qt::ArrowCursor ); 00178 } 00179 00180 void QgsQueryBuilder::test() 00181 { 00182 // test the sql statement to see if it works 00183 // by counting the number of records that would be 00184 // returned 00185 00186 if ( mLayer->setSubsetString( txtSQL->toPlainText() ) ) 00187 { 00188 mUseUnfilteredLayer->setDisabled( mLayer->subsetString().isEmpty() ); 00189 00190 QMessageBox::information( this, 00191 tr( "Query Result" ), 00192 tr( "The where clause returned %n row(s).", "returned test rows", mLayer->featureCount() ) ); 00193 } 00194 else if ( mLayer->dataProvider()->hasErrors() ) 00195 { 00196 QMessageBox::warning( this, 00197 tr( "Query Failed" ), 00198 tr( "An error occurred when executing the query." ) 00199 + tr( "\nThe data provider said:\n%1" ).arg( mLayer->dataProvider()->errors().join( "\n" ) ) ); 00200 mLayer->dataProvider()->clearErrors(); 00201 } 00202 else 00203 { 00204 QMessageBox::warning( this, 00205 tr( "Query Failed" ), 00206 tr( "An error occurred when executing the query." ) ); 00207 } 00208 } 00209 00210 void QgsQueryBuilder::accept() 00211 { 00212 if ( !mLayer->setSubsetString( txtSQL->toPlainText() ) ) 00213 { 00214 //error in query - show the problem 00215 if ( mLayer->dataProvider()->hasErrors() ) 00216 { 00217 QMessageBox::warning( this, 00218 tr( "Query Failed" ), 00219 tr( "An error occurred when executing the query." ) 00220 + tr( "\nThe data provider said:\n%1" ).arg( mLayer->dataProvider()->errors().join( "\n" ) ) ); 00221 mLayer->dataProvider()->clearErrors(); 00222 } 00223 else 00224 { 00225 QMessageBox::warning( this, tr( "Error in Query" ), tr( "The subset string could not be set" ) ); 00226 } 00227 00228 return; 00229 } 00230 00231 QDialog::accept(); 00232 } 00233 00234 void QgsQueryBuilder::reject() 00235 { 00236 if ( mLayer->subsetString() != mOrigSubsetString ) 00237 mLayer->setSubsetString( mOrigSubsetString ); 00238 00239 QDialog::reject(); 00240 } 00241 00242 void QgsQueryBuilder::on_btnEqual_clicked() 00243 { 00244 txtSQL->insertPlainText( " = " ); 00245 } 00246 00247 void QgsQueryBuilder::on_btnLessThan_clicked() 00248 { 00249 txtSQL->insertPlainText( " < " ); 00250 } 00251 00252 void QgsQueryBuilder::on_btnGreaterThan_clicked() 00253 { 00254 txtSQL->insertPlainText( " > " ); 00255 } 00256 00257 void QgsQueryBuilder::on_btnPct_clicked() 00258 { 00259 txtSQL->insertPlainText( "%" ); 00260 } 00261 00262 void QgsQueryBuilder::on_btnIn_clicked() 00263 { 00264 txtSQL->insertPlainText( " IN " ); 00265 } 00266 00267 void QgsQueryBuilder::on_btnNotIn_clicked() 00268 { 00269 txtSQL->insertPlainText( " NOT IN " ); 00270 } 00271 00272 void QgsQueryBuilder::on_btnLike_clicked() 00273 { 00274 txtSQL->insertPlainText( " LIKE " ); 00275 } 00276 00277 QString QgsQueryBuilder::sql() 00278 { 00279 return txtSQL->toPlainText(); 00280 } 00281 00282 void QgsQueryBuilder::setSql( QString sqlStatement ) 00283 { 00284 txtSQL->setText( sqlStatement ); 00285 } 00286 00287 void QgsQueryBuilder::on_lstFields_clicked( const QModelIndex &index ) 00288 { 00289 if ( mPreviousFieldRow != index.row() ) 00290 { 00291 mPreviousFieldRow = index.row(); 00292 00293 btnSampleValues->setEnabled( true ); 00294 btnGetAllValues->setEnabled( true ); 00295 00296 mModelValues->clear(); 00297 } 00298 } 00299 00300 void QgsQueryBuilder::on_lstFields_doubleClicked( const QModelIndex &index ) 00301 { 00302 txtSQL->insertPlainText( "\"" + mLayer->pendingFields()[ mModelFields->data( index, Qt::UserRole+1 ).toInt()].name() + "\"" ); 00303 } 00304 00305 void QgsQueryBuilder::on_lstValues_doubleClicked( const QModelIndex &index ) 00306 { 00307 QVariant value = mModelValues->data( index, Qt::UserRole + 1 ); 00308 if ( value.isNull() ) 00309 txtSQL->insertPlainText( "NULL" ); 00310 else if ( value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong ) 00311 txtSQL->insertPlainText( value.toString() ); 00312 else 00313 txtSQL->insertPlainText( "'" + value.toString().replace( "'", "''" ) + "'" ); 00314 } 00315 00316 void QgsQueryBuilder::on_btnLessEqual_clicked() 00317 { 00318 txtSQL->insertPlainText( " <= " ); 00319 } 00320 00321 void QgsQueryBuilder::on_btnGreaterEqual_clicked() 00322 { 00323 txtSQL->insertPlainText( " >= " ); 00324 } 00325 00326 void QgsQueryBuilder::on_btnNotEqual_clicked() 00327 { 00328 txtSQL->insertPlainText( " != " ); 00329 } 00330 00331 void QgsQueryBuilder::on_btnAnd_clicked() 00332 { 00333 txtSQL->insertPlainText( " AND " ); 00334 } 00335 00336 void QgsQueryBuilder::on_btnNot_clicked() 00337 { 00338 txtSQL->insertPlainText( " NOT " ); 00339 } 00340 00341 void QgsQueryBuilder::on_btnOr_clicked() 00342 { 00343 txtSQL->insertPlainText( " OR " ); 00344 } 00345 00346 void QgsQueryBuilder::clear() 00347 { 00348 txtSQL->clear(); 00349 mLayer->setSubsetString( "" ); 00350 mUseUnfilteredLayer->setDisabled( true ); 00351 } 00352 00353 void QgsQueryBuilder::on_btnILike_clicked() 00354 { 00355 txtSQL->insertPlainText( " ILIKE " ); 00356 } 00357 00358 void QgsQueryBuilder::setDatasourceDescription( QString uri ) 00359 { 00360 lblDataUri->setText( uri ); 00361 }