29#include <QDialogButtonBox>
31#include <QRegularExpression>
32#include <QTreeWidgetItemIterator>
34#include "moc_qgsnewdatabasetablenamewidget.cpp"
37QStringList QgsNewDatabaseTableNameWidget::FILESYSTEM_BASED_DATAITEM_PROVIDERS { QStringLiteral(
"GPKG" ), QStringLiteral(
"spatialite" ) };
41 const QStringList &providersFilter,
50 mBrowserModel->initialize();
54 mBrowserModel = browserModel;
61 mOkButton->setEnabled(
false );
63 QStringList shownDataItemProvidersFilter;
66 for (
const auto &provider : providerList )
68 if ( provider->dataProviderKey().isEmpty() )
78 if ( providersFilter.isEmpty() || providersFilter.contains( provider->dataProviderKey() ) )
80 mShownProviders.insert( provider->dataProviderKey() );
81 shownDataItemProvidersFilter.push_back( provider->name() );
88 mBrowserProxyModel.setBrowserModel( mBrowserModel );
91 if ( !providersFilter.isEmpty() && shownDataItemProvidersFilter.isEmpty() )
93 shownDataItemProvidersFilter = providersFilter;
95 mBrowserProxyModel.setShownDataItemProviderKeyFilter( shownDataItemProvidersFilter );
96 mBrowserProxyModel.setShowLayers(
false );
97 mBrowserTreeView->setHeaderHidden(
true );
98 mBrowserTreeView->setModel( &mBrowserProxyModel );
99 mBrowserTreeView->setBrowserModel( mBrowserModel );
102 connect( mNewTableName, &QLineEdit::textChanged,
this, [
this] {
103 mTableName = mNewTableName->text();
109 connect( mActionRefresh, &QAction::triggered,
this, [
this] {
110 refreshModel( QModelIndex() );
113 connect( mBrowserTreeView, &QgsBrowserTreeView::clicked,
this, [
this](
const QModelIndex &index ) {
114 if ( index.isValid() )
116 if (
const QgsDataItem *dataItem = mBrowserProxyModel.dataItem( index ) )
118 if (
const QgsDataCollectionItem *collectionItem = qobject_cast<const QgsDataCollectionItem *>( dataItem ) )
121 bool validationRequired {
false };
122 const QString oldSchema { mSchemaName };
124 if ( mDataProviderKey != providerKey )
127 mDataProviderKey = providerKey;
129 validationRequired =
true;
132 if ( collectionItem->layerCollection() )
134 mIsFilePath = FILESYSTEM_BASED_DATAITEM_PROVIDERS.contains( collectionItem->providerKey() );
136 mSchemaName = mIsFilePath ? collectionItem->path().remove( QRegularExpression( QStringLiteral(
"^[A-z]+:/" ) ) ) : collectionItem->name();
137 mConnectionName = mIsFilePath ? collectionItem->name() : collectionItem->parent()->name();
138 if ( oldSchema != mSchemaName )
143 validationRequired =
true;
147 if ( validationRequired )
165 mOkButton->setVisible( visible );
168void QgsNewDatabaseTableNameWidget::refreshModel(
const QModelIndex &index )
174 mBrowserModel->
refresh( index );
177 for (
int i = 0; i < mBrowserModel->rowCount( index ); i++ )
179 const QModelIndex idx = mBrowserModel->index( i, 0, index );
180 const QModelIndex proxyIdx = mBrowserProxyModel.mapFromSource( idx );
181 QgsDataItem *child = mBrowserModel->dataItem( idx );
199void QgsNewDatabaseTableNameWidget::updateUri()
201 const QString oldUri { mUri };
203 if ( dataProviderMetadata )
205 QgsAbstractProviderConnection *conn { dataProviderMetadata->
findConnection( mConnectionName ) };
208 QVariantMap uriParts = dataProviderMetadata->
decodeUri( conn->
uri() );
209 uriParts[QStringLiteral(
"layerName" )] = mTableName;
210 uriParts[QStringLiteral(
"schema" )] = mSchemaName;
211 uriParts[QStringLiteral(
"table" )] = mTableName;
214 uriParts[QStringLiteral(
"dbname" )] = mSchemaName;
216 mUri = dataProviderMetadata->
encodeUri( uriParts );
228 if ( mUri != oldUri )
251 return mDataProviderKey;
254void QgsNewDatabaseTableNameWidget::validate()
256 const bool wasValid { mIsValid };
258 mIsValid = !mDataProviderKey.isEmpty() && mShownProviders.contains( mDataProviderKey ) && !mSchemaName.isEmpty() && !mTableName.isEmpty() && !tableNames().contains( mTableName );
260 mValidationError.clear();
263 bool isError {
false };
267 if ( mTableName.isEmpty() && mSchemaName.isEmpty() )
269 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
271 else if ( !mTableName.isEmpty() && !mSchemaName.isEmpty() && tableNames().contains( mTableName ) )
274 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
276 else if ( mSchemaName.isEmpty() )
278 mValidationError = tr(
"Select a database schema" );
280 else if ( mTableName.isEmpty() )
282 mValidationError = tr(
"Enter a unique name for the new table" );
284 else if ( tableNames().contains( mTableName ) )
286 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
290 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
294 mValidationResults->setStyleSheet( isError ? QStringLiteral(
"* { color: red; }" ) : QString() );
296 mValidationResults->setText( mValidationError );
297 mValidationResults->setVisible( !mIsValid );
298 if ( wasValid != mIsValid )
304QStringList QgsNewDatabaseTableNameWidget::tableNames()
306 QStringList tableNames;
307 const QModelIndex index { mBrowserTreeView->currentIndex() };
308 if ( index.isValid() )
310 QgsDataItem *dataItem { mBrowserProxyModel.dataItem( index ) };
319 QgsDataItem *parentDataItem { mIsFilePath ? dataItem : dataItem->
parent() };
320 if ( parentDataItem )
322 QgsAbstractProviderConnection *conn { metadata->
findConnection( parentDataItem->
name() ) };
325 const QString cacheKey { conn->
uri() + dataItem->
name() };
326 if ( mTableNamesCache.contains( cacheKey ) )
328 tableNames = mTableNamesCache.value( cacheKey );
330 else if ( conn &&
static_cast<QgsAbstractDatabaseProviderConnection *
>( conn ) )
332 const auto tables {
static_cast<QgsAbstractDatabaseProviderConnection *
>( conn )->tables( dataItem->
name() ) };
333 for (
const auto &tp : tables )
335 tableNames.push_back( tp.tableName() );
337 mTableNamesCache[cacheKey] = tableNames;
355 return mValidationError;
360 QWidget::showEvent( e );
362 if ( !lastSelectedPath.isEmpty() )
364 const QModelIndexList items = mBrowserProxyModel.match(
365 mBrowserProxyModel.index( 0, 0 ),
367 QVariant::fromValue( lastSelectedPath ),
371 if ( items.count() > 0 )
373 const QModelIndex expandIndex = items.at( 0 );
374 if ( expandIndex.isValid() )
376 mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
377 mBrowserTreeView->expand( expandIndex );
390 QVBoxLayout *vl =
new QVBoxLayout();
391 vl->addWidget( mWidget, 1 );
392 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
393 connect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
394 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
395 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
397 vl->addWidget( buttonBox );
403 return mWidget->schema();
408 return mWidget->uri();
413 return mWidget->table();
418 return mWidget->dataProviderKey();
423 return mWidget->isValid();
428 return mWidget->validationError();
@ Databases
Can provides items which corresponds to databases.
@ 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,...
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.
void initialize()
Delayed initialization, needed because the provider registry must be already populated.
@ Path
Item path used to access path in the tree, see QgsDataItem::mPath.
A browser item for collections of data.
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.
QString name() const
Returns the name of the item (the displayed text for the item).
QgsDataItem * parent() const
Gets item parent.
QString providerKey() const
Returns the provider key that created this item (e.g.
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.
Stores settings for use within QGIS.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.