mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-09 00:05:52 -04:00
596 lines
21 KiB
C++
596 lines
21 KiB
C++
/***************************************************************************
|
|
qgsspatialitesourceselect.cpp
|
|
Dialog to select SpatiaLite layer(s) and add it to the map canvas
|
|
-------------------
|
|
begin : Dec 2008
|
|
copyright : (C) 2008 by Sandro Furieri
|
|
email : a.furieri@lqt.it
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "qgsspatialitesourceselect.h"
|
|
#include "qgsspatialiteconnection.h"
|
|
|
|
#include "qgslogger.h"
|
|
#include "qgsapplication.h"
|
|
#include "qgsquerybuilder.h"
|
|
#include "qgsdatasourceuri.h"
|
|
#include "qgsvectorlayer.h"
|
|
#include "qgssettings.h"
|
|
#include "qgsproviderregistry.h"
|
|
|
|
#include <QInputDialog>
|
|
#include <QMessageBox>
|
|
#include <QTextStream>
|
|
#include <QTableWidgetItem>
|
|
#include <QHeaderView>
|
|
#include <QStringList>
|
|
#include <QPushButton>
|
|
|
|
#ifdef _MSC_VER
|
|
#define strcasecmp(a,b) stricmp(a,b)
|
|
#endif
|
|
|
|
QgsSpatiaLiteSourceSelect::QgsSpatiaLiteSourceSelect( QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode theWidgetMode ):
|
|
QgsAbstractDataSourceWidget( parent, fl, theWidgetMode )
|
|
{
|
|
setupUi( this );
|
|
connect( btnConnect, &QPushButton::clicked, this, &QgsSpatiaLiteSourceSelect::btnConnect_clicked );
|
|
connect( btnNew, &QPushButton::clicked, this, &QgsSpatiaLiteSourceSelect::btnNew_clicked );
|
|
connect( btnDelete, &QPushButton::clicked, this, &QgsSpatiaLiteSourceSelect::btnDelete_clicked );
|
|
connect( mSearchGroupBox, &QGroupBox::toggled, this, &QgsSpatiaLiteSourceSelect::mSearchGroupBox_toggled );
|
|
connect( mSearchTableEdit, &QLineEdit::textChanged, this, &QgsSpatiaLiteSourceSelect::mSearchTableEdit_textChanged );
|
|
connect( mSearchColumnComboBox, static_cast<void ( QComboBox::* )( const QString & )>( &QComboBox::currentIndexChanged ), this, &QgsSpatiaLiteSourceSelect::mSearchColumnComboBox_currentIndexChanged );
|
|
connect( mSearchModeComboBox, static_cast<void ( QComboBox::* )( const QString & )>( &QComboBox::currentIndexChanged ), this, &QgsSpatiaLiteSourceSelect::mSearchModeComboBox_currentIndexChanged );
|
|
connect( cbxAllowGeometrylessTables, &QCheckBox::stateChanged, this, &QgsSpatiaLiteSourceSelect::cbxAllowGeometrylessTables_stateChanged );
|
|
connect( cmbConnections, static_cast<void ( QComboBox::* )( int )>( &QComboBox::activated ), this, &QgsSpatiaLiteSourceSelect::cmbConnections_activated );
|
|
connect( mTablesTreeView, &QTreeView::clicked, this, &QgsSpatiaLiteSourceSelect::mTablesTreeView_clicked );
|
|
connect( mTablesTreeView, &QTreeView::doubleClicked, this, &QgsSpatiaLiteSourceSelect::mTablesTreeView_doubleClicked );
|
|
setupButtons( buttonBox );
|
|
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsSpatiaLiteSourceSelect::showHelp );
|
|
|
|
QgsSettings settings;
|
|
restoreGeometry( settings.value( QStringLiteral( "Windows/SpatiaLiteSourceSelect/geometry" ) ).toByteArray() );
|
|
mHoldDialogOpen->setChecked( settings.value( QStringLiteral( "Windows/SpatiaLiteSourceSelect/HoldDialogOpen" ), false ).toBool() );
|
|
|
|
setWindowTitle( tr( "Add SpatiaLite Layer(s)" ) );
|
|
btnEdit->hide(); // hide the edit button
|
|
btnSave->hide();
|
|
btnLoad->hide();
|
|
|
|
mStatsButton = new QPushButton( tr( "&Update Statistics" ) );
|
|
connect( mStatsButton, &QAbstractButton::clicked, this, &QgsSpatiaLiteSourceSelect::updateStatistics );
|
|
mStatsButton->setEnabled( false );
|
|
|
|
|
|
mBuildQueryButton = new QPushButton( tr( "&Set Filter" ) );
|
|
connect( mBuildQueryButton, &QAbstractButton::clicked, this, &QgsSpatiaLiteSourceSelect::buildQuery );
|
|
mBuildQueryButton->setEnabled( false );
|
|
|
|
if ( widgetMode() != QgsProviderRegistry::WidgetMode::None )
|
|
{
|
|
mHoldDialogOpen->hide();
|
|
}
|
|
|
|
buttonBox->addButton( mBuildQueryButton, QDialogButtonBox::ActionRole );
|
|
buttonBox->addButton( mStatsButton, QDialogButtonBox::ActionRole );
|
|
|
|
populateConnectionList();
|
|
|
|
mSearchModeComboBox->addItem( tr( "Wildcard" ) );
|
|
mSearchModeComboBox->addItem( tr( "RegExp" ) );
|
|
|
|
mSearchColumnComboBox->addItem( tr( "All" ) );
|
|
mSearchColumnComboBox->addItem( tr( "Table" ) );
|
|
mSearchColumnComboBox->addItem( tr( "Type" ) );
|
|
mSearchColumnComboBox->addItem( tr( "Geometry column" ) );
|
|
mSearchColumnComboBox->addItem( tr( "Sql" ) );
|
|
|
|
mProxyModel.setParent( this );
|
|
mProxyModel.setFilterKeyColumn( -1 );
|
|
mProxyModel.setFilterCaseSensitivity( Qt::CaseInsensitive );
|
|
mProxyModel.setDynamicSortFilter( true );
|
|
mProxyModel.setSourceModel( &mTableModel );
|
|
mTablesTreeView->setModel( &mProxyModel );
|
|
mTablesTreeView->setSortingEnabled( true );
|
|
|
|
connect( mTablesTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsSpatiaLiteSourceSelect::treeWidgetSelectionChanged );
|
|
|
|
//for Qt < 4.3.2, passing -1 to include all model columns
|
|
//in search does not seem to work
|
|
mSearchColumnComboBox->setCurrentIndex( 1 );
|
|
|
|
//hide the search options by default
|
|
//they will be shown when the user ticks
|
|
//the search options group box
|
|
mSearchLabel->setVisible( false );
|
|
mSearchColumnComboBox->setVisible( false );
|
|
mSearchColumnsLabel->setVisible( false );
|
|
mSearchModeComboBox->setVisible( false );
|
|
mSearchModeLabel->setVisible( false );
|
|
mSearchTableEdit->setVisible( false );
|
|
|
|
cbxAllowGeometrylessTables->setDisabled( true );
|
|
}
|
|
|
|
QgsSpatiaLiteSourceSelect::~QgsSpatiaLiteSourceSelect()
|
|
{
|
|
QgsSettings settings;
|
|
settings.setValue( QStringLiteral( "Windows/SpatiaLiteSourceSelect/geometry" ), saveGeometry() );
|
|
settings.setValue( QStringLiteral( "Windows/SpatiaLiteSourceSelect/HoldDialogOpen" ), mHoldDialogOpen->isChecked() );
|
|
}
|
|
|
|
|
|
// Remember which database is selected
|
|
void QgsSpatiaLiteSourceSelect::cmbConnections_activated( int )
|
|
{
|
|
dbChanged();
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::buildQuery()
|
|
{
|
|
setSql( mTablesTreeView->currentIndex() );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::updateStatistics()
|
|
{
|
|
QString subKey = cmbConnections->currentText();
|
|
int idx = subKey.indexOf( '@' );
|
|
if ( idx > 0 )
|
|
subKey.truncate( idx );
|
|
|
|
QString msg = tr( "Are you sure you want to update the internal statistics for DB: %1?\n\n"
|
|
"This could take a long time (depending on the DB size), "
|
|
"but implies better performance thereafter." ).arg( subKey );
|
|
QMessageBox::StandardButton result =
|
|
QMessageBox::information( this, tr( "Confirm Update Statistics" ), msg, QMessageBox::Ok | QMessageBox::Cancel );
|
|
if ( result != QMessageBox::Ok )
|
|
return;
|
|
|
|
// trying to connect to SpatiaLite DB
|
|
QgsSpatiaLiteConnection conn( subKey );
|
|
if ( conn.updateStatistics() )
|
|
{
|
|
QMessageBox::information( this, tr( "Update Statistics" ),
|
|
tr( "Internal statistics successfully updated for: %1" ).arg( subKey ) );
|
|
}
|
|
else
|
|
{
|
|
QMessageBox::critical( this, tr( "Update Statistics" ),
|
|
tr( "Error while updating internal statistics for: %1" ).arg( subKey ) );
|
|
}
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::cbxAllowGeometrylessTables_stateChanged( int )
|
|
{
|
|
btnConnect_clicked();
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::mTablesTreeView_clicked( const QModelIndex &index )
|
|
{
|
|
mBuildQueryButton->setEnabled( index.parent().isValid() );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::mTablesTreeView_doubleClicked( const QModelIndex &index )
|
|
{
|
|
setSql( index );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::mSearchGroupBox_toggled( bool checked )
|
|
{
|
|
if ( mSearchTableEdit->text().isEmpty() )
|
|
return;
|
|
|
|
mSearchTableEdit_textChanged( checked ? mSearchTableEdit->text() : QLatin1String( "" ) );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::mSearchTableEdit_textChanged( const QString &text )
|
|
{
|
|
if ( mSearchModeComboBox->currentText() == tr( "Wildcard" ) )
|
|
{
|
|
mProxyModel._setFilterWildcard( text );
|
|
}
|
|
else if ( mSearchModeComboBox->currentText() == tr( "RegExp" ) )
|
|
{
|
|
mProxyModel._setFilterRegExp( text );
|
|
}
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::mSearchColumnComboBox_currentIndexChanged( const QString &text )
|
|
{
|
|
if ( text == tr( "All" ) )
|
|
{
|
|
mProxyModel.setFilterKeyColumn( -1 );
|
|
}
|
|
else if ( text == tr( "Table" ) )
|
|
{
|
|
mProxyModel.setFilterKeyColumn( 0 );
|
|
}
|
|
else if ( text == tr( "Type" ) )
|
|
{
|
|
mProxyModel.setFilterKeyColumn( 1 );
|
|
}
|
|
else if ( text == tr( "Geometry column" ) )
|
|
{
|
|
mProxyModel.setFilterKeyColumn( 2 );
|
|
}
|
|
else if ( text == tr( "Sql" ) )
|
|
{
|
|
mProxyModel.setFilterKeyColumn( 3 );
|
|
}
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::mSearchModeComboBox_currentIndexChanged( const QString &text )
|
|
{
|
|
Q_UNUSED( text );
|
|
mSearchTableEdit_textChanged( mSearchTableEdit->text() );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::setLayerType( const QString &table, const QString &column, const QString &type )
|
|
{
|
|
mTableModel.setGeometryTypesForTable( table, column, type );
|
|
mTablesTreeView->sortByColumn( 0, Qt::AscendingOrder );
|
|
}
|
|
|
|
|
|
void QgsSpatiaLiteSourceSelect::populateConnectionList()
|
|
{
|
|
cmbConnections->clear();
|
|
Q_FOREACH ( const QString &name, QgsSpatiaLiteConnection::connectionList() )
|
|
{
|
|
// retrieving the SQLite DB name and full path
|
|
QString text = name + tr( "@" ) + QgsSpatiaLiteConnection::connectionPath( name );
|
|
cmbConnections->addItem( text );
|
|
}
|
|
setConnectionListPosition();
|
|
|
|
btnConnect->setDisabled( cmbConnections->count() == 0 );
|
|
btnDelete->setDisabled( cmbConnections->count() == 0 );
|
|
|
|
cmbConnections->setDisabled( cmbConnections->count() == 0 );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::btnNew_clicked()
|
|
{
|
|
if ( ! newConnection( this ) )
|
|
return;
|
|
populateConnectionList();
|
|
emit connectionsChanged();
|
|
}
|
|
|
|
bool QgsSpatiaLiteSourceSelect::newConnection( QWidget *parent )
|
|
{
|
|
// Retrieve last used project dir from persistent settings
|
|
QgsSettings settings;
|
|
QString lastUsedDir = settings.value( QStringLiteral( "UI/lastSpatiaLiteDir" ), QDir::homePath() ).toString();
|
|
|
|
QString myFile = QFileDialog::getOpenFileName( parent,
|
|
tr( "Choose a SpatiaLite/SQLite DB to open" ),
|
|
lastUsedDir, tr( "SpatiaLite DB" ) + " (*.sqlite *.db *.sqlite3 *.db3 *.s3db);;" + tr( "All files" ) + " (*)" );
|
|
|
|
if ( myFile.isEmpty() )
|
|
return false;
|
|
|
|
QFileInfo myFI( myFile );
|
|
QString myPath = myFI.path();
|
|
QString myName = myFI.fileName();
|
|
QString savedName = myFI.fileName();
|
|
QString baseKey = QStringLiteral( "/SpatiaLite/connections/" );
|
|
|
|
// TODO: keep the test
|
|
//handle = openSpatiaLiteDb( myFI.canonicalFilePath() );
|
|
//if ( !handle )
|
|
// return false;
|
|
// OK, this one is a valid SpatiaLite DB
|
|
//closeSpatiaLiteDb( handle );
|
|
|
|
// if there is already a connection with this name, ask for a new name
|
|
while ( ! settings.value( baseKey + savedName + "/sqlitepath", "" ).toString().isEmpty() )
|
|
{
|
|
bool ok;
|
|
savedName = QInputDialog::getText( nullptr, tr( "Cannot add connection '%1'" ).arg( myName ),
|
|
tr( "A connection with the same name already exists,\nplease provide a new name:" ), QLineEdit::Normal,
|
|
QLatin1String( "" ), &ok );
|
|
if ( !ok || savedName.isEmpty() )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Persist last used SpatiaLite dir
|
|
settings.setValue( QStringLiteral( "UI/lastSpatiaLiteDir" ), myPath );
|
|
// inserting this SQLite DB path
|
|
settings.setValue( baseKey + "selected", savedName );
|
|
settings.setValue( baseKey + savedName + "/sqlitepath", myFI.canonicalFilePath() );
|
|
return true;
|
|
}
|
|
|
|
QString QgsSpatiaLiteSourceSelect::layerURI( const QModelIndex &index )
|
|
{
|
|
QString tableName = mTableModel.itemFromIndex( index.sibling( index.row(), 0 ) )->text();
|
|
QString geomColumnName = mTableModel.itemFromIndex( index.sibling( index.row(), 2 ) )->text();
|
|
QString sql = mTableModel.itemFromIndex( index.sibling( index.row(), 3 ) )->text();
|
|
|
|
if ( geomColumnName.contains( QLatin1String( " AS " ) ) )
|
|
{
|
|
int a = geomColumnName.indexOf( QLatin1String( " AS " ) );
|
|
QString typeName = geomColumnName.mid( a + 4 ); //only the type name
|
|
geomColumnName = geomColumnName.left( a ); //only the geom column name
|
|
QString geomFilter;
|
|
|
|
if ( typeName == QLatin1String( "POINT" ) )
|
|
{
|
|
geomFilter = QStringLiteral( "geometrytype(\"%1\") IN ('POINT','MULTIPOINT')" ).arg( geomColumnName );
|
|
}
|
|
else if ( typeName == QLatin1String( "LINESTRING" ) )
|
|
{
|
|
geomFilter = QStringLiteral( "geometrytype(\"%1\") IN ('LINESTRING','MULTILINESTRING')" ).arg( geomColumnName );
|
|
}
|
|
else if ( typeName == QLatin1String( "POLYGON" ) )
|
|
{
|
|
geomFilter = QStringLiteral( "geometrytype(\"%1\") IN ('POLYGON','MULTIPOLYGON')" ).arg( geomColumnName );
|
|
}
|
|
|
|
if ( !geomFilter.isEmpty() && !sql.contains( geomFilter ) )
|
|
{
|
|
if ( !sql.isEmpty() )
|
|
{
|
|
sql += QLatin1String( " AND " );
|
|
}
|
|
|
|
sql += geomFilter;
|
|
}
|
|
}
|
|
|
|
QgsDataSourceUri uri( connectionInfo() );
|
|
uri.setDataSource( QLatin1String( "" ), tableName, geomColumnName, sql, QLatin1String( "" ) );
|
|
return uri.uri();
|
|
}
|
|
|
|
// Slot for deleting an existing connection
|
|
void QgsSpatiaLiteSourceSelect::btnDelete_clicked()
|
|
{
|
|
QString subKey = cmbConnections->currentText();
|
|
int idx = subKey.indexOf( '@' );
|
|
if ( idx > 0 )
|
|
subKey.truncate( idx );
|
|
|
|
QString msg = tr( "Are you sure you want to remove the %1 connection and all associated settings?" ).arg( subKey );
|
|
QMessageBox::StandardButton result =
|
|
QMessageBox::information( this, tr( "Confirm Delete" ), msg, QMessageBox::Ok | QMessageBox::Cancel );
|
|
if ( result != QMessageBox::Ok )
|
|
return;
|
|
|
|
QgsSpatiaLiteConnection::deleteConnection( subKey );
|
|
|
|
populateConnectionList();
|
|
emit connectionsChanged();
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::addButtonClicked()
|
|
{
|
|
m_selectedTables.clear();
|
|
|
|
typedef QMap < int, bool >schemaInfo;
|
|
QMap < QString, schemaInfo > dbInfo;
|
|
|
|
QItemSelection selection = mTablesTreeView->selectionModel()->selection();
|
|
QModelIndexList selectedIndices = selection.indexes();
|
|
QStandardItem *currentItem = nullptr;
|
|
|
|
QModelIndexList::const_iterator selected_it = selectedIndices.constBegin();
|
|
for ( ; selected_it != selectedIndices.constEnd(); ++selected_it )
|
|
{
|
|
if ( !selected_it->parent().isValid() )
|
|
{
|
|
//top level items only contain the schema names
|
|
continue;
|
|
}
|
|
currentItem = mTableModel.itemFromIndex( mProxyModel.mapToSource( *selected_it ) );
|
|
if ( !currentItem )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
QString currentSchemaName = currentItem->parent()->text();
|
|
|
|
int currentRow = currentItem->row();
|
|
if ( !dbInfo[currentSchemaName].contains( currentRow ) )
|
|
{
|
|
dbInfo[currentSchemaName][currentRow] = true;
|
|
m_selectedTables << layerURI( mProxyModel.mapToSource( *selected_it ) );
|
|
}
|
|
}
|
|
|
|
if ( m_selectedTables.empty() )
|
|
{
|
|
QMessageBox::information( this, tr( "Select Table" ), tr( "You must select a table in order to add a Layer." ) );
|
|
}
|
|
else
|
|
{
|
|
emit addDatabaseLayers( m_selectedTables, QStringLiteral( "spatialite" ) );
|
|
if ( widgetMode() == QgsProviderRegistry::WidgetMode::None && ! mHoldDialogOpen->isChecked() )
|
|
{
|
|
accept();
|
|
}
|
|
}
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::btnConnect_clicked()
|
|
{
|
|
cbxAllowGeometrylessTables->setEnabled( false );
|
|
|
|
QString subKey = cmbConnections->currentText();
|
|
int idx = subKey.indexOf( '@' );
|
|
if ( idx > 0 )
|
|
subKey.truncate( idx );
|
|
|
|
// trying to connect to SpatiaLite DB
|
|
QgsSpatiaLiteConnection conn( subKey );
|
|
mSqlitePath = conn.path();
|
|
|
|
QApplication::setOverrideCursor( Qt::WaitCursor );
|
|
|
|
QgsSpatiaLiteConnection::Error err;
|
|
err = conn.fetchTables( cbxAllowGeometrylessTables->isChecked() );
|
|
|
|
QApplication::restoreOverrideCursor();
|
|
|
|
if ( err != QgsSpatiaLiteConnection::NoError )
|
|
{
|
|
QString errCause = conn.errorMessage();
|
|
switch ( err )
|
|
{
|
|
case QgsSpatiaLiteConnection::NotExists:
|
|
QMessageBox::critical( this, tr( "SpatiaLite DB Open Error" ),
|
|
tr( "Database does not exist: %1" ).arg( mSqlitePath ) );
|
|
break;
|
|
case QgsSpatiaLiteConnection::FailedToOpen:
|
|
QMessageBox::critical( this, tr( "SpatiaLite DB Open Error" ),
|
|
tr( "Failure while connecting to: %1\n\n%2" ).arg( mSqlitePath, errCause ) );
|
|
break;
|
|
case QgsSpatiaLiteConnection::FailedToGetTables:
|
|
QMessageBox::critical( this, tr( "SpatiaLite getTableInfo Error" ),
|
|
tr( "Failure exploring tables from: %1\n\n%2" ).arg( mSqlitePath, errCause ) );
|
|
break;
|
|
case QgsSpatiaLiteConnection::FailedToCheckMetadata:
|
|
QMessageBox::critical( this, tr( "SpatiaLite metadata check failed" ),
|
|
tr( "Failure getting table metadata... is %1 really a SpatiaLite database?\n\n%2" ).arg( mSqlitePath, errCause ) );
|
|
break;
|
|
default:
|
|
QMessageBox::critical( this, tr( "SpatiaLite Error" ),
|
|
tr( "Unexpected error when working with %1\n\n%2" ).arg( mSqlitePath, errCause ) );
|
|
}
|
|
mSqlitePath = QString();
|
|
return;
|
|
}
|
|
|
|
QModelIndex rootItemIndex = mTableModel.indexFromItem( mTableModel.invisibleRootItem() );
|
|
mTableModel.removeRows( 0, mTableModel.rowCount( rootItemIndex ), rootItemIndex );
|
|
|
|
// populate the table list
|
|
// get the list of suitable tables and columns and populate the UI
|
|
|
|
mTableModel.setSqliteDb( subKey );
|
|
|
|
QList<QgsSpatiaLiteConnection::TableEntry> tables = conn.tables();
|
|
Q_FOREACH ( const QgsSpatiaLiteConnection::TableEntry &table, tables )
|
|
{
|
|
mTableModel.addTableEntry( table.type, table.tableName, table.column, QLatin1String( "" ) );
|
|
}
|
|
|
|
if ( cmbConnections->count() > 0 )
|
|
{
|
|
mStatsButton->setEnabled( true );
|
|
}
|
|
|
|
mTablesTreeView->sortByColumn( 0, Qt::AscendingOrder );
|
|
|
|
//expand all the toplevel items
|
|
int numTopLevelItems = mTableModel.invisibleRootItem()->rowCount();
|
|
for ( int i = 0; i < numTopLevelItems; ++i )
|
|
{
|
|
mTablesTreeView->expand( mProxyModel.mapFromSource( mTableModel.indexFromItem( mTableModel.invisibleRootItem()->child( i ) ) ) );
|
|
}
|
|
mTablesTreeView->resizeColumnToContents( 0 );
|
|
mTablesTreeView->resizeColumnToContents( 1 );
|
|
|
|
cbxAllowGeometrylessTables->setEnabled( true );
|
|
}
|
|
|
|
QStringList QgsSpatiaLiteSourceSelect::selectedTables()
|
|
{
|
|
return m_selectedTables;
|
|
}
|
|
|
|
QString QgsSpatiaLiteSourceSelect::connectionInfo()
|
|
{
|
|
return QStringLiteral( "dbname='%1'" ).arg( QString( mSqlitePath ).replace( '\'', QLatin1String( "\\'" ) ) );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::setSql( const QModelIndex &index )
|
|
{
|
|
QModelIndex idx = mProxyModel.mapToSource( index );
|
|
QString tableName = mTableModel.itemFromIndex( idx.sibling( idx.row(), 0 ) )->text();
|
|
|
|
QgsVectorLayer *vlayer = new QgsVectorLayer( layerURI( idx ), tableName, QStringLiteral( "spatialite" ) );
|
|
|
|
if ( !vlayer->isValid() )
|
|
{
|
|
delete vlayer;
|
|
return;
|
|
}
|
|
|
|
// create a query builder object
|
|
QgsQueryBuilder *gb = new QgsQueryBuilder( vlayer, this );
|
|
if ( gb->exec() )
|
|
{
|
|
mTableModel.setSql( mProxyModel.mapToSource( index ), gb->sql() );
|
|
}
|
|
|
|
delete gb;
|
|
delete vlayer;
|
|
}
|
|
|
|
QString QgsSpatiaLiteSourceSelect::fullDescription( const QString &table, const QString &column, const QString &type )
|
|
{
|
|
QString full_desc;
|
|
full_desc += table + "\" (" + column + ") " + type;
|
|
return full_desc;
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::dbChanged()
|
|
{
|
|
// Remember which database was selected.
|
|
QgsSettings settings;
|
|
settings.setValue( QStringLiteral( "SpatiaLite/connections/selected" ), cmbConnections->currentText() );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::refresh()
|
|
{
|
|
populateConnectionList();
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::setConnectionListPosition()
|
|
{
|
|
QgsSettings settings;
|
|
// If possible, set the item currently displayed database
|
|
QString toSelect = settings.value( QStringLiteral( "SpatiaLite/connections/selected" ) ).toString();
|
|
|
|
toSelect += '@' + settings.value( "/SpatiaLite/connections/" + toSelect + "/sqlitepath" ).toString();
|
|
|
|
cmbConnections->setCurrentIndex( cmbConnections->findText( toSelect ) );
|
|
|
|
if ( cmbConnections->currentIndex() < 0 )
|
|
{
|
|
if ( toSelect.isNull() )
|
|
cmbConnections->setCurrentIndex( 0 );
|
|
else
|
|
cmbConnections->setCurrentIndex( cmbConnections->count() - 1 );
|
|
}
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::setSearchExpression( const QString ®exp )
|
|
{
|
|
Q_UNUSED( regexp );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::treeWidgetSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected )
|
|
{
|
|
Q_UNUSED( deselected )
|
|
emit enableButtons( !selected.isEmpty() );
|
|
}
|
|
|
|
void QgsSpatiaLiteSourceSelect::showHelp()
|
|
{
|
|
QgsHelp::openHelp( QStringLiteral( "managing_data_source/opening_data.html#spatialite-layers" ) );
|
|
}
|