Skip to content
Permalink
Browse files
Committed patch from #901 - fixes for pg query dialog
git-svn-id: http://svn.osgeo.org/qgis/trunk@8061 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
timlinux committed Jan 28, 2008
1 parent f84ae5a commit 13b58c560be4b1114b115093d9860d5de6859d69
Showing with 145 additions and 74 deletions.
  1. +92 −71 src/app/qgspgquerybuilder.cpp
  2. +8 −1 src/app/qgspgquerybuilder.h
  3. +45 −2 src/ui/qgspgquerybuilderbase.ui
@@ -24,7 +24,7 @@ QgsPgQueryBuilder::QgsPgQueryBuilder(QWidget *parent, Qt::WFlags fl)
: QDialog(parent, fl)
{
setupUi(this);
setupListViews();
setupGuiViews();
}
// constructor used when the query builder must make its own
// connection to the database
@@ -33,7 +33,7 @@ QgsPgQueryBuilder::QgsPgQueryBuilder(QgsDataSourceURI *uri,
: QDialog(parent, fl), mUri(uri)
{
setupUi(this);
setupListViews();
setupGuiViews();
// The query builder must make its own connection to the database when
// using this constructor
QString connInfo = mUri->connInfo();
@@ -71,7 +71,7 @@ QgsPgQueryBuilder::QgsPgQueryBuilder(QString tableName, PGconn *con,
: QDialog(parent, fl), mPgConnection(con)
{
setupUi(this);
setupListViews();
setupGuiViews();
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>"))
@@ -138,8 +138,10 @@ void QgsPgQueryBuilder::populateFields()
mFieldMap[fieldName] = QgsField(fieldName, type, fieldType);
QStandardItem *myItem = new QStandardItem(fieldName);
myItem->setEditable(false);
mModelFields->insertRow(mModelFields->rowCount(),myItem);
mModelFields->insertRow(mModelFields->rowCount(),myItem);
}
// All fields get ... setup
setupLstFieldsModel();
}
else
{
@@ -148,13 +150,16 @@ void QgsPgQueryBuilder::populateFields()
PQclear(result);
}

void QgsPgQueryBuilder::setupListViews()
void QgsPgQueryBuilder::setupLstFieldsModel()
{
//Models
lstFields->setModel(mModelFields);
}

void QgsPgQueryBuilder::setupGuiViews()
{
//Initialize the models
mModelFields = new QStandardItemModel();
mModelValues = new QStandardItemModel();
lstFields->setModel(mModelFields);
lstValues->setModel(mModelValues);
// Modes
lstFields->setViewMode(QListView::ListMode);
lstValues->setViewMode(QListView::ListMode);
@@ -163,99 +168,88 @@ void QgsPgQueryBuilder::setupListViews()
// Performance tip since Qt 4.1
lstFields->setUniformItemSizes(true);
lstValues->setUniformItemSizes(true);
// Colored rows
lstFields->setAlternatingRowColors(true);
lstValues->setAlternatingRowColors(true);
}

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

QString sql = "SELECT DISTINCT \"" + myFieldName + "\" " +
"FROM (SELECT \"" + myFieldName + "\" " +
"FROM " + mUri->quotedTablename() + " " +
"LIMIT 5000) AS foo " +
"ORDER BY \"" + myFieldName + "\" "+
"LIMIT 25";
// clear the values list
// clear the model
mModelValues->clear();

// determine the field type
QgsField field = mFieldMap[myFieldName];
bool isCharField = field.typeName().find("char") > -1;
PGresult *result = PQexec(mPgConnection, (const char *) (sql.utf8()));
QgsField field = mFieldMap[mModelFields->data(lstFields->currentIndex()).toString()];
bool mActualFieldIsChar = field.typeName().find("char") > -1;

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

if (PQresultStatus(result) == PGRES_TUPLES_OK)
{
int rowCount = PQntuples(result);
for(int i=0; i < rowCount; i++)
{
QString value = QString::fromUtf8(PQgetvalue(result, i, 0));
if(isCharField)
{
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>");
QMessageBox::warning(this, tr("Database error"), tr("<p>Failed to get sample of field values using SQL:</p><p>") + theSQL + "</p><p>Error message was: "+ QString(PQerrorMessage(mPgConnection)) + "</p>");
}
// free the result set
PQclear(result);
}

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

QgsField field = mFieldMap[mModelFields->data(lstFields->currentIndex()).toString()];
bool mActualFieldIsChar = field.typeName().find("char") > -1;

QString sql = "SELECT DISTINCT \"" + myFieldName + "\" " +
"FROM (SELECT \"" + myFieldName + "\" " +
"FROM " + mUri->quotedTablename() + " " +
"LIMIT 5000) AS foo " +
"ORDER BY \"" + myFieldName + "\" "+
"LIMIT 25";

//delete connection mModelValues and lstValues
QStandardItemModel *tmp = new QStandardItemModel();
lstValues->setModel(tmp);
//Clear and fill the mModelValues
fillValues(sql);
lstValues->setModel(mModelValues);
lstValues->setCursor(Qt::ArrowCursor);
//delete the tmp
delete tmp;

}

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

QString sql = "select distinct \"" + myFieldName
+ "\" from " + mUri->quotedTablename() + " order by \"" + myFieldName + "\"";
// clear the values list
mModelValues->clear();
// determine the field type
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)
{
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)) );
}
// free the result set
PQclear(result);

//delete connection mModelValues and lstValues
QStandardItemModel *tmp = new QStandardItemModel();
lstValues->setModel(tmp);
//Clear and fill the mModelValues
fillValues(sql);
lstValues->setModel(mModelValues);
lstValues->setCursor(Qt::ArrowCursor);
//delete the tmp
delete tmp;
}

void QgsPgQueryBuilder::on_btnTest_clicked()
@@ -398,14 +392,41 @@ void QgsPgQueryBuilder::setSql( QString sqlStatement)
txtSQL->setText(sqlStatement);
}

void QgsPgQueryBuilder::on_lstFields_clicked( const QModelIndex &index )
{
if (mPreviousFieldRow != index.row())
{
mPreviousFieldRow = index.row();

// If type is gemetry .. normal users don't want to get values?
QgsField field = mFieldMap[mModelFields->data(lstFields->currentIndex()).toString()];
if (field.typeName().find("geometry") > -1)
{
btnSampleValues->setEnabled(false);
btnGetAllValues->setEnabled(false);
}else
{
btnSampleValues->setEnabled(true);
btnGetAllValues->setEnabled(true);
}
mModelValues->clear();
}
}

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

void QgsPgQueryBuilder::on_lstValues_doubleClicked( const QModelIndex &index )
{
txtSQL->insert(mModelValues->data(index).toString());
if (mActualFieldIsChar)
{
txtSQL->insert("'" + mModelValues->data(index).toString() + "'");
}else
{
txtSQL->insert(mModelValues->data(index).toString());
}
}

void QgsPgQueryBuilder::on_btnLessEqual_clicked()
@@ -87,6 +87,7 @@ class QgsPgQueryBuilder : public QDialog, private Ui::QgsPgQueryBuilderBase {
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();
@@ -123,7 +124,9 @@ class QgsPgQueryBuilder : public QDialog, private Ui::QgsPgQueryBuilderBase {
/*!
* Setup models for listviews
*/
void setupListViews();
void setupGuiViews();
void setupLstFieldsModel();
void fillValues(QString theSQL);

/*! Get the number of records that would be returned by the current SQL
* @return Number of records or -1 if an error was encountered
@@ -149,5 +152,9 @@ class QgsPgQueryBuilder : public QDialog, private Ui::QgsPgQueryBuilderBase {
QStandardItemModel *mModelFields;
//! Model for values ListView
QStandardItemModel *mModelValues;
//! Actual field char?
bool mActualFieldIsChar;
//! Previous field row to delete model
int mPreviousFieldRow;
};
#endif //QGSPGQUERYBUILDER_H
@@ -249,26 +249,62 @@
</property>
<item row="2" column="1" >
<widget class="QPushButton" name="btnGetAllValues" >
<property name="toolTip" >
<string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
p, li { white-space: pre-wrap; }
&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Retrieve &lt;span style=" font-weight:600;">all&lt;/span> the record in the vector file (&lt;span style=" font-style:italic;">if the table is big, the operation can consume some time&lt;/span>)&lt;/p>&lt;/body>&lt;/html></string>
</property>
<property name="text" >
<string>All</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QPushButton" name="btnSampleValues" >
<property name="toolTip" >
<string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
p, li { white-space: pre-wrap; }
&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Take a &lt;span style=" font-weight:600;">sample&lt;/span> of records in the vector file&lt;/p>&lt;/body>&lt;/html></string>
</property>
<property name="text" >
<string>Sample</string>
</property>
</widget>
</item>
<item rowspan="2" row="0" column="0" colspan="2" >
<widget class="QListView" name="lstValues" />
<widget class="QListView" name="lstValues" >
<property name="whatsThis" >
<string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
p, li { white-space: pre-wrap; }
&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">List of values for the current field.&lt;/p>&lt;/body>&lt;/html></string>
</property>
<property name="autoFillBackground" >
<bool>true</bool>
</property>
<property name="selectionBehavior" >
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="uniformItemSizes" >
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" >
<widget class="QGroupBox" name="groupBox1" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title" >
<string>Fields</string>
</property>
@@ -280,7 +316,14 @@
<number>6</number>
</property>
<item row="0" column="0" >
<widget class="QListView" name="lstFields" />
<widget class="QListView" name="lstFields" >
<property name="whatsThis" >
<string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
p, li { white-space: pre-wrap; }
&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">List of fields in this vector file&lt;/p>&lt;/body>&lt;/html></string>
</property>
</widget>
</item>
</layout>
</widget>

0 comments on commit 13b58c5

Please sign in to comment.