Skip to content

Commit fd07c21

Browse files
author
jef
committedNov 20, 2007
PostGIS layer selection:
- actually do the geometry type lookup threaded - combobox removed and replaced with multiple rows, one each geometry type - add wait cursors while looking up tables and inserting layers git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@7627 c8812cc2-4d05-0410-92ff-de0c093fc19c

File tree

3 files changed

+113
-130
lines changed

3 files changed

+113
-130
lines changed
 

‎src/app/qgisapp.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2071,9 +2071,11 @@ void QgisApp::addDatabaseLayer()
20712071
// add files to the map canvas
20722072
QStringList tables = dbs->selectedTables();
20732073

2074+
QApplication::setOverrideCursor(Qt::waitCursor);
2075+
20742076
QString connInfo = dbs->connInfo();
20752077
// for each selected table, connect to the database, parse the WKT geometry,
2076-
// and build a cavnasitem for it
2078+
// and build a canvasitem for it
20772079
// readWKB(connInfo,tables);
20782080
QStringList::Iterator it = tables.begin();
20792081
while (it != tables.end())
@@ -2086,7 +2088,6 @@ void QgisApp::addDatabaseLayer()
20862088
{
20872089
// register this layer with the central layers registry
20882090
QgsMapLayerRegistry::instance()->addMapLayer(layer);
2089-
20902091
}
20912092
else
20922093
{
@@ -2097,6 +2098,9 @@ void QgisApp::addDatabaseLayer()
20972098
//qWarning("incrementing iterator");
20982099
++it;
20992100
}
2101+
2102+
QApplication::restoreOverrideCursor();
2103+
21002104
statusBar()->message(mMapCanvas->extent().stringRep(2));
21012105
}
21022106

‎src/app/qgsdbsourceselect.cpp

Lines changed: 93 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -156,49 +156,6 @@ void QgsDbSourceSelect::on_cmbConnections_activated(int)
156156
dbChanged();
157157
}
158158

159-
void QgsDbSourceSelect::updateTypeInfo(int row, QString type)
160-
{
161-
QComboBox *cb = static_cast<QComboBox *>(lstTables->cellWidget(row,dbssType));
162-
if(!cb)
163-
{
164-
QTableWidgetItem *item = lstTables->takeItem(row,dbssType);
165-
delete item;
166-
}
167-
#if 0 // Qt 4.3
168-
else
169-
lstTables->removeCellWidget(row, dbssType);
170-
#endif
171-
172-
if( type.contains(",") )
173-
{
174-
QStringList types = type.split(",");
175-
176-
cb = new QComboBox(lstTables);
177-
for(int i=0; i<types.size(); i++) {
178-
cb->addItem( mLayerIcons.value(types[i]).second, mLayerIcons.value(types[i]).first);
179-
}
180-
cb->setCurrentIndex(0);
181-
cb->setToolTip( tr("select import type for multi type layer") );
182-
#if 0 // Qt 4.3
183-
cb->setMinimumContentsLength(mCbMinLength);
184-
cb->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
185-
#endif
186-
lstTables->setCellWidget(row, dbssType, cb);
187-
}
188-
else
189-
{
190-
if (!mLayerIcons.contains(type))
191-
type="UNKNOWN";
192-
193-
QTableWidgetItem *iconItem = new QTableWidgetItem();
194-
iconItem->setIcon( mLayerIcons.value(type).second );
195-
iconItem->setToolTip( mLayerIcons.value(type).first );
196-
lstTables->setItem(row, dbssType, iconItem);
197-
198-
lstTables->setItem(row, dbssType, new QTableWidgetItem(*lstTables->item(row,dbssType)));
199-
}
200-
}
201-
202159
void QgsDbSourceSelect::setLayerType(QString schema,
203160
QString table, QString column,
204161
QString type)
@@ -207,14 +164,31 @@ void QgsDbSourceSelect::setLayerType(QString schema,
207164

208165
// Find the right row in the table by searching for the text that
209166
// was put into the Name column.
210-
QString full_desc = fullDescription(schema, table, column);
167+
QString full_desc = fullDescription(schema, table, column, "WAITING");
211168

212169
QList<QTableWidgetItem*> ii = lstTables->findItems(full_desc, Qt::MatchExactly);
213170

214171
if (ii.count() > 0)
215172
{
216-
updateTypeInfo( lstTables->row(ii.at(0)), type);
217-
lstTables->resizeColumnToContents(dbssType);
173+
int row = lstTables->row(ii.at(0));
174+
175+
if(type!="")
176+
{
177+
QStringList types = type.split(",");
178+
updateRow(row, fullDescription(schema, table, column, "AS " + types[0]), types[0]);
179+
180+
for(int i=1; i<types.size(); i++) {
181+
lstTables->insertRow(row+1);
182+
initRow(row+1);
183+
updateRow(row+1, fullDescription(schema, table, column, "AS " + types[i]), types[i]);
184+
}
185+
186+
lstTables->resizeColumnsToContents();
187+
}
188+
else
189+
{
190+
lstTables->removeRow(row);
191+
}
218192
}
219193
}
220194

@@ -249,7 +223,6 @@ void QgsDbSourceSelect::populateConnectionList()
249223
}
250224
void QgsDbSourceSelect::addNewConnection()
251225
{
252-
253226
QgsNewConnection *nc = new QgsNewConnection(this);
254227

255228
if (nc->exec())
@@ -295,31 +268,21 @@ void QgsDbSourceSelect::addTables()
295268
{
296269
//store the table info
297270

298-
for (int i = 0; i < lstTables->rowCount();)
271+
for (int i=0; i<lstTables->rowCount(); i++)
299272
{
300273
if ( lstTables->isItemSelected(lstTables->item(i, dbssDetail)) )
301274
{
302275
QString table = lstTables->item(i,dbssDetail)->text();
303-
QString query = table + " sql=";
276+
QString query;
304277

305-
QComboBox *cb = static_cast<QComboBox *>( lstTables->cellWidget(i, dbssType) );
306-
if(cb)
307-
{
278+
bool applyFilter = table.contains(") AS ");
279+
if( applyFilter ) {
308280
int i = table.find("(");
309281
int j = table.find(")");
310282
QString column = table.mid(i+1,j-i-1);
311-
QString type;
312-
313-
QMapIterator <QString, QPair < QString, QIcon > > it(mLayerIcons);
314-
while( it.hasNext() ) {
315-
it.next();
316-
317-
if( it.value().first == cb->currentText() ) {
318-
type=it.key();
319-
break;
320-
}
321-
}
322-
283+
QString type = table.mid(j+5);
284+
query += table.left(j+1) + " sql=";
285+
323286
if( type=="POINT" ) {
324287
query += QString("GeometryType(\"%1\") IN ('POINT','MULTIPOINT')").arg(column);
325288
} else if(type=="LINESTRING") {
@@ -330,31 +293,61 @@ void QgsDbSourceSelect::addTables()
330293
continue;
331294
}
332295
}
296+
else
297+
{
298+
query += table + " sql=";
299+
}
333300

334301
QTableWidgetItem *sqlItem = lstTables->item(i, dbssSql);
335302
if (sqlItem && sqlItem->text()!="" )
336303
{
337-
if(cb)
304+
if(applyFilter)
338305
query += QString(" AND (%1)").arg( sqlItem->text() );
339306
else
340307
query += sqlItem->text();
341308
}
342309

343310
m_selectedTables += query;
344311
}
345-
i++;
346312
}
347313

348314
// BEGIN CHANGES ECOS
349-
if (m_selectedTables.empty() == true)
315+
if ( m_selectedTables.empty() )
350316
QMessageBox::information(this, tr("Select Table"), tr("You must select a table in order to add a Layer."));
351317
else
352318
accept();
353319
// END CHANGES ECOS
354320
}
355321

322+
void QgsDbSourceSelect::initRow(int row)
323+
{
324+
QTableWidgetItem *iconItem = new QTableWidgetItem();
325+
lstTables->setItem(row, dbssType, iconItem);
326+
327+
QTableWidgetItem *textItem = new QTableWidgetItem();
328+
textItem->setToolTip( tr("double click to open PostgreSQL query builder") );
329+
lstTables->setItem(row, dbssDetail, textItem);
330+
}
331+
332+
void QgsDbSourceSelect::updateRow(int row, QString detail, QString type)
333+
{
334+
if (!mLayerIcons.contains(type))
335+
type="UNKNOWN";
336+
337+
QTableWidgetItem *iconItem = lstTables->item(row, dbssType);
338+
iconItem->setIcon( mLayerIcons.value(type).second );
339+
iconItem->setToolTip( mLayerIcons.value(type).first );
340+
341+
lstTables->item(row, dbssDetail)->setText( detail );
342+
}
343+
356344
void QgsDbSourceSelect::on_btnConnect_clicked()
357345
{
346+
if(mColumnTypeThread)
347+
{
348+
mColumnTypeThread->stop();
349+
mColumnTypeThread=0;
350+
}
358351
// populate the table list
359352
QSettings settings;
360353

@@ -445,16 +438,6 @@ void QgsDbSourceSelect::on_btnConnect_clicked()
445438
mLayerIcons.insert("UNKNOWN",
446439
qMakePair(tr("Unknown layer type"),
447440
QIcon(myThemePath+"/mIconUnknownLayerType.png")));
448-
449-
#if 0 // Qt 4.3
450-
mCbMinLength = 0;
451-
QMapIterator <QString, QPair < QString, QIcon > > it(mLayerIcons);
452-
while( it.hasNext() ) {
453-
it.next();
454-
int len = it.value().first.length();;
455-
mCbMinLength = mCbMinLength<len ? len : mCbMinLength;
456-
}
457-
#endif
458441
}
459442
//qDebug("Connection succeeded");
460443
// tell the DB that we want text encoded in UTF8
@@ -476,14 +459,12 @@ void QgsDbSourceSelect::on_btnConnect_clicked()
476459
geomCol::const_iterator iter = details.begin();
477460
for (; iter != details.end(); ++iter)
478461
{
462+
QString type = iter->second;
479463
int row = lstTables->rowCount();
480464
lstTables->setRowCount(row+1);
481465

482-
QTableWidgetItem *textItem = new QTableWidgetItem(iter->first);
483-
textItem->setToolTip( tr("double click to open PostgreSQL query builder") );
484-
lstTables->setItem(row, dbssDetail, textItem);
485-
486-
updateTypeInfo(row, iter->second);
466+
initRow(row);
467+
updateRow(row, iter->first, type);
487468
}
488469

489470
// And tidy up the columns & rows
@@ -494,19 +475,13 @@ void QgsDbSourceSelect::on_btnConnect_clicked()
494475
// may take a long time to return
495476
if (mColumnTypeThread != NULL)
496477
{
497-
connect(mColumnTypeThread,
498-
SIGNAL(setLayerType(QString,QString,QString,QString)),
499-
this,
500-
SLOT(setLayerType(QString,QString,QString,QString)));
501-
// Do it in a thread. Does not yet cope correctly with the
502-
// layer selection dialog box closing before the thread
503-
// completes, nor the qgis process ending before the
504-
// thread completes, nor does the thread know to stop working
505-
// when the user chooses a layer.
506-
//mColumnTypeThread->start();
507-
508-
// do it in this process for the moment.
509-
mColumnTypeThread->getLayerTypes();
478+
connect(mColumnTypeThread, SIGNAL(setLayerType(QString,QString,QString,QString)),
479+
this, SLOT(setLayerType(QString,QString,QString,QString)));
480+
connect(this, SIGNAL(finished()),
481+
mColumnTypeThread, SLOT(stop()) );
482+
483+
// Do it in a thread.
484+
mColumnTypeThread->start();
510485
}
511486
}
512487
else
@@ -590,6 +565,8 @@ bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
590565
{
591566
bool ok = false;
592567

568+
QApplication::setOverrideCursor(Qt::waitCursor);
569+
593570
QString sql = "select * from geometry_columns";
594571
// where f_table_schema ='" + settings.readEntry(key + "/database") + "'";
595572
sql += " order by f_table_schema,f_table_name";
@@ -620,35 +597,23 @@ bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
620597
{
621598
QString column = PQgetvalue(result, idx, PQfnumber(result, "f_geometry_column"));
622599
QString type = PQgetvalue(result, idx, PQfnumber(result, "type"));
623-
QString v = "";
624-
625-
if (schemaName.length() > 0)
626-
{
627-
v += '"';
628-
v += schemaName;
629-
v += "\".";
630-
}
631-
632-
v += '"';
633-
v += tableName;
634-
v += "\" (";
635-
v += column;
636-
v += ")";
637-
638600

601+
QString as = "";
639602
if(type=="GEOMETRY" && !searchGeometryColumnsOnly) {
640603
addSearchGeometryColumn(schemaName, tableName, column);
641-
type="WAITING";
604+
as=type="WAITING";
642605
}
643606

644-
details.push_back(geomPair(v, type));
607+
details.push_back(geomPair(fullDescription(schemaName, tableName, column, as), type));
645608
}
646609
PQclear(exists);
647610
}
648611
ok = true;
649612
}
650613
PQclear(result);
651614

615+
QApplication::restoreOverrideCursor();
616+
652617
if (searchGeometryColumnsOnly)
653618
return ok;
654619

@@ -685,11 +650,8 @@ bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
685650
QString column = PQgetvalue(result, i, 2); // attname
686651
QString relkind = PQgetvalue(result, i, 3); // relation kind
687652

688-
QString full_desc = fullDescription(schema, table, column);
689-
690653
addSearchGeometryColumn(schema, table, column);
691-
692-
details.push_back(geomPair(full_desc, "WAITING"));
654+
details.push_back(geomPair(fullDescription(schema, table, column, "WAITING"), "WAITING"));
693655
}
694656
ok = true;
695657

@@ -706,12 +668,12 @@ void QgsDbSourceSelect::showHelp()
706668
QgsContextHelp::run(context_id);
707669
}
708670
QString QgsDbSourceSelect::fullDescription(QString schema, QString table,
709-
QString column)
671+
QString column, QString type)
710672
{
711673
QString full_desc = "";
712674
if (schema.length() > 0)
713675
full_desc = '"' + schema + "\".\"";
714-
full_desc += table + "\" (" + column + ")";
676+
full_desc += table + "\" (" + column + ") " + type;
715677
return full_desc;
716678
}
717679
void QgsDbSourceSelect::dbChanged()
@@ -765,33 +727,43 @@ void QgsGeomColumnTypeThread::addGeometryColumn(QString schema, QString table, Q
765727
columns.push_back(column);
766728
}
767729

730+
void QgsGeomColumnTypeThread::stop()
731+
{
732+
mStopped=true;
733+
}
734+
768735
void QgsGeomColumnTypeThread::getLayerTypes()
769736
{
737+
mStopped=false;
738+
770739
PGconn *pd = PQconnectdb(mConnInfo.toLocal8Bit().data());
771740
if (PQstatus(pd) == CONNECTION_OK)
772741
{
773742
PQsetClientEncoding(pd, "UNICODE");
774743

775-
for (uint i = 0; i < schemas.size(); ++i)
744+
for (uint i = 0; i<schemas.size(); i++)
776745
{
777746
QString query = QgsDbSourceSelect::makeGeomQuery(schemas[i],
778747
tables[i],
779748
columns[i]);
780-
QgsDebugMsg("Running SQL:" + query);
781749
PGresult* gresult = PQexec(pd, query.toLocal8Bit().data());
782750
QString type;
783751
if (PQresultStatus(gresult) == PGRES_TUPLES_OK) {
784752
QStringList types;
785753

786754
for(int j=0; j<PQntuples(gresult); j++) {
787755
QString type = PQgetvalue(gresult, j, 0);
788-
types += type!="" ? type : "UNKNOWN";
756+
if(type!="")
757+
types += type;
789758
}
790759

791760
type = types.join(",");
792761
}
793762
PQclear(gresult);
794763

764+
if(mStopped)
765+
break;
766+
795767
// Now tell the layer list dialog box...
796768
emit setLayerType(schemas[i], tables[i], columns[i], type);
797769
}

‎src/app/qgsdbsourceselect.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ class QgisApp;
4242
* \brief Dialog to create connections and add tables from PostgresQL.
4343
*
4444
* This dialog allows the user to define and save connection information
45-
* for PostGIS enabled PostgresQL databases. The user can then connect and add
45+
* for PostGIS enabled PostgreSQL databases. The user can then connect and add
4646
* tables from the database to the map canvas.
4747
*/
4848
class QgsDbSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase
4949
{
50-
Q_OBJECT
50+
Q_OBJECT
5151
public:
5252

5353
//! Constructor
@@ -76,7 +76,7 @@ class QgsDbSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase
7676
// geometry type of a column
7777
static QString makeGeomQuery(QString schema, QString table, QString column);
7878

79-
public slots:
79+
public slots:
8080
/*! Connects to the database using the stored connection parameters.
8181
* Once connected, available layers are displayed.
8282
*/
@@ -115,11 +115,13 @@ class QgsDbSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase
115115
void setConnectionListPosition();
116116
// Show the context help for the dialog
117117
void showHelp();
118-
// update type column
119-
void updateTypeInfo(int row, QString type);
118+
// initialize row
119+
void initRow(int row);
120+
// update the row
121+
void updateRow(int row, QString detail, QString type);
120122
// Combine the schema, table and column data into a single string
121123
// useful for display to the user
122-
QString fullDescription(QString schema, QString table, QString column);
124+
QString fullDescription(QString schema, QString table, QString column, QString type);
123125
// The column labels
124126
QStringList mColumnLabels;
125127
// Our thread for doing long running queries
@@ -161,12 +163,17 @@ class QgsGeomColumnTypeThread : public QThread
161163
virtual void run() { getLayerTypes(); }
162164
void getLayerTypes();
163165

164-
signals:
166+
signals:
165167
void setLayerType(QString schema, QString table, QString column,
166168
QString type);
167169

170+
public slots:
171+
void stop();
172+
173+
168174
private:
169175
QString mConnInfo;
176+
bool mStopped;
170177
std::vector<QString> schemas, tables, columns;
171178
};
172179

0 commit comments

Comments
 (0)
Please sign in to comment.