37#include "moc_qgsnewmemorylayerdialog.cpp"
39using namespace Qt::StringLiterals;
44 dialog.
setCrs( defaultCrs );
45 if ( dialog.exec() == QDialog::Rejected )
52 const QString name = dialog.
layerName().isEmpty() ? tr(
"New scratch layer" ) : dialog.
layerName();
58 : QDialog( parent, fl )
63 mNameLineEdit->setText( tr(
"New scratch layer" ) );
83 for (
const auto type : geomTypes )
85 mGeometryTypeBox->setCurrentIndex( -1 );
87 mGeometryWithZCheckBox->setEnabled(
false );
88 mGeometryWithMCheckBox->setEnabled(
false );
89 mCrsSelector->setEnabled(
false );
90 mCrsSelector->setShowAccuracyWarnings(
true );
105 mTypeBox->addItem(
QgsFields::iconForFieldType( QMetaType::Type::User, QMetaType::Type::UnknownType, u
"geometry"_s ), tr(
"Geometry" ),
"geometry" );
106 mTypeBox_currentIndexChanged( 0 );
108 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
109 mPrecision->setValidator(
new QIntValidator( 0, 30,
this ) );
111 mAddAttributeButton->setEnabled(
false );
112 mRemoveAttributeButton->setEnabled(
false );
113 mButtonUp->setEnabled(
false );
114 mButtonDown->setEnabled(
false );
116 mOkButton = mButtonBox->button( QDialogButtonBox::Ok );
117 mOkButton->setEnabled(
false );
119 connect( mGeometryTypeBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewMemoryLayerDialog::geometryTypeChanged );
120 connect( mFieldNameEdit, &QLineEdit::textChanged,
this, &QgsNewMemoryLayerDialog::fieldNameChanged );
121 connect( mTypeBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewMemoryLayerDialog::mTypeBox_currentIndexChanged );
122 connect( mAttributeView, &QTreeWidget::itemSelectionChanged,
this, &QgsNewMemoryLayerDialog::selectionChanged );
123 connect( mAddAttributeButton, &QToolButton::clicked,
this, &QgsNewMemoryLayerDialog::mAddAttributeButton_clicked );
124 connect( mRemoveAttributeButton, &QToolButton::clicked,
this, &QgsNewMemoryLayerDialog::mRemoveAttributeButton_clicked );
125 connect( mButtonUp, &QToolButton::clicked,
this, &QgsNewMemoryLayerDialog::moveFieldsUp );
126 connect( mButtonDown, &QToolButton::clicked,
this, &QgsNewMemoryLayerDialog::moveFieldsDown );
128 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsNewMemoryLayerDialog::showHelp );
130 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsNewMemoryLayerDialog::reject );
132 mNameLineEdit->selectAll();
133 mNameLineEdit->setFocus();
139 geomType =
static_cast<Qgis::WkbType>( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
143 if ( mGeometryWithZCheckBox->isChecked() )
145 if ( mGeometryWithMCheckBox->isChecked() )
152void QgsNewMemoryLayerDialog::geometryTypeChanged(
int )
157 mGeometryWithZCheckBox->setEnabled( isSpatial );
158 mGeometryWithMCheckBox->setEnabled( isSpatial );
159 mCrsSelector->setEnabled( isSpatial );
161 const bool ok = ( !mNameLineEdit->text().isEmpty() && mGeometryTypeBox->currentIndex() != -1 );
162 mOkButton->setEnabled( ok );
165void QgsNewMemoryLayerDialog::mTypeBox_currentIndexChanged(
int )
167 const QString fieldType = mTypeBox->currentData().toString();
168 if ( fieldType ==
"string"_L1 )
170 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
171 mWidth->setText( u
"255"_s );
173 mPrecision->setEnabled(
false );
174 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
175 mWidth->setEnabled(
true );
177 else if ( fieldType ==
"integer"_L1 )
179 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
180 mWidth->setText( u
"10"_s );
182 mPrecision->setEnabled(
false );
183 mWidth->setValidator(
new QIntValidator( 1, 10,
this ) );
184 mWidth->setEnabled(
true );
186 else if ( fieldType ==
"double"_L1 )
188 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 30 )
189 mWidth->setText( u
"30"_s );
190 if ( mPrecision->text().toInt() < 1 || mPrecision->text().toInt() > 30 )
191 mPrecision->setText( u
"6"_s );
192 mPrecision->setEnabled(
true );
193 mWidth->setValidator(
new QIntValidator( 1, 20,
this ) );
194 mWidth->setEnabled(
true );
196 else if ( fieldType ==
"bool"_L1 )
199 mWidth->setEnabled(
false );
201 mPrecision->setEnabled(
false );
203 else if ( fieldType ==
"date"_L1 )
206 mWidth->setEnabled(
false );
208 mPrecision->setEnabled(
false );
210 else if ( fieldType ==
"time"_L1 )
213 mWidth->setEnabled(
false );
215 mPrecision->setEnabled(
false );
217 else if ( fieldType ==
"datetime"_L1 )
220 mWidth->setEnabled(
false );
222 mPrecision->setEnabled(
false );
224 else if ( fieldType == u
"binary"_s
225 || fieldType == u
"stringlist"_s
226 || fieldType == u
"integerlist"_s
227 || fieldType == u
"doublelist"_s
228 || fieldType == u
"integer64list"_s
229 || fieldType == u
"map"_s
230 || fieldType ==
"geometry"_L1 )
233 mWidth->setEnabled(
false );
235 mPrecision->setEnabled(
false );
245 mCrsSelector->setCrs(
crs );
250 return mCrsSelector->crs();
255 return mNameLineEdit->text();
258void QgsNewMemoryLayerDialog::fieldNameChanged(
const QString &name )
260 mAddAttributeButton->setDisabled( name.isEmpty() || !mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
263void QgsNewMemoryLayerDialog::selectionChanged()
265 mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
266 mButtonUp->setDisabled( mAttributeView->selectedItems().isEmpty() );
267 mButtonDown->setDisabled( mAttributeView->selectedItems().isEmpty() );
274 QTreeWidgetItemIterator it( mAttributeView );
277 const QString name( ( *it )->text( 0 ) );
278 const QString typeName( ( *it )->text( 1 ) );
279 const int width = ( *it )->text( 2 ).toInt();
280 const int precision = ( *it )->text( 3 ).toInt();
281 QMetaType::Type fieldType = QMetaType::Type::UnknownType;
282 QMetaType::Type fieldSubType = QMetaType::Type::UnknownType;
283 if ( typeName ==
"string"_L1 )
284 fieldType = QMetaType::Type::QString;
285 else if ( typeName ==
"integer"_L1 )
286 fieldType = QMetaType::Type::Int;
287 else if ( typeName ==
"double"_L1 )
288 fieldType = QMetaType::Type::Double;
289 else if ( typeName ==
"bool"_L1 )
290 fieldType = QMetaType::Type::Bool;
291 else if ( typeName ==
"date"_L1 )
292 fieldType = QMetaType::Type::QDate;
293 else if ( typeName ==
"time"_L1 )
294 fieldType = QMetaType::Type::QTime;
295 else if ( typeName ==
"datetime"_L1 )
296 fieldType = QMetaType::Type::QDateTime;
297 else if ( typeName ==
"binary"_L1 )
298 fieldType = QMetaType::Type::QByteArray;
299 else if ( typeName ==
"stringlist"_L1 )
301 fieldType = QMetaType::Type::QStringList;
302 fieldSubType = QMetaType::Type::QString;
304 else if ( typeName ==
"integerlist"_L1 )
306 fieldType = QMetaType::Type::QVariantList;
307 fieldSubType = QMetaType::Type::Int;
309 else if ( typeName ==
"doublelist"_L1 )
311 fieldType = QMetaType::Type::QVariantList;
312 fieldSubType = QMetaType::Type::Double;
314 else if ( typeName ==
"integer64list"_L1 )
316 fieldType = QMetaType::Type::QVariantList;
317 fieldSubType = QMetaType::Type::LongLong;
319 else if ( typeName ==
"map"_L1 )
320 fieldType = QMetaType::Type::QVariantMap;
321 else if ( typeName ==
"geometry"_L1 )
322 fieldType = QMetaType::Type::User;
324 const QgsField field =
QgsField( name, fieldType, typeName, width, precision, QString(), fieldSubType );
334 if ( !mFieldNameEdit->text().trimmed().isEmpty() )
336 const QString currentFieldName = mFieldNameEdit->text();
337 if (
fields().lookupField( currentFieldName ) == -1 )
339 if ( QMessageBox::question(
this, tr(
"New Temporary Scratch Layer" ), tr(
"The field “%1” has not been added to the fields list. Are you sure you want to proceed and discard this field?" ).arg( currentFieldName ), QMessageBox::Ok | QMessageBox::Cancel ) != QMessageBox::Ok )
349void QgsNewMemoryLayerDialog::mAddAttributeButton_clicked()
351 if ( !mFieldNameEdit->text().isEmpty() )
353 const QString fieldName = mFieldNameEdit->text();
354 const QString fieldType = mTypeBox->currentData( Qt::UserRole ).toString();
355 const QString width = mWidth->text();
356 const QString precision = mPrecision->text();
357 mAttributeView->addTopLevelItem(
new QTreeWidgetItem( QStringList() << fieldName << fieldType << width << precision ) );
359 mFieldNameEdit->clear();
361 if ( !mFieldNameEdit->hasFocus() )
363 mFieldNameEdit->setFocus();
368void QgsNewMemoryLayerDialog::mRemoveAttributeButton_clicked()
370 delete mAttributeView->currentItem();
373void QgsNewMemoryLayerDialog::showHelp()
375 QgsHelp::openHelp( u
"managing_data_source/create_layers.html#creating-a-new-temporary-scratch-layer"_s );
378void QgsNewMemoryLayerDialog::moveFieldsUp()
380 int currentRow = mAttributeView->currentIndex().row();
381 if ( currentRow == 0 )
384 mAttributeView->insertTopLevelItem( currentRow - 1, mAttributeView->takeTopLevelItem( currentRow ) );
385 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow - 1, 0 ) );
388void QgsNewMemoryLayerDialog::moveFieldsDown()
390 int currentRow = mAttributeView->currentIndex().row();
391 if ( currentRow == mAttributeView->topLevelItemCount() - 1 )
394 mAttributeView->insertTopLevelItem( currentRow + 1, mAttributeView->takeTopLevelItem( currentRow ) );
395 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow + 1, 0 ) );
WkbType
The WKB type describes the number of dimensions a geometry has.
@ CompoundCurve
CompoundCurve.
@ MultiPolygon
MultiPolygon.
@ MultiLineString
MultiLineString.
@ CurvePolygon
CurvePolygon.
@ PolyhedralSurface
PolyhedralSurface.
@ MultiSurface
MultiSurface.
Represents a coordinate reference system (CRS).
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
static QIcon iconForFieldType(QMetaType::Type type, QMetaType::Type subType=QMetaType::Type::UnknownType, const QString &typeString=QString())
Returns an icon corresponding to a field type.
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...
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
static QIcon iconForWkbType(Qgis::WkbType type)
Returns the icon for a vector layer whose geometry type is provided.
static QgsVectorLayer * createMemoryLayer(const QString &name, const QgsFields &fields, Qgis::WkbType geometryType=Qgis::WkbType::NoGeometry, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem(), bool loadDefaultStyle=true) SIP_FACTORY
Creates a new memory layer using the specified parameters.
QgsCoordinateReferenceSystem crs() const
Returns the selected CRS for the new layer.
QgsFields fields() const
Returns attributes for the new layer.
QString layerName() const
Returns the layer name.
Qgis::WkbType selectedType() const
Returns the selected geometry type.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs value for the new layer in the dialog.
static QgsVectorLayer * runAndCreateLayer(QWidget *parent=nullptr, const QgsCoordinateReferenceSystem &defaultCrs=QgsCoordinateReferenceSystem())
Runs the dialog and creates a new memory layer.
QgsNewMemoryLayerDialog(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
New dialog constructor.
static QString typeToDisplayString(QMetaType::Type type, QMetaType::Type subType=QMetaType::Type::UnknownType)
Returns a user-friendly translated string representing a QVariant type.
Represents a vector layer which manages a vector based dataset.
static Q_INVOKABLE QString translatedDisplayString(Qgis::WkbType type)
Returns a translated display string type for a WKB type, e.g., the geometry name used in WKT geometry...
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
#define QgsDebugError(str)