@@ -29,6 +29,10 @@ email : sherman at mrcc.com
29
29
#include < QMessageBox>
30
30
#include < QSettings>
31
31
#include < QTextOStream>
32
+ #include < QTableWidgetItem>
33
+ #include < QIcon>
34
+ #include < QHeaderView>
35
+
32
36
#include < cassert>
33
37
#include < iostream>
34
38
@@ -98,6 +102,13 @@ QgsDbSourceSelect::QgsDbSourceSelect(QgisApp *app, Qt::WFlags fl)
98
102
{
99
103
mEncodingComboBox ->setCurrentText (lastUsedEncoding);
100
104
}
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 ();
101
112
}
102
113
/* * Autoconnected SLOTS **/
103
114
// Slot for adding a new connection
@@ -117,7 +128,7 @@ void QgsDbSourceSelect::on_btnAdd_clicked()
117
128
}
118
129
119
130
// 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)
121
132
{
122
133
setSql (item);
123
134
}
@@ -199,15 +210,16 @@ void QgsDbSourceSelect::deleteConnection()
199
210
void QgsDbSourceSelect::addTables ()
200
211
{
201
212
// store the table info
202
- Q3ListViewItemIterator it ( lstTables );
203
- while ( it.current () )
204
- {
205
- Q3ListViewItem *item = it.current ();
206
- ++it;
207
213
208
- if ( item->isSelected () )
214
+ for (int i = 0 ; i < lstTables->rowCount (); ++i)
215
+ {
216
+ if (lstTables->isItemSelected (lstTables->item (i, 0 )))
209
217
{
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;
211
223
}
212
224
}
213
225
@@ -264,9 +276,12 @@ void QgsDbSourceSelect::on_btnConnect_clicked()
264
276
{
265
277
// create the pixmaps for the layer types
266
278
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
+
270
285
assert (!pxPoint.isNull ());
271
286
// qDebug("Connection succeeded");
272
287
// tell the DB that we want text encoded in UTF8
@@ -281,26 +296,73 @@ void QgsDbSourceSelect::on_btnConnect_clicked()
281
296
geomCol::const_iterator iter = details.begin ();
282
297
for (; iter != details.end (); ++iter)
283
298
{
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
+ {
286
303
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
+ {
288
318
p = &pxPoly;
289
- else if (iter->second == " LINESTRING" || iter->second == " MULTILINESTRING" )
319
+ toolTipText = tr (" Polygon layer" );
320
+ }
321
+ else if (iter->second == " LINESTRING" )
322
+ {
290
323
p = &pxLine;
291
-
292
- if (p != 0 )
324
+ toolTipText = tr (" Linestring layer" );
325
+ }
326
+ else if (iter->second == " MULTILINESTRING" )
293
327
{
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" );
298
335
}
299
336
else
300
337
{
301
338
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);
302
353
}
303
354
}
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 ();
304
366
}
305
367
else
306
368
{
@@ -309,7 +371,7 @@ void QgsDbSourceSelect::on_btnConnect_clicked()
309
371
}
310
372
// BEGIN CHANGES ECOS
311
373
if (cmbConnections->count () > 0 )
312
- btnAdd->setEnabled (true );
374
+ btnAdd->setEnabled (true );
313
375
// END CHANGES ECOS
314
376
} else
315
377
{
@@ -330,15 +392,22 @@ QString QgsDbSourceSelect::connInfo()
330
392
{
331
393
return m_connInfo;
332
394
}
333
- void QgsDbSourceSelect::setSql (Q3ListViewItem *item)
395
+ void QgsDbSourceSelect::setSql (QTableWidgetItem *item)
334
396
{
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 ();
335
404
// Parse out the table name
336
- QString table = item-> text ( 1 ) .left (item-> text ( 1 ) .find (" (" ));
405
+ QString table = tableText .left (tableText .find (" (" ));
337
406
assert (pd != 0 );
338
407
// create a query builder object
339
408
QgsPgQueryBuilder * pgb = new QgsPgQueryBuilder (table, pd, this );
340
409
// set the current sql in the query builder sql box
341
- pgb->setSql (item-> text ( 2 ) );
410
+ pgb->setSql (sqlText );
342
411
// set the PG connection object so it can be used to fetch the
343
412
// fields for the table, get sample values, and test the query
344
413
pgb->setConnection (pd);
@@ -347,16 +416,20 @@ void QgsDbSourceSelect::setSql(Q3ListViewItem *item)
347
416
{
348
417
// if user accepts, store the sql for the layer so it can be used
349
418
// 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 );
351
429
}
352
430
// delete the query builder object
353
431
delete pgb;
354
432
}
355
- void QgsDbSourceSelect::addLayer (Q3ListBoxItem * item)
356
- {
357
- qgisApp->addVectorLayer (m_connInfo, item->text (), " postgres" );
358
- // lstTables->setSelected(item, false);
359
- }
360
433
361
434
bool QgsDbSourceSelect::getGeometryColumnInfo (PGconn *pg,
362
435
geomCol& details)
@@ -390,23 +463,23 @@ bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
390
463
391
464
PGresult* exists = PQexec (pg, sql.toLocal8Bit ().data ());
392
465
if (PQntuples (exists) == 1 )
393
- {
394
- QString v = " " ;
466
+ {
467
+ QString v = " " ;
395
468
396
- if (schemaName.length () > 0 )
397
- {
398
- v += schemaName;
399
- v += " ." ;
400
- }
469
+ if (schemaName.length () > 0 )
470
+ {
471
+ v += schemaName;
472
+ v += " ." ;
473
+ }
401
474
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 += " )" ;
406
479
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
+ }
410
483
PQclear (exists);
411
484
}
412
485
ok = true ;
@@ -417,7 +490,8 @@ bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
417
490
// geometry_columns table. This code is specific to postgresql,
418
491
// but an equivalent query should be possible in other
419
492
// 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 "
421
495
" pg_attribute, pg_class, pg_type, pg_namespace where pg_type.typname = 'geometry' and "
422
496
" pg_attribute.atttypid = pg_type.oid and pg_attribute.attrelid = pg_class.oid "
423
497
" and cast(pg_class.relname as character varying) not in "
@@ -436,34 +510,46 @@ bool QgsDbSourceSelect::getGeometryColumnInfo(PGconn *pg,
436
510
// Make the assumption that the geometry type for the first
437
511
// row is the same as for all other rows.
438
512
439
- // Flag these not geometry_columns table tables so that the UI
440
- // can indicate this????
441
513
QString table = PQgetvalue (result, i, 0 ); // relname
442
514
QString schema = PQgetvalue (result, i, 1 ); // nspname
443
515
QString column = PQgetvalue (result, i, 2 ); // attname
516
+ QString relkind = PQgetvalue (result, i, 3 ); // relation kind
444
517
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" )
452
520
{
453
- QString myError = (tr (" Access to relation " ) + table + tr (" using sql;\n " ) + query +
454
- tr (" \n has 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 (" \n has 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);
456
537
}
457
- else
538
+ /*
539
+ // Commented out temporarily...
540
+ else // view
458
541
{
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;
465
545
}
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));
467
553
}
468
554
ok = true ;
469
555
0 commit comments