Index: src/app/qgspgquerybuilder.cpp =================================================================== --- src/app/qgspgquerybuilder.cpp (revisión: 7925) +++ src/app/qgspgquerybuilder.cpp (copia de trabajo) @@ -14,8 +14,8 @@ ***************************************************************************/ /* $Id$ */ #include -#include #include +#include #include "qgspgquerybuilder.h" #include #include @@ -24,6 +24,7 @@ : QDialog(parent, fl) { setupUi(this); + setupListViews(); } // constructor used when the query builder must make its own // connection to the database @@ -32,6 +33,7 @@ : 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(); @@ -69,6 +71,7 @@ : 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 %1 in database %2 on host %3, user %4")) @@ -133,7 +136,9 @@ #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 @@ -143,21 +148,39 @@ 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())); @@ -169,14 +192,12 @@ QString value = QString::fromUtf8(PQgetvalue(result, i, 0)); if(isCharField) { - lstValues->insertItem("'" + value + "'"); + value = "'" + value + "'"; } - else - { - lstValues->insertItem(value); - } + QStandardItem *myItem = new QStandardItem(value); + myItem->setEditable(false); + mModelValues->insertRow(mModelValues->rowCount(),myItem); } - }else { QMessageBox::warning(this, tr("Database error"), tr("

Failed to get sample of field values using SQL:

") + sql + "

Error message was: "+ QString(PQerrorMessage(mPgConnection)) + "

"); @@ -187,15 +208,16 @@ 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())); @@ -203,20 +225,31 @@ 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 + "'"); + value = "'" + value + "'"; } - else - { - lstValues->insertItem(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)) ); @@ -365,14 +398,14 @@ 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() Index: src/app/qgspgquerybuilder.h =================================================================== --- src/app/qgspgquerybuilder.h (revisión: 7925) +++ src/app/qgspgquerybuilder.h (copia de trabajo) @@ -20,7 +20,9 @@ { #include } - +#include +#include +#include #include "ui_qgspgquerybuilderbase.h" #include "qgisgui.h" #include "qgsfield.h" @@ -85,8 +87,8 @@ 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(); @@ -118,6 +120,10 @@ * 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 @@ -139,6 +145,9 @@ 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 Index: src/app/qgssearchquerybuilder.cpp =================================================================== --- src/app/qgssearchquerybuilder.cpp (revisión: 7925) +++ src/app/qgssearchquerybuilder.cpp (copia de trabajo) @@ -15,8 +15,9 @@ /* $Id$ */ #include -#include +#include #include +#include #include "qgsfeature.h" #include "qgsfield.h" #include "qgssearchquerybuilder.h" @@ -31,6 +32,7 @@ : QDialog(parent, fl), mLayer(layer) { setupUi(this); + setupListViews(); setWindowTitle(tr("Search query builder")); @@ -53,25 +55,49 @@ 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); @@ -84,8 +110,13 @@ 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(); @@ -97,10 +128,20 @@ } // add item only if it's not there already - if (lstValues->findItem(value) == 0) - lstValues->insertItem(value); - + QList 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() @@ -245,14 +286,14 @@ 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() Index: src/app/qgssearchquerybuilder.h =================================================================== --- src/app/qgssearchquerybuilder.h (revisión: 7925) +++ src/app/qgssearchquerybuilder.h (copia de trabajo) @@ -19,6 +19,8 @@ #include #include +#include +#include #include "ui_qgspgquerybuilderbase.h" #include "qgisgui.h" @@ -59,8 +61,8 @@ void on_btnLike_clicked(); void on_btnILike_clicked(); - 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(); @@ -93,7 +95,11 @@ /*! * Populate the field list for the selected table */ - void populateFields(); + 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 @@ -109,10 +115,12 @@ private: //! Layer for which is the query builder opened - QgsVectorLayer* mLayer; - + QgsVectorLayer* mLayer; //! Map that holds field information, keyed by field name QMap mFieldMap; - + //! Model for fields ListView + QStandardItemModel *mModelFields; + //! Model for values ListView + QStandardItemModel *mModelValues; }; #endif //QGSSEARCHQUERYBUILDER_H Index: src/ui/qgspgquerybuilderbase.ui =================================================================== --- src/ui/qgspgquerybuilderbase.ui (revisión: 7925) +++ src/ui/qgspgquerybuilderbase.ui (copia de trabajo) @@ -12,9 +12,7 @@ - - 7 - 7 + 0 0 @@ -29,24 +27,48 @@ true - + 9 - + + 9 + + + 9 + + + 9 + + 6 + + 6 + Operators - + 11 - + + 11 + + + 11 + + + 11 + + 10 + + 10 + @@ -150,12 +172,21 @@ - - 0 - 6 + + 0 + + + 0 + + + 0 + + + 0 + @@ -230,9 +261,7 @@ - - 7 - 7 + 0 0 @@ -241,29 +270,41 @@ Values - + 10 - + + 10 + + + 10 + + + 10 + + 6 - + + 6 + + All - - - - + Sample + + + @@ -273,14 +314,26 @@ Fields - + 10 - + + 10 + + + 10 + + + 10 + + 6 + + 6 + - + @@ -304,14 +357,26 @@ SQL where clause - + 10 - + + 10 + + + 10 + + + 10 + + 6 + + 6 + - + @@ -319,21 +384,7 @@ - - - Q3ListBox - Q3Frame -
q3listbox.h
-
- - Q3TextEdit - Q3Frame -
q3textedit.h
-
-
- lstFields - lstValues btnSampleValues btnGetAllValues btnEqual @@ -350,7 +401,6 @@ btnAnd btnOr btnNot - txtSQL btnClear btnTest btnOk