Skip to content

Commit

Permalink
Committed patch from ticket #897 - port pg and attribute search dialo…
Browse files Browse the repository at this point in the history
…gs to qt4

git-svn-id: http://svn.osgeo.org/qgis/trunk@7933 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
timlinux committed Jan 11, 2008
1 parent a53cc5d commit 5e59df4
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 94 deletions.
93 changes: 63 additions & 30 deletions src/app/qgspgquerybuilder.cpp
Expand Up @@ -14,8 +14,8 @@
***************************************************************************/
/* $Id$ */
#include <iostream>
#include <q3listbox.h>
#include <QMessageBox>
#include <QListView>
#include "qgspgquerybuilder.h"
#include <qgslogger.h>
#include <QRegExp>
Expand All @@ -24,6 +24,7 @@ QgsPgQueryBuilder::QgsPgQueryBuilder(QWidget *parent, Qt::WFlags fl)
: QDialog(parent, fl)
{
setupUi(this);
setupListViews();
}
// constructor used when the query builder must make its own
// connection to the database
Expand All @@ -32,6 +33,7 @@ QgsPgQueryBuilder::QgsPgQueryBuilder(QgsDataSourceURI *uri,
: QDialog(parent, fl), mUri(uri)
{
setupUi(this);
setupListViews();
// The query builder must make its own connection to the database when
// using this constructor
QString connInfo = mUri->connInfo();
Expand Down Expand Up @@ -69,6 +71,7 @@ QgsPgQueryBuilder::QgsPgQueryBuilder(QString tableName, PGconn *con,
: QDialog(parent, fl), mPgConnection(con)
{
setupUi(this);
setupListViews();
mOwnConnection = false; // we don't own this connection since it was passed to us
mUri = new QgsDataSourceURI( "table=" + tableName);
QString datasource = QString(tr("Table <b>%1</b> in database <b>%2</b> on host <b>%3</b>, user <b>%4</b>"))
Expand Down Expand Up @@ -133,7 +136,9 @@ void QgsPgQueryBuilder::populateFields()
#endif
QVariant::Type type = QVariant::String; // TODO: should be set correctly [MD]
mFieldMap[fieldName] = QgsField(fieldName, type, fieldType);
lstFields->insertItem(fieldName);
QStandardItem *myItem = new QStandardItem(fieldName);
myItem->setEditable(false);
mModelFields->insertRow(mModelFields->rowCount(),myItem);
}
}
else
Expand All @@ -143,21 +148,39 @@ void QgsPgQueryBuilder::populateFields()
PQclear(result);
}

void QgsPgQueryBuilder::setupListViews()
{
//Models
mModelFields = new QStandardItemModel();
mModelValues = new QStandardItemModel();
lstFields->setModel(mModelFields);
lstValues->setModel(mModelValues);
// 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);
}

void QgsPgQueryBuilder::on_btnSampleValues_clicked()
{
if (lstFields->currentText().isEmpty())
QString myFieldName = mModelFields->data(lstFields->currentIndex()).toString();
if (myFieldName.isEmpty())
return;

QString sql = "SELECT DISTINCT \"" + lstFields->currentText() + "\" " +
"FROM (SELECT \"" + lstFields->currentText() + "\" " +
QString sql = "SELECT DISTINCT \"" + myFieldName + "\" " +
"FROM (SELECT \"" + myFieldName + "\" " +
"FROM " + mUri->quotedTablename() + " " +
"LIMIT 5000) AS foo " +
"ORDER BY \"" + lstFields->currentText() + "\" "+
"ORDER BY \"" + myFieldName + "\" "+
"LIMIT 25";
// clear the values list
lstValues->clear();
mModelValues->clear();
// determine the field type
QgsField field = mFieldMap[lstFields->currentText()];
QgsField field = mFieldMap[myFieldName];
bool isCharField = field.typeName().find("char") > -1;
PGresult *result = PQexec(mPgConnection, (const char *) (sql.utf8()));

Expand All @@ -169,14 +192,12 @@ void QgsPgQueryBuilder::on_btnSampleValues_clicked()
QString value = QString::fromUtf8(PQgetvalue(result, i, 0));
if(isCharField)
{
lstValues->insertItem("'" + value + "'");
}
else
{
lstValues->insertItem(value);
value = "'" + value + "'";
}
QStandardItem *myItem = new QStandardItem(value);
myItem->setEditable(false);
mModelValues->insertRow(mModelValues->rowCount(),myItem);
}

}else
{
QMessageBox::warning(this, tr("Database error"), tr("<p>Failed to get sample of field values using SQL:</p><p>") + sql + "</p><p>Error message was: "+ QString(PQerrorMessage(mPgConnection)) + "</p>");
Expand All @@ -187,36 +208,48 @@ void QgsPgQueryBuilder::on_btnSampleValues_clicked()

void QgsPgQueryBuilder::on_btnGetAllValues_clicked()
{
if (lstFields->currentText().isEmpty())
QString myFieldName = mModelFields->data(lstFields->currentIndex()).toString();
if (myFieldName.isEmpty())
return;

QString sql = "select distinct \"" + lstFields->currentText()
+ "\" from " + mUri->quotedTablename() + " order by \"" + lstFields->currentText() + "\"";
QString sql = "select distinct \"" + myFieldName
+ "\" from " + mUri->quotedTablename() + " order by \"" + myFieldName + "\"";
// clear the values list
lstValues->clear();
mModelValues->clear();
// determine the field type
QgsField field = mFieldMap[lstFields->currentText()];
QgsField field = mFieldMap[myFieldName];
bool isCharField = field.typeName().find("char") > -1;

PGresult *result = PQexec(mPgConnection, (const char *) (sql.utf8()));

if (PQresultStatus(result) == PGRES_TUPLES_OK)
{
int rowCount = PQntuples(result);

lstValues->setCursor(Qt::WaitCursor);
// Block for better performance
mModelValues->blockSignals(true);
lstValues->setUpdatesEnabled(false);

for(int i=0; i < rowCount; i++)
{
QString value = QString::fromUtf8(PQgetvalue(result, i, 0));

if(isCharField)
{
lstValues->insertItem("'" + value + "'");
}
else
{
lstValues->insertItem(value);
value = "'" + value + "'";
}
QStandardItem *myItem = new QStandardItem(value);
myItem->setEditable(false);
mModelValues->insertRow(mModelValues->rowCount(),myItem);
}


// Unblock for normal use
mModelValues->blockSignals(false);
lstValues->setUpdatesEnabled(true);
// TODO: already sorted, signal emit to refresh model
mModelValues->sort(0);
lstValues->setCursor(Qt::ArrowCursor);

}else
{
QMessageBox::warning(this, tr("Database error"), tr("Failed to get sample of field values") + QString(PQerrorMessage(mPgConnection)) );
Expand Down Expand Up @@ -365,14 +398,14 @@ void QgsPgQueryBuilder::setSql( QString sqlStatement)
txtSQL->setText(sqlStatement);
}

void QgsPgQueryBuilder::on_lstFields_doubleClicked( Q3ListBoxItem *item )
void QgsPgQueryBuilder::on_lstFields_doubleClicked( const QModelIndex &index )
{
txtSQL->insert("\"" + item->text() + "\"");
txtSQL->insert("\"" + mModelFields->data(index).toString() + "\"");
}

void QgsPgQueryBuilder::on_lstValues_doubleClicked( Q3ListBoxItem *item )
void QgsPgQueryBuilder::on_lstValues_doubleClicked( const QModelIndex &index )
{
txtSQL->insert(item->text());
txtSQL->insert(mModelValues->data(index).toString());
}

void QgsPgQueryBuilder::on_btnLessEqual_clicked()
Expand Down
17 changes: 13 additions & 4 deletions src/app/qgspgquerybuilder.h
Expand Up @@ -20,7 +20,9 @@ extern "C"
{
#include <libpq-fe.h>
}

#include <QStandardItemModel>
#include <QStandardItem>
#include <QModelIndex>
#include "ui_qgspgquerybuilderbase.h"
#include "qgisgui.h"
#include "qgsfield.h"
Expand Down Expand Up @@ -85,8 +87,8 @@ class QgsPgQueryBuilder : public QDialog, private Ui::QgsPgQueryBuilderBase {
void on_btnILike_clicked();
QString sql();
void setSql( QString sqlStatement);
void on_lstFields_doubleClicked( Q3ListBoxItem *item );
void on_lstValues_doubleClicked( Q3ListBoxItem *item );
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();
Expand Down Expand Up @@ -118,6 +120,10 @@ class QgsPgQueryBuilder : public QDialog, private Ui::QgsPgQueryBuilderBase {
* Populate the field list for the selected table
*/
void populateFields();
/*!
* Setup models for listviews
*/
void setupListViews();

/*! Get the number of records that would be returned by the current SQL
* @return Number of records or -1 if an error was encountered
Expand All @@ -139,6 +145,9 @@ class QgsPgQueryBuilder : public QDialog, private Ui::QgsPgQueryBuilderBase {
QString mPgErrorMessage;
//! Flag to indicate if the class owns the connection to the pg database
bool mOwnConnection;

//! Model for fields ListView
QStandardItemModel *mModelFields;
//! Model for values ListView
QStandardItemModel *mModelValues;
};
#endif //QGSPGQUERYBUILDER_H
67 changes: 54 additions & 13 deletions src/app/qgssearchquerybuilder.cpp
Expand Up @@ -15,8 +15,9 @@
/* $Id$ */

#include <iostream>
#include <q3listbox.h>
#include <QListView>
#include <QMessageBox>
#include <QStandardItem>
#include "qgsfeature.h"
#include "qgsfield.h"
#include "qgssearchquerybuilder.h"
Expand All @@ -31,6 +32,7 @@ QgsSearchQueryBuilder::QgsSearchQueryBuilder(QgsVectorLayer* layer,
: QDialog(parent, fl), mLayer(layer)
{
setupUi(this);
setupListViews();

setWindowTitle(tr("Search query builder"));

Expand All @@ -53,25 +55,49 @@ QgsSearchQueryBuilder::~QgsSearchQueryBuilder()

void QgsSearchQueryBuilder::populateFields()
{
#ifdef QGISDEBUG
std::cout << "QgsSearchQueryBuilder::populateFields" << std::endl;
#endif
const QgsFieldMap& fields = mLayer->getDataProvider()->fields();
for (QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it)
{
QString fieldName = it->name();

mFieldMap[fieldName] = it.key();
lstFields->insertItem(fieldName);
QStandardItem *myItem = new QStandardItem(fieldName);
myItem->setEditable(false);
mModelFields->insertRow(mModelFields->rowCount(),myItem);
}
}

void QgsSearchQueryBuilder::setupListViews()
{
#ifdef QGISDEBUG
std::cout << "QgsSearchQueryBuilder::setupListViews" << std::endl;
#endif
//Models
mModelFields = new QStandardItemModel();
mModelValues = new QStandardItemModel();
lstFields->setModel(mModelFields);
lstValues->setModel(mModelValues);
// 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);
}

void QgsSearchQueryBuilder::getFieldValues(uint limit)
{
// clear the values list
lstValues->clear();
mModelValues->clear();

QgsVectorDataProvider* provider = mLayer->getDataProvider();

// determine the field type
QString fieldName = lstFields->currentText();
QString fieldName = mModelFields->data(lstFields->currentIndex()).toString();
int fieldIndex = mFieldMap[fieldName];
QgsField field = provider->fields()[fieldIndex];
bool numeric = (field.type() == QVariant::Int || field.type() == QVariant::Double);
Expand All @@ -84,8 +110,13 @@ void QgsSearchQueryBuilder::getFieldValues(uint limit)

provider->select(attrs, QgsRect(), false);

lstValues->setCursor(Qt::WaitCursor);
// Block for better performance
mModelValues->blockSignals(true);
lstValues->setUpdatesEnabled(false);

while (provider->getNextFeature(feat) &&
(limit == 0 || lstValues->count() != limit))
(limit == 0 || mModelValues->rowCount() != limit))
{
const QgsAttributeMap& attributes = feat.attributeMap();
value = attributes[fieldIndex].toString();
Expand All @@ -97,10 +128,20 @@ void QgsSearchQueryBuilder::getFieldValues(uint limit)
}

// add item only if it's not there already
if (lstValues->findItem(value) == 0)
lstValues->insertItem(value);

QList<QStandardItem *> items = mModelValues->findItems(value);
if (items.isEmpty())
{
QStandardItem *myItem = new QStandardItem(value);
myItem->setEditable(false);
mModelValues->insertRow(mModelValues->rowCount(),myItem);
}
}
// Unblock for normal use
mModelValues->blockSignals(false);
lstValues->setUpdatesEnabled(true);
// TODO: already sorted, signal emit to refresh model
mModelValues->sort(0);
lstValues->setCursor(Qt::ArrowCursor);
}

void QgsSearchQueryBuilder::on_btnSampleValues_clicked()
Expand Down Expand Up @@ -245,14 +286,14 @@ void QgsSearchQueryBuilder::setSearchString(QString searchString)
txtSQL->setText(searchString);
}

void QgsSearchQueryBuilder::on_lstFields_doubleClicked( Q3ListBoxItem *item )
void QgsSearchQueryBuilder::on_lstFields_doubleClicked( const QModelIndex &index )
{
txtSQL->insert(item->text());
txtSQL->insert(mModelFields->data(index).toString());
}

void QgsSearchQueryBuilder::on_lstValues_doubleClicked( Q3ListBoxItem *item )
void QgsSearchQueryBuilder::on_lstValues_doubleClicked( const QModelIndex &index )
{
txtSQL->insert(item->text());
txtSQL->insert(mModelValues->data(index).toString());
}

void QgsSearchQueryBuilder::on_btnLessEqual_clicked()
Expand Down

0 comments on commit 5e59df4

Please sign in to comment.