29#include <QDialogButtonBox>
31#include <QRegularExpression>
33#include <QTreeWidgetItemIterator>
35#include "moc_qgsnewdatabasetablenamewidget.cpp"
37using namespace Qt::StringLiterals;
40QStringList QgsNewDatabaseTableNameWidget::FILESYSTEM_BASED_DATAITEM_PROVIDERS { u
"GPKG"_s, u
"spatialite"_s };
49 mBrowserModel->initialize();
53 mBrowserModel = browserModel;
60 mOkButton->setEnabled(
false );
62 QStringList shownDataItemProvidersFilter;
65 for (
const auto &provider : providerList )
67 if ( provider->dataProviderKey().isEmpty() )
77 if ( providersFilter.isEmpty() || providersFilter.contains( provider->dataProviderKey() ) )
79 mShownProviders.insert( provider->dataProviderKey() );
80 shownDataItemProvidersFilter.push_back( provider->name() );
87 mBrowserProxyModel.setBrowserModel( mBrowserModel );
90 if ( !providersFilter.isEmpty() && shownDataItemProvidersFilter.isEmpty() )
92 shownDataItemProvidersFilter = providersFilter;
94 mBrowserProxyModel.setShownDataItemProviderKeyFilter( shownDataItemProvidersFilter );
95 mBrowserProxyModel.setShowLayers(
false );
96 mBrowserTreeView->setHeaderHidden(
true );
97 mBrowserTreeView->setModel( &mBrowserProxyModel );
98 mBrowserTreeView->setBrowserModel( mBrowserModel );
101 connect( mNewTableName, &QLineEdit::textChanged,
this, [
this] {
102 mTableName = mNewTableName->text();
108 connect( mActionRefresh, &QAction::triggered,
this, [
this] { refreshModel( QModelIndex() ); } );
110 connect( mBrowserTreeView, &QgsBrowserTreeView::clicked,
this, [
this](
const QModelIndex &index ) {
111 if ( index.isValid() )
113 if (
const QgsDataItem *dataItem = mBrowserProxyModel.dataItem( index ) )
115 if (
const QgsDataCollectionItem *collectionItem = qobject_cast<const QgsDataCollectionItem *>( dataItem ) )
118 bool validationRequired {
false };
119 const QString oldSchema { mSchemaName };
121 if ( mDataProviderKey != providerKey )
124 mDataProviderKey = providerKey;
126 validationRequired =
true;
129 if ( collectionItem->layerCollection() )
131 mIsFilePath = FILESYSTEM_BASED_DATAITEM_PROVIDERS.contains( collectionItem->providerKey() );
133 mSchemaName = mIsFilePath ? collectionItem->path().remove( QRegularExpression( u
"^[A-z]+:/"_s ) ) : collectionItem->name();
134 mConnectionName = mIsFilePath ? collectionItem->name() : collectionItem->parent()->name();
135 if ( oldSchema != mSchemaName )
140 validationRequired =
true;
144 if ( validationRequired )
162 mOkButton->setVisible( visible );
165void QgsNewDatabaseTableNameWidget::refreshModel(
const QModelIndex &index )
171 mBrowserModel->
refresh( index );
174 for (
int i = 0; i < mBrowserModel->rowCount( index ); i++ )
176 const QModelIndex idx = mBrowserModel->index( i, 0, index );
177 const QModelIndex proxyIdx = mBrowserProxyModel.mapFromSource( idx );
178 QgsDataItem *child = mBrowserModel->dataItem( idx );
196void QgsNewDatabaseTableNameWidget::updateUri()
198 const QString oldUri { mUri };
200 if ( dataProviderMetadata )
202 QgsAbstractProviderConnection *conn { dataProviderMetadata->
findConnection( mConnectionName ) };
205 QVariantMap uriParts = dataProviderMetadata->
decodeUri( conn->
uri() );
206 uriParts[u
"layerName"_s] = mTableName;
207 uriParts[u
"schema"_s] = mSchemaName;
208 uriParts[u
"table"_s] = mTableName;
211 uriParts[u
"dbname"_s] = mSchemaName;
213 mUri = dataProviderMetadata->
encodeUri( uriParts );
225 if ( mUri != oldUri )
248 return mDataProviderKey;
251void QgsNewDatabaseTableNameWidget::validate()
253 const bool wasValid { mIsValid };
255 mIsValid = !mDataProviderKey.isEmpty() && mShownProviders.contains( mDataProviderKey ) && !mSchemaName.isEmpty() && !mTableName.isEmpty() && !tableNames().contains( mTableName );
257 mValidationError.clear();
260 bool isError {
false };
264 if ( mTableName.isEmpty() && mSchemaName.isEmpty() )
266 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
268 else if ( !mTableName.isEmpty() && !mSchemaName.isEmpty() && tableNames().contains( mTableName ) )
271 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
273 else if ( mSchemaName.isEmpty() )
275 mValidationError = tr(
"Select a database schema" );
277 else if ( mTableName.isEmpty() )
279 mValidationError = tr(
"Enter a unique name for the new table" );
281 else if ( tableNames().contains( mTableName ) )
283 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
287 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
291 mValidationResults->setStyleSheet( isError ? u
"* { color: red; }"_s : QString() );
293 mValidationResults->setText( mValidationError );
294 mValidationResults->setVisible( !mIsValid );
295 if ( wasValid != mIsValid )
301QStringList QgsNewDatabaseTableNameWidget::tableNames()
303 QStringList tableNames;
304 const QModelIndex index { mBrowserTreeView->currentIndex() };
305 if ( index.isValid() )
307 QgsDataItem *dataItem { mBrowserProxyModel.dataItem( index ) };
316 QgsDataItem *parentDataItem { mIsFilePath ? dataItem : dataItem->
parent() };
317 if ( parentDataItem )
319 QgsAbstractProviderConnection *conn { metadata->
findConnection( parentDataItem->
name() ) };
323 if ( mTableNamesCache.contains(
cacheKey ) )
325 tableNames = mTableNamesCache.value(
cacheKey );
327 else if ( conn &&
static_cast<QgsAbstractDatabaseProviderConnection *
>( conn ) )
329 const auto tables {
static_cast<QgsAbstractDatabaseProviderConnection *
>( conn )->tables( dataItem->
name() ) };
330 for (
const auto &tp : tables )
332 tableNames.push_back( tp.tableName() );
334 mTableNamesCache[
cacheKey] = tableNames;
352 return mValidationError;
357 QWidget::showEvent( e );
359 if ( !lastSelectedPath.isEmpty() )
361 const QModelIndexList items
362 = mBrowserProxyModel.match( mBrowserProxyModel.index( 0, 0 ),
static_cast<int>(
QgsBrowserModel::CustomRole::Path ), QVariant::fromValue( lastSelectedPath ), 1, Qt::MatchRecursive );
363 if ( items.count() > 0 )
365 const QModelIndex expandIndex = items.at( 0 );
366 if ( expandIndex.isValid() )
368 mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
369 mBrowserTreeView->expand( expandIndex );
382 QVBoxLayout *vl =
new QVBoxLayout();
383 vl->addWidget( mWidget, 1 );
384 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
385 connect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
386 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
387 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
389 vl->addWidget( buttonBox );
395 return mWidget->schema();
400 return mWidget->uri();
405 return mWidget->table();
410 return mWidget->dataProviderKey();
415 return mWidget->isValid();
420 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.
const QString cacheKey(const QString &pathIn)