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, [=] {
102 mTableName = mNewTableName->text();
108 connect( mActionRefresh, &QAction::triggered,
this, [=] {
109 refreshModel( QModelIndex() );
112 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" ), mBrowserProxyModel.data( index, static_cast<int>( QgsBrowserModel::CustomRole::Path ) ).toString(), QgsSettings::Section::Gui );
142 validationRequired = true;
146 if ( validationRequired )
164 mOkButton->setVisible( visible );
167void QgsNewDatabaseTableNameWidget::refreshModel(
const QModelIndex &index )
173 mBrowserModel->
refresh( index );
176 for (
int i = 0; i < mBrowserModel->
rowCount( index ); i++ )
178 const QModelIndex idx = mBrowserModel->
index( i, 0, index );
179 const QModelIndex proxyIdx = mBrowserProxyModel.mapFromSource( idx );
198void QgsNewDatabaseTableNameWidget::updateUri()
200 const QString oldUri { mUri };
202 if ( dataProviderMetadata )
207 QVariantMap uriParts = dataProviderMetadata->decodeUri( conn->uri() );
208 uriParts[QStringLiteral(
"layerName" )] = mTableName;
209 uriParts[QStringLiteral(
"schema" )] = mSchemaName;
210 uriParts[QStringLiteral(
"table" )] = mTableName;
213 uriParts[QStringLiteral(
"dbname" )] = mSchemaName;
215 mUri = dataProviderMetadata->encodeUri( uriParts );
227 if ( mUri != oldUri )
250 return mDataProviderKey;
253void QgsNewDatabaseTableNameWidget::validate()
255 const bool wasValid { mIsValid };
257 mIsValid = !mDataProviderKey.isEmpty() && mShownProviders.contains( mDataProviderKey ) && !mSchemaName.isEmpty() && !mTableName.isEmpty() && !tableNames().contains( mTableName );
259 mValidationError.clear();
262 bool isError {
false };
266 if ( mTableName.isEmpty() && mSchemaName.isEmpty() )
268 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
270 else if ( !mTableName.isEmpty() && !mSchemaName.isEmpty() && tableNames().contains( mTableName ) )
273 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
275 else if ( mSchemaName.isEmpty() )
277 mValidationError = tr(
"Select a database schema" );
279 else if ( mTableName.isEmpty() )
281 mValidationError = tr(
"Enter a unique name for the new table" );
283 else if ( tableNames().contains( mTableName ) )
285 mValidationError = tr(
"A table named '%1' already exists" ).arg( mTableName );
289 mValidationError = tr(
"Select a database schema and enter a unique name for the new table" );
293 mValidationResults->setStyleSheet( isError ? QStringLiteral(
"* { color: red; }" ) : QString() );
295 mValidationResults->setText( mValidationError );
296 mValidationResults->setVisible( !mIsValid );
297 if ( wasValid != mIsValid )
303QStringList QgsNewDatabaseTableNameWidget::tableNames()
305 QStringList tableNames;
306 const QModelIndex index { mBrowserTreeView->currentIndex() };
307 if ( index.isValid() )
318 QgsDataItem *parentDataItem { mIsFilePath ? dataItem : dataItem->parent() };
319 if ( parentDataItem )
324 const QString cacheKey { conn->
uri() + dataItem->name() };
325 if ( mTableNamesCache.contains( cacheKey ) )
327 tableNames = mTableNamesCache.value( cacheKey );
332 for (
const auto &tp : tables )
334 tableNames.push_back( tp.tableName() );
336 mTableNamesCache[cacheKey] = tableNames;
354 return mValidationError;
359 QWidget::showEvent( e );
361 if ( !lastSelectedPath.isEmpty() )
363 const QModelIndexList items = mBrowserProxyModel.match(
364 mBrowserProxyModel.index( 0, 0 ),
366 QVariant::fromValue( lastSelectedPath ),
370 if ( items.count() > 0 )
372 const QModelIndex expandIndex = items.at( 0 );
373 if ( expandIndex.isValid() )
375 mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
376 mBrowserTreeView->expand( expandIndex );
389 QVBoxLayout *vl =
new QVBoxLayout();
390 vl->addWidget( mWidget, 1 );
391 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
392 connect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
393 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
394 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
396 vl->addWidget( buttonBox );
407 return mWidget->
uri();
412 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.