17#include <QTreeWidgetItemIterator>
30#include <QRegularExpression>
31#include <QDialogButtonBox>
35QStringList QgsNewDatabaseTableNameWidget::FILESYSTEM_BASED_DATAITEM_PROVIDERS { QStringLiteral(
"GPKG" ), QStringLiteral(
"spatialite" ) };
39 const QStringList &providersFilter,
52 mBrowserModel = browserModel;
59 mOkButton->setEnabled(
false );
61 QStringList shownDataItemProvidersFilter;
64 for (
const auto &provider : providerList )
66 if ( provider->dataProviderKey().isEmpty() )
76 if ( providersFilter.isEmpty() || providersFilter.contains( provider->dataProviderKey() ) )
78 mShownProviders.insert( provider->dataProviderKey() );
79 shownDataItemProvidersFilter.push_back( provider->name() );
89 if ( ! providersFilter.isEmpty() && shownDataItemProvidersFilter.isEmpty() )
91 shownDataItemProvidersFilter = providersFilter;
95 mBrowserTreeView->setHeaderHidden(
true );
96 mBrowserTreeView->setModel( &mBrowserProxyModel );
97 mBrowserTreeView->setBrowserModel( mBrowserModel );
100 connect( mNewTableName, &QLineEdit::textChanged,
this, [ = ]
102 mTableName = mNewTableName->text();
108 connect( mActionRefresh, &QAction::triggered,
this, [ = ]
110 refreshModel( QModelIndex() );
113 connect( mBrowserTreeView, &QgsBrowserTreeView::clicked,
this, [ = ](
const QModelIndex & index )
115 if ( index.isValid() )
117 if ( const QgsDataItem *dataItem = mBrowserProxyModel.dataItem( index ) )
119 if ( const QgsDataCollectionItem *collectionItem = qobject_cast<const QgsDataCollectionItem *>( dataItem ) )
121 const QString providerKey { QgsApplication::dataItemProviderRegistry()->dataProviderKey( dataItem->providerKey() ) };
122 bool validationRequired { false };
123 const QString oldSchema { mSchemaName };
125 if ( mDataProviderKey != providerKey )
128 mDataProviderKey = providerKey;
129 emit providerKeyChanged( providerKey );
130 validationRequired = true;
133 if ( collectionItem->layerCollection( ) )
135 mIsFilePath = FILESYSTEM_BASED_DATAITEM_PROVIDERS.contains( collectionItem->providerKey() );
137 mSchemaName = mIsFilePath ? collectionItem->path().remove( QRegularExpression( QStringLiteral(
"^[A-z]+:/" ) ) ) : collectionItem->name();
138 mConnectionName = mIsFilePath ? collectionItem->name() : collectionItem->parent()->name();
139 if ( oldSchema != mSchemaName )
141 emit schemaNameChanged( mSchemaName );
143 QgsSettings().setValue( QStringLiteral(
"newDatabaseTableNameWidgetLastSelectedItem" ),
144 mBrowserProxyModel.data( index, QgsBrowserGuiModel::PathRole ).toString(), QgsSettings::Section::Gui );
145 validationRequired = true;
149 if ( validationRequired )
167 mOkButton->setVisible( visible );
170void QgsNewDatabaseTableNameWidget::refreshModel(
const QModelIndex &index )
177 mBrowserModel->
refresh( index );
180 for (
int i = 0; i < mBrowserModel->
rowCount( index ); i++ )
182 const QModelIndex idx = mBrowserModel->
index( i, 0, index );
183 const QModelIndex proxyIdx = mBrowserProxyModel.mapFromSource( idx );
202void QgsNewDatabaseTableNameWidget::updateUri()
204 const QString oldUri { mUri };
206 if ( dataProviderMetadata )
211 QVariantMap uriParts = dataProviderMetadata->decodeUri( conn->uri() );
212 uriParts[ QStringLiteral(
"layerName" ) ] = mTableName;
213 uriParts[ QStringLiteral(
"schema" ) ] = mSchemaName;
214 uriParts[ QStringLiteral(
"table" ) ] = mTableName;
217 uriParts[ QStringLiteral(
"dbname" ) ] = mSchemaName;
219 mUri = dataProviderMetadata->encodeUri( uriParts );
231 if ( mUri != oldUri )
254 return mDataProviderKey;
257void QgsNewDatabaseTableNameWidget::validate()
259 const bool wasValid { mIsValid };
261 mIsValid = ! mDataProviderKey.isEmpty() &&
262 mShownProviders.contains( mDataProviderKey ) &&
263 ! mSchemaName.isEmpty() &&
264 ! mTableName.isEmpty() &&
265 ! tableNames( ).contains( mTableName );
267 mValidationError.clear();
270 bool isError {
false };
274 if ( mTableName.isEmpty() && mSchemaName.isEmpty() )
276 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
278 else if ( ! mTableName.isEmpty() &&
279 ! mSchemaName.isEmpty() &&
280 tableNames( ).contains( mTableName ) )
283 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
285 else if ( mSchemaName.isEmpty() )
287 mValidationError = tr(
"Select a database schema" );
289 else if ( mTableName.isEmpty() )
291 mValidationError = tr(
"Enter a unique name for the new table" );
293 else if ( tableNames( ).contains( mTableName ) )
295 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
299 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
303 mValidationResults->setStyleSheet( isError ?
304 QStringLiteral(
"* { color: red; }" ) :
307 mValidationResults->setText( mValidationError );
308 mValidationResults->setVisible( ! mIsValid );
309 if ( wasValid != mIsValid )
315QStringList QgsNewDatabaseTableNameWidget::tableNames()
317 QStringList tableNames;
318 const QModelIndex index { mBrowserTreeView->currentIndex() };
319 if ( index.isValid() )
330 QgsDataItem *parentDataItem { mIsFilePath ? dataItem : dataItem->parent() };
331 if ( parentDataItem )
336 const QString cacheKey { conn->
uri() + dataItem->name() };
337 if ( mTableNamesCache.contains( cacheKey ) )
339 tableNames = mTableNamesCache.value( cacheKey );
344 for (
const auto &tp : tables )
346 tableNames.push_back( tp.tableName() );
348 mTableNamesCache[ cacheKey ] = tableNames;
366 return mValidationError;
371 QWidget::showEvent( e );
372 const QString lastSelectedPath(
QgsSettings().value( QStringLiteral(
"newDatabaseTableNameWidgetLastSelectedItem" ),
374 if ( ! lastSelectedPath.isEmpty() )
376 const QModelIndexList items = mBrowserProxyModel.match(
377 mBrowserProxyModel.index( 0, 0 ),
379 QVariant::fromValue( lastSelectedPath ),
381 Qt::MatchRecursive );
382 if ( items.count( ) > 0 )
384 const QModelIndex expandIndex = items.at( 0 );
385 if ( expandIndex.isValid() )
387 mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
388 mBrowserTreeView->expand( expandIndex );
401 QVBoxLayout *vl =
new QVBoxLayout();
402 vl->addWidget( mWidget, 1 );
403 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
404 connect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
405 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
406 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
408 vl->addWidget( buttonBox );
419 return mWidget->
uri();
424 return mWidget->
table();
@ Fertile
Can create children. Even items without this capability may have children, but cannot create them,...
@ Fast
CreateChildren() is fast enough to be run in main thread when refreshing items, most root items (wms,...
The QgsAbstractDatabaseProviderConnection class provides common functionality for DB based connection...
The QgsAbstractProviderConnection provides an interface for data provider connections.
QString uri() const
Returns the connection data source URI string representation.
static QgsDataItemProviderRegistry * dataItemProviderRegistry()
Returns the application's data item provider registry, which keeps a list of data item providers that...
A model for showing available data sources and other items in a structured tree.
QgsDataItem * dataItem(const QModelIndex &idx) const
Returns the data item at the specified index, or nullptr if no item exists at the index.
void refresh(const QString &path)
Refresh item specified by path.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void initialize()
Delayed initialization, needed because the provider registry must be already populated.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
@ PathRole
Item path used to access path in the tree, see QgsDataItem::mPath.
void setShowLayers(bool showLayers)
Sets show layers to showLayers.
void setShownDataItemProviderKeyFilter(const QStringList &shownItemsFilter)
Sets a filter to show data items based on QgsDataItem::providerKey() associated with the item.
QgsDataItem * dataItem(const QModelIndex &index) const
Returns the data item at the specified proxy index, or nullptr if no item exists at the index.
void setBrowserModel(QgsBrowserModel *model)
Sets the underlying browser model.
QList< QgsDataItemProvider * > providers() const
Returns the list of available providers.
QString dataProviderKey(const QString &dataItemProviderName)
Returns the (possibly blank) data provider key for a given data item provider name.
Base class for all items in the model.
virtual Qgis::BrowserItemCapabilities capabilities2() const
Returns the capabilities for the data item.
virtual void depopulate()
Remove children recursively and set as not populated. This is used when refreshing collapsed items.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
This class is a composition of two QSettings instances:
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.