28#include <QItemSelectionModel>
33#include "moc_qgsdbimportvectorlayerdialog.cpp"
35using namespace Qt::StringLiterals;
39 , mConnection( connection )
42 setObjectName(
"QgsDbImportVectorLayerDialog" );
49 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
50 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QgsDbImportVectorLayerDialog::doImport );
52 Q_ASSERT( connection );
54 mFieldsView->setDestinationEditable(
true );
57 mFieldsView->setNativeTypes( connection->
nativeTypes() );
61 QgsDebugError( u
"Could not retrieve connection native types: %1"_s.arg( e.
what() ) );
63 connect( mResetButton, &QPushButton::clicked,
this, &QgsDbImportVectorLayerDialog::loadFieldsFromLayer );
64 connect( mAddButton, &QPushButton::clicked,
this, &QgsDbImportVectorLayerDialog::addField );
69 mEditButton->setPopupMode( QToolButton::InstantPopup );
72 QMenu *menu =
new QMenu( mEditButton );
75 menu->addAction( tr(
"Convert All Field Names to Lowercase" ),
this, [
this]() {
77 for (
int i = 0; i < model->
rowCount(); i++ )
80 const QString name = model->
data( index, Qt::EditRole ).toString();
81 model->
setData( index, name.toLower(), Qt::EditRole );
85 menu->addAction( tr(
"Convert All Field Names to Uppercase" ),
this, [
this]() {
87 for (
int i = 0; i < model->
rowCount(); i++ )
90 const QString name = model->
data( index, Qt::EditRole ).toString();
91 model->
setData( index, name.toUpper(), Qt::EditRole );
95 mEditButton->setMenu( menu );
98 if ( supportsSchemas )
100 std::unique_ptr<QgsAbstractDatabaseProviderConnection> schemeComboConn;
103 mLayoutSchemeCombo->addWidget( mSchemaCombo );
107 delete mLabelSchemas;
108 mLabelSchemas =
nullptr;
109 delete mLayoutSchemeCombo;
110 mLayoutSchemeCombo =
nullptr;
114 if ( !supportsPrimaryKeyName )
116 delete mLabelPrimaryKey;
117 mLabelPrimaryKey =
nullptr;
118 delete mEditPrimaryKey;
119 mEditPrimaryKey =
nullptr;
123 if ( !supportsGeomColumnName )
125 delete mLabelGeometryColumn;
126 mLabelGeometryColumn =
nullptr;
127 delete mEditGeometryColumnName;
128 mEditGeometryColumnName =
nullptr;
132 if ( !supportsTableComments )
134 delete mLabelComment;
135 mLabelComment =
nullptr;
137 mEditComment =
nullptr;
140 mExtentGroupBox->setTitleBase( tr(
"Filter by Extent" ) );
141 mExtentGroupBox->setCheckable(
true );
142 mExtentGroupBox->setChecked(
false );
143 mExtentGroupBox->setCollapsed(
true );
145 mFilterExpressionWidget->registerExpressionContextGenerator(
this );
148 sourceLayerComboChanged();
155 delete mSourceLayerComboBox;
156 mSourceLayerComboBox =
nullptr;
157 delete mFilterExpressionWidget;
158 mFilterExpressionWidget =
nullptr;
160 mFieldsView =
nullptr;
166 mSchemaCombo->setSchema(
schema );
171 mOwnedSource.reset();
172 mSourceLayer =
nullptr;
179 mOwnedSource.reset( vl );
180 mBlockSourceLayerChanges++;
181 mSourceLayerComboBox->setAdditionalLayers( { vl } );
182 mSourceLayerComboBox->setLayer( vl );
183 mBlockSourceLayerChanges--;
184 setSourceLayer( mOwnedSource.get() );
188 mBlockSourceLayerChanges++;
189 mSourceLayerComboBox->setLayer( vl );
190 mBlockSourceLayerChanges--;
191 setSourceLayer( vl );
195void QgsDbImportVectorLayerDialog::setSourceLayer(
QgsVectorLayer *layer )
197 mSourceLayer = layer;
198 if ( !mSourceLayer || !mSourceLayer->dataProvider() )
201 mEditTable->setText( layer->
name() );
203 const bool isSpatial = mSourceLayer->isSpatial();
204 if ( mEditGeometryColumnName )
205 mEditGeometryColumnName->setEnabled( isSpatial );
207 mCrsSelector->setEnabled( isSpatial );
209 mExtentGroupBox->setEnabled( isSpatial );
211 mExtentGroupBox->setChecked(
false );
213 const bool extentFilterEnabled = mExtentGroupBox->isChecked();
214 mExtentGroupBox->setOriginalExtent( mSourceLayer->extent(), mSourceLayer->crs() );
215 mExtentGroupBox->setOutputExtentFromOriginal();
216 mExtentGroupBox->setChecked( extentFilterEnabled );
217 mExtentGroupBox->setCollapsed( !extentFilterEnabled );
219 mFilterExpressionWidget->setLayer( mSourceLayer );
221 if ( mEditPrimaryKey )
225 const QgsAttributeList pkAttributes = mSourceLayer->dataProvider()->pkAttributeIndexes();
226 QString primaryKey = !pkAttributes.isEmpty() ? mSourceLayer->dataProvider()->fields().at( pkAttributes.at( 0 ) ).name() : QString();
227 if ( primaryKey.isEmpty() )
230 primaryKey = dsUri.keyColumn();
232 if ( primaryKey.isEmpty() )
234 primaryKey = mConnection->defaultPrimaryKeyColumnName();
237 mEditPrimaryKey->setText( primaryKey );
240 if ( mEditGeometryColumnName )
244 QString geomColumn = mSourceLayer->dataProvider()->geometryColumnName();
245 if ( geomColumn.isEmpty() )
247 QgsDataSourceUri dsUri( mSourceLayer->source() );
248 geomColumn = dsUri.geometryColumn();
250 if ( geomColumn.isEmpty() )
252 geomColumn = mConnection->defaultGeometryColumnName();
255 mEditGeometryColumnName->setText( geomColumn );
260 mCrsSelector->setCrs( mSourceLayer->crs() );
265 mEditComment->setPlainText( mSourceLayer->metadata().abstract() );
268 mFieldsView->setSourceLayer( mSourceLayer );
269 mFieldsView->setSourceFields( mSourceLayer->fields() );
270 mFieldsView->setDestinationFields( mSourceLayer->fields() );
272 const bool selectedFeatures = mSourceLayer->selectedFeatureCount() > 0;
273 mSourceLayerOnlySelected->setEnabled( selectedFeatures );
276void QgsDbImportVectorLayerDialog::loadFieldsFromLayer()
280 mFieldsView->setSourceFields( mSourceLayer->fields() );
281 mFieldsView->setDestinationFields( mSourceLayer->fields() );
285void QgsDbImportVectorLayerDialog::addField()
287 const int rowCount = mFieldsView->model()->rowCount();
288 mFieldsView->appendField( QgsField( u
"new_field"_s ), u
"NULL"_s );
289 const QModelIndex index = mFieldsView->model()->index( rowCount, 0 );
290 mFieldsView->selectionModel()->select( index, QItemSelectionModel::SelectionFlags( QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current | QItemSelectionModel::Rows ) );
291 mFieldsView->scrollTo( index );
296 return mSchemaCombo ? mSchemaCombo->currentSchema() : QString();
301 return mEditTable->text();
306 return mEditComment ? mEditComment->toPlainText() : QString();
314 mExtentGroupBox->setMapCanvas( canvas,
false );
318void QgsDbImportVectorLayerDialog::doImport()
327 if ( !mSourceLayer || !mSourceLayer->dataProvider() )
330 QString destinationUri;
331 QVariantMap providerOptions;
334 exporterOptions.
layerName = mEditTable->text();
336 exporterOptions.
schema = mSchemaCombo->currentSchema();
337 exporterOptions.
wkbType = mSourceLayer->wkbType();
338 if ( mEditPrimaryKey && !mEditPrimaryKey->text().trimmed().isEmpty() )
340 if ( mEditGeometryColumnName )
345 destinationUri = mConnection->createVectorLayerExporterDestinationUri( exporterOptions, providerOptions );
353 QVariantMap allProviderOptions = extraProviderOptions;
354 for (
auto it = providerOptions.constBegin(); it != providerOptions.constEnd(); ++it )
356 allProviderOptions.insert( it.key(), it.value() );
360 if ( mChkDropTable->isChecked() )
362 allProviderOptions.insert( u
"overwrite"_s,
true );
368 allProviderOptions.insert( u
"skipConvertFields"_s,
true );
376 if ( !mFilterExpressionWidget->expression().isEmpty() )
382 if ( mExtentGroupBox->isEnabled() && mExtentGroupBox->isChecked() )
387 if ( mSourceLayerOnlySelected->isEnabled() && mSourceLayerOnlySelected->isChecked() )
392 const QList<QgsFieldMappingModel::Field> fieldMapping = mFieldsView->mapping();
393 QList<QgsVectorLayerExporter::OutputField> outputFields;
394 outputFields.reserve( fieldMapping.size() );
401 return std::make_unique<QgsVectorLayerExporterTask>( mSourceLayer->clone(), destinationUri, mConnection->providerKey(), exportOptions, allProviderOptions,
true );
411void QgsDbImportVectorLayerDialog::sourceLayerComboChanged()
413 if ( mBlockSourceLayerChanges )
416 if ( mSourceLayerComboBox->currentLayer() == mSourceLayer )
419 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.
static QgsProject * instance()
Returns the QgsProject singleton instance.
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.
Q_DECL_DEPRECATED 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.