17 #include <QTreeWidgetItemIterator>
28 #include <QRegularExpression>
29 #include <QDialogButtonBox>
30 #include <QPushButton>
33 QStringList QgsNewDatabaseTableNameWidget::FILESYSTEM_BASED_DATAITEM_PROVIDERS { QStringLiteral(
"GPKG" ), QStringLiteral(
"spatialite" ) };
37 const QStringList &providersFilter,
50 mBrowserModel = browserModel;
57 mOkButton->setEnabled(
false );
59 QStringList shownDataItemProvidersFilter;
62 for (
const auto &provider : providerList )
64 if ( provider->dataProviderKey().isEmpty() )
72 if ( provider->capabilities() & QgsDataProvider::DataCapability::Database )
74 if ( providersFilter.isEmpty() || providersFilter.contains( provider->dataProviderKey() ) )
76 mShownProviders.insert( provider->dataProviderKey() );
77 shownDataItemProvidersFilter.push_back( provider->name() );
87 if ( ! providersFilter.isEmpty() && shownDataItemProvidersFilter.isEmpty() )
89 shownDataItemProvidersFilter = providersFilter;
93 mBrowserTreeView->setHeaderHidden(
true );
94 mBrowserTreeView->setModel( &mBrowserProxyModel );
95 mBrowserTreeView->setBrowserModel( mBrowserModel );
98 connect( mNewTableName, &QLineEdit::textChanged,
this, [ = ]
100 mTableName = mNewTableName->text();
106 connect( mActionRefresh, &QAction::triggered,
this, [ = ]
108 refreshModel( QModelIndex() );
111 connect( mBrowserTreeView, &QgsBrowserTreeView::clicked,
this, [ = ](
const QModelIndex & index )
113 if ( index.isValid() )
115 if ( const QgsDataItem *dataItem = mBrowserProxyModel.dataItem( index ) )
117 if ( const QgsDataCollectionItem *collectionItem = qobject_cast<const QgsDataCollectionItem *>( dataItem ) )
119 const QString providerKey { QgsApplication::dataItemProviderRegistry()->dataProviderKey( dataItem->providerKey() ) };
120 bool validationRequired { false };
121 const QString oldSchema { mSchemaName };
123 if ( mDataProviderKey != providerKey )
126 mDataProviderKey = providerKey;
127 emit providerKeyChanged( providerKey );
128 validationRequired = true;
131 if ( collectionItem->layerCollection( ) )
133 mIsFilePath = FILESYSTEM_BASED_DATAITEM_PROVIDERS.contains( collectionItem->providerKey() );
135 mSchemaName = mIsFilePath ? collectionItem->path().remove( QRegularExpression( QStringLiteral(
"^[A-z]+:/" ) ) ) : collectionItem->name();
136 mConnectionName = mIsFilePath ? collectionItem->name() : collectionItem->parent()->name();
137 if ( oldSchema != mSchemaName )
139 emit schemaNameChanged( mSchemaName );
141 QgsSettings().setValue( QStringLiteral(
"newDatabaseTableNameWidgetLastSelectedItem" ),
142 mBrowserProxyModel.data( index, QgsBrowserGuiModel::PathRole ).toString(), QgsSettings::Section::Gui );
143 validationRequired = true;
147 if ( validationRequired )
165 mOkButton->setVisible( visible );
168 void QgsNewDatabaseTableNameWidget::refreshModel(
const QModelIndex &index )
175 mBrowserModel->
refresh( index );
178 for (
int i = 0; i < mBrowserModel->
rowCount( index ); i++ )
180 QModelIndex idx = mBrowserModel->
index( i, 0, index );
181 QModelIndex proxyIdx = mBrowserProxyModel.mapFromSource( idx );
186 if ( mBrowserTreeView->isExpanded( proxyIdx ) || mBrowserTreeView->hasExpandedDescendant( proxyIdx ) || ( child && child->
capabilities2() &
QgsDataItem::Fast ) )
200 void QgsNewDatabaseTableNameWidget::updateUri()
202 const QString oldUri { mUri };
204 if ( dataProviderMetadata )
209 QVariantMap uriParts = dataProviderMetadata->decodeUri( conn->uri() );
210 uriParts[ QStringLiteral(
"layerName" ) ] = mTableName;
211 uriParts[ QStringLiteral(
"schema" ) ] = mSchemaName;
212 uriParts[ QStringLiteral(
"table" ) ] = mTableName;
215 uriParts[ QStringLiteral(
"dbname" ) ] = mSchemaName;
217 mUri = dataProviderMetadata->encodeUri( uriParts );
229 if ( mUri != oldUri )
252 return mDataProviderKey;
255 void QgsNewDatabaseTableNameWidget::validate()
257 const bool wasValid { mIsValid };
259 mIsValid = ! mDataProviderKey.isEmpty() &&
260 mShownProviders.contains( mDataProviderKey ) &&
261 ! mSchemaName.isEmpty() &&
262 ! mTableName.isEmpty() &&
263 ! tableNames( ).contains( mTableName );
265 mValidationError.clear();
268 bool isError {
false };
272 if ( mTableName.isEmpty() && mSchemaName.isEmpty() )
274 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
276 else if ( ! mTableName.isEmpty() &&
277 ! mSchemaName.isEmpty() &&
278 tableNames( ).contains( mTableName ) )
281 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
283 else if ( mSchemaName.isEmpty() )
285 mValidationError = tr(
"Select a database schema" );
287 else if ( mTableName.isEmpty() )
289 mValidationError = tr(
"Enter a unique name for the new table" );
291 else if ( tableNames( ).contains( mTableName ) )
293 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
297 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
301 mValidationResults->setStyleSheet( isError ?
302 QStringLiteral(
"* { color: red; }" ) :
305 mValidationResults->setText( mValidationError );
306 mValidationResults->setVisible( ! mIsValid );
307 if ( wasValid != mIsValid )
313 QStringList QgsNewDatabaseTableNameWidget::tableNames()
315 QStringList tableNames;
316 QModelIndex index { mBrowserTreeView->currentIndex() };
317 if ( index.isValid() )
328 QgsDataItem *parentDataItem { mIsFilePath ? dataItem : dataItem->parent() };
329 if ( parentDataItem )
334 const QString cacheKey { conn->
uri() + dataItem->name() };
335 if ( mTableNamesCache.contains( cacheKey ) )
337 tableNames = mTableNamesCache.value( cacheKey );
342 for (
const auto &tp : tables )
344 tableNames.push_back( tp.tableName() );
346 mTableNamesCache[ cacheKey ] = tableNames;
364 return mValidationError;
369 QWidget::showEvent( e );
370 QString lastSelectedPath(
QgsSettings().value( QStringLiteral(
"newDatabaseTableNameWidgetLastSelectedItem" ),
371 QString(), QgsSettings::Section::Gui ).toString() );
372 if ( ! lastSelectedPath.isEmpty() )
374 QModelIndexList items = mBrowserProxyModel.match(
375 mBrowserProxyModel.index( 0, 0 ),
377 QVariant::fromValue( lastSelectedPath ),
379 Qt::MatchRecursive );
380 if ( items.count( ) > 0 )
382 QModelIndex expandIndex = items.at( 0 );
383 if ( expandIndex.isValid() )
385 mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
386 mBrowserTreeView->expand( expandIndex );
399 QVBoxLayout *vl =
new QVBoxLayout();
400 vl->addWidget( mWidget, 1 );
401 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
402 connect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
403 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
404 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
406 vl->addWidget( buttonBox );
417 return mWidget->
uri();
422 return mWidget->
table();
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 Capabilities capabilities2() const
Returns the capabilities for the data item.
@ 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,...
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.