17 #include <QTreeWidgetItemIterator>
30 #include <QRegularExpression>
31 #include <QDialogButtonBox>
32 #include <QPushButton>
35 QStringList 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() )
74 if ( provider->capabilities() & QgsDataProvider::DataCapability::Database )
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 );
170 void QgsNewDatabaseTableNameWidget::refreshModel(
const QModelIndex &index )
173 QgsDataItem *item = mBrowserModel->dataItem( 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 );
184 QgsDataItem *child = mBrowserModel->dataItem( idx );
202 void 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 )
233 emit uriChanged( mUri );
254 return mDataProviderKey;
257 void 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 )
311 emit validationChanged( mIsValid );
315 QStringList QgsNewDatabaseTableNameWidget::tableNames()
317 QStringList tableNames;
318 const QModelIndex index { mBrowserTreeView->currentIndex() };
319 if ( index.isValid() )
321 QgsDataItem *dataItem { mBrowserProxyModel.dataItem( index ) };
325 if ( ! dataProviderKey.isEmpty() )
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" ),
373 QString(), QgsSettings::Section::Gui ).toString() );
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 );
400 mWidget =
new QgsNewDatabaseTableNameWidget( browserModel, providersFilter );
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 );
414 return mWidget->schema();
419 return mWidget->uri();
424 return mWidget->table();
429 return mWidget->dataProviderKey();
434 return mWidget->isValid();
439 return mWidget->validationError();