Quantum GIS API Documentation  1.8
src/gui/qgsquerybuilder.cpp
Go to the documentation of this file.
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   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   // All fields get ... setup
00073   setupLstFieldsModel();
00074 }
00075 
00076 void QgsQueryBuilder::setupLstFieldsModel()
00077 {
00078   lstFields->setModel( mModelFields );
00079 }
00080 
00081 void QgsQueryBuilder::setupGuiViews()
00082 {
00083   //Initialize the models
00084   mModelFields = new QStandardItemModel();
00085   mModelValues = new QStandardItemModel();
00086   // Modes
00087   lstFields->setViewMode( QListView::ListMode );
00088   lstValues->setViewMode( QListView::ListMode );
00089   lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
00090   lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
00091   // Performance tip since Qt 4.1
00092   lstFields->setUniformItemSizes( true );
00093   lstValues->setUniformItemSizes( true );
00094   // Colored rows
00095   lstFields->setAlternatingRowColors( true );
00096   lstValues->setAlternatingRowColors( true );
00097 }
00098 
00099 void QgsQueryBuilder::fillValues( int idx, int limit )
00100 {
00101   // clear the model
00102   mModelValues->clear();
00103 
00104   // determine the field type
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   //delete connection mModelValues and lstValues
00128   QStandardItemModel *tmp = new QStandardItemModel();
00129   lstValues->setModel( tmp );
00130   //Clear and fill the mModelValues
00131   fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), 25 );
00132   lstValues->setModel( mModelValues );
00133   lstValues->setCursor( Qt::ArrowCursor );
00134   //delete the tmp
00135   delete tmp;
00136 
00137 }
00138 
00139 void QgsQueryBuilder::on_btnGetAllValues_clicked()
00140 {
00141   lstValues->setCursor( Qt::WaitCursor );
00142 
00143   //delete connection mModelValues and lstValues
00144   QStandardItemModel *tmp = new QStandardItemModel();
00145   lstValues->setModel( tmp );
00146   //Clear and fill the mModelValues
00147   fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), -1 );
00148   lstValues->setModel( mModelValues );
00149   lstValues->setCursor( Qt::ArrowCursor );
00150   //delete the tmp
00151   delete tmp;
00152 }
00153 
00154 void QgsQueryBuilder::test()
00155 {
00156   // test the sql statement to see if it works
00157   // by counting the number of records that would be
00158   // returned
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   if ( !mLayer->setSubsetString( txtSQL->toPlainText() ) )
00185   {
00186     //error in query - show the problem
00187     if ( mLayer->dataProvider()->hasErrors() )
00188     {
00189       QMessageBox::warning( this,
00190                             tr( "Query Failed" ),
00191                             tr( "An error occurred when executing the query." )
00192                             + tr( "\nThe data provider said:\n%1" ).arg( mLayer->dataProvider()->errors().join( "\n" ) ) );
00193       mLayer->dataProvider()->clearErrors();
00194     }
00195     else
00196     {
00197       QMessageBox::warning( this, tr( "Error in Query" ), tr( "The subset string could not be set" ) );
00198     }
00199 
00200     return;
00201   }
00202 
00203   QDialog::accept();
00204 }
00205 
00206 void QgsQueryBuilder::reject()
00207 {
00208   if ( mLayer->subsetString() != mOrigSubsetString )
00209     mLayer->setSubsetString( mOrigSubsetString );
00210 
00211   QDialog::reject();
00212 }
00213 
00214 void QgsQueryBuilder::on_btnEqual_clicked()
00215 {
00216   txtSQL->insertPlainText( " = " );
00217 }
00218 
00219 void QgsQueryBuilder::on_btnLessThan_clicked()
00220 {
00221   txtSQL->insertPlainText( " < " );
00222 }
00223 
00224 void QgsQueryBuilder::on_btnGreaterThan_clicked()
00225 {
00226   txtSQL->insertPlainText( " > " );
00227 }
00228 
00229 void QgsQueryBuilder::on_btnPct_clicked()
00230 {
00231   txtSQL->insertPlainText( "%" );
00232 }
00233 
00234 void QgsQueryBuilder::on_btnIn_clicked()
00235 {
00236   txtSQL->insertPlainText( " IN " );
00237 }
00238 
00239 void QgsQueryBuilder::on_btnNotIn_clicked()
00240 {
00241   txtSQL->insertPlainText( " NOT IN " );
00242 }
00243 
00244 void QgsQueryBuilder::on_btnLike_clicked()
00245 {
00246   txtSQL->insertPlainText( " LIKE " );
00247 }
00248 
00249 QString QgsQueryBuilder::sql()
00250 {
00251   return txtSQL->toPlainText();
00252 }
00253 
00254 void QgsQueryBuilder::setSql( QString sqlStatement )
00255 {
00256   txtSQL->setText( sqlStatement );
00257 }
00258 
00259 void QgsQueryBuilder::on_lstFields_clicked( const QModelIndex &index )
00260 {
00261   if ( mPreviousFieldRow != index.row() )
00262   {
00263     mPreviousFieldRow = index.row();
00264 
00265     btnSampleValues->setEnabled( true );
00266     btnGetAllValues->setEnabled( true );
00267 
00268     mModelValues->clear();
00269   }
00270 }
00271 
00272 void QgsQueryBuilder::on_lstFields_doubleClicked( const QModelIndex &index )
00273 {
00274   txtSQL->insertPlainText( "\"" + mLayer->pendingFields()[ mModelFields->data( index, Qt::UserRole+1 ).toInt()].name() + "\"" );
00275 }
00276 
00277 void QgsQueryBuilder::on_lstValues_doubleClicked( const QModelIndex &index )
00278 {
00279   QVariant value = mModelValues->data( index, Qt::UserRole + 1 );
00280   if ( value.isNull() )
00281     txtSQL->insertPlainText( "NULL" );
00282   else if ( value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong )
00283     txtSQL->insertPlainText( value.toString() );
00284   else
00285     txtSQL->insertPlainText( "'" + value.toString().replace( "'", "''" ) + "'" );
00286 }
00287 
00288 void QgsQueryBuilder::on_btnLessEqual_clicked()
00289 {
00290   txtSQL->insertPlainText( " <= " );
00291 }
00292 
00293 void QgsQueryBuilder::on_btnGreaterEqual_clicked()
00294 {
00295   txtSQL->insertPlainText( " >= " );
00296 }
00297 
00298 void QgsQueryBuilder::on_btnNotEqual_clicked()
00299 {
00300   txtSQL->insertPlainText( " != " );
00301 }
00302 
00303 void QgsQueryBuilder::on_btnAnd_clicked()
00304 {
00305   txtSQL->insertPlainText( " AND " );
00306 }
00307 
00308 void QgsQueryBuilder::on_btnNot_clicked()
00309 {
00310   txtSQL->insertPlainText( " NOT " );
00311 }
00312 
00313 void QgsQueryBuilder::on_btnOr_clicked()
00314 {
00315   txtSQL->insertPlainText( " OR " );
00316 }
00317 
00318 void QgsQueryBuilder::clear()
00319 {
00320   txtSQL->clear();
00321   mLayer->setSubsetString( "" );
00322 }
00323 
00324 void QgsQueryBuilder::on_btnILike_clicked()
00325 {
00326   txtSQL->insertPlainText( " ILIKE " );
00327 }
00328 void QgsQueryBuilder::setDatasourceDescription( QString uri )
00329 {
00330   lblDataUri->setText( uri );
00331 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines