Skip to content

Commit 54b5884

Browse files
author
g_j_m
committed
Replace Q3ListView with QTable for the layer list
Provide framework for better response when populating layer list - (finding the layer type can take some time with complex views and qgis appears to hang) - more to come... Misc. code tidy up git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@5016 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 5646fa9 commit 54b5884

File tree

5 files changed

+175
-88
lines changed

5 files changed

+175
-88
lines changed
715 Bytes
Loading
574 Bytes
Loading

src/gui/qgsdbsourceselect.cpp

+152-66
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ email : sherman at mrcc.com
2929
#include <QMessageBox>
3030
#include <QSettings>
3131
#include <QTextOStream>
32+
#include <QTableWidgetItem>
33+
#include <QIcon>
34+
#include <QHeaderView>
35+
3236
#include <cassert>
3337
#include <iostream>
3438

@@ -98,6 +102,13 @@ QgsDbSourceSelect::QgsDbSourceSelect(QgisApp *app, Qt::WFlags fl)
98102
{
99103
mEncodingComboBox->setCurrentText(lastUsedEncoding);
100104
}
105+
106+
// Do some things that couldn't be done in designer
107+
lstTables->horizontalHeader()->setStretchLastSection(true);
108+
QStringList labels;
109+
labels += tr("Type"); labels += tr("Name"); labels += tr("Sql");
110+
lstTables->setHorizontalHeaderLabels(labels);
111+
lstTables->verticalHeader()->hide();
101112
}
102113
/** Autoconnected SLOTS **/
103114
// Slot for adding a new connection
@@ -117,7 +128,7 @@ void QgsDbSourceSelect::on_btnAdd_clicked()
117128
}
118129

119130
// Slot for opening the query builder when a layer is double clicked
120-
void QgsDbSourceSelect::on_lstTables_doubleClicked(Q3ListViewItem *item)
131+
void QgsDbSourceSelect::on_lstTables_itemDoubleClicked(QTableWidgetItem *item)
121132
{
122133
setSql(item);
123134
}
@@ -199,15 +210,16 @@ void QgsDbSourceSelect::deleteConnection()
199210
void QgsDbSourceSelect::addTables()
200211
{
201212
//store the table info
202-
Q3ListViewItemIterator it( lstTables );
203-
while ( it.current() )
204-
{
205-
Q3ListViewItem *item = it.current();
206-
++it;
207213

208-
if ( item->isSelected() )
214+
for (int i = 0; i < lstTables->rowCount(); ++i)
215+
{
216+
if (lstTables->isItemSelected(lstTables->item(i, 0)))
209217
{
210-
m_selectedTables += item->text(1) + " sql=" + item->text(2);
218+
QString table = lstTables->item(i,1)->text() + " sql=";
219+
QTableWidgetItem* sqlItem = lstTables->item(i,2);
220+
if (sqlItem)
221+
table += sqlItem->text();
222+
m_selectedTables += table;
211223
}
212224
}
213225

@@ -264,9 +276,12 @@ void QgsDbSourceSelect::on_btnConnect_clicked()
264276
{
265277
// create the pixmaps for the layer types
266278
QString myThemePath = QgsApplication::themePath();
267-
QPixmap pxPoint(myThemePath+"/mIconPointLayer.png");
268-
QPixmap pxLine(myThemePath+"/mIconLineLayer.png");
269-
QPixmap pxPoly(myThemePath+"/mIconPolygonLayer.png");
279+
QIcon pxPoint(myThemePath+"/mIconPointLayer.png");
280+
QIcon pxLine(myThemePath+"/mIconLineLayer.png");
281+
QIcon pxPoly(myThemePath+"/mIconPolygonLayer.png");
282+
QIcon pxWaiting(myThemePath+"/mIconWaitingForLayerType.png");
283+
QIcon pxUnknown(myThemePath+"/mIconUnknownLayerType.png");
284+
270285
assert (!pxPoint.isNull());
271286
//qDebug("Connection succeeded");
272287
// tell the DB that we want text encoded in UTF8
@@ -281,26 +296,73 @@ void QgsDbSourceSelect::on_btnConnect_clicked()
281296
geomCol::const_iterator iter = details.begin();
282297
for (; iter != details.end(); ++iter)
283298
{
284-
QPixmap *p = 0;
285-
if (iter->second == "POINT" || iter->second == "MULTIPOINT")
299+
QString toolTipText;
300+
QIcon *p = 0;
301+
if (iter->second == "POINT")
302+
{
286303
p = &pxPoint;
287-
else if (iter->second == "MULTIPOLYGON" || iter->second == "POLYGON")
304+
toolTipText = tr("Point layer");
305+
}
306+
else if (iter->second == "MULTIPOINT")
307+
{
308+
p = &pxPoint;
309+
toolTipText = tr("Multi-point layer");
310+
}
311+
else if (iter->second == "MULTIPOLYGON")
312+
{
313+
p = &pxPoly;
314+
toolTipText = tr("Multi-polygon layer");
315+
}
316+
else if (iter->second == "POLYGON")
317+
{
288318
p = &pxPoly;
289-
else if (iter->second == "LINESTRING" || iter->second == "MULTILINESTRING")
319+
toolTipText = tr("Polygon layer");
320+
}
321+
else if (iter->second == "LINESTRING")
322+
{
290323
p = &pxLine;
291-
292-
if (p != 0)
324+
toolTipText = tr("Linestring layer");
325+
}
326+
else if (iter->second == "MULTILINESTRING")
293327
{
294-
Q3ListViewItem *lItem = new Q3ListViewItem(lstTables);
295-
lItem->setText(1,iter->first);
296-
lItem->setPixmap(0,*p);
297-
lstTables->insertItem(lItem);
328+
p = &pxLine;
329+
toolTipText = tr("Multi-linestring layer");
330+
}
331+
else if (iter->second == "WAITING")
332+
{
333+
p = &pxWaiting;
334+
toolTipText = tr("Waiting for layer type");
298335
}
299336
else
300337
{
301338
qDebug(("Unknown geometry type of " + iter->second).toLocal8Bit().data());
339+
toolTipText = tr("Unknown layer type");
340+
p = &pxUnknown;
341+
}
342+
343+
if (p != 0)
344+
{
345+
QTableWidgetItem *iconItem = new QTableWidgetItem();
346+
iconItem->setIcon(*p);
347+
iconItem->setToolTip(toolTipText);
348+
QTableWidgetItem *textItem = new QTableWidgetItem(iter->first);
349+
int row = lstTables->rowCount();
350+
lstTables->setRowCount(row+1);
351+
lstTables->setItem(row, 0, iconItem);
352+
lstTables->setItem(row, 1, textItem);
302353
}
303354
}
355+
// For some reason not clear to me, the table header labels
356+
// set in the constructor have reverted to '1', '2', and '3'
357+
// by here. Hence we reset them. This seems like a bug in Qt
358+
// (4.1.1).
359+
QStringList labels;
360+
labels += tr("Type"); labels += tr("Name"); labels += tr("Sql");
361+
lstTables->setHorizontalHeaderLabels(labels);
362+
363+
// And tidy up the columns & rows
364+
lstTables->resizeColumnsToContents();
365+
lstTables->resizeRowsToContents();
304366
}
305367
else
306368
{
@@ -309,7 +371,7 @@ void QgsDbSourceSelect::on_btnConnect_clicked()
309371
}
310372
// BEGIN CHANGES ECOS
311373
if (cmbConnections->count() > 0)
312-
btnAdd->setEnabled(true);
374+
btnAdd->setEnabled(true);
313375
// END CHANGES ECOS
314376
} else
315377
{
@@ -330,15 +392,22 @@ QString QgsDbSourceSelect::connInfo()
330392
{
331393
return m_connInfo;
332394
}
333-
void QgsDbSourceSelect::setSql(Q3ListViewItem *item)
395+
void QgsDbSourceSelect::setSql(QTableWidgetItem *item)
334396
{
397+
int row = lstTables->row(item);
398+
QString tableText = lstTables->item(row, 1)->text();
399+
400+
QTableWidgetItem* sqlItem = lstTables->item(row, 2);
401+
QString sqlText;
402+
if (sqlItem)
403+
sqlText = sqlItem->text();
335404
// Parse out the table name
336-
QString table = item->text(1).left(item->text(1).find("("));
405+
QString table = tableText.left(tableText.find("("));
337406
assert(pd != 0);
338407
// create a query builder object
339408
QgsPgQueryBuilder * pgb = new QgsPgQueryBuilder(table, pd, this);
340409
// set the current sql in the query builder sql box
341-
pgb->setSql(item->text(2));
410+
pgb->setSql(sqlText);
342411
// set the PG connection object so it can be used to fetch the
343412
// fields for the table, get sample values, and test the query
344413
pgb->setConnection(pd);
@@ -347,16 +416,20 @@ void QgsDbSourceSelect::setSql(Q3ListViewItem *item)
347416
{
348417
// if user accepts, store the sql for the layer so it can be used
349418
// if and when the layer is added to the map
350-
item->setText(2, pgb->sql());
419+
if (!sqlItem)
420+
{
421+
sqlItem = new QTableWidgetItem();
422+
lstTables->setItem(row, 2, sqlItem);
423+
}
424+
sqlItem->setText(pgb->sql());
425+
// Ensure that the current row remains selected
426+
lstTables->setItemSelected(lstTables->item(row,0), true);
427+
lstTables->setItemSelected(lstTables->item(row,1), true);
428+
lstTables->setItemSelected(lstTables->item(row,2), true);
351429
}
352430
// delete the query builder object
353431
delete pgb;
354432
}
355-
void QgsDbSourceSelect::addLayer(Q3ListBoxItem * item)
356-
{
357-
qgisApp->addVectorLayer(m_connInfo, item->text(), "postgres");
358-
// lstTables->setSelected(item, false);
359-
}
360433

361434
bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
362435
geomCol& details)
@@ -390,23 +463,23 @@ bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
390463

391464
PGresult* exists = PQexec(pg, sql.toLocal8Bit().data());
392465
if (PQntuples(exists) == 1)
393-
{
394-
QString v = "";
466+
{
467+
QString v = "";
395468

396-
if (schemaName.length() > 0)
397-
{
398-
v += schemaName;
399-
v += ".";
400-
}
469+
if (schemaName.length() > 0)
470+
{
471+
v += schemaName;
472+
v += ".";
473+
}
401474

402-
v += tableName;
403-
v += " (";
404-
v += PQgetvalue(result, idx, PQfnumber(result, "f_geometry_column"));
405-
v += ")";
475+
v += tableName;
476+
v += " (";
477+
v += PQgetvalue(result, idx, PQfnumber(result, "f_geometry_column"));
478+
v += ")";
406479

407-
QString type = PQgetvalue(result, idx, PQfnumber(result, "type"));
408-
details.push_back(geomPair(v, type));
409-
}
480+
QString type = PQgetvalue(result, idx, PQfnumber(result, "type"));
481+
details.push_back(geomPair(v, type));
482+
}
410483
PQclear(exists);
411484
}
412485
ok = true;
@@ -417,7 +490,8 @@ bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
417490
// geometry_columns table. This code is specific to postgresql,
418491
// but an equivalent query should be possible in other
419492
// databases.
420-
sql = "select pg_class.relname, pg_namespace.nspname, pg_attribute.attname from "
493+
sql = "select pg_class.relname, pg_namespace.nspname, pg_attribute.attname, "
494+
"pg_class.relkind from "
421495
"pg_attribute, pg_class, pg_type, pg_namespace where pg_type.typname = 'geometry' and "
422496
"pg_attribute.atttypid = pg_type.oid and pg_attribute.attrelid = pg_class.oid "
423497
"and cast(pg_class.relname as character varying) not in "
@@ -436,34 +510,46 @@ bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
436510
// Make the assumption that the geometry type for the first
437511
// row is the same as for all other rows.
438512

439-
// Flag these not geometry_columns table tables so that the UI
440-
// can indicate this????
441513
QString table = PQgetvalue(result, i, 0); // relname
442514
QString schema = PQgetvalue(result, i, 1); // nspname
443515
QString column = PQgetvalue(result, i, 2); // attname
516+
QString relkind = PQgetvalue(result, i, 3); // relation kind
444517

445-
QString query = "select GeometryType(" + column + ") from ";
446-
if (schema.length() > 0)
447-
query += "\"" + schema + "\".";
448-
query += "\"" + table + "\" where " + column + " is not null limit 1";
449-
450-
PGresult* gresult = PQexec(pg, query.toLocal8Bit().data());
451-
if (PQresultStatus(gresult) != PGRES_TUPLES_OK)
518+
QString type = "WAITING";
519+
if (relkind == "r" || relkind == "v")
452520
{
453-
QString myError = (tr("Access to relation ") + table + tr(" using sql;\n") + query +
454-
tr("\nhas failed. The database said:\n"));
455-
qDebug(myError + QString(PQresultErrorMessage(gresult)));
521+
QString query = "select GeometryType(" + column + ") from ";
522+
if (schema.length() > 0)
523+
query += "\"" + schema + "\".";
524+
query += "\"" + table + "\" where " + column + " is not null limit 1";
525+
526+
PGresult* gresult = PQexec(pg, query.toLocal8Bit().data());
527+
if (PQresultStatus(gresult) != PGRES_TUPLES_OK)
528+
{
529+
QString myError = (tr("Access to relation ") + table + tr(" using sql;\n") + query +
530+
tr("\nhas failed. The database said:\n"));
531+
qDebug(myError + QString(PQresultErrorMessage(gresult)));
532+
type = "UNKNOWN";
533+
}
534+
else
535+
type = PQgetvalue(gresult, 0, 0); // GeometryType
536+
PQclear(gresult);
456537
}
457-
else
538+
/*
539+
// Commented out temporarily...
540+
else // view
458541
{
459-
QString type = PQgetvalue(gresult, 0, 0); // GeometryType
460-
QString full_desc = "";
461-
if (schema.length() > 0)
462-
full_desc = schema + ".";
463-
full_desc += table + " (" + column + ")";
464-
details.push_back(geomPair(full_desc, type));
542+
// store the column details and do the query in a thread
543+
std::cout << "Doing " << (schema+'.'+table+'.'+column).toLocal8Bit().data()
544+
<< " later" << std::endl;
465545
}
466-
PQclear(gresult);
546+
*/
547+
548+
QString full_desc = "";
549+
if (schema.length() > 0)
550+
full_desc = schema + ".";
551+
full_desc += table + " (" + column + ")";
552+
details.push_back(geomPair(full_desc, type));
467553
}
468554
ok = true;
469555

src/gui/qgsdbsourceselect.h

+7-9
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,16 @@ class QgsDbSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase
4949
void addNewConnection();
5050
//! Opens a dialog to edit an existing connection
5151
void editConnection();
52-
//! Deletes the selected connection
53-
void deleteConnection();
54-
//! Populate the connection list combo box
55-
void populateConnectionList();
52+
//! Deletes the selected connection
53+
void deleteConnection();
54+
//! Populate the connection list combo box
55+
void populateConnectionList();
5656
//! Determines the tables the user selected and closes the dialog
57-
void addTables();
57+
void addTables();
5858
//! String list containing the selected tables
5959
QStringList selectedTables();
6060
//! Connection info (database, host, user, password)
6161
QString connInfo();
62-
//! Add the layer selected when user double-clicks the mouse
63-
void addLayer(Q3ListBoxItem *item);
6462
//! Return the name of the selected encoding (e.g. UTf-8, ISO-8559-1, etc/)
6563
QString encoding();
6664
// Store the selected database
@@ -74,8 +72,8 @@ class QgsDbSourceSelect : public QDialog, private Ui::QgsDbSourceSelectBase
7472
void on_btnNew_clicked();
7573
void on_btnEdit_clicked();
7674
void on_btnDelete_clicked();
77-
void on_lstTables_doubleClicked(Q3ListViewItem *);
78-
void setSql(Q3ListViewItem *);
75+
void on_lstTables_itemDoubleClicked(QTableWidgetItem *);
76+
void setSql(QTableWidgetItem *);
7977
void on_btnHelp_clicked();
8078
private:
8179

0 commit comments

Comments
 (0)