17 #include <QTreeWidgetItemIterator> 
   25 #include "qgssettings.h" 
   30 #include <QRegularExpression> 
   31 #include <QDialogButtonBox> 
   32 #include <QPushButton> 
   35 QStringList QgsNewDatabaseTableNameWidget::FILESYSTEM_BASED_DATAITEM_PROVIDERS { QStringLiteral( 
"GPKG" ), QStringLiteral( 
"spatialite" ) };
 
   39   const QStringList &providersFilter,
 
   52     mBrowserModel = browserModel;
 
   59   mOkButton->setEnabled( 
false );
 
   61   QStringList shownDataItemProvidersFilter;
 
   64   for ( 
const auto &provider : providerList )
 
   66     if ( provider->dataProviderKey().isEmpty() )
 
   74     if ( provider->capabilities() & QgsDataProvider::DataCapability::Database )
 
   76       if ( providersFilter.isEmpty() || providersFilter.contains( provider->dataProviderKey() ) )
 
   78         mShownProviders.insert( provider->dataProviderKey() );
 
   79         shownDataItemProvidersFilter.push_back( provider->name() );
 
   89   if ( ! providersFilter.isEmpty() && shownDataItemProvidersFilter.isEmpty() )
 
   91     shownDataItemProvidersFilter = providersFilter;
 
   95   mBrowserTreeView->setHeaderHidden( 
true );
 
   96   mBrowserTreeView->setModel( &mBrowserProxyModel );
 
   97   mBrowserTreeView->setBrowserModel( mBrowserModel );
 
  100   connect( mNewTableName, &QLineEdit::textChanged, 
this, [ = ]
 
  102     mTableName = mNewTableName->text();
 
  108   connect( mActionRefresh, &QAction::triggered, 
this, [ = ]
 
  110     refreshModel( QModelIndex() );
 
  113   connect( mBrowserTreeView, &QgsBrowserTreeView::clicked, 
this, [ = ]( 
const QModelIndex & index )
 
  115     if ( index.isValid() )
 
  117       if ( const QgsDataItem *dataItem = mBrowserProxyModel.dataItem( index ) )
 
  119         if ( const QgsDataCollectionItem *collectionItem = qobject_cast<const QgsDataCollectionItem *>( dataItem ) )
 
  121           const QString providerKey { QgsApplication::dataItemProviderRegistry()->dataProviderKey( dataItem->providerKey() ) };
 
  122           bool validationRequired { false };
 
  123           const QString oldSchema { mSchemaName };
 
  125           if ( mDataProviderKey != providerKey )
 
  128             mDataProviderKey = providerKey;
 
  129             emit providerKeyChanged( providerKey );
 
  130             validationRequired = true;
 
  133           if ( collectionItem->layerCollection( ) )
 
  135             mIsFilePath = FILESYSTEM_BASED_DATAITEM_PROVIDERS.contains( collectionItem->providerKey() );
 
  137             mSchemaName = mIsFilePath ? collectionItem->path().remove( QRegularExpression( QStringLiteral( 
"^[A-z]+:/" ) ) ) : collectionItem->name(); 
 
  138             mConnectionName = mIsFilePath ? collectionItem->name() : collectionItem->parent()->name();
 
  139             if ( oldSchema != mSchemaName )
 
  141               emit schemaNameChanged( mSchemaName );
 
  143               QgsSettings().setValue( QStringLiteral( 
"newDatabaseTableNameWidgetLastSelectedItem" ),
 
  144                                       mBrowserProxyModel.data( index, QgsBrowserGuiModel::PathRole ).toString(), QgsSettings::Section::Gui );
 
  145               validationRequired = true;
 
  149           if ( validationRequired )
 
  167   mOkButton->setVisible( visible );
 
  170 void QgsNewDatabaseTableNameWidget::refreshModel( 
const QModelIndex &index )
 
  177     mBrowserModel->
refresh( index );
 
  180   for ( 
int i = 0; i < mBrowserModel->
rowCount( index ); i++ )
 
  182     QModelIndex idx = mBrowserModel->
index( i, 0, index );
 
  183     QModelIndex proxyIdx = mBrowserProxyModel.mapFromSource( idx );
 
  202 void QgsNewDatabaseTableNameWidget::updateUri()
 
  204   const QString oldUri { mUri };
 
  206   if ( dataProviderMetadata )
 
  211       QVariantMap uriParts = dataProviderMetadata->decodeUri( conn->uri() );
 
  212       uriParts[ QStringLiteral( 
"layerName" ) ] = mTableName;
 
  213       uriParts[ QStringLiteral( 
"schema" ) ] = mSchemaName;
 
  214       uriParts[ QStringLiteral( 
"table" ) ] = mTableName;
 
  217         uriParts[ QStringLiteral( 
"dbname" ) ] = mSchemaName;
 
  219       mUri = dataProviderMetadata->encodeUri( uriParts );
 
  231   if ( mUri != oldUri )
 
  254   return mDataProviderKey;
 
  257 void QgsNewDatabaseTableNameWidget::validate()
 
  259   const bool wasValid { mIsValid };
 
  261   mIsValid = ! mDataProviderKey.isEmpty() &&
 
  262              mShownProviders.contains( mDataProviderKey ) &&
 
  263              ! mSchemaName.isEmpty() &&
 
  264              ! mTableName.isEmpty() &&
 
  265              ! tableNames( ).contains( mTableName );
 
  267   mValidationError.clear();
 
  270   bool isError { 
false };
 
  274     if ( mTableName.isEmpty() && mSchemaName.isEmpty() )
 
  276       mValidationError = tr( 
"Select a database schema and enter a unique name for the new table" );
 
  278     else if ( ! mTableName.isEmpty() &&
 
  279               ! mSchemaName.isEmpty() &&
 
  280               tableNames( ).contains( mTableName ) )
 
  283       mValidationError = tr( 
"A table named '%1' already exists" ).arg( mTableName );
 
  285     else if ( mSchemaName.isEmpty() )
 
  287       mValidationError = tr( 
"Select a database schema" );
 
  289     else if ( mTableName.isEmpty() )
 
  291       mValidationError = tr( 
"Enter a unique name for the new table" );
 
  293     else if ( tableNames( ).contains( mTableName ) )
 
  295       mValidationError = tr( 
"A table named '%1' already exists" ).arg( mTableName );
 
  299       mValidationError = tr( 
"Select a database schema and enter a unique name for the new table" );
 
  303   mValidationResults->setStyleSheet( isError ?
 
  304                                      QStringLiteral( 
"* { color: red; }" ) :
 
  307   mValidationResults->setText( mValidationError );
 
  308   mValidationResults->setVisible( ! mIsValid );
 
  309   if ( wasValid != mIsValid )
 
  315 QStringList QgsNewDatabaseTableNameWidget::tableNames()
 
  317   QStringList tableNames;
 
  318   QModelIndex index { mBrowserTreeView->currentIndex() };
 
  319   if ( index.isValid() )
 
  330           QgsDataItem *parentDataItem { mIsFilePath ? dataItem : dataItem->parent() };
 
  331           if ( parentDataItem )
 
  336               const QString cacheKey { conn->
uri() + dataItem->name() };
 
  337               if ( mTableNamesCache.contains( cacheKey ) )
 
  339                 tableNames = mTableNamesCache.value( cacheKey );
 
  344                 for ( 
const auto &tp : tables )
 
  346                   tableNames.push_back( tp.tableName() );
 
  348                 mTableNamesCache[ cacheKey ] = tableNames;
 
  366   return mValidationError;
 
  371   QWidget::showEvent( e );
 
  372   QString lastSelectedPath( QgsSettings().value( QStringLiteral( 
"newDatabaseTableNameWidgetLastSelectedItem" ),
 
  373                             QString(), QgsSettings::Section::Gui ).toString() );
 
  374   if ( ! lastSelectedPath.isEmpty() )
 
  376     QModelIndexList items = mBrowserProxyModel.match(
 
  377                               mBrowserProxyModel.index( 0, 0 ),
 
  379                               QVariant::fromValue( lastSelectedPath ),
 
  381                               Qt::MatchRecursive );
 
  382     if ( items.count( ) > 0 )
 
  384       QModelIndex expandIndex = items.at( 0 );
 
  385       if ( expandIndex.isValid() )
 
  387         mBrowserTreeView->scrollTo( expandIndex, QgsBrowserTreeView::ScrollHint::PositionAtTop );
 
  388         mBrowserTreeView->expand( expandIndex );
 
  401   QVBoxLayout *vl = 
new QVBoxLayout();
 
  402   vl->addWidget( mWidget, 1 );
 
  403   QDialogButtonBox *buttonBox = 
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
 
  404   connect( buttonBox, &QDialogButtonBox::accepted, 
this, &QDialog::accept );
 
  405   connect( buttonBox, &QDialogButtonBox::rejected, 
this, &QDialog::reject );
 
  406   buttonBox->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
  408   vl->addWidget( buttonBox );
 
  419   return mWidget->
uri();
 
  424   return mWidget->
table();
 
@ 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
@ 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 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.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.