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" ) );
82 for (
const auto type : geomTypes )
84 mGeometryTypeBox->setCurrentIndex( -1 );
86 mGeometryWithZCheckBox->setEnabled(
false );
87 mGeometryWithMCheckBox->setEnabled(
false );
88 mCrsSelector->setEnabled(
false );
89 mCrsSelector->setShowAccuracyWarnings(
true );
104 mTypeBox->addItem(
QgsFields::iconForFieldType( QMetaType::Type::User, QMetaType::Type::UnknownType, u
"geometry"_s ), tr(
"Geometry" ),
"geometry" );
105 mTypeBox_currentIndexChanged( 0 );
107 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
108 mPrecision->setValidator(
new QIntValidator( 0, 30,
this ) );
110 mAddAttributeButton->setEnabled(
false );
111 mRemoveAttributeButton->setEnabled(
false );
112 mButtonUp->setEnabled(
false );
113 mButtonDown->setEnabled(
false );
115 mOkButton = mButtonBox->button( QDialogButtonBox::Ok );
116 mOkButton->setEnabled(
false );
118 connect( mGeometryTypeBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewMemoryLayerDialog::geometryTypeChanged );
119 connect( mFieldNameEdit, &QLineEdit::textChanged,
this, &QgsNewMemoryLayerDialog::fieldNameChanged );
120 connect( mTypeBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsNewMemoryLayerDialog::mTypeBox_currentIndexChanged );
121 connect( mAttributeView, &QTreeWidget::itemSelectionChanged,
this, &QgsNewMemoryLayerDialog::selectionChanged );
122 connect( mAddAttributeButton, &QToolButton::clicked,
this, &QgsNewMemoryLayerDialog::mAddAttributeButton_clicked );
123 connect( mRemoveAttributeButton, &QToolButton::clicked,
this, &QgsNewMemoryLayerDialog::mRemoveAttributeButton_clicked );
124 connect( mButtonUp, &QToolButton::clicked,
this, &QgsNewMemoryLayerDialog::moveFieldsUp );
125 connect( mButtonDown, &QToolButton::clicked,
this, &QgsNewMemoryLayerDialog::moveFieldsDown );
127 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsNewMemoryLayerDialog::showHelp );
129 connect( mButtonBox, &QDialogButtonBox::rejected,
this, &QgsNewMemoryLayerDialog::reject );
131 mNameLineEdit->selectAll();
132 mNameLineEdit->setFocus();
138 geomType =
static_cast<Qgis::WkbType>( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
142 if ( mGeometryWithZCheckBox->isChecked() )
144 if ( mGeometryWithMCheckBox->isChecked() )
151void QgsNewMemoryLayerDialog::geometryTypeChanged(
int )
156 mGeometryWithZCheckBox->setEnabled( isSpatial );
157 mGeometryWithMCheckBox->setEnabled( isSpatial );
158 mCrsSelector->setEnabled( isSpatial );
160 const bool ok = ( !mNameLineEdit->text().isEmpty() && mGeometryTypeBox->currentIndex() != -1 );
161 mOkButton->setEnabled( ok );
164void QgsNewMemoryLayerDialog::mTypeBox_currentIndexChanged(
int )
166 const QString fieldType = mTypeBox->currentData().toString();
167 if ( fieldType ==
"string"_L1 )
169 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
170 mWidth->setText( u
"255"_s );
172 mPrecision->setEnabled(
false );
173 mWidth->setValidator(
new QIntValidator( 1, 255,
this ) );
174 mWidth->setEnabled(
true );
176 else if ( fieldType ==
"integer"_L1 )
178 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
179 mWidth->setText( u
"10"_s );
181 mPrecision->setEnabled(
false );
182 mWidth->setValidator(
new QIntValidator( 1, 10,
this ) );
183 mWidth->setEnabled(
true );
185 else if ( fieldType ==
"double"_L1 )
187 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 30 )
188 mWidth->setText( u
"30"_s );
189 if ( mPrecision->text().toInt() < 1 || mPrecision->text().toInt() > 30 )
190 mPrecision->setText( u
"6"_s );
191 mPrecision->setEnabled(
true );
192 mWidth->setValidator(
new QIntValidator( 1, 20,
this ) );
193 mWidth->setEnabled(
true );
195 else if ( fieldType ==
"bool"_L1 )
198 mWidth->setEnabled(
false );
200 mPrecision->setEnabled(
false );
202 else if ( fieldType ==
"date"_L1 )
205 mWidth->setEnabled(
false );
207 mPrecision->setEnabled(
false );
209 else if ( fieldType ==
"time"_L1 )
212 mWidth->setEnabled(
false );
214 mPrecision->setEnabled(
false );
216 else if ( fieldType ==
"datetime"_L1 )
219 mWidth->setEnabled(
false );
221 mPrecision->setEnabled(
false );
223 else if ( fieldType == u
"binary"_s
224 || fieldType == u
"stringlist"_s
225 || fieldType == u
"integerlist"_s
226 || fieldType == u
"doublelist"_s
227 || fieldType == u
"integer64list"_s
228 || fieldType == u
"map"_s
229 || fieldType ==
"geometry"_L1 )
232 mWidth->setEnabled(
false );
234 mPrecision->setEnabled(
false );
244 mCrsSelector->setCrs(
crs );
249 return mCrsSelector->crs();
254 return mNameLineEdit->text();
257void QgsNewMemoryLayerDialog::fieldNameChanged(
const QString &name )
259 mAddAttributeButton->setDisabled( name.isEmpty() || !mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
262void QgsNewMemoryLayerDialog::selectionChanged()
264 mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
265 mButtonUp->setDisabled( mAttributeView->selectedItems().isEmpty() );
266 mButtonDown->setDisabled( mAttributeView->selectedItems().isEmpty() );
273 QTreeWidgetItemIterator it( mAttributeView );
276 const QString name( ( *it )->text( 0 ) );
277 const QString typeName( ( *it )->text( 1 ) );
278 const int width = ( *it )->text( 2 ).toInt();
279 const int precision = ( *it )->text( 3 ).toInt();
280 QMetaType::Type fieldType = QMetaType::Type::UnknownType;
281 QMetaType::Type fieldSubType = QMetaType::Type::UnknownType;
282 if ( typeName ==
"string"_L1 )
283 fieldType = QMetaType::Type::QString;
284 else if ( typeName ==
"integer"_L1 )
285 fieldType = QMetaType::Type::Int;
286 else if ( typeName ==
"double"_L1 )
287 fieldType = QMetaType::Type::Double;
288 else if ( typeName ==
"bool"_L1 )
289 fieldType = QMetaType::Type::Bool;
290 else if ( typeName ==
"date"_L1 )
291 fieldType = QMetaType::Type::QDate;
292 else if ( typeName ==
"time"_L1 )
293 fieldType = QMetaType::Type::QTime;
294 else if ( typeName ==
"datetime"_L1 )
295 fieldType = QMetaType::Type::QDateTime;
296 else if ( typeName ==
"binary"_L1 )
297 fieldType = QMetaType::Type::QByteArray;
298 else if ( typeName ==
"stringlist"_L1 )
300 fieldType = QMetaType::Type::QStringList;
301 fieldSubType = QMetaType::Type::QString;
303 else if ( typeName ==
"integerlist"_L1 )
305 fieldType = QMetaType::Type::QVariantList;
306 fieldSubType = QMetaType::Type::Int;
308 else if ( typeName ==
"doublelist"_L1 )
310 fieldType = QMetaType::Type::QVariantList;
311 fieldSubType = QMetaType::Type::Double;
313 else if ( typeName ==
"integer64list"_L1 )
315 fieldType = QMetaType::Type::QVariantList;
316 fieldSubType = QMetaType::Type::LongLong;
318 else if ( typeName ==
"map"_L1 )
319 fieldType = QMetaType::Type::QVariantMap;
320 else if ( typeName ==
"geometry"_L1 )
321 fieldType = QMetaType::Type::User;
323 const QgsField field =
QgsField( name, fieldType, typeName, width, precision, QString(), fieldSubType );
333 if ( !mFieldNameEdit->text().trimmed().isEmpty() )
335 const QString currentFieldName = mFieldNameEdit->text();
336 if (
fields().lookupField( currentFieldName ) == -1 )
338 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 )
348void QgsNewMemoryLayerDialog::mAddAttributeButton_clicked()
350 if ( !mFieldNameEdit->text().isEmpty() )
352 const QString fieldName = mFieldNameEdit->text();
353 const QString fieldType = mTypeBox->currentData( Qt::UserRole ).toString();
354 const QString width = mWidth->text();
355 const QString precision = mPrecision->text();
356 mAttributeView->addTopLevelItem(
new QTreeWidgetItem( QStringList() << fieldName << fieldType << width << precision ) );
358 mFieldNameEdit->clear();
360 if ( !mFieldNameEdit->hasFocus() )
362 mFieldNameEdit->setFocus();
367void QgsNewMemoryLayerDialog::mRemoveAttributeButton_clicked()
369 delete mAttributeView->currentItem();
372void QgsNewMemoryLayerDialog::showHelp()
374 QgsHelp::openHelp( u
"managing_data_source/create_layers.html#creating-a-new-temporary-scratch-layer"_s );
377void QgsNewMemoryLayerDialog::moveFieldsUp()
379 int currentRow = mAttributeView->currentIndex().row();
380 if ( currentRow == 0 )
383 mAttributeView->insertTopLevelItem( currentRow - 1, mAttributeView->takeTopLevelItem( currentRow ) );
384 mAttributeView->setCurrentIndex( mAttributeView->model()->index( currentRow - 1, 0 ) );
387void QgsNewMemoryLayerDialog::moveFieldsDown()
389 int currentRow = mAttributeView->currentIndex().row();
390 if ( currentRow == mAttributeView->topLevelItemCount() - 1 )
393 mAttributeView->insertTopLevelItem( currentRow + 1, mAttributeView->takeTopLevelItem( currentRow ) );
394 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)