17#include <QTreeWidgetItemIterator>
20#include "moc_qgsnewdatabasetablenamewidget.cpp"
31#include <QRegularExpression>
32#include <QDialogButtonBox>
36QStringList QgsNewDatabaseTableNameWidget::FILESYSTEM_BASED_DATAITEM_PROVIDERS { QStringLiteral(
"GPKG" ), QStringLiteral(
"spatialite" ) };
40 const QStringList &providersFilter,
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() );
90 if ( ! providersFilter.isEmpty() && shownDataItemProvidersFilter.isEmpty() )
92 shownDataItemProvidersFilter = providersFilter;
96 mBrowserTreeView->setHeaderHidden(
true );
97 mBrowserTreeView->setModel( &mBrowserProxyModel );
98 mBrowserTreeView->setBrowserModel( mBrowserModel );
101 connect( mNewTableName, &QLineEdit::textChanged,
this, [ = ]
103 mTableName = mNewTableName->text();
109 connect( mActionRefresh, &QAction::triggered,
this, [ = ]
111 refreshModel( QModelIndex() );
114 connect( mBrowserTreeView, &QgsBrowserTreeView::clicked,
this, [ = ](
const QModelIndex & index )
116 if ( index.isValid() )
118 if ( const QgsDataItem *dataItem = mBrowserProxyModel.dataItem( index ) )
120 if ( const QgsDataCollectionItem *collectionItem = qobject_cast<const QgsDataCollectionItem *>( dataItem ) )
122 const QString providerKey { QgsApplication::dataItemProviderRegistry()->dataProviderKey( dataItem->providerKey() ) };
123 bool validationRequired { false };
124 const QString oldSchema { mSchemaName };
126 if ( mDataProviderKey != providerKey )
129 mDataProviderKey = providerKey;
130 emit providerKeyChanged( providerKey );
131 validationRequired = true;
134 if ( collectionItem->layerCollection( ) )
136 mIsFilePath = FILESYSTEM_BASED_DATAITEM_PROVIDERS.contains( collectionItem->providerKey() );
138 mSchemaName = mIsFilePath ? collectionItem->path().remove( QRegularExpression( QStringLiteral(
"^[A-z]+:/" ) ) ) : collectionItem->name();
139 mConnectionName = mIsFilePath ? collectionItem->name() : collectionItem->parent()->name();
140 if ( oldSchema != mSchemaName )
142 emit schemaNameChanged( mSchemaName );
144 QgsSettings().setValue( QStringLiteral(
"newDatabaseTableNameWidgetLastSelectedItem" ),
145 mBrowserProxyModel.data( index, static_cast< int >( QgsBrowserModel::CustomRole::Path ) ).toString(), QgsSettings::Section::Gui );
146 validationRequired = true;
150 if ( validationRequired )
168 mOkButton->setVisible( visible );
171void QgsNewDatabaseTableNameWidget::refreshModel(
const QModelIndex &index )
178 mBrowserModel->
refresh( index );
181 for (
int i = 0; i < mBrowserModel->
rowCount( index ); i++ )
183 const QModelIndex idx = mBrowserModel->
index( i, 0, index );
184 const QModelIndex proxyIdx = mBrowserProxyModel.mapFromSource( idx );
203void QgsNewDatabaseTableNameWidget::updateUri()
205 const QString oldUri { mUri };
207 if ( dataProviderMetadata )
212 QVariantMap uriParts = dataProviderMetadata->decodeUri( conn->uri() );
213 uriParts[ QStringLiteral(
"layerName" ) ] = mTableName;
214 uriParts[ QStringLiteral(
"schema" ) ] = mSchemaName;
215 uriParts[ QStringLiteral(
"table" ) ] = mTableName;
218 uriParts[ QStringLiteral(
"dbname" ) ] = mSchemaName;
220 mUri = dataProviderMetadata->encodeUri( uriParts );
232 if ( mUri != oldUri )
255 return mDataProviderKey;
258void QgsNewDatabaseTableNameWidget::validate()
260 const bool wasValid { mIsValid };
262 mIsValid = ! mDataProviderKey.isEmpty() &&
263 mShownProviders.contains( mDataProviderKey ) &&
264 ! mSchemaName.isEmpty() &&
265 ! mTableName.isEmpty() &&
266 ! tableNames( ).contains( mTableName );
268 mValidationError.clear();
271 bool isError {
false };
275 if ( mTableName.isEmpty() && mSchemaName.isEmpty() )
277 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
279 else if ( ! mTableName.isEmpty() &&
280 ! mSchemaName.isEmpty() &&
281 tableNames( ).contains( mTableName ) )
284 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
286 else if ( mSchemaName.isEmpty() )
288 mValidationError = tr(
"Select a database schema" );
290 else if ( mTableName.isEmpty() )
292 mValidationError = tr(
"Enter a unique name for the new table" );
294 else if ( tableNames( ).contains( mTableName ) )
296 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
300 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
304 mValidationResults->setStyleSheet( isError ?
305 QStringLiteral(
"* { color: red; }" ) :
308 mValidationResults->setText( mValidationError );
309 mValidationResults->setVisible( ! mIsValid );
310 if ( wasValid != mIsValid )
316QStringList QgsNewDatabaseTableNameWidget::tableNames()
318 QStringList tableNames;
319 const QModelIndex index { mBrowserTreeView->currentIndex() };
320 if ( index.isValid() )
331 QgsDataItem *parentDataItem { mIsFilePath ? dataItem : dataItem->parent() };
332 if ( parentDataItem )
337 const QString cacheKey { conn->
uri() + dataItem->name() };
338 if ( mTableNamesCache.contains( cacheKey ) )
340 tableNames = mTableNamesCache.value( cacheKey );
345 for (
const auto &tp : tables )
347 tableNames.push_back( tp.tableName() );
349 mTableNamesCache[ cacheKey ] = tableNames;
367 return mValidationError;
372 QWidget::showEvent( e );
373 const QString lastSelectedPath(
QgsSettings().value( QStringLiteral(
"newDatabaseTableNameWidgetLastSelectedItem" ),
375 if ( ! lastSelectedPath.isEmpty() )
377 const QModelIndexList items = mBrowserProxyModel.match(
378 mBrowserProxyModel.index( 0, 0 ),
380 QVariant::fromValue( lastSelectedPath ),
382 Qt::MatchRecursive );
383 if ( items.count( ) > 0 )
385 const QModelIndex expandIndex = items.at( 0 );
386 if ( expandIndex.isValid() )
388 mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
389 mBrowserTreeView->expand( expandIndex );
402 QVBoxLayout *vl =
new QVBoxLayout();
403 vl->addWidget( mWidget, 1 );
404 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
405 connect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
406 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
407 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
409 vl->addWidget( buttonBox );
420 return mWidget->
uri();
425 return mWidget->
table();
@ 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,...
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
@ Path
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 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.
This class is a composition of two QSettings instances:
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.