- replace SaQueryBuilder with QgsQueryBuilder

- replace SaDbFilterProxyModel with QgsDbFilterProxyModel
- remove spurious copy of QgsDbFilterProxyModel from postgres provider
- fix #4491
This commit is contained in:
Juergen E. Fischer 2012-05-26 10:01:36 +02:00
parent 3c6f91706c
commit ed70b941e8
10 changed files with 18 additions and 705 deletions

View File

@ -181,26 +181,23 @@ void QgsQueryBuilder::test()
void QgsQueryBuilder::accept()
{
// if user hits Ok and there is no query, skip the validation
if ( !txtSQL->toPlainText().trimmed().isEmpty() )
if ( !mLayer->setSubsetString( txtSQL->toPlainText() ) )
{
if ( !mLayer->setSubsetString( txtSQL->toPlainText() ) )
//error in query - show the problem
if ( mLayer->dataProvider()->hasErrors() )
{
//error in query - show the problem
if ( mLayer->dataProvider()->hasErrors() )
{
QMessageBox::warning( this,
tr( "Query Failed" ),
tr( "An error occurred when executing the query." )
+ tr( "\nThe data provider said:\n%1" ).arg( mLayer->dataProvider()->errors().join( "\n" ) ) );
mLayer->dataProvider()->clearErrors();
}
else
{
QMessageBox::warning( this, tr( "Error in Query" ), tr( "The subset string could not be set" ) );
}
return;
QMessageBox::warning( this,
tr( "Query Failed" ),
tr( "An error occurred when executing the query." )
+ tr( "\nThe data provider said:\n%1" ).arg( mLayer->dataProvider()->errors().join( "\n" ) ) );
mLayer->dataProvider()->clearErrors();
}
else
{
QMessageBox::warning( this, tr( "Error in Query" ), tr( "The subset string could not be set" ) );
}
return;
}
QDialog::accept();

View File

@ -6,8 +6,6 @@ SET (sqlanywhere_SRCS
sasourceselect.cpp
sanewconnection.cpp
sadbtablemodel.cpp
sadbfilterproxymodel.cpp
saquerybuilder.cpp
)
SET (sqlanywhere_UIS
@ -21,7 +19,6 @@ SET (sqlanywhere_MOC_HDRS
sanewconnection.h
salayer.h
sadbtablemodel.h
saquerybuilder.h
)
SET (sqlanywhere_RCCS sqlanywhere.qrc)

View File

@ -1,63 +0,0 @@
/***************************************************************************
sadbfilterproxymodel.cpp
A class that implements a custom filter and can be used as a proxy for SaDbTableModel
-------------------
begin : Dec 2010
copyright : (C) 2010 by iAnywhere Solutions, Inc.
author : David DeHaan
email : ddehaan at sybase dot com
This class was copied and modified from QgsDbFilterProxyModel because that
class is not accessible to QGIS plugins. Therefore, the author gratefully
acknowledges the following copyright on the original content:
qgsdbfilterproxymodel.cpp
begin : Dec 2007
copyright : (C) 2007 by Marco Hugentobler
email : marco dot hugentobler at karto dot baug dot ethz dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "sadbfilterproxymodel.h"
SaDbFilterProxyModel::SaDbFilterProxyModel( QObject* parent ): QSortFilterProxyModel( parent )
{
}
SaDbFilterProxyModel::~SaDbFilterProxyModel()
{
}
bool SaDbFilterProxyModel::filterAcceptsRow( int row, const QModelIndex & source_parent ) const
{
//if parent is valid, we have a toplevel item that should be always shown
if ( !source_parent.isValid() )
{
return true;
}
//else we have a row that describes a table and that
//should be tested using the given wildcard/regexp
return QSortFilterProxyModel::filterAcceptsRow( row, source_parent );
}
void SaDbFilterProxyModel::_setFilterWildcard( const QString& pattern )
{
QSortFilterProxyModel::setFilterWildcard( pattern );
emit layoutChanged();
}
void SaDbFilterProxyModel::_setFilterRegExp( const QString& pattern )
{
QSortFilterProxyModel::setFilterRegExp( pattern );
emit layoutChanged();
}

View File

@ -1,47 +0,0 @@
/***************************************************************************
sadbfilterproxymodel.h
A class that implements a custom filter and can be used as a proxy for SaDbTableModel
-------------------
begin : Dec 2010
copyright : (C) 2010 by iAnywhere Solutions, Inc.
author : David DeHaan
email : ddehaan at sybase dot com
This class was copied and modified from QgsDbFilterProxyModel because that
class is not accessible to QGIS plugins. Therefore, the author gratefully
acknowledges the following copyright on the original content:
qgsdbfilterproxymodel.h
begin : Dec 2007
copyright : (C) 2007 by Marco Hugentobler
email : marco dot hugentobler at karto dot baug dot ethz dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef SADBFILTERPROXYMODEL_H
#define SADBFILTERPROXYMODEL_H
#include <QSortFilterProxyModel>
/**A class that implements a custom filter and can be used
as a proxy for SaDbTableModel*/
class SaDbFilterProxyModel: public QSortFilterProxyModel
{
public:
SaDbFilterProxyModel( QObject* parent = 0 );
~SaDbFilterProxyModel();
/**Calls QSortFilterProxyModel::setFilterWildcard and triggers update*/
void _setFilterWildcard( const QString& pattern );
/**Calls QSortFilterProxyModel::setFilterRegExp and triggers update*/
void _setFilterRegExp( const QString& pattern );
protected:
virtual bool filterAcceptsRow( int row, const QModelIndex & source_parent ) const;
};
#endif // SADBFILTERPROXYMODEL_H

View File

@ -1,331 +0,0 @@
/***************************************************************************
saquerybuilder.cpp
Query builder for layers backed by SQL Anywhere database.
-------------------
begin : Dec 2010
copyright : (C) 2010 by iAnywhere Solutions, Inc.
author : David DeHaan
email : ddehaan at sybase dot com
This class was copied and modified from QgsQueryBuilder because that
class is not accessible to QGIS plugins. Therefore, the author gratefully
acknowledges the following copyright on the original content:
qgsquerybuilder.cpp
Date : 2004-11-19
Copyright : (C) 2004 by Gary E.Sherman
Email : sherman at mrcc.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "saquerybuilder.h"
#include "qgslogger.h"
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"
#include <QListView>
#include <QMessageBox>
#include <QRegExp>
#include <QPushButton>
// constructor used when the query builder must make its own
// connection to the database
SaQueryBuilder::SaQueryBuilder( QgsVectorLayer *layer,
QWidget *parent, Qt::WFlags fl )
: QDialog( parent, fl ), mLayer( layer )
{
setupUi( this );
connect( buttonBox, SIGNAL( helpRequested() ), this, SLOT( helpClicked() ) );
QPushButton *pbn = new QPushButton( tr( "&Test" ) );
buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
connect( pbn, SIGNAL( clicked() ), this, SLOT( test() ) );
pbn = new QPushButton( tr( "&Clear" ) );
buttonBox->addButton( pbn, QDialogButtonBox::ActionRole );
connect( pbn, SIGNAL( clicked() ), this, SLOT( clear() ) );
// remove the ILIKE button since ILIKE is a PostgreSQL special
// not supported by SQL Anywhere
btnILike->setVisible( false );
setupGuiViews();
mOrigSubsetString = layer->subsetString();
lblDataUri->setText( layer->publicSource() );
txtSQL->setText( mOrigSubsetString );
populateFields();
}
SaQueryBuilder::~SaQueryBuilder()
{
}
void SaQueryBuilder::populateFields()
{
for ( QgsFieldMap::const_iterator it = mLayer->pendingFields().begin(); it != mLayer->pendingFields().end(); it++ )
{
QStandardItem *myItem = new QStandardItem( it->name() );
myItem->setData( it.key() );
myItem->setEditable( false );
mModelFields->insertRow( mModelFields->rowCount(), myItem );
}
// All fields get ... setup
setupLstFieldsModel();
}
void SaQueryBuilder::setupLstFieldsModel()
{
lstFields->setModel( mModelFields );
}
void SaQueryBuilder::setupGuiViews()
{
//Initialize the models
mModelFields = new QStandardItemModel();
mModelValues = new QStandardItemModel();
// Modes
lstFields->setViewMode( QListView::ListMode );
lstValues->setViewMode( QListView::ListMode );
lstFields->setSelectionBehavior( QAbstractItemView::SelectRows );
lstValues->setSelectionBehavior( QAbstractItemView::SelectRows );
// Performance tip since Qt 4.1
lstFields->setUniformItemSizes( true );
lstValues->setUniformItemSizes( true );
// Colored rows
lstFields->setAlternatingRowColors( true );
lstValues->setAlternatingRowColors( true );
}
void SaQueryBuilder::fillValues( int idx, QString subsetString, int limit )
{
// clear the model
mModelValues->clear();
if ( !mLayer->setSubsetString( subsetString ) )
{
QMessageBox::information( this, tr( "Invalid Query" ), tr( "Setting the query failed" ) );
return;
}
// determine the field type
QList<QVariant> values;
mLayer->uniqueValues( idx, values, limit );
for ( int i = 0; i < values.size(); i++ )
{
QStandardItem *myItem = new QStandardItem( values[i].toString() );
myItem->setEditable( false );
mModelValues->insertRow( mModelValues->rowCount(), myItem );
}
}
void SaQueryBuilder::on_btnSampleValues_clicked()
{
lstValues->setCursor( Qt::WaitCursor );
//delete connection mModelValues and lstValues
QStandardItemModel *tmp = new QStandardItemModel();
lstValues->setModel( tmp );
//Clear and fill the mModelValues
fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), mOrigSubsetString, 25 );
lstValues->setModel( mModelValues );
lstValues->setCursor( Qt::ArrowCursor );
//delete the tmp
delete tmp;
}
void SaQueryBuilder::on_btnGetAllValues_clicked()
{
lstValues->setCursor( Qt::WaitCursor );
//delete connection mModelValues and lstValues
QStandardItemModel *tmp = new QStandardItemModel();
lstValues->setModel( tmp );
//Clear and fill the mModelValues
fillValues( mModelFields->data( lstFields->currentIndex(), Qt::UserRole + 1 ).toInt(), mOrigSubsetString, -1 );
lstValues->setModel( mModelValues );
lstValues->setCursor( Qt::ArrowCursor );
//delete the tmp
delete tmp;
}
void SaQueryBuilder::test()
{
// test the sql statement to see if it works
// by counting the number of records that would be
// returned
// if there is no sql, issue a warning
if ( txtSQL->toPlainText().isEmpty() )
{
QMessageBox::information( this,
tr( "No Query" ),
tr( "You must create a query before you can test it" ) );
}
else if ( mLayer->setSubsetString( txtSQL->toPlainText() ) )
{
QMessageBox::information( this,
tr( "Query Result" ),
tr( "The where clause returned %n row(s).", "returned test rows", mLayer->featureCount() ) );
}
else
{
QMessageBox::warning( this,
tr( "Query Failed" ),
tr( "An error occurred when executing the query" ) );
}
}
// Slot for showing help
void SaQueryBuilder::helpClicked()
{
// QgsContextHelp::run( context_id );
}
void SaQueryBuilder::accept()
{
// if user hits Ok and there is no query, skip the validation
if ( !txtSQL->toPlainText().trimmed().isEmpty() )
{
if ( !mLayer->setSubsetString( txtSQL->toPlainText() ) )
{
//error in query - show the problem
QMessageBox::warning( this, tr( "Error in Query" ), tr( "The subset string could not be set" ) );
return;
}
}
QDialog::accept();
}
void SaQueryBuilder::reject()
{
if ( mLayer->subsetString() != mOrigSubsetString )
mLayer->setSubsetString( mOrigSubsetString );
QDialog::reject();
}
void SaQueryBuilder::on_btnEqual_clicked()
{
txtSQL->insertPlainText( " = " );
}
void SaQueryBuilder::on_btnLessThan_clicked()
{
txtSQL->insertPlainText( " < " );
}
void SaQueryBuilder::on_btnGreaterThan_clicked()
{
txtSQL->insertPlainText( " > " );
}
void SaQueryBuilder::on_btnPct_clicked()
{
txtSQL->insertPlainText( "%" );
}
void SaQueryBuilder::on_btnIn_clicked()
{
txtSQL->insertPlainText( " IN " );
}
void SaQueryBuilder::on_btnNotIn_clicked()
{
txtSQL->insertPlainText( " NOT IN " );
}
void SaQueryBuilder::on_btnLike_clicked()
{
txtSQL->insertPlainText( " LIKE " );
}
QString SaQueryBuilder::sql()
{
return txtSQL->toPlainText();
}
void SaQueryBuilder::setSql( QString sqlStatement )
{
txtSQL->setText( sqlStatement );
}
void SaQueryBuilder::on_lstFields_clicked( const QModelIndex &index )
{
if ( mPreviousFieldRow != index.row() )
{
mPreviousFieldRow = index.row();
btnSampleValues->setEnabled( true );
btnGetAllValues->setEnabled( true );
mModelValues->clear();
}
}
void SaQueryBuilder::on_lstFields_doubleClicked( const QModelIndex &index )
{
txtSQL->insertPlainText( "\"" + mLayer->pendingFields()[ mModelFields->data( index, Qt::UserRole+1 ).toInt()].name() + "\"" );
}
void SaQueryBuilder::on_lstValues_doubleClicked( const QModelIndex &index )
{
txtSQL->insertPlainText( "'" + mModelValues->data( index ).toString() + "'" );
}
void SaQueryBuilder::on_btnLessEqual_clicked()
{
txtSQL->insertPlainText( " <= " );
}
void SaQueryBuilder::on_btnGreaterEqual_clicked()
{
txtSQL->insertPlainText( " >= " );
}
void SaQueryBuilder::on_btnNotEqual_clicked()
{
txtSQL->insertPlainText( " != " );
}
void SaQueryBuilder::on_btnAnd_clicked()
{
txtSQL->insertPlainText( " AND " );
}
void SaQueryBuilder::on_btnNot_clicked()
{
txtSQL->insertPlainText( " NOT " );
}
void SaQueryBuilder::on_btnOr_clicked()
{
txtSQL->insertPlainText( " OR " );
}
void SaQueryBuilder::clear()
{
txtSQL->clear();
}
void SaQueryBuilder::on_btnILike_clicked()
{
txtSQL->insertPlainText( " ILIKE " );
}
void SaQueryBuilder::setDatasourceDescription( QString uri )
{
lblDataUri->setText( uri );
}

View File

@ -1,148 +0,0 @@
/***************************************************************************
saquerybuilder.h
Query builder for layers backed by SQL Anywhere database.
-------------------
begin : Dec 2010
copyright : (C) 2010 by iAnywhere Solutions, Inc.
author : David DeHaan
email : ddehaan at sybase dot com
This class was copied and modified from QgsQueryBuilder because that
class is not accessible to QGIS plugins. Therefore, the author gratefully
acknowledges the following copyright on the original content:
qgsquerybuilder.cpp
Date : 2004-11-19
Copyright : (C) 2004 by Gary E.Sherman
Email : sherman at mrcc.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef SAQUERYBUILDER_H
#define SAQUERYBUILDER_H
#include <map>
#include <vector>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QModelIndex>
#include "ui_qgsquerybuilderbase.h"
#include "qgisgui.h"
#include "qgsfield.h"
#include "qgscontexthelp.h"
class QgsVectorLayer;
/*!
* \class SaQueryBuilder
* \brief Query Builder for SQL Anywhere layers.
*
* The query builder allows interactive creation of a SQL for limiting the
* features displayed in a database layer. The fields in the table are
* displayed and sample values (or all values) can be viewed to aid in
* constructing the query. A test function returns the number of features that
* will be returned.
*
* This class was cloned from QgsQueryBuilder because that class is part
* of the qgis application and unfortunately cannot be linked into plugins.
*/
class SaQueryBuilder : public QDialog, private Ui::QgsQueryBuilderBase
{
Q_OBJECT
public:
//! Default constructor - not very useful
SaQueryBuilder( QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );
/*! This constructor is used when the query builder is called from the
* source selection dialog
* @param layer existing vector layer
* @param parent Parent widget
* @param fl dialog flags
*/
SaQueryBuilder( QgsVectorLayer *layer, QWidget *parent = 0,
Qt::WFlags fl = QgisGui::ModalDialogFlags );
~SaQueryBuilder();
public slots:
void accept();
void reject();
void helpClicked();
void clear();
void on_btnEqual_clicked();
void on_btnLessThan_clicked();
void on_btnGreaterThan_clicked();
void on_btnPct_clicked();
void on_btnIn_clicked();
void on_btnNotIn_clicked();
void on_btnLike_clicked();
void on_btnILike_clicked();
QString sql();
void setSql( QString sqlStatement );
void on_lstFields_clicked( const QModelIndex &index );
void on_lstFields_doubleClicked( const QModelIndex &index );
void on_lstValues_doubleClicked( const QModelIndex &index );
void on_btnLessEqual_clicked();
void on_btnGreaterEqual_clicked();
void on_btnNotEqual_clicked();
void on_btnAnd_clicked();
void on_btnNot_clicked();
void on_btnOr_clicked();
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
/*! Test the constructed sql statement to see if the database likes it.
* The number of rows that would be returned is displayed in a message box.
* The test uses a "select count(*) from ..." query to test the SQL
* statement.
* @param showResults If true, the results are displayed in a QMessageBox
*/
void test();
/*!
* Get all distinct values for the field. Values are inserted
* into the value list box
*/
void on_btnGetAllValues_clicked();
/*!
* Get sample distinct values for the selected field. The sample size is
* limited to an arbitrary value (currently set to 25). The values
* are inserted into the values list box.
*/
void on_btnSampleValues_clicked();
void setDatasourceDescription( QString uri );
private:
/*!
* Populate the field list for the selected table
*/
void populateFields();
/*!
* Setup models for listviews
*/
void setupGuiViews();
void setupLstFieldsModel();
void fillValues( int idx, QString subsetString, int limit );
// private members
//! Model for fields ListView
QStandardItemModel *mModelFields;
//! Model for values ListView
QStandardItemModel *mModelValues;
//! Previous field row to delete model
int mPreviousFieldRow;
//! vector layer
QgsVectorLayer *mLayer;
//! original subset string
QString mOrigSubsetString;
};
#endif //SAQUERYBUILDER_H

View File

@ -26,7 +26,7 @@
#include "sasourceselect.h"
#include "sanewconnection.h"
#include "saquerybuilder.h"
#include "qgsquerybuilder.h"
#include "qgisapp.h"
#include "qgslogger.h"
@ -464,7 +464,7 @@ void SaSourceSelect::setSql( const QModelIndex &index )
}
// create a query builder object
SaQueryBuilder *qb = new SaQueryBuilder( vlayer, this );
QgsQueryBuilder *qb = new QgsQueryBuilder( vlayer, this );
if ( qb->exec() )
{
mTableModel.setSql( mProxyModel.mapToSource( index ), qb->sql() );

View File

@ -28,7 +28,7 @@
#define SASOURCESELECT_H
#include "ui_sasourceselectbase.h"
#include "sadbfilterproxymodel.h"
#include "qgsdbfilterproxymodel.h"
#include "sadbtablemodel.h"
#include "sqlanyconnection.h"
#include "sqlanystatement.h"
@ -181,7 +181,7 @@ class SaSourceSelect : public QDialog, private Ui::SaSourceSelectBase
//! Model that acts as datasource for mTableTreeWidget
SaDbTableModel mTableModel;
SaDbFilterProxyModel mProxyModel;
QgsDbFilterProxyModel mProxyModel;
// button for building queries
QPushButton *mBuildQueryButton;

View File

@ -1,53 +0,0 @@
/***************************************************************************
qgsdbfilterproxymodel.cpp - description
-------------------------
begin : Dec 2007
copyright : (C) 2007 by Marco Hugentobler
email : marco dot hugentobler at karto dot baug dot ethz dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsdbfilterproxymodel.h"
QgsDbFilterProxyModel::QgsDbFilterProxyModel( QObject* parent ): QSortFilterProxyModel( parent )
{
}
QgsDbFilterProxyModel::~QgsDbFilterProxyModel()
{
}
bool QgsDbFilterProxyModel::filterAcceptsRow( int row, const QModelIndex & source_parent ) const
{
//if parent is valid, we have a toplevel item that should be always shown
if ( !source_parent.isValid() )
{
return true;
}
//else we have a row that describes a table and that
//should be tested using the given wildcard/regexp
return QSortFilterProxyModel::filterAcceptsRow( row, source_parent );
}
void QgsDbFilterProxyModel::_setFilterWildcard( const QString& pattern )
{
QSortFilterProxyModel::setFilterWildcard( pattern );
emit layoutChanged();
}
void QgsDbFilterProxyModel::_setFilterRegExp( const QString& pattern )
{
QSortFilterProxyModel::setFilterRegExp( pattern );
emit layoutChanged();
}

View File

@ -1,39 +0,0 @@
/***************************************************************************
qgsdbfilterproxymodel.h - description
-----------------------
begin : Dec 2007
copyright : (C) 2007 by Marco Hugentobler
email : marco dot hugentobler at karto dot baug dot ethz dot ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSDBFILTERPROXYMODEL_H
#define QGSDBFILTERPROXYMODEL_H
#include <QSortFilterProxyModel>
/**A class that implements a custom filter and can be used
as a proxy for QgsDbTableModel*/
class CORE_EXPORT QgsDbFilterProxyModel: public QSortFilterProxyModel
{
public:
QgsDbFilterProxyModel( QObject* parent = 0 );
~QgsDbFilterProxyModel();
/**Calls QSortFilterProxyModel::setFilterWildcard and triggers update*/
void _setFilterWildcard( const QString& pattern );
/**Calls QSortFilterProxyModel::setFilterRegExp and triggers update*/
void _setFilterRegExp( const QString& pattern );
protected:
virtual bool filterAcceptsRow( int row, const QModelIndex & source_parent ) const;
};
#endif