27#include <QItemSelectionModel>
32#include "moc_qgsdbimportvectorlayerdialog.cpp"
34using namespace Qt::StringLiterals;
38 , mConnection( connection )
41 setObjectName(
"QgsDbImportVectorLayerDialog" );
48 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
49 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QgsDbImportVectorLayerDialog::doImport );
51 Q_ASSERT( connection );
53 mFieldsView->setDestinationEditable(
true );
56 mFieldsView->setNativeTypes( connection->
nativeTypes() );
60 QgsDebugError( u
"Could not retrieve connection native types: %1"_s.arg( e.
what() ) );
62 connect( mResetButton, &QPushButton::clicked,
this, &QgsDbImportVectorLayerDialog::loadFieldsFromLayer );
63 connect( mAddButton, &QPushButton::clicked,
this, &QgsDbImportVectorLayerDialog::addField );
68 mEditButton->setPopupMode( QToolButton::InstantPopup );
71 QMenu *menu =
new QMenu( mEditButton );
74 menu->addAction( tr(
"Convert All Field Names to Lowercase" ),
this, [
this]() {
76 for (
int i = 0; i < model->
rowCount(); i++ )
79 const QString name = model->
data( index, Qt::EditRole ).toString();
80 model->
setData( index, name.toLower(), Qt::EditRole );
84 menu->addAction( tr(
"Convert All Field Names to Uppercase" ),
this, [
this]() {
86 for (
int i = 0; i < model->
rowCount(); i++ )
89 const QString name = model->
data( index, Qt::EditRole ).toString();
90 model->
setData( index, name.toUpper(), Qt::EditRole );
94 mEditButton->setMenu( menu );
97 if ( supportsSchemas )
99 std::unique_ptr<QgsAbstractDatabaseProviderConnection> schemeComboConn;
102 mLayoutSchemeCombo->addWidget( mSchemaCombo );
106 delete mLabelSchemas;
107 mLabelSchemas =
nullptr;
108 delete mLayoutSchemeCombo;
109 mLayoutSchemeCombo =
nullptr;
113 if ( !supportsPrimaryKeyName )
115 delete mLabelPrimaryKey;
116 mLabelPrimaryKey =
nullptr;
117 delete mEditPrimaryKey;
118 mEditPrimaryKey =
nullptr;
122 if ( !supportsGeomColumnName )
124 delete mLabelGeometryColumn;
125 mLabelGeometryColumn =
nullptr;
126 delete mEditGeometryColumnName;
127 mEditGeometryColumnName =
nullptr;
131 if ( !supportsTableComments )
133 delete mLabelComment;
134 mLabelComment =
nullptr;
136 mEditComment =
nullptr;
139 mExtentGroupBox->setTitleBase( tr(
"Filter by Extent" ) );
140 mExtentGroupBox->setCheckable(
true );
141 mExtentGroupBox->setChecked(
false );
142 mExtentGroupBox->setCollapsed(
true );
144 mFilterExpressionWidget->registerExpressionContextGenerator(
this );
147 sourceLayerComboChanged();
154 delete mSourceLayerComboBox;
155 mSourceLayerComboBox =
nullptr;
156 delete mFilterExpressionWidget;
157 mFilterExpressionWidget =
nullptr;
159 mFieldsView =
nullptr;
165 mSchemaCombo->setSchema(
schema );
170 mOwnedSource.reset();
171 mSourceLayer =
nullptr;
178 mOwnedSource.reset( vl );
179 mBlockSourceLayerChanges++;
180 mSourceLayerComboBox->setAdditionalLayers( { vl } );
181 mSourceLayerComboBox->setLayer( vl );
182 mBlockSourceLayerChanges--;
183 setSourceLayer( mOwnedSource.get() );
187 mBlockSourceLayerChanges++;
188 mSourceLayerComboBox->setLayer( vl );
189 mBlockSourceLayerChanges--;
190 setSourceLayer( vl );
194void QgsDbImportVectorLayerDialog::setSourceLayer(
QgsVectorLayer *layer )
196 mSourceLayer = layer;
197 if ( !mSourceLayer || !mSourceLayer->dataProvider() )
200 mEditTable->setText( layer->
name() );
202 const bool isSpatial = mSourceLayer->isSpatial();
203 if ( mEditGeometryColumnName )
204 mEditGeometryColumnName->setEnabled( isSpatial );
206 mCrsSelector->setEnabled( isSpatial );
208 mExtentGroupBox->setEnabled( isSpatial );
210 mExtentGroupBox->setChecked(
false );
212 const bool extentFilterEnabled = mExtentGroupBox->isChecked();
213 mExtentGroupBox->setOriginalExtent( mSourceLayer->extent(), mSourceLayer->crs() );
214 mExtentGroupBox->setOutputExtentFromOriginal();
215 mExtentGroupBox->setChecked( extentFilterEnabled );
216 mExtentGroupBox->setCollapsed( !extentFilterEnabled );
218 mFilterExpressionWidget->setLayer( mSourceLayer );
220 if ( mEditPrimaryKey )
224 const QgsAttributeList pkAttributes = mSourceLayer->dataProvider()->pkAttributeIndexes();
225 QString primaryKey = !pkAttributes.isEmpty() ? mSourceLayer->dataProvider()->fields().at( pkAttributes.at( 0 ) ).name() : QString();
226 if ( primaryKey.isEmpty() )
229 primaryKey = dsUri.keyColumn();
231 if ( primaryKey.isEmpty() )
233 primaryKey = mConnection->defaultPrimaryKeyColumnName();
236 mEditPrimaryKey->setText( primaryKey );
239 if ( mEditGeometryColumnName )
243 QString geomColumn = mSourceLayer->dataProvider()->geometryColumnName();
244 if ( geomColumn.isEmpty() )
246 QgsDataSourceUri dsUri( mSourceLayer->source() );
247 geomColumn = dsUri.geometryColumn();
249 if ( geomColumn.isEmpty() )
251 geomColumn = mConnection->defaultGeometryColumnName();
254 mEditGeometryColumnName->setText( geomColumn );
259 mCrsSelector->setCrs( mSourceLayer->crs() );
264 mEditComment->setPlainText( mSourceLayer->metadata().abstract() );
267 mFieldsView->setSourceLayer( mSourceLayer );
268 mFieldsView->setSourceFields( mSourceLayer->fields() );
269 mFieldsView->setDestinationFields( mSourceLayer->fields() );
271 const bool selectedFeatures = mSourceLayer->selectedFeatureCount() > 0;
272 mSourceLayerOnlySelected->setEnabled( selectedFeatures );
275void QgsDbImportVectorLayerDialog::loadFieldsFromLayer()
279 mFieldsView->setSourceFields( mSourceLayer->fields() );
280 mFieldsView->setDestinationFields( mSourceLayer->fields() );
284void QgsDbImportVectorLayerDialog::addField()
286 const int rowCount = mFieldsView->model()->rowCount();
287 mFieldsView->appendField( QgsField( u
"new_field"_s ), u
"NULL"_s );
288 const QModelIndex index = mFieldsView->model()->index( rowCount, 0 );
289 mFieldsView->selectionModel()->select( index, QItemSelectionModel::SelectionFlags( QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current | QItemSelectionModel::Rows ) );
290 mFieldsView->scrollTo( index );
295 return mSchemaCombo ? mSchemaCombo->currentSchema() : QString();
300 return mEditTable->text();
305 return mEditComment ? mEditComment->toPlainText() : QString();
313 mExtentGroupBox->setMapCanvas( canvas,
false );
317void QgsDbImportVectorLayerDialog::doImport()
326 if ( !mSourceLayer || !mSourceLayer->dataProvider() )
329 QString destinationUri;
330 QVariantMap providerOptions;
333 exporterOptions.
layerName = mEditTable->text();
335 exporterOptions.
schema = mSchemaCombo->currentSchema();
336 exporterOptions.
wkbType = mSourceLayer->wkbType();
337 if ( mEditPrimaryKey && !mEditPrimaryKey->text().trimmed().isEmpty() )
339 if ( mEditGeometryColumnName )
344 destinationUri = mConnection->createVectorLayerExporterDestinationUri( exporterOptions, providerOptions );
352 QVariantMap allProviderOptions = extraProviderOptions;
353 for (
auto it = providerOptions.constBegin(); it != providerOptions.constEnd(); ++it )
355 allProviderOptions.insert( it.key(), it.value() );
359 if ( mChkDropTable->isChecked() )
361 allProviderOptions.insert( u
"overwrite"_s,
true );
367 allProviderOptions.insert( u
"skipConvertFields"_s,
true );
375 if ( !mFilterExpressionWidget->expression().isEmpty() )
381 if ( mExtentGroupBox->isEnabled() && mExtentGroupBox->isChecked() )
386 if ( mSourceLayerOnlySelected->isEnabled() && mSourceLayerOnlySelected->isChecked() )
391 const QList<QgsFieldMappingModel::Field> fieldMapping = mFieldsView->mapping();
392 QList<QgsVectorLayerExporter::OutputField> outputFields;
393 outputFields.reserve( fieldMapping.size() );
400 return std::make_unique<QgsVectorLayerExporterTask>( mSourceLayer->clone(), destinationUri, mConnection->providerKey(), exportOptions, allProviderOptions,
true );
410void QgsDbImportVectorLayerDialog::sourceLayerComboChanged()
412 if ( mBlockSourceLayerChanges )
415 if ( mSourceLayerComboBox->currentLayer() == mSourceLayer )
418 setSourceLayer( qobject_cast< QgsVectorLayer * >( mSourceLayerComboBox->currentLayer() ) );
@ SetPrimaryKeyName
Can set the name of the primary key column.
@ SetGeometryColumnName
Can set the name of the geometry column.
@ SetTableComment
Can set comments for tables via setTableComment().
Provides common functionality for database based connections.
@ Schemas
Can list schemas (if not set, the connection does not support schemas).
virtual QList< QgsVectorDataProvider::NativeType > nativeTypes() const =0
Returns a list of native types supported by the connection.
Represents a coordinate reference system (CRS).
Stores the component parts of a data source URI (e.g.
A combo box which displays the list of schemas for a specific database connection.
void setDestinationSchema(const QString &schema)
Sets the destination schema for the new table.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
std::unique_ptr< QgsVectorLayerExporterTask > createExporterTask(const QVariantMap &extraProviderOptions=QVariantMap())
Creates a new exporter task to match the settings defined in the dialog.
void setMapCanvas(QgsMapCanvas *canvas)
Sets a map canvas to associate with the dialog.
~QgsDbImportVectorLayerDialog() override
void setSourceUri(const QgsMimeDataUtils::Uri &uri)
Sets the source table uri.
QString schema() const
Returns the destination schema.
QString tableName() const
Returns the destination table name.
QString tableComment() const
Returns the optional comment to use for the new table.
QgsDbImportVectorLayerDialog(QgsAbstractDatabaseProviderConnection *connection, QWidget *parent=nullptr)
Constructor for QgsDbImportVectorLayerDialog.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
Holds mapping information for mapping from one set of QgsFields to another.
@ DestinationName
Destination field name.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
bool setData(const QModelIndex &index, const QVariant &value, int role) override
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Map canvas is a class for displaying all GIS data types on a canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
void layerChanged(QgsMapLayer *layer)
Emitted whenever the currently selected layer changes.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
Custom exception class for provider connection related exceptions.
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.
A QgsRectangle with associated coordinate reference system.
Encapsulates options for use with QgsVectorLayerExporter.
void setExtent(const QgsReferencedRectangle &extent)
Sets an extent filter for the features to export.
void setOutputFields(const QList< QgsVectorLayerExporter::OutputField > &fields)
Sets the output field definitions for the destination table.
void setSelectedOnly(bool selected)
Sets whether the export should only include selected features.
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination coordinate reference system to use for exported features.
void setFilterExpression(const QString &expression)
Set the filter expression for the features to export.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context to use when a filterExpression() is set.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context to use when transforming exported features.
Represents a vector layer which manages a vector based dataset.
QList< int > QgsAttributeList
#define QgsDebugError(str)
Stores all information required to create a QgsVectorLayerExporter for the backend.
QStringList primaryKeyColumns
List of primary key column names. Note that some providers may ignore this if not supported.
QString schema
Optional schema for the new layer. May not be supported by all providers.
QString geometryColumn
Preferred name for the geometry column, if required. Note that some providers may ignore this if a sp...
QString layerName
Name for the new layer.
Qgis::WkbType wkbType
WKB type for destination layer geometry.
The Field struct holds information about a mapped field.
QgsVectorLayer * vectorLayer(bool &owner, QString &error) const
Gets vector layer from uri if possible, otherwise returns nullptr and error is set.
Encapsulates output field definition.