00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00026
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 lblDataUri->setText( layer->name() );
00051 txtSQL->setText( mOrigSubsetString );
00052
00053 populateFields();
00054 }
00055
00056 QgsQueryBuilder::~QgsQueryBuilder()
00057 {
00058 QSettings settings;
00059 settings.setValue( "/Windows/QueryBuilder/geometry", saveGeometry() );
00060 }
00061
00062 void QgsQueryBuilder::populateFields()
00063 {
00064 for ( QgsFieldMap::const_iterator it = mLayer->pendingFields().begin(); it != mLayer->pendingFields().end(); it++ )
00065 {
00066 QStandardItem *myItem = new QStandardItem( it->name() );
00067 myItem->setData( it.key() );
00068 myItem->setEditable( false );
00069 mModelFields->insertRow( mModelFields->rowCount(), myItem );
00070 }
00071
00072
00073 setupLstFieldsModel();
00074 }
00075
00076 void QgsQueryBuilder::setupLstFieldsModel()
00077 {
00078 lstFields->setModel( mModelFields );
00079 }
00080
00081 void QgsQueryBuilder::setupGuiViews()
00082 {
00083
00084 mModelFields = new QStandardItemModel();
00085 mModelValues = new QStandardItemModel();
00086
00087 lstFields->setViewMode( QListView::ListMode );
00088 lstValues->setViewMode( QListView::ListMode );
00089 lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
00090 lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
00091
00092 lstFields->setUniformItemSizes( true );
00093 lstValues->setUniformItemSizes( true );
00094
00095 lstFields->setAlternatingRowColors( true );
00096 lstValues->setAlternatingRowColors( true );
00097 }
00098
00099 void QgsQueryBuilder::fillValues( int idx, int limit )
00100 {
00101
00102 mModelValues->clear();
00103
00104
00105 QList<QVariant> values;
00106 mLayer->uniqueValues( idx, values, limit );
00107
00108 QSettings settings;
00109 QString nullValue = settings.value( "qgis/nullValue", "NULL" ).toString();
00110
00111 QgsDebugMsg( QString( "nullValue: %1" ).arg( nullValue ) );
00112
00113 for ( int i = 0; i < values.size(); i++ )
00114 {
00115 QStandardItem *myItem = new QStandardItem( values[i].isNull() ? nullValue : values[i].toString() );
00116 myItem->setEditable( false );
00117 myItem->setData( values[i], Qt::UserRole + 1 );
00118 mModelValues->insertRow( mModelValues->rowCount(), myItem );
00119 QgsDebugMsg( QString( "Value is null: %1\nvalue: %2" ).arg( values[i].isNull() ).arg( values[i].isNull() ? nullValue : values[i].toString() ) );
00120 }
00121 }
00122
00123 void QgsQueryBuilder::on_btnSampleValues_clicked()
00124 {
00125 lstValues->setCursor( Qt::WaitCursor );
00126
00127
00128 QStandardItemModel *tmp = new QStandardItemModel();
00129 lstValues->setModel( tmp );
00130
00131 fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), 25 );
00132 lstValues->setModel( mModelValues );
00133 lstValues->setCursor( Qt::ArrowCursor );
00134
00135 delete tmp;
00136
00137 }
00138
00139 void QgsQueryBuilder::on_btnGetAllValues_clicked()
00140 {
00141 lstValues->setCursor( Qt::WaitCursor );
00142
00143
00144 QStandardItemModel *tmp = new QStandardItemModel();
00145 lstValues->setModel( tmp );
00146
00147 fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), -1 );
00148 lstValues->setModel( mModelValues );
00149 lstValues->setCursor( Qt::ArrowCursor );
00150
00151 delete tmp;
00152 }
00153
00154 void QgsQueryBuilder::test()
00155 {
00156
00157
00158
00159
00160 if ( mLayer->setSubsetString( txtSQL->toPlainText() ) )
00161 {
00162 QMessageBox::information( this,
00163 tr( "Query Result" ),
00164 tr( "The where clause returned %n row(s).", "returned test rows", mLayer->featureCount() ) );
00165 }
00166 else if ( mLayer->dataProvider()->hasErrors() )
00167 {
00168 QMessageBox::warning( this,
00169 tr( "Query Failed" ),
00170 tr( "An error occurred when executing the query." )
00171 + tr( "\nThe data provider said:\n%1" ).arg( mLayer->dataProvider()->errors().join( "\n" ) ) );
00172 mLayer->dataProvider()->clearErrors();
00173 }
00174 else
00175 {
00176 QMessageBox::warning( this,
00177 tr( "Query Failed" ),
00178 tr( "An error occurred when executing the query." ) );
00179 }
00180 }
00181
00182 void QgsQueryBuilder::accept()
00183 {
00184
00185 if ( !txtSQL->toPlainText().trimmed().isEmpty() )
00186 {
00187 if ( !mLayer->setSubsetString( txtSQL->toPlainText() ) )
00188 {
00189
00190 if ( mLayer->dataProvider()->hasErrors() )
00191 {
00192 QMessageBox::warning( this,
00193 tr( "Query Failed" ),
00194 tr( "An error occurred when executing the query." )
00195 + tr( "\nThe data provider said:\n%1" ).arg( mLayer->dataProvider()->errors().join( "\n" ) ) );
00196 mLayer->dataProvider()->clearErrors();
00197 }
00198 else
00199 {
00200 QMessageBox::warning( this, tr( "Error in Query" ), tr( "The subset string could not be set" ) );
00201 }
00202 return;
00203 }
00204 }
00205
00206 QDialog::accept();
00207 }
00208
00209 void QgsQueryBuilder::reject()
00210 {
00211 if ( mLayer->subsetString() != mOrigSubsetString )
00212 mLayer->setSubsetString( mOrigSubsetString );
00213
00214 QDialog::reject();
00215 }
00216
00217 void QgsQueryBuilder::on_btnEqual_clicked()
00218 {
00219 txtSQL->insertPlainText( " = " );
00220 }
00221
00222 void QgsQueryBuilder::on_btnLessThan_clicked()
00223 {
00224 txtSQL->insertPlainText( " < " );
00225 }
00226
00227 void QgsQueryBuilder::on_btnGreaterThan_clicked()
00228 {
00229 txtSQL->insertPlainText( " > " );
00230 }
00231
00232 void QgsQueryBuilder::on_btnPct_clicked()
00233 {
00234 txtSQL->insertPlainText( "%" );
00235 }
00236
00237 void QgsQueryBuilder::on_btnIn_clicked()
00238 {
00239 txtSQL->insertPlainText( " IN " );
00240 }
00241
00242 void QgsQueryBuilder::on_btnNotIn_clicked()
00243 {
00244 txtSQL->insertPlainText( " NOT IN " );
00245 }
00246
00247 void QgsQueryBuilder::on_btnLike_clicked()
00248 {
00249 txtSQL->insertPlainText( " LIKE " );
00250 }
00251
00252 QString QgsQueryBuilder::sql()
00253 {
00254 return txtSQL->toPlainText();
00255 }
00256
00257 void QgsQueryBuilder::setSql( QString sqlStatement )
00258 {
00259 txtSQL->setText( sqlStatement );
00260 }
00261
00262 void QgsQueryBuilder::on_lstFields_clicked( const QModelIndex &index )
00263 {
00264 if ( mPreviousFieldRow != index.row() )
00265 {
00266 mPreviousFieldRow = index.row();
00267
00268 btnSampleValues->setEnabled( true );
00269 btnGetAllValues->setEnabled( true );
00270
00271 mModelValues->clear();
00272 }
00273 }
00274
00275 void QgsQueryBuilder::on_lstFields_doubleClicked( const QModelIndex &index )
00276 {
00277 txtSQL->insertPlainText( "\"" + mLayer->pendingFields()[ mModelFields->data( index, Qt::UserRole+1 ).toInt()].name() + "\"" );
00278 }
00279
00280 void QgsQueryBuilder::on_lstValues_doubleClicked( const QModelIndex &index )
00281 {
00282 QVariant value = mModelValues->data( index, Qt::UserRole + 1 );
00283 if ( value.isNull() )
00284 txtSQL->insertPlainText( "NULL" );
00285 else if ( value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong )
00286 txtSQL->insertPlainText( value.toString() );
00287 else
00288 txtSQL->insertPlainText( "'" + value.toString().replace( "'", "''" ) + "'" );
00289 }
00290
00291 void QgsQueryBuilder::on_btnLessEqual_clicked()
00292 {
00293 txtSQL->insertPlainText( " <= " );
00294 }
00295
00296 void QgsQueryBuilder::on_btnGreaterEqual_clicked()
00297 {
00298 txtSQL->insertPlainText( " >= " );
00299 }
00300
00301 void QgsQueryBuilder::on_btnNotEqual_clicked()
00302 {
00303 txtSQL->insertPlainText( " != " );
00304 }
00305
00306 void QgsQueryBuilder::on_btnAnd_clicked()
00307 {
00308 txtSQL->insertPlainText( " AND " );
00309 }
00310
00311 void QgsQueryBuilder::on_btnNot_clicked()
00312 {
00313 txtSQL->insertPlainText( " NOT " );
00314 }
00315
00316 void QgsQueryBuilder::on_btnOr_clicked()
00317 {
00318 txtSQL->insertPlainText( " OR " );
00319 }
00320
00321 void QgsQueryBuilder::clear()
00322 {
00323 txtSQL->clear();
00324 mLayer->setSubsetString( "" );
00325 }
00326
00327 void QgsQueryBuilder::on_btnILike_clicked()
00328 {
00329 txtSQL->insertPlainText( " ILIKE " );
00330 }
00331 void QgsQueryBuilder::setDatasourceDescription( QString uri )
00332 {
00333 lblDataUri->setText( uri );
00334 }