Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
postgres provider: support tables with mixed srids
  • Loading branch information
jef-n committed Jan 22, 2012
1 parent ff3bdcd commit 60b6ad9
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 159 deletions.
2 changes: 1 addition & 1 deletion src/core/qgsdatasourceuri.cpp
Expand Up @@ -136,7 +136,7 @@ QgsDataSourceURI::QgsDataSourceURI( QString uri )
{
mGeometryType = QGis::Point;
}
else if ( geomTypeUpper == "LINESTRING" )
else if ( geomTypeUpper == "LINE" )
{
mGeometryType = QGis::Line;
}
Expand Down
1 change: 1 addition & 0 deletions src/providers/postgres/qgscolumntypethread.cpp
Expand Up @@ -53,6 +53,7 @@ void QgsGeomColumnTypeThread::run()
else
{
layerProperty.type = "";
layerProperty.srid = "";
}

// Now tell the layer list dialog box...
Expand Down
48 changes: 32 additions & 16 deletions src/providers/postgres/qgspgsourceselect.cpp
Expand Up @@ -77,6 +77,14 @@ QWidget *QgsPgSourceSelectDelegate::createEditor( QWidget *parent, const QStyleO
}
}

if ( index.column() == QgsPgTableModel::dbtmSrid )
{
QLineEdit *le = new QLineEdit( parent );
le->setValidator( new QIntValidator( -1, 999999, parent ) );
le->insert( index.data( Qt::DisplayRole ).toString() );
return le;
}

return 0;
}

Expand Down Expand Up @@ -151,13 +159,11 @@ QgsPgSourceSelect::QgsPgSourceSelect( QWidget *parent, Qt::WFlags fl, bool manag
mProxyModel.setParent( this );
mProxyModel.setFilterKeyColumn( -1 );
mProxyModel.setFilterCaseSensitivity( Qt::CaseInsensitive );
mProxyModel.setDynamicSortFilter( true );
mProxyModel.setSourceModel( &mTableModel );

mTablesTreeView->setModel( &mProxyModel );
mTablesTreeView->setSortingEnabled( true );

mTablesTreeView->setEditTriggers( QAbstractItemView::CurrentChanged );

mTablesTreeView->setItemDelegate( new QgsPgSourceSelectDelegate( this ) );

QSettings settings;
Expand Down Expand Up @@ -366,9 +372,8 @@ void QgsPgSourceSelect::on_mSearchModeComboBox_currentIndexChanged( const QStrin

void QgsPgSourceSelect::setLayerType( QgsPostgresLayerProperty layerProperty )
{
QgsDebugMsg( "entering." );
mTableModel.setGeometryTypesForTable( layerProperty );
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmTable, Qt::AscendingOrder );
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmSchema, Qt::AscendingOrder );
}

QgsPgSourceSelect::~QgsPgSourceSelect()
Expand Down Expand Up @@ -421,13 +426,18 @@ QString QgsPgSourceSelect::layerURI( const QModelIndex &index )
// no primary key for view selected
return QString::null;

QString schemaName = mTableModel.itemFromIndex( index.sibling( index.row(), QgsPgTableModel::dbtmSchema ) )->text();
QString tableName = mTableModel.itemFromIndex( index.sibling( index.row(), QgsPgTableModel::dbtmTable ) )->text();
QString geomColumnName = mTableModel.itemFromIndex( index.sibling( index.row(), QgsPgTableModel::dbtmGeomCol ) )->text();
QString schemaName = index.sibling( index.row(), QgsPgTableModel::dbtmSchema ).data( Qt::DisplayRole ).toString();
QString tableName = index.sibling( index.row(), QgsPgTableModel::dbtmTable ).data( Qt::DisplayRole ).toString();
QString geomColumnName = index.sibling( index.row(), QgsPgTableModel::dbtmGeomCol ).data( Qt::DisplayRole ).toString();

QString srid = index.sibling( index.row(), QgsPgTableModel::dbtmSrid ).data( Qt::DisplayRole ).toString();
bool ok;
srid.toInt( &ok );
if ( !ok )
return QString::null;

QString srid = mTableModel.itemFromIndex( index.sibling( index.row(), QgsPgTableModel::dbtmSrid ) )->text();
bool selectAtId = mTableModel.itemFromIndex( index.sibling( index.row(), QgsPgTableModel::dbtmSelectAtId ) )->checkState() == Qt::Checked;
QString sql = mTableModel.itemFromIndex( index.sibling( index.row(), QgsPgTableModel::dbtmSql ) )->text();
QString sql = index.sibling( index.row(), QgsPgTableModel::dbtmSql ).data( Qt::DisplayRole ).toString();

QgsDataSourceURI uri( m_connInfo );
uri.setDataSource( schemaName, tableName, geomType != QGis::NoGeometry ? geomColumnName : QString::null, sql, pkColumnName );
Expand Down Expand Up @@ -514,17 +524,20 @@ void QgsPgSourceSelect::on_btnConnect_clicked()
foreach( QgsPostgresLayerProperty layer, layers )
{
QString type = layer.type;
QString srid = layer.srid;
if ( !searchGeometryColumnsOnly && !layer.geometryColName.isNull() )
{
if ( type == "GEOMETRY" || type == QString::null )
if ( type == "GEOMETRY" || type.isNull() || srid.isEmpty() )
{
addSearchGeometryColumn( layer );
type = "";
srid = "";
}
}
QgsDebugMsg( QString( "adding table %1.%2" ).arg( layer.schemaName ).arg( layer.tableName ) );

layer.type = type;
layer.srid = srid;
mTableModel.addTableEntry( layer );
}

Expand All @@ -538,9 +551,6 @@ void QgsPgSourceSelect::on_btnConnect_clicked()
if ( cmbConnections->count() > 0 && !mColumnTypeThread )
mAddButton->setEnabled( true );

mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmTable, Qt::AscendingOrder );
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmSchema, Qt::AscendingOrder );

//if we have only one schema item, expand it by default
int numTopLevelItems = mTableModel.invisibleRootItem()->rowCount();
if ( numTopLevelItems < 2 || mTableModel.tableCount() < 20 )
Expand All @@ -555,7 +565,11 @@ void QgsPgSourceSelect::on_btnConnect_clicked()
conn->disconnect();

if ( !mColumnTypeThread )
{
QApplication::restoreOverrideCursor();
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmTable, Qt::AscendingOrder );
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmSchema, Qt::AscendingOrder );
}
}
else
{
Expand All @@ -575,6 +589,9 @@ void QgsPgSourceSelect::columnThreadFinished()

if ( cmbConnections->count() > 0 )
mAddButton->setEnabled( true );

mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmTable, Qt::AscendingOrder );
mTablesTreeView->sortByColumn( QgsPgTableModel::dbtmSchema, Qt::AscendingOrder );
}

QStringList QgsPgSourceSelect::selectedTables()
Expand Down Expand Up @@ -640,8 +657,7 @@ void QgsPgSourceSelect::addSearchGeometryColumn( QgsPostgresLayerProperty layerP
emit addGeometryColumn( layerProperty );
}

QString QgsPgSourceSelect::fullDescription( QString schema, QString table,
QString column, QString type )
QString QgsPgSourceSelect::fullDescription( QString schema, QString table, QString column, QString type )
{
QString full_desc = "";
if ( !schema.isEmpty() )
Expand Down
116 changes: 75 additions & 41 deletions src/providers/postgres/qgspgtablemodel.cpp
Expand Up @@ -76,21 +76,18 @@ void QgsPgTableModel::addTableEntry( QgsPostgresLayerProperty layerProperty )
QList<QStandardItem*> childItemList;

QStandardItem *schemaNameItem = new QStandardItem( layerProperty.schemaName );
schemaNameItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
schemaNameItem->setFlags( Qt::ItemIsEnabled );

QStandardItem *typeItem = new QStandardItem( iconForGeomType( geomType ), geomType == QGis::UnknownGeometry ? tr( "Waiting..." ) : QgsPostgresConn::displayStringForGeomType( geomType ) );
QStandardItem *typeItem = new QStandardItem( iconForGeomType( geomType ),
geomType == QGis::UnknownGeometry
? tr( "Detecting..." )
: QgsPostgresConn::displayStringForGeomType( geomType ) );
typeItem->setData( geomType == QGis::UnknownGeometry, Qt::UserRole + 1 );
typeItem->setData( geomType, Qt::UserRole + 2 );
typeItem->setFlags(( geomType != QGis::UnknownGeometry ? Qt::ItemIsEnabled : Qt::NoItemFlags ) | Qt::ItemIsSelectable | Qt::ItemIsEditable );

QStandardItem *tableItem = new QStandardItem( layerProperty.tableName );
tableItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem *geomItem = new QStandardItem( layerProperty.geometryColName );
geomItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QStandardItem *sridItem = new QStandardItem( QString::number( layerProperty.srid ) );
sridItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
QStandardItem *sridItem = new QStandardItem( layerProperty.srid );

QString pkText, pkCol = "";
switch ( layerProperty.pkCols.size() )
Expand All @@ -101,17 +98,18 @@ void QgsPgTableModel::addTableEntry( QgsPostgresLayerProperty layerProperty )
}

QStandardItem *pkItem = new QStandardItem( pkText );
if ( pkText == tr( "Select..." ) )
pkItem->setFlags( pkItem->flags() | Qt::ItemIsEditable );

pkItem->setData( layerProperty.pkCols, Qt::UserRole + 1 );
pkItem->setData( pkCol, Qt::UserRole + 2 );
pkItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );

QStandardItem *selItem = new QStandardItem( "" );
selItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable );
selItem->setFlags( selItem->flags() | Qt::ItemIsUserCheckable );
selItem->setCheckState( Qt::Checked );
selItem->setToolTip( tr( "Disable 'Fast Access to Features at ID' capability to force keeping the attribute table in memory (e.g. in case of expensive views)." ) );

QStandardItem* sqlItem = new QStandardItem( layerProperty.sql );
sqlItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );

childItemList << schemaNameItem;
childItemList << tableItem;
Expand All @@ -122,6 +120,14 @@ void QgsPgTableModel::addTableEntry( QgsPostgresLayerProperty layerProperty )
childItemList << selItem;
childItemList << sqlItem;

if ( geomType == QGis::UnknownGeometry || layerProperty.srid.isEmpty() )
{
foreach( QStandardItem *item, childItemList )
{
item->setFlags( item->flags() & ~( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable ) );
}
}

schemaItem->appendRow( childItemList );

++mTableCount;
Expand Down Expand Up @@ -164,6 +170,7 @@ void QgsPgTableModel::setSql( const QModelIndex &index, const QString &sql )
{
continue;
}

QModelIndex currentTableIndex = currentChildIndex.sibling( i, dbtmTable );
if ( !currentTableIndex.isValid() )
{
Expand All @@ -176,8 +183,7 @@ void QgsPgTableModel::setSql( const QModelIndex &index, const QString &sql )
continue;
}

if ( itemFromIndex( currentTableIndex )->text() == tableName &&
itemFromIndex( currentGeomIndex )->text() == geomName )
if ( itemFromIndex( currentTableIndex )->text() == tableName && itemFromIndex( currentGeomIndex )->text() == geomName )
{
QModelIndex sqlIndex = currentChildIndex.sibling( i, dbtmSql );
if ( sqlIndex.isValid() )
Expand All @@ -192,6 +198,8 @@ void QgsPgTableModel::setSql( const QModelIndex &index, const QString &sql )
void QgsPgTableModel::setGeometryTypesForTable( QgsPostgresLayerProperty layerProperty )
{
QStringList typeList = layerProperty.type.split( ",", QString::SkipEmptyParts );
QStringList sridList = layerProperty.srid.split( ",", QString::SkipEmptyParts );
Q_ASSERT( typeList.size() == sridList.size() );

//find schema item and table item
QStandardItem* schemaItem;
Expand All @@ -213,53 +221,54 @@ void QgsPgTableModel::setGeometryTypesForTable( QgsPostgresLayerProperty layerPr
continue;
}

QModelIndex currentTypeIndex = currentChildIndex.sibling( i, dbtmType );
QModelIndex currentTableIndex = currentChildIndex.sibling( i, dbtmTable );
QModelIndex currentGeomColumnIndex = currentChildIndex.sibling( i, dbtmGeomCol );
QModelIndex currentPkColumnIndex = currentChildIndex.sibling( i, dbtmPkCol );
QModelIndex currentSridIndex = currentChildIndex.sibling( i, dbtmSrid );

if ( !currentTypeIndex.isValid()
|| !currentTableIndex.isValid()
|| !currentGeomColumnIndex.isValid()
|| !currentPkColumnIndex.isValid()
|| !currentSridIndex.isValid()
)
QList<QStandardItem *> row;

for ( int j = 0; j < dbtmColumns; j++ )
{
continue;
row << itemFromIndex( currentChildIndex.sibling( i, j ) );
}

QString tableText = itemFromIndex( currentTableIndex )->text();
QString geomColText = itemFromIndex( currentGeomColumnIndex )->text();
QStandardItem *typeItem = itemFromIndex( currentTypeIndex );
QStandardItem *sridItem = itemFromIndex( currentSridIndex );

if ( tableText == layerProperty.tableName && geomColText == layerProperty.geometryColName )
if ( row[ dbtmTable ]->text() == layerProperty.tableName && row[ dbtmGeomCol ]->text() == layerProperty.geometryColName )
{
sridItem->setText( QString::number( layerProperty.srid ) );
row[ dbtmSrid ]->setText( layerProperty.srid );

if ( typeList.isEmpty() )
{
typeItem->setText( tr( "Select..." ) );
row[ dbtmType ]->setText( tr( "Select..." ) );
row[ dbtmType ]->setFlags( row[ dbtmType ]->flags() | Qt::ItemIsEditable );

row[ dbtmSrid ]->setText( tr( "Enter..." ) );
row[ dbtmSrid ]->setFlags( row[ dbtmSrid ]->flags() | Qt::ItemIsEditable );

foreach( QStandardItem *item, row )
{
item->setFlags( item->flags() | Qt::ItemIsEnabled );
}
}
else
{
// update existing row
QGis::GeometryType geomType = QgsPostgresConn::geomTypeFromPostgis( typeList.at( 0 ) );

typeItem->setIcon( iconForGeomType( geomType ) );
typeItem->setText( QgsPostgresConn::displayStringForGeomType( geomType ) );
typeItem->setData( false, Qt::UserRole + 1 );
typeItem->setData( geomType, Qt::UserRole + 2 );
row[ dbtmType ]->setIcon( iconForGeomType( geomType ) );
row[ dbtmType ]->setText( QgsPostgresConn::displayStringForGeomType( geomType ) );
row[ dbtmType ]->setData( false, Qt::UserRole + 1 );
row[ dbtmType ]->setData( geomType, Qt::UserRole + 2 );

row[ dbtmSrid ]->setText( sridList.at( 0 ) );

foreach( QStandardItem *item, row )
{
item->setFlags( item->flags() | Qt::ItemIsSelectable | Qt::ItemIsEnabled );
}

for ( int j = 1; j < typeList.size(); j++ )
{
layerProperty.type = typeList[j];
layerProperty.srid = sridList[j];
addTableEntry( layerProperty );
}
}

typeItem->setFlags( typeItem->flags() | Qt::ItemIsEnabled );
}
}
}
Expand All @@ -280,3 +289,28 @@ QIcon QgsPgTableModel::iconForGeomType( QGis::GeometryType type )
return QIcon( QgsDataItem::getThemePixmap( "/mIconLayer.png" ) );
}
}

bool QgsPgTableModel::setData( const QModelIndex &idx, const QVariant &value, int role )
{
if ( !QStandardItemModel::setData( idx, value, role ) )
return false;

if ( idx.column() == dbtmType || idx.column() == dbtmSrid )
{
bool ok;
idx.sibling( idx.row(), dbtmSrid ).data().toInt( &ok );

ok &= idx.sibling( idx.row(), dbtmType ).data( Qt::UserRole + 2 ).toInt() != QGis::UnknownGeometry;

for ( int i = 0; i < dbtmColumns; i++ )
{
QStandardItem *item = itemFromIndex( idx.sibling( idx.row(), i ) );
if ( ok )
item->setFlags( item->flags() | Qt::ItemIsSelectable );
else
item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
}
}

return true;
}
3 changes: 3 additions & 0 deletions src/providers/postgres/qgspgtablemodel.h
Expand Up @@ -58,6 +58,9 @@ class QgsPgTableModel : public QStandardItemModel
dbtmColumns
};

bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole );


static QIcon iconForGeomType( QGis::GeometryType type );

private:
Expand Down

0 comments on commit 60b6ad9

Please sign in to comment.