mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-07 00:03:52 -05:00
QgsNewDatabaseTableNameWidget implementation (WIP)
This commit is contained in:
parent
7edf1f286b
commit
700a411285
@ -133,19 +133,40 @@ filterByLayerType() is ``True``.
|
|||||||
.. seealso:: :py:func:`setFilterByLayerType`
|
.. seealso:: :py:func:`setFilterByLayerType`
|
||||||
%End
|
%End
|
||||||
|
|
||||||
void setDataItemProviderKeyFilter( const QStringList &filter );
|
void setDataItemProviderKeyFilter( const QStringList &hiddenItemsFilter );
|
||||||
%Docstring
|
%Docstring
|
||||||
Sets the customization filters for data items based on item's data provider key
|
Sets a filter to hide data items based on on item's data provider key.
|
||||||
|
|
||||||
By default browser model shows all items from all available data items provider and few special
|
By default browser model shows all items from all available data item providers and few special
|
||||||
items (e.g. Favourites). To customize the behavior, set the filter to not load certain data items.
|
items (e.g. Favourites).
|
||||||
|
To customize the behavior, set the filter to not load certain data items.
|
||||||
The items that are not based on data item providers have prefix "special:", for example
|
The items that are not based on data item providers have prefix "special:", for example
|
||||||
"special:Favourites", "special:Home", "PostGIS", "MSSQL"
|
"special:Favorites", "special:Home", "PostGIS", "MSSQL"
|
||||||
|
|
||||||
All items created by the providers listed in filter are hidden from the layer tree.
|
All items created by the providers listed in filter are hidden from the layer tree.
|
||||||
This filter is always evaluated.
|
This filter is always evaluated.
|
||||||
|
|
||||||
|
:param hiddenItemsFilter: a list of data provider prefixes that will be hidden.
|
||||||
|
|
||||||
.. versionadded:: 3.12
|
.. versionadded:: 3.12
|
||||||
|
%End
|
||||||
|
|
||||||
|
bool showLayers() const;
|
||||||
|
%Docstring
|
||||||
|
Returns ``True`` if layers must be shown, this flag is ``True`` by default.
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`setShowLayers`
|
||||||
|
|
||||||
|
.. versionadded:: 3.14
|
||||||
|
%End
|
||||||
|
|
||||||
|
void setShowLayers( bool showLayers );
|
||||||
|
%Docstring
|
||||||
|
Sets show layers to ``showLayers``
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`showLayers`
|
||||||
|
|
||||||
|
.. versionadded:: 3.14
|
||||||
%End
|
%End
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
100
python/gui/auto_generated/qgsnewdatabasetablenamewidget.sip.in
Normal file
100
python/gui/auto_generated/qgsnewdatabasetablenamewidget.sip.in
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* This file has been generated automatically from *
|
||||||
|
* *
|
||||||
|
* src/gui/qgsnewdatabasetablenamewidget.h *
|
||||||
|
* *
|
||||||
|
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class QgsNewDatabaseTableNameWidget : QWidget
|
||||||
|
{
|
||||||
|
%Docstring
|
||||||
|
The QgsNewDatabaseTableNameWidget class embeds the browser view to
|
||||||
|
select a DB schema and a new table name.
|
||||||
|
|
||||||
|
The table name is validated for uniqueness and the selected
|
||||||
|
data item provider, schema and table names can be retrieved with
|
||||||
|
getters.
|
||||||
|
|
||||||
|
.. versionadded:: 3.14
|
||||||
|
%End
|
||||||
|
|
||||||
|
%TypeHeaderCode
|
||||||
|
#include "qgsnewdatabasetablenamewidget.h"
|
||||||
|
%End
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit QgsNewDatabaseTableNameWidget( QgsBrowserGuiModel *browserModel = 0,
|
||||||
|
const QStringList &providersFilter = QStringList(),
|
||||||
|
QWidget *parent = 0 );
|
||||||
|
%Docstring
|
||||||
|
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 parent: optional parent for this widget
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString schema();
|
||||||
|
%Docstring
|
||||||
|
Returns the currently selected schema for the new table
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString table();
|
||||||
|
%Docstring
|
||||||
|
Returns the current name of the new table
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString dataItemProviderName();
|
||||||
|
%Docstring
|
||||||
|
Returns the currently selected data item provider name (which is NOT the data provider key!) for the new table
|
||||||
|
%End
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
%Docstring
|
||||||
|
Returns ``True`` if the widget contains a valid new table name
|
||||||
|
%End
|
||||||
|
|
||||||
|
QString validationError();
|
||||||
|
%Docstring
|
||||||
|
Returns the validation error or an empty string is the widget status is valid
|
||||||
|
%End
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void validationChanged( bool isValid );
|
||||||
|
%Docstring
|
||||||
|
This signal is emitted whenever the validation status of the widget changes.
|
||||||
|
|
||||||
|
:param isValid: ``True`` if the current status of the widget is valid
|
||||||
|
%End
|
||||||
|
|
||||||
|
void schemaNameChanged( const QString &schemaName );
|
||||||
|
%Docstring
|
||||||
|
This signal is emitted when the user selects a schema.
|
||||||
|
|
||||||
|
:param schemaName: the name of the selected schema
|
||||||
|
%End
|
||||||
|
|
||||||
|
void tableNameChanged( const QString &tableName );
|
||||||
|
%Docstring
|
||||||
|
This signal is emitted when the user enters a table name
|
||||||
|
|
||||||
|
:param tableName: the name of the new table
|
||||||
|
%End
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* This file has been generated automatically from *
|
||||||
|
* *
|
||||||
|
* src/gui/qgsnewdatabasetablenamewidget.h *
|
||||||
|
* *
|
||||||
|
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||||
|
************************************************************************/
|
||||||
@ -59,6 +59,7 @@
|
|||||||
%Include auto_generated/qgsdataitemguiprovider.sip
|
%Include auto_generated/qgsdataitemguiprovider.sip
|
||||||
%Include auto_generated/qgsdataitemguiproviderregistry.sip
|
%Include auto_generated/qgsdataitemguiproviderregistry.sip
|
||||||
%Include auto_generated/qgsdatasourceselectdialog.sip
|
%Include auto_generated/qgsdatasourceselectdialog.sip
|
||||||
|
%Include auto_generated/qgsnewdatabasetablenamewidget.sip
|
||||||
%Include auto_generated/qgsdetaileditemdata.sip
|
%Include auto_generated/qgsdetaileditemdata.sip
|
||||||
%Include auto_generated/qgsdetaileditemdelegate.sip
|
%Include auto_generated/qgsdetaileditemdelegate.sip
|
||||||
%Include auto_generated/qgsdetaileditemwidget.sip
|
%Include auto_generated/qgsdetaileditemwidget.sip
|
||||||
|
|||||||
@ -153,9 +153,28 @@ bool QgsBrowserProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &s
|
|||||||
if ( !filterAcceptsProviderKey( sourceIndex ) || !filterRootAcceptsProviderKey( sourceIndex ) )
|
if ( !filterAcceptsProviderKey( sourceIndex ) || !filterRootAcceptsProviderKey( sourceIndex ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if ( ! mShowLayers )
|
||||||
|
{
|
||||||
|
QgsDataItem *item = mModel->dataItem( sourceIndex );
|
||||||
|
if ( qobject_cast< QgsLayerItem * >( item ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return filterAcceptsItem( sourceIndex ) || filterAcceptsAncestor( sourceIndex ) || filterAcceptsDescendant( sourceIndex );
|
return filterAcceptsItem( sourceIndex ) || filterAcceptsAncestor( sourceIndex ) || filterAcceptsDescendant( sourceIndex );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QgsBrowserProxyModel::showLayers() const
|
||||||
|
{
|
||||||
|
return mShowLayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsBrowserProxyModel::setShowLayers( bool showLayers )
|
||||||
|
{
|
||||||
|
mShowLayers = showLayers;
|
||||||
|
}
|
||||||
|
|
||||||
QgsMapLayerType QgsBrowserProxyModel::layerType() const
|
QgsMapLayerType QgsBrowserProxyModel::layerType() const
|
||||||
{
|
{
|
||||||
return mLayerType;
|
return mLayerType;
|
||||||
|
|||||||
@ -144,19 +144,38 @@ class CORE_EXPORT QgsBrowserProxyModel : public QSortFilterProxyModel
|
|||||||
void setLayerType( QgsMapLayerType type );
|
void setLayerType( QgsMapLayerType type );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the customization filters for data items based on item's data provider key
|
* Sets a filter to hide data items based on on item's data provider key.
|
||||||
*
|
*
|
||||||
* By default browser model shows all items from all available data items provider and few special
|
* By default browser model shows all items from all available data item providers and few special
|
||||||
* items (e.g. Favourites). To customize the behavior, set the filter to not load certain data items.
|
* items (e.g. Favourites).
|
||||||
|
* To customize the behavior, set the filter to not load certain data items.
|
||||||
* The items that are not based on data item providers have prefix "special:", for example
|
* The items that are not based on data item providers have prefix "special:", for example
|
||||||
* "special:Favourites", "special:Home", "PostGIS", "MSSQL"
|
* "special:Favorites", "special:Home", "PostGIS", "MSSQL"
|
||||||
*
|
*
|
||||||
* All items created by the providers listed in filter are hidden from the layer tree.
|
* All items created by the providers listed in filter are hidden from the layer tree.
|
||||||
* This filter is always evaluated.
|
* This filter is always evaluated.
|
||||||
*
|
*
|
||||||
|
* \param hiddenItemsFilter a list of data provider prefixes that will be hidden.
|
||||||
|
*
|
||||||
* \since QGIS 3.12
|
* \since QGIS 3.12
|
||||||
*/
|
*/
|
||||||
void setDataItemProviderKeyFilter( const QStringList &filter );
|
void setDataItemProviderKeyFilter( const QStringList &hiddenItemsFilter );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns TRUE if layers must be shown, this flag is TRUE by default.
|
||||||
|
*
|
||||||
|
* \see setShowLayers()
|
||||||
|
* \since QGIS 3.14
|
||||||
|
*/
|
||||||
|
bool showLayers() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets show layers to \a showLayers
|
||||||
|
*
|
||||||
|
* \see showLayers()
|
||||||
|
* \since QGIS 3.14
|
||||||
|
*/
|
||||||
|
void setShowLayers( bool showLayers );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -172,6 +191,7 @@ class CORE_EXPORT QgsBrowserProxyModel : public QSortFilterProxyModel
|
|||||||
Qt::CaseSensitivity mCaseSensitivity = Qt::CaseInsensitive;
|
Qt::CaseSensitivity mCaseSensitivity = Qt::CaseInsensitive;
|
||||||
|
|
||||||
bool mFilterByLayerType = false;
|
bool mFilterByLayerType = false;
|
||||||
|
bool mShowLayers = true;
|
||||||
QgsMapLayerType mLayerType = QgsMapLayerType::VectorLayer;
|
QgsMapLayerType mLayerType = QgsMapLayerType::VectorLayer;
|
||||||
|
|
||||||
//! Update filter
|
//! Update filter
|
||||||
@ -194,6 +214,8 @@ class CORE_EXPORT QgsBrowserProxyModel : public QSortFilterProxyModel
|
|||||||
|
|
||||||
//! Root item accepts provider key.
|
//! Root item accepts provider key.
|
||||||
bool filterRootAcceptsProviderKey( const QModelIndex &sourceIndex ) const;
|
bool filterRootAcceptsProviderKey( const QModelIndex &sourceIndex ) const;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QGSBROWSERPROXYMODEL_H
|
#endif // QGSBROWSERPROXYMODEL_H
|
||||||
|
|||||||
@ -351,6 +351,7 @@ SET(QGIS_GUI_SRCS
|
|||||||
qgsdataitemguiproviderregistry.cpp
|
qgsdataitemguiproviderregistry.cpp
|
||||||
qgsdatumtransformdialog.cpp
|
qgsdatumtransformdialog.cpp
|
||||||
qgsdatasourceselectdialog.cpp
|
qgsdatasourceselectdialog.cpp
|
||||||
|
qgsnewdatabasetablenamewidget.cpp
|
||||||
qgsdetaileditemdata.cpp
|
qgsdetaileditemdata.cpp
|
||||||
qgsdetaileditemdelegate.cpp
|
qgsdetaileditemdelegate.cpp
|
||||||
qgsdetaileditemwidget.cpp
|
qgsdetaileditemwidget.cpp
|
||||||
@ -563,6 +564,7 @@ SET(QGIS_GUI_HDRS
|
|||||||
qgsdataitemguiproviderregistry.h
|
qgsdataitemguiproviderregistry.h
|
||||||
qgsdatasourcemanagerdialog.h
|
qgsdatasourcemanagerdialog.h
|
||||||
qgsdatasourceselectdialog.h
|
qgsdatasourceselectdialog.h
|
||||||
|
qgsnewdatabasetablenamewidget.h
|
||||||
qgsdatumtransformdialog.h
|
qgsdatumtransformdialog.h
|
||||||
qgsdetaileditemdata.h
|
qgsdetaileditemdata.h
|
||||||
qgsdetaileditemdelegate.h
|
qgsdetaileditemdelegate.h
|
||||||
|
|||||||
206
src/gui/qgsnewdatabasetablenamewidget.cpp
Normal file
206
src/gui/qgsnewdatabasetablenamewidget.cpp
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsnewdatabasetablenamewidget.cpp - QgsNewDatabaseTableNameWidget
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
begin : 9.3.2020
|
||||||
|
copyright : (C) 2020 by Alessandro Pasotti
|
||||||
|
email : elpaso at itopen dot 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 <QTreeWidgetItemIterator>
|
||||||
|
|
||||||
|
#include "qgsnewdatabasetablenamewidget.h"
|
||||||
|
#include "qgsapplication.h"
|
||||||
|
#include "qgsdataitemproviderregistry.h"
|
||||||
|
#include "qgsdataitemprovider.h"
|
||||||
|
|
||||||
|
QgsNewDatabaseTableNameWidget::QgsNewDatabaseTableNameWidget(
|
||||||
|
QgsBrowserGuiModel *browserModel,
|
||||||
|
const QStringList &providersFilter,
|
||||||
|
QWidget *parent )
|
||||||
|
: QWidget( parent )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// Initalize the browser
|
||||||
|
if ( ! browserModel )
|
||||||
|
{
|
||||||
|
mBrowserModel = new QgsBrowserGuiModel( this );
|
||||||
|
mBrowserModel->initialize();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mBrowserModel = browserModel;
|
||||||
|
mBrowserModel->initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
setupUi( this );
|
||||||
|
|
||||||
|
QStringList hiddenProviders
|
||||||
|
{
|
||||||
|
QStringLiteral( "special:Favorites" ),
|
||||||
|
QStringLiteral( "special:Drives" ),
|
||||||
|
QStringLiteral( "special:Volumes" ),
|
||||||
|
QStringLiteral( "special:Home" ),
|
||||||
|
QStringLiteral( "special:ProjectHome" )
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto providerList { QgsApplication::dataItemProviderRegistry()->providers() };
|
||||||
|
for ( const auto &provider : providerList )
|
||||||
|
{
|
||||||
|
if ( provider->capabilities() & QgsDataProvider::DataCapability::Database )
|
||||||
|
{
|
||||||
|
if ( ! providersFilter.isEmpty() && ! providersFilter.contains( provider->name() ) )
|
||||||
|
{
|
||||||
|
hiddenProviders.push_back( provider->name() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mShownProviders.insert( provider->name() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hiddenProviders.push_back( provider->name() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mBrowserProxyModel.setBrowserModel( mBrowserModel );
|
||||||
|
mBrowserProxyModel.setDataItemProviderKeyFilter( hiddenProviders );
|
||||||
|
mBrowserProxyModel.setShowLayers( false );
|
||||||
|
mBrowserTreeView->setHeaderHidden( true );
|
||||||
|
mBrowserTreeView->setExpandsOnDoubleClick( false );
|
||||||
|
mBrowserTreeView->setModel( &mBrowserProxyModel );
|
||||||
|
mBrowserTreeView->setBrowserModel( mBrowserModel );
|
||||||
|
|
||||||
|
// Connections
|
||||||
|
connect( mNewTableName, &QLineEdit::textChanged, this, [ = ]
|
||||||
|
{
|
||||||
|
mTableName = mNewTableName->text();
|
||||||
|
emit tableNameChanged( mTableName );
|
||||||
|
validate();
|
||||||
|
} );
|
||||||
|
|
||||||
|
connect( mBrowserTreeView, &QgsBrowserTreeView::clicked, this, [ = ]( const QModelIndex & index )
|
||||||
|
{
|
||||||
|
if ( index.isValid() )
|
||||||
|
{
|
||||||
|
const QgsDataItem *dataItem( mBrowserProxyModel.dataItem( index ) );
|
||||||
|
if ( dataItem )
|
||||||
|
{
|
||||||
|
const QgsDataCollectionItem *collectionItem = qobject_cast<const QgsDataCollectionItem *>( dataItem );
|
||||||
|
if ( collectionItem )
|
||||||
|
{
|
||||||
|
if ( mShownProviders.contains( collectionItem->name() ) )
|
||||||
|
{
|
||||||
|
if ( mDataProviderName != collectionItem->name() )
|
||||||
|
{
|
||||||
|
mSchemaName.clear();
|
||||||
|
mDataProviderName = collectionItem->name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSchemaName = collectionItem->name();
|
||||||
|
emit schemaNameChanged( mSchemaName );
|
||||||
|
}
|
||||||
|
validate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
mValidationResults->hide();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsNewDatabaseTableNameWidget::schema()
|
||||||
|
{
|
||||||
|
return mSchemaName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsNewDatabaseTableNameWidget::table()
|
||||||
|
{
|
||||||
|
return mTableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsNewDatabaseTableNameWidget::dataItemProviderName()
|
||||||
|
{
|
||||||
|
return mDataProviderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsNewDatabaseTableNameWidget::validate()
|
||||||
|
{
|
||||||
|
// Check table uniqueness
|
||||||
|
mIsValid = ! mDataProviderName.isEmpty() &&
|
||||||
|
mShownProviders.contains( mDataProviderName ) &&
|
||||||
|
! mSchemaName.isEmpty() &&
|
||||||
|
! mTableName.isEmpty() &&
|
||||||
|
! tableNames( ).contains( mTableName );
|
||||||
|
|
||||||
|
mValidationError.clear();
|
||||||
|
|
||||||
|
if ( ! mIsValid )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( mTableName.isEmpty() )
|
||||||
|
{
|
||||||
|
mValidationError = tr( "Enter a unique name for the new table" );
|
||||||
|
}
|
||||||
|
else if ( mSchemaName.isEmpty() )
|
||||||
|
{
|
||||||
|
mValidationError = tr( "Select a database schema" );
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mValidationResults->setText( mValidationError );
|
||||||
|
mValidationResults->setVisible( ! mIsValid );
|
||||||
|
emit validationChanged( mIsValid );
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList QgsNewDatabaseTableNameWidget::tableNames()
|
||||||
|
{
|
||||||
|
QStringList tableNames;
|
||||||
|
QModelIndex index { mBrowserTreeView->currentIndex() };
|
||||||
|
if ( index.isValid() )
|
||||||
|
{
|
||||||
|
for ( int row = 0; row < mBrowserProxyModel.rowCount( ); ++row )
|
||||||
|
{
|
||||||
|
// Column 1 contains the
|
||||||
|
index = mBrowserProxyModel.index( row, 1, index );
|
||||||
|
if ( index.isValid() )
|
||||||
|
{
|
||||||
|
const QgsDataItem *dataItem { mBrowserProxyModel.dataItem( index ) };
|
||||||
|
if ( dataItem )
|
||||||
|
{
|
||||||
|
tableNames.push_back( dataItem->name() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tableNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QgsNewDatabaseTableNameWidget::isValid() const
|
||||||
|
{
|
||||||
|
return mIsValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsNewDatabaseTableNameWidget::validationError()
|
||||||
|
{
|
||||||
|
return mValidationError;
|
||||||
|
}
|
||||||
124
src/gui/qgsnewdatabasetablenamewidget.h
Normal file
124
src/gui/qgsnewdatabasetablenamewidget.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsnewdatabasetablenamewidget.h - QgsNewDatabaseTableNameWidget
|
||||||
|
|
||||||
|
---------------------
|
||||||
|
begin : 9.3.2020
|
||||||
|
copyright : (C) 2020 by Alessandro Pasotti
|
||||||
|
email : elpaso at itopen dot 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. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
#ifndef QGSNEWDATABASETABLENAMEWIDGET_H
|
||||||
|
#define QGSNEWDATABASETABLENAMEWIDGET_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "ui_qgsnewdatabasetablenamewidget.h"
|
||||||
|
|
||||||
|
#include "qgis_gui.h"
|
||||||
|
#include "qgsbrowserguimodel.h"
|
||||||
|
#include "qgsbrowserproxymodel.h"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup gui
|
||||||
|
* The QgsNewDatabaseTableNameWidget class embeds the browser view to
|
||||||
|
* select a DB schema and a new table name.
|
||||||
|
*
|
||||||
|
* The table name is validated for uniqueness and the selected
|
||||||
|
* data item provider, schema and table names can be retrieved with
|
||||||
|
* getters.
|
||||||
|
*
|
||||||
|
* \since QGIS 3.14
|
||||||
|
*/
|
||||||
|
class GUI_EXPORT QgsNewDatabaseTableNameWidget : public QWidget, private Ui::QgsNewDatabaseTableNameWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 parent optional parent for this widget
|
||||||
|
*/
|
||||||
|
explicit QgsNewDatabaseTableNameWidget( QgsBrowserGuiModel *browserModel = nullptr,
|
||||||
|
const QStringList &providersFilter = QStringList(),
|
||||||
|
QWidget *parent = nullptr );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently selected schema for the new table
|
||||||
|
*/
|
||||||
|
QString schema();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current name of the new table
|
||||||
|
*/
|
||||||
|
QString table();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently selected data item provider name (which is NOT the data provider key!) for the new table
|
||||||
|
*/
|
||||||
|
QString dataItemProviderName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns TRUE if the widget contains a valid new table name
|
||||||
|
*/
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the validation error or an empty string is the widget status is valid
|
||||||
|
*/
|
||||||
|
QString validationError();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted whenever the validation status of the widget changes.
|
||||||
|
*
|
||||||
|
* \param isValid TRUE if the current status of the widget is valid
|
||||||
|
*/
|
||||||
|
void validationChanged( bool isValid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted when the user selects a schema.
|
||||||
|
*
|
||||||
|
* \param schemaName the name of the selected schema
|
||||||
|
*/
|
||||||
|
void schemaNameChanged( const QString &schemaName );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signal is emitted when the user enters a table name
|
||||||
|
*
|
||||||
|
* \param tableName the name of the new table
|
||||||
|
*/
|
||||||
|
void tableNameChanged( const QString &tableName );
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QgsBrowserProxyModel mBrowserProxyModel;
|
||||||
|
QgsBrowserGuiModel *mBrowserModel = nullptr;
|
||||||
|
void validate();
|
||||||
|
QStringList tableNames();
|
||||||
|
QString mDataProviderName;
|
||||||
|
QString mTableName;
|
||||||
|
QString mSchemaName;
|
||||||
|
QSet<QString> mShownProviders;
|
||||||
|
bool mIsValid = false;
|
||||||
|
QString mValidationError;
|
||||||
|
|
||||||
|
// For testing:
|
||||||
|
friend class TestQgsNewDatabaseTableNameWidget;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSNEWDATABASETABLENAMEWIDGET_H
|
||||||
130
src/ui/qgsnewdatabasetablenamewidget.ui
Normal file
130
src/ui/qgsnewdatabasetablenamewidget.ui
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>QgsNewDatabaseTableNameWidget</class>
|
||||||
|
<widget class="QWidget" name="QgsNewDatabaseTableNameWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>700</width>
|
||||||
|
<height>629</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QgsBrowserTreeView" name="mBrowserTreeView"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>New table name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="mNewTableName">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>name of the new table</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="mValidationResults">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Validation results</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
<action name="mActionRefresh">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/mActionRefresh.svg</normaloff>:/images/themes/default/mActionRefresh.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="mActionShowFilter">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/mActionFilter2.svg</normaloff>:/images/themes/default/mActionFilter2.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Filter Browser</string>
|
||||||
|
</property>
|
||||||
|
<property name="iconText">
|
||||||
|
<string>Filter Browser</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Filter Browser</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="mActionCollapse">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../images/images.qrc">
|
||||||
|
<normaloff>:/images/themes/default/mActionCollapseTree.svg</normaloff>:/images/themes/default/mActionCollapseTree.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Collapse All</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Collapse All</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>QgsBrowserTreeView</class>
|
||||||
|
<extends>QTreeView</extends>
|
||||||
|
<header>qgsbrowsertreeview.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources>
|
||||||
|
<include location="../../images/images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@ -161,3 +161,4 @@ ADD_QGIS_TEST(relationreferencewidget testqgsrelationreferencewidget.cpp)
|
|||||||
ADD_QGIS_TEST(featurelistcombobox testqgsfeaturelistcombobox.cpp)
|
ADD_QGIS_TEST(featurelistcombobox testqgsfeaturelistcombobox.cpp)
|
||||||
ADD_QGIS_TEST(texteditwrapper testqgstexteditwrapper.cpp)
|
ADD_QGIS_TEST(texteditwrapper testqgstexteditwrapper.cpp)
|
||||||
ADD_QGIS_TEST(tableeditorwidget testqgstableeditor.cpp)
|
ADD_QGIS_TEST(tableeditorwidget testqgstableeditor.cpp)
|
||||||
|
ADD_QGIS_TEST(newdatabasetablewidget testqgsnewdatabasetablewidget.cpp)
|
||||||
|
|||||||
164
tests/src/gui/testqgsnewdatabasetablewidget.cpp
Normal file
164
tests/src/gui/testqgsnewdatabasetablewidget.cpp
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
testqgsfilefiledownloader.cpp
|
||||||
|
--------------------------------------
|
||||||
|
Date : 09.03.2020
|
||||||
|
Copyright : (C) 2020 Alessandro Pasotti
|
||||||
|
Email : elpaso at itopen dot 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 "qgstest.h"
|
||||||
|
#include <QObject>
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QSignalSpy>
|
||||||
|
|
||||||
|
#include "qgsnewdatabasetablenamewidget.h"
|
||||||
|
#include "qgsprovidermetadata.h"
|
||||||
|
#include "qgsproviderregistry.h"
|
||||||
|
#include "qgsabstractproviderconnection.h"
|
||||||
|
|
||||||
|
class TestQgsNewDatabaseTableNameWidget: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
TestQgsNewDatabaseTableNameWidget() = default;
|
||||||
|
|
||||||
|
void testWidget();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase(); // will be called before the first testfunction is executed.
|
||||||
|
void cleanupTestCase(); // will be called after the last testfunction was executed.
|
||||||
|
void init(); // will be called before each testfunction is executed.
|
||||||
|
void cleanup(); // will be called after every testfunction.
|
||||||
|
|
||||||
|
void testWidgetFilters();
|
||||||
|
void testWidgetSignals();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void TestQgsNewDatabaseTableNameWidget::initTestCase()
|
||||||
|
{
|
||||||
|
QgsApplication::init();
|
||||||
|
QgsApplication::initQgis();
|
||||||
|
// Add some connections to test with
|
||||||
|
QgsProviderMetadata *md { QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "postgres" ) ) };
|
||||||
|
QgsAbstractProviderConnection *conn { md->createConnection( qgetenv( "QGIS_PGTEST_DB" ) ) };
|
||||||
|
md->saveConnection( conn, QStringLiteral( "PG_1" ) );
|
||||||
|
conn = md->createConnection( qgetenv( " QGIS_PGTEST_DB" ) );
|
||||||
|
md->saveConnection( conn, QStringLiteral( "PG_2" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestQgsNewDatabaseTableNameWidget::cleanupTestCase()
|
||||||
|
{
|
||||||
|
QgsApplication::exitQgis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestQgsNewDatabaseTableNameWidget::init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestQgsNewDatabaseTableNameWidget::cleanup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestQgsNewDatabaseTableNameWidget::testWidgetFilters()
|
||||||
|
{
|
||||||
|
std::unique_ptr<QgsNewDatabaseTableNameWidget> w { qgis::make_unique<QgsNewDatabaseTableNameWidget>( nullptr, QStringList{ "NOT_EXISTS" } ) };
|
||||||
|
QCOMPARE( w->mBrowserProxyModel.rowCount(), 0 );
|
||||||
|
std::unique_ptr<QgsNewDatabaseTableNameWidget> w2 { qgis::make_unique<QgsNewDatabaseTableNameWidget>( nullptr ) };
|
||||||
|
QVERIFY( w2->mBrowserProxyModel.rowCount() > 0 );
|
||||||
|
std::unique_ptr<QgsNewDatabaseTableNameWidget> w3 { qgis::make_unique<QgsNewDatabaseTableNameWidget>( nullptr, QStringList{ "PostGIS" } ) };
|
||||||
|
QVERIFY( w3->mBrowserProxyModel.rowCount() > 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestQgsNewDatabaseTableNameWidget::testWidgetSignals()
|
||||||
|
{
|
||||||
|
std::unique_ptr<QgsNewDatabaseTableNameWidget> w { qgis::make_unique<QgsNewDatabaseTableNameWidget>( nullptr, QStringList{ "PostGIS" } ) };
|
||||||
|
|
||||||
|
auto index = w->mBrowserModel->findPath( QStringLiteral( "pg:/PG_1" ) );
|
||||||
|
QVERIFY( index.isValid() );
|
||||||
|
w->mBrowserModel->dataItem( index )->populate( true );
|
||||||
|
w->mBrowserTreeView->expandAll();
|
||||||
|
|
||||||
|
QVERIFY( ! w->isValid() );
|
||||||
|
|
||||||
|
QSignalSpy validationSpy( w.get(), SIGNAL( validationChanged( bool ) ) );
|
||||||
|
QSignalSpy schemaSpy( w.get(), SIGNAL( schemaNameChanged( QString ) ) );
|
||||||
|
QSignalSpy tableSpy( w.get(), SIGNAL( tableNameChanged( QString ) ) );
|
||||||
|
|
||||||
|
index = w->mBrowserProxyModel.mapToSource( w->mBrowserProxyModel.index( 0, 0 ) );
|
||||||
|
QVERIFY( index.isValid() );
|
||||||
|
QCOMPARE( w->mBrowserModel->data( index, Qt::DisplayRole ).toString(), QString( "PostGIS" ) );
|
||||||
|
QRect rect = w->mBrowserTreeView->visualRect( w->mBrowserProxyModel.mapFromSource( index ) );
|
||||||
|
QVERIFY( rect.isValid() );
|
||||||
|
QTest::mouseClick( w->mBrowserTreeView->viewport(), Qt::LeftButton, 0, rect.topLeft() );
|
||||||
|
|
||||||
|
QVERIFY( ! w->isValid() );
|
||||||
|
|
||||||
|
QCOMPARE( validationSpy.count(), 1 );
|
||||||
|
auto arguments = validationSpy.takeLast();
|
||||||
|
QCOMPARE( arguments.at( 0 ).toBool(), false );
|
||||||
|
QCOMPARE( schemaSpy.count(), 0 );
|
||||||
|
|
||||||
|
// Find qgis_test schema item
|
||||||
|
index = w->mBrowserModel->findPath( QStringLiteral( "pg:/PG_1/qgis_test" ), Qt::MatchFlag::MatchStartsWith );
|
||||||
|
QVERIFY( index.isValid() );
|
||||||
|
w->mBrowserTreeView->scrollTo( w->mBrowserProxyModel.mapFromSource( index ) );
|
||||||
|
rect = w->mBrowserTreeView->visualRect( w->mBrowserProxyModel.mapFromSource( index ) );
|
||||||
|
QVERIFY( rect.isValid() );
|
||||||
|
QTest::mouseClick( w->mBrowserTreeView->viewport(), Qt::LeftButton, 0, rect.center() );
|
||||||
|
QCOMPARE( validationSpy.count(), 1 );
|
||||||
|
arguments = validationSpy.takeLast();
|
||||||
|
QCOMPARE( arguments.at( 0 ).toBool(), false );
|
||||||
|
QCOMPARE( schemaSpy.count(), 1 );
|
||||||
|
arguments = schemaSpy.takeLast();
|
||||||
|
QCOMPARE( arguments.at( 0 ).toString(), QString( "qgis_test" ) );
|
||||||
|
|
||||||
|
w->mNewTableName->setText( QStringLiteral( "someNewTableData" ) );
|
||||||
|
QCOMPARE( tableSpy.count(), 1 );
|
||||||
|
arguments = tableSpy.takeLast();
|
||||||
|
QCOMPARE( arguments.at( 0 ).toString(), QString( "someNewTableData" ) );
|
||||||
|
|
||||||
|
QVERIFY( w->isValid() );
|
||||||
|
|
||||||
|
// Test unique
|
||||||
|
w->mNewTableName->setText( QStringLiteral( "someData" ) );
|
||||||
|
QCOMPARE( tableSpy.count(), 1 );
|
||||||
|
arguments = tableSpy.takeLast();
|
||||||
|
QCOMPARE( arguments.at( 0 ).toString(), QString( "someData" ) );
|
||||||
|
|
||||||
|
QVERIFY( ! w->isValid() );
|
||||||
|
|
||||||
|
// Test getters
|
||||||
|
QCOMPARE( w->table(), QString( "someData" ) );
|
||||||
|
QCOMPARE( w->schema(), QString( "qgis_test" ) );
|
||||||
|
QCOMPARE( w->dataItemProviderName(), QString( "postgres" ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TestQgsNewDatabaseTableNameWidget::testWidget()
|
||||||
|
{
|
||||||
|
QDialog d;
|
||||||
|
QVBoxLayout layout;
|
||||||
|
d.setLayout( &layout );
|
||||||
|
std::unique_ptr<QgsNewDatabaseTableNameWidget> w { qgis::make_unique<QgsNewDatabaseTableNameWidget>( nullptr, QStringList{ "PostGIS" } ) };
|
||||||
|
d.layout()->addWidget( w.get() );
|
||||||
|
|
||||||
|
d.exec();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QGSTEST_MAIN( TestQgsNewDatabaseTableNameWidget )
|
||||||
|
#include "testqgsnewdatabasetablewidget.moc"
|
||||||
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user