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 };
44 const QStringList &providersFilter,
53 mBrowserModel->initialize();
57 mBrowserModel = browserModel;
64 mOkButton->setEnabled(
false );
66 QStringList shownDataItemProvidersFilter;
69 for (
const auto &provider : providerList )
71 if ( provider->dataProviderKey().isEmpty() )
81 if ( providersFilter.isEmpty() || providersFilter.contains( provider->dataProviderKey() ) )
83 mShownProviders.insert( provider->dataProviderKey() );
84 shownDataItemProvidersFilter.push_back( provider->name() );
91 mBrowserProxyModel.setBrowserModel( mBrowserModel );
94 if ( !providersFilter.isEmpty() && shownDataItemProvidersFilter.isEmpty() )
96 shownDataItemProvidersFilter = providersFilter;
98 mBrowserProxyModel.setShownDataItemProviderKeyFilter( shownDataItemProvidersFilter );
99 mBrowserProxyModel.setShowLayers(
false );
100 mBrowserTreeView->setHeaderHidden(
true );
101 mBrowserTreeView->setModel( &mBrowserProxyModel );
102 mBrowserTreeView->setBrowserModel( mBrowserModel );
105 connect( mNewTableName, &QLineEdit::textChanged,
this, [
this] {
106 mTableName = mNewTableName->text();
112 connect( mActionRefresh, &QAction::triggered,
this, [
this] {
113 refreshModel( QModelIndex() );
116 connect( mBrowserTreeView, &QgsBrowserTreeView::clicked,
this, [
this](
const QModelIndex &index ) {
117 if ( index.isValid() )
119 if (
const QgsDataItem *dataItem = mBrowserProxyModel.dataItem( index ) )
121 if (
const QgsDataCollectionItem *collectionItem = qobject_cast<const QgsDataCollectionItem *>( dataItem ) )
124 bool validationRequired {
false };
125 const QString oldSchema { mSchemaName };
127 if ( mDataProviderKey != providerKey )
130 mDataProviderKey = providerKey;
132 validationRequired =
true;
135 if ( collectionItem->layerCollection() )
137 mIsFilePath = FILESYSTEM_BASED_DATAITEM_PROVIDERS.contains( collectionItem->providerKey() );
139 mSchemaName = mIsFilePath ? collectionItem->path().remove( QRegularExpression( u
"^[A-z]+:/"_s ) ) : collectionItem->name();
140 mConnectionName = mIsFilePath ? collectionItem->name() : collectionItem->parent()->name();
141 if ( oldSchema != mSchemaName )
146 validationRequired =
true;
150 if ( validationRequired )
168 mOkButton->setVisible( visible );
171void 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 );
184 QgsDataItem *child = mBrowserModel->dataItem( idx );
202void QgsNewDatabaseTableNameWidget::updateUri()
204 const QString oldUri { mUri };
206 if ( dataProviderMetadata )
208 QgsAbstractProviderConnection *conn { dataProviderMetadata->
findConnection( mConnectionName ) };
211 QVariantMap uriParts = dataProviderMetadata->
decodeUri( conn->
uri() );
212 uriParts[u
"layerName"_s] = mTableName;
213 uriParts[u
"schema"_s] = mSchemaName;
214 uriParts[u
"table"_s] = mTableName;
217 uriParts[u
"dbname"_s] = 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() && mShownProviders.contains( mDataProviderKey ) && !mSchemaName.isEmpty() && !mTableName.isEmpty() && !tableNames().contains( mTableName );
263 mValidationError.clear();
266 bool isError {
false };
270 if ( mTableName.isEmpty() && mSchemaName.isEmpty() )
272 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
274 else if ( !mTableName.isEmpty() && !mSchemaName.isEmpty() && tableNames().contains( mTableName ) )
277 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
279 else if ( mSchemaName.isEmpty() )
281 mValidationError = tr(
"Select a database schema" );
283 else if ( mTableName.isEmpty() )
285 mValidationError = tr(
"Enter a unique name for the new table" );
287 else if ( tableNames().contains( mTableName ) )
289 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
293 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
297 mValidationResults->setStyleSheet( isError ? u
"* { color: red; }"_s : QString() );
299 mValidationResults->setText( mValidationError );
300 mValidationResults->setVisible( !mIsValid );
301 if ( wasValid != mIsValid )
307QStringList QgsNewDatabaseTableNameWidget::tableNames()
309 QStringList tableNames;
310 const QModelIndex index { mBrowserTreeView->currentIndex() };
311 if ( index.isValid() )
313 QgsDataItem *dataItem { mBrowserProxyModel.dataItem( index ) };
322 QgsDataItem *parentDataItem { mIsFilePath ? dataItem : dataItem->
parent() };
323 if ( parentDataItem )
325 QgsAbstractProviderConnection *conn { metadata->
findConnection( parentDataItem->
name() ) };
329 if ( mTableNamesCache.contains(
cacheKey ) )
331 tableNames = mTableNamesCache.value(
cacheKey );
333 else if ( conn &&
static_cast<QgsAbstractDatabaseProviderConnection *
>( conn ) )
335 const auto tables {
static_cast<QgsAbstractDatabaseProviderConnection *
>( conn )->tables( dataItem->
name() ) };
336 for (
const auto &tp : tables )
338 tableNames.push_back( tp.tableName() );
340 mTableNamesCache[
cacheKey] = tableNames;
358 return mValidationError;
363 QWidget::showEvent( e );
365 if ( !lastSelectedPath.isEmpty() )
367 const QModelIndexList items = mBrowserProxyModel.match(
368 mBrowserProxyModel.index( 0, 0 ),
370 QVariant::fromValue( lastSelectedPath ),
374 if ( items.count() > 0 )
376 const QModelIndex expandIndex = items.at( 0 );
377 if ( expandIndex.isValid() )
379 mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
380 mBrowserTreeView->expand( expandIndex );
393 QVBoxLayout *vl =
new QVBoxLayout();
394 vl->addWidget( mWidget, 1 );
395 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
396 connect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
397 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
398 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
400 vl->addWidget( buttonBox );
406 return mWidget->schema();
411 return mWidget->uri();
416 return mWidget->table();
421 return mWidget->dataProviderKey();
426 return mWidget->isValid();
431 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)