27#include <QItemSelectionModel>
32#include "moc_qgsdbimportvectorlayerdialog.cpp"
34using namespace Qt::StringLiterals;
38 , mConnection( connection )
41 setObjectName(
"QgsDbImportVectorLayerDialog" );
47 mExtentGroupBox->setOutputCrs( crs );
50 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QDialog::reject );
51 connect( mButtonBox, &QDialogButtonBox::accepted,
this, &QgsDbImportVectorLayerDialog::doImport );
53 Q_ASSERT( connection );
55 mFieldsView->setDestinationEditable(
true );
58 mFieldsView->setNativeTypes( connection->
nativeTypes() );
62 QgsDebugError( u
"Could not retrieve connection native types: %1"_s.arg( e.
what() ) );
64 connect( mResetButton, &QPushButton::clicked,
this, &QgsDbImportVectorLayerDialog::loadFieldsFromLayer );
65 connect( mAddButton, &QPushButton::clicked,
this, &QgsDbImportVectorLayerDialog::addField );
70 mEditButton->setPopupMode( QToolButton::InstantPopup );
73 QMenu *menu =
new QMenu( mEditButton );
76 menu->addAction( tr(
"Convert All Field Names to Lowercase" ),
this, [
this]() {
78 for (
int i = 0; i < model->
rowCount(); i++ )
81 const QString name = model->
data( index, Qt::EditRole ).toString();
82 model->
setData( index, name.toLower(), Qt::EditRole );
86 menu->addAction( tr(
"Convert All Field Names to Uppercase" ),
this, [
this]() {
88 for (
int i = 0; i < model->
rowCount(); i++ )
91 const QString name = model->
data( index, Qt::EditRole ).toString();
92 model->
setData( index, name.toUpper(), Qt::EditRole );
96 mEditButton->setMenu( menu );
99 if ( supportsSchemas )
101 std::unique_ptr<QgsAbstractDatabaseProviderConnection> schemeComboConn;
104 mLayoutSchemeCombo->addWidget( mSchemaCombo );
108 delete mLabelSchemas;
109 mLabelSchemas =
nullptr;
110 delete mLayoutSchemeCombo;
111 mLayoutSchemeCombo =
nullptr;
115 if ( !supportsPrimaryKeyName )
117 delete mLabelPrimaryKey;
118 mLabelPrimaryKey =
nullptr;
119 delete mEditPrimaryKey;
120 mEditPrimaryKey =
nullptr;
124 if ( !supportsGeomColumnName )
126 delete mLabelGeometryColumn;
127 mLabelGeometryColumn =
nullptr;
128 delete mEditGeometryColumnName;
129 mEditGeometryColumnName =
nullptr;
133 if ( !supportsTableComments )
135 delete mLabelComment;
136 mLabelComment =
nullptr;
138 mEditComment =
nullptr;
141 mExtentGroupBox->setTitleBase( tr(
"Filter by Extent" ) );
142 mExtentGroupBox->setCheckable(
true );
143 mExtentGroupBox->setChecked(
false );
144 mExtentGroupBox->setCollapsed(
true );
146 mFilterExpressionWidget->registerExpressionContextGenerator(
this );
149 sourceLayerComboChanged();
156 delete mSourceLayerComboBox;
157 mSourceLayerComboBox =
nullptr;
158 delete mFilterExpressionWidget;
159 mFilterExpressionWidget =
nullptr;
161 mFieldsView =
nullptr;
167 mSchemaCombo->setSchema(
schema );
172 mOwnedSource.reset();
173 mSourceLayer =
nullptr;
180 mOwnedSource.reset( vl );
181 mBlockSourceLayerChanges++;
182 mSourceLayerComboBox->setAdditionalLayers( { vl } );
183 mSourceLayerComboBox->setLayer( vl );
184 mBlockSourceLayerChanges--;
185 setSourceLayer( mOwnedSource.get() );
189 mBlockSourceLayerChanges++;
190 mSourceLayerComboBox->setLayer( vl );
191 mBlockSourceLayerChanges--;
192 setSourceLayer( vl );
196void QgsDbImportVectorLayerDialog::setSourceLayer(
QgsVectorLayer *layer )
198 mSourceLayer = layer;
199 if ( !mSourceLayer || !mSourceLayer->dataProvider() )
202 mEditTable->setText( layer->
name() );
204 const bool isSpatial = mSourceLayer->isSpatial();
205 if ( mEditGeometryColumnName )
206 mEditGeometryColumnName->setEnabled( isSpatial );
208 mCrsSelector->setEnabled( isSpatial );
210 mExtentGroupBox->setEnabled( isSpatial );
212 mExtentGroupBox->setChecked(
false );
214 const bool extentFilterEnabled = mExtentGroupBox->isChecked();
215 mExtentGroupBox->setOriginalExtent( mSourceLayer->extent(), mSourceLayer->crs() );
216 mExtentGroupBox->setOutputExtentFromOriginal();
217 mExtentGroupBox->setChecked( extentFilterEnabled );
218 mExtentGroupBox->setCollapsed( !extentFilterEnabled );
220 mFilterExpressionWidget->setLayer( mSourceLayer );
222 if ( mEditPrimaryKey )
226 const QgsAttributeList pkAttributes = mSourceLayer->dataProvider()->pkAttributeIndexes();
227 QString primaryKey = !pkAttributes.isEmpty() ? mSourceLayer->dataProvider()->fields().at( pkAttributes.at( 0 ) ).name() : QString();
228 if ( primaryKey.isEmpty() )
231 primaryKey = dsUri.keyColumn();
233 if ( primaryKey.isEmpty() )
235 primaryKey = mConnection->defaultPrimaryKeyColumnName();
238 mEditPrimaryKey->setText( primaryKey );
241 if ( mEditGeometryColumnName )
245 QString geomColumn = mSourceLayer->dataProvider()->geometryColumnName();
246 if ( geomColumn.isEmpty() )
248 QgsDataSourceUri dsUri( mSourceLayer->source() );
249 geomColumn = dsUri.geometryColumn();
251 if ( geomColumn.isEmpty() )
253 geomColumn = mConnection->defaultGeometryColumnName();
256 mEditGeometryColumnName->setText( geomColumn );
261 mCrsSelector->setCrs( mSourceLayer->crs() );
266 mEditComment->setPlainText( mSourceLayer->metadata().abstract() );
269 mFieldsView->setSourceLayer( mSourceLayer );
270 mFieldsView->setSourceFields( mSourceLayer->fields() );
271 mFieldsView->setDestinationFields( mSourceLayer->fields() );
273 const bool selectedFeatures = mSourceLayer->selectedFeatureCount() > 0;
274 mSourceLayerOnlySelected->setEnabled( selectedFeatures );
277void QgsDbImportVectorLayerDialog::loadFieldsFromLayer()
281 mFieldsView->setSourceFields( mSourceLayer->fields() );
282 mFieldsView->setDestinationFields( mSourceLayer->fields() );
286void QgsDbImportVectorLayerDialog::addField()
288 const int rowCount = mFieldsView->model()->rowCount();
289 mFieldsView->appendField( QgsField( u
"new_field"_s ), u
"NULL"_s );
290 const QModelIndex index = mFieldsView->model()->index( rowCount, 0 );
291 mFieldsView->selectionModel()->select(
293 QItemSelectionModel::SelectionFlags(
294 QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current | QItemSelectionModel::Rows
297 mFieldsView->scrollTo( index );
302 return mSchemaCombo ? mSchemaCombo->currentSchema() : QString();
307 return mEditTable->text();
312 return mEditComment ? mEditComment->toPlainText() : QString();
320 mExtentGroupBox->setMapCanvas( canvas,
false );
324void QgsDbImportVectorLayerDialog::doImport()
333 if ( !mSourceLayer || !mSourceLayer->dataProvider() )
336 QString destinationUri;
337 QVariantMap providerOptions;
340 exporterOptions.
layerName = mEditTable->text();
342 exporterOptions.
schema = mSchemaCombo->currentSchema();
343 exporterOptions.
wkbType = mSourceLayer->wkbType();
344 if ( mEditPrimaryKey && !mEditPrimaryKey->text().trimmed().isEmpty() )
346 if ( mEditGeometryColumnName )
351 destinationUri = mConnection->createVectorLayerExporterDestinationUri( exporterOptions, providerOptions );
359 QVariantMap allProviderOptions = extraProviderOptions;
360 for (
auto it = providerOptions.constBegin(); it != providerOptions.constEnd(); ++it )
362 allProviderOptions.insert( it.key(), it.value() );
366 if ( mChkDropTable->isChecked() )
368 allProviderOptions.insert( u
"overwrite"_s,
true );
374 allProviderOptions.insert( u
"skipConvertFields"_s,
true );
382 if ( !mFilterExpressionWidget->expression().isEmpty() )
388 if ( mExtentGroupBox->isEnabled() && mExtentGroupBox->isChecked() )
393 if ( mSourceLayerOnlySelected->isEnabled() && mSourceLayerOnlySelected->isChecked() )
398 const QList<QgsFieldMappingModel::Field> fieldMapping = mFieldsView->mapping();
399 QList<QgsVectorLayerExporter::OutputField> outputFields;
400 outputFields.reserve( fieldMapping.size() );
407 return std::make_unique<QgsVectorLayerExporterTask>( mSourceLayer->clone(), destinationUri, mConnection->providerKey(), exportOptions, allProviderOptions,
true );
417void QgsDbImportVectorLayerDialog::sourceLayerComboChanged()
419 if ( mBlockSourceLayerChanges )
422 if ( mSourceLayerComboBox->currentLayer() == mSourceLayer )
425 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.