Skip to content

Commit

Permalink
New database table widget new signals & tests
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Mar 10, 2020
1 parent d1404ac commit b42bddd
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 67 deletions.
22 changes: 18 additions & 4 deletions python/gui/auto_generated/qgsnewdatabasetablenamewidget.sip.in
Expand Up @@ -20,6 +20,11 @@ The table name is validated for uniqueness and the selected
data item provider, schema and table names can be retrieved with
getters.

.. warning::

The data provider that originated the data item provider
must support the connections API

.. versionadded:: 3.14
%End

Expand All @@ -35,8 +40,9 @@ getters.
Constructs a new QgsNewDatabaseTableNameWidget

:param browserModel: an existing browser model (typically from app), if NULL an instance will be created
:param providersFilter: optional white list of item provider names (not data providers!) that should be
shown in the widget, if not specified all providers data items with database capabilities will be shown
:param providersFilter: optional white list of data provider keys that should be
shown in the widget, if not specified all providers data items with database
capabilities will be shown
:param parent: optional parent for this widget
%End

Expand All @@ -50,9 +56,9 @@ Returns the currently selected schema for the new table
Returns the current name of the new table
%End

QString dataItemProviderName();
QString dataProviderKey();
%Docstring
Returns the currently selected data item provider name (which is NOT the data provider key!) for the new table
Returns the currently selected data item provider key
%End

bool isValid() const;
Expand Down Expand Up @@ -88,6 +94,14 @@ This signal is emitted when the user enters a table name
:param tableName: the name of the new table
%End

void providerKeyChanged( const QString &providerKey );
%Docstring
This signal is emitted when the selects a data provider or a schema name
that has a different data provider than the previously selected one.

:param providerKey: the data provider key of the selected schema
%End


};

Expand Down
118 changes: 89 additions & 29 deletions src/gui/qgsnewdatabasetablenamewidget.cpp
Expand Up @@ -20,6 +20,8 @@
#include "qgsapplication.h"
#include "qgsdataitemproviderregistry.h"
#include "qgsdataitemprovider.h"
#include "qgsproviderregistry.h"
#include "qgsprovidermetadata.h"

QgsNewDatabaseTableNameWidget::QgsNewDatabaseTableNameWidget(
QgsBrowserGuiModel *browserModel,
Expand All @@ -28,7 +30,6 @@ QgsNewDatabaseTableNameWidget::QgsNewDatabaseTableNameWidget(
: QWidget( parent )
{


// Initalize the browser
if ( ! browserModel )
{
Expand All @@ -43,6 +44,8 @@ QgsNewDatabaseTableNameWidget::QgsNewDatabaseTableNameWidget(

setupUi( this );

mValidationResults->setStyleSheet( QStringLiteral( "* { font-weight: bold; color: red; }" ) );

QStringList hiddenProviders
{
QStringLiteral( "special:Favorites" ),
Expand All @@ -55,15 +58,26 @@ QgsNewDatabaseTableNameWidget::QgsNewDatabaseTableNameWidget(
const auto providerList { QgsApplication::dataItemProviderRegistry()->providers() };
for ( const auto &provider : providerList )
{
if ( provider->dataProviderKey().isEmpty() )
{
hiddenProviders.push_back( provider->name() );
continue;
}
QgsProviderMetadata *md { QgsProviderRegistry::instance()->providerMetadata( provider->dataProviderKey() ) };
if ( ! md )
{
hiddenProviders.push_back( provider->name() );
continue;
}
if ( provider->capabilities() & QgsDataProvider::DataCapability::Database )
{
if ( ! providersFilter.isEmpty() && ! providersFilter.contains( provider->name() ) )
if ( ! providersFilter.isEmpty() && ! providersFilter.contains( provider->dataProviderKey() ) )
{
hiddenProviders.push_back( provider->name() );
}
else
{
mShownProviders.insert( provider->name() );
mShownProviders.insert( provider->dataProviderKey() );
}
}
else
Expand Down Expand Up @@ -98,26 +112,41 @@ QgsNewDatabaseTableNameWidget::QgsNewDatabaseTableNameWidget(
const QgsDataCollectionItem *collectionItem = qobject_cast<const QgsDataCollectionItem *>( dataItem );
if ( collectionItem )
{
if ( mShownProviders.contains( collectionItem->name() ) )
const QString providerKey { QgsApplication::dataItemProviderRegistry()->dataProviderKey( dataItem->providerKey() ) };
if ( mShownProviders.contains( providerKey ) )
{
if ( mDataProviderName != collectionItem->name() )
bool validationRequired { false };
const QString oldSchema { mSchemaName };

if ( mDataProviderKey != providerKey )
{
mSchemaName.clear();
mDataProviderName = collectionItem->name();
emit providerKeyChanged( providerKey );
mDataProviderKey = providerKey;
validate();
}

if ( collectionItem->layerCollection( ) )
{
mSchemaName = collectionItem->name(); // it may be cleared
if ( oldSchema != collectionItem->name() )
{
emit schemaNameChanged( mSchemaName );
validationRequired = true;
}
}

if ( validationRequired )
{
validate();
}
}
else
{
mSchemaName = collectionItem->name();
emit schemaNameChanged( mSchemaName );
}
validate();
}
}
}
} );

mValidationResults->hide();
validate();

}

Expand All @@ -131,16 +160,17 @@ QString QgsNewDatabaseTableNameWidget::table()
return mTableName;
}

QString QgsNewDatabaseTableNameWidget::dataItemProviderName()
QString QgsNewDatabaseTableNameWidget::dataProviderKey()
{
return mDataProviderName;
return mDataProviderKey;
}

void QgsNewDatabaseTableNameWidget::validate()
{
const bool wasValid { mIsValid };
// Check table uniqueness
mIsValid = ! mDataProviderName.isEmpty() &&
mShownProviders.contains( mDataProviderName ) &&
mIsValid = ! mDataProviderKey.isEmpty() &&
mShownProviders.contains( mDataProviderKey ) &&
! mSchemaName.isEmpty() &&
! mTableName.isEmpty() &&
! tableNames( ).contains( mTableName );
Expand All @@ -149,27 +179,39 @@ void QgsNewDatabaseTableNameWidget::validate()

if ( ! mIsValid )
{

if ( mTableName.isEmpty() )
if ( mTableName.isEmpty() && mSchemaName.isEmpty() )
{
mValidationError = tr( "Enter a unique name for the new table" );
mValidationError = tr( "Select a database schema and enter a unique name for the new table" );
}
else if ( ! mTableName.isEmpty() &&
! mSchemaName.isEmpty() &&
tableNames( ).contains( mTableName ) )
{
mValidationError = tr( "A table named '%1' already exists" ).arg( mTableName );
}
else if ( mSchemaName.isEmpty() )
{
mValidationError = tr( "Select a database schema" );
}
else if ( mTableName.isEmpty() )
{
mValidationError = tr( "Enter a unique name for the new table" );
}
else if ( tableNames( ).contains( mTableName ) )
{
mValidationError = tr( "A table named '%1' already exists" ).arg( mTableName );
}
else
{
mValidationError = tr( "Select a schema and enter a unique name for the new table" );
mValidationError = tr( "Select a database schema and enter a unique name for the new table" );
}
}
mValidationResults->setText( mValidationError );
mValidationResults->setVisible( ! mIsValid );
emit validationChanged( mIsValid );
if ( wasValid != mIsValid )
{
emit validationChanged( mIsValid );
}
}

QStringList QgsNewDatabaseTableNameWidget::tableNames()
Expand All @@ -178,16 +220,34 @@ QStringList QgsNewDatabaseTableNameWidget::tableNames()
QModelIndex index { mBrowserTreeView->currentIndex() };
if ( index.isValid() )
{
for ( int row = 0; row < mBrowserProxyModel.rowCount( ); ++row )
QgsDataItem *dataItem { mBrowserProxyModel.dataItem( index ) };
if ( dataItem )
{
// Column 1 contains the
index = mBrowserProxyModel.index( row, 1, index );
if ( index.isValid() )
const QString dataProviderKey { QgsApplication::dataItemProviderRegistry()->dataProviderKey( dataItem->providerKey() ) };
if ( ! dataProviderKey.isEmpty() )
{
const QgsDataItem *dataItem { mBrowserProxyModel.dataItem( index ) };
if ( dataItem )
QgsProviderMetadata *md { QgsProviderRegistry::instance()->providerMetadata( dataProviderKey ) };
if ( md )
{
tableNames.push_back( dataItem->name() );
QgsDataItem *parentDataItem { dataItem->parent() };
if ( parentDataItem )
{
QgsAbstractProviderConnection *conn { md->findConnection( parentDataItem->name() ) };
const QString cacheKey { conn->uri() + dataItem->name() };
if ( mTableNamesCache.contains( cacheKey ) )
{
tableNames = mTableNamesCache.value( cacheKey );
}
else if ( conn && static_cast<QgsAbstractDatabaseProviderConnection *>( conn ) )
{
const auto tables { static_cast<QgsAbstractDatabaseProviderConnection *>( conn )->tables( dataItem->name() ) };
for ( const auto &tp : tables )
{
tableNames.push_back( tp.tableName() );
}
mTableNamesCache[ cacheKey ] = tableNames;
}
}
}
}
}
Expand Down
26 changes: 21 additions & 5 deletions src/gui/qgsnewdatabasetablenamewidget.h
Expand Up @@ -34,6 +34,9 @@
* data item provider, schema and table names can be retrieved with
* getters.
*
* \warning The data provider that originated the data item provider
* must support the connections API
*
* \since QGIS 3.14
*/
class GUI_EXPORT QgsNewDatabaseTableNameWidget : public QWidget, private Ui::QgsNewDatabaseTableNameWidget
Expand All @@ -46,8 +49,9 @@ class GUI_EXPORT QgsNewDatabaseTableNameWidget : public QWidget, private Ui::Qgs
* Constructs a new QgsNewDatabaseTableNameWidget
*
* \param browserModel an existing browser model (typically from app), if NULL an instance will be created
* \param providersFilter optional white list of item provider names (not data providers!) that should be
* shown in the widget, if not specified all providers data items with database capabilities will be shown
* \param providersFilter optional white list of data provider keys that should be
* shown in the widget, if not specified all providers data items with database
* capabilities will be shown
* \param parent optional parent for this widget
*/
explicit QgsNewDatabaseTableNameWidget( QgsBrowserGuiModel *browserModel = nullptr,
Expand All @@ -65,9 +69,9 @@ class GUI_EXPORT QgsNewDatabaseTableNameWidget : public QWidget, private Ui::Qgs
QString table();

/**
* Returns the currently selected data item provider name (which is NOT the data provider key!) for the new table
* Returns the currently selected data item provider key
*/
QString dataItemProviderName();
QString dataProviderKey();

/**
* Returns TRUE if the widget contains a valid new table name
Expand Down Expand Up @@ -102,19 +106,31 @@ class GUI_EXPORT QgsNewDatabaseTableNameWidget : public QWidget, private Ui::Qgs
*/
void tableNameChanged( const QString &tableName );

/**
* This signal is emitted when the selects a data provider or a schema name
* that has a different data provider than the previously selected one.
*
* \param providerKey the data provider key of the selected schema
*/
void providerKeyChanged( const QString &providerKey );


private:

QgsBrowserProxyModel mBrowserProxyModel;
QgsBrowserGuiModel *mBrowserModel = nullptr;
void validate();
QStringList tableNames();
QString mDataProviderName;
QString mDataProviderKey;
QString mTableName;
QString mSchemaName;
//! List of data provider keys of shown providers
QSet<QString> mShownProviders;
bool mIsValid = false;
QString mValidationError;
//! Table names cache
QMap<QString, QStringList> mTableNamesCache;


// For testing:
friend class TestQgsNewDatabaseTableNameWidget;
Expand Down

0 comments on commit b42bddd

Please sign in to comment.