QGIS API Documentation 3.28.14-Firenze (exported)
Loading...
Searching...
No Matches
qgsnewmemorylayerdialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsnewmemorylayerdialog.cpp
3 -------------------
4 begin : September 2014
5 copyright : (C) 2014 by Nyall Dawson, Marco Hugentobler
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19#include "qgsapplication.h"
20#include "qgis.h"
22#include "qgsproviderregistry.h"
24#include "qgsvectorlayer.h"
25#include "qgsfield.h"
26#include "qgsfields.h"
27#include "qgssettings.h"
29#include "qgsgui.h"
30#include "qgsiconutils.h"
31#include "qgsvariantutils.h"
32
33#include <QPushButton>
34#include <QComboBox>
35#include <QUuid>
36#include <QFileDialog>
37
39{
40 QgsNewMemoryLayerDialog dialog( parent );
41 dialog.setCrs( defaultCrs );
42 if ( dialog.exec() == QDialog::Rejected )
43 {
44 return nullptr;
45 }
46
47 const QgsWkbTypes::Type geometrytype = dialog.selectedType();
48 const QgsFields fields = dialog.fields();
49 const QString name = dialog.layerName().isEmpty() ? tr( "New scratch layer" ) : dialog.layerName();
50 QgsVectorLayer *newLayer = QgsMemoryProviderUtils::createMemoryLayer( name, fields, geometrytype, dialog.crs() );
51 return newLayer;
52}
53
54QgsNewMemoryLayerDialog::QgsNewMemoryLayerDialog( QWidget *parent, Qt::WindowFlags fl )
55 : QDialog( parent, fl )
56{
57 setupUi( this );
59
60 mNameLineEdit->setText( tr( "New scratch layer" ) );
61
62 const QgsWkbTypes::Type geomTypes[] =
63 {
75 };
76
77 for ( const auto type : geomTypes )
78 mGeometryTypeBox->addItem( QgsIconUtils::iconForWkbType( type ), QgsWkbTypes::translatedDisplayString( type ), type );
79 mGeometryTypeBox->setCurrentIndex( -1 );
80
81 mGeometryWithZCheckBox->setEnabled( false );
82 mGeometryWithMCheckBox->setEnabled( false );
83 mCrsSelector->setEnabled( false );
84 mCrsSelector->setShowAccuracyWarnings( true );
85
86 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::String ), QgsVariantUtils::typeToDisplayString( QVariant::String ), "string" );
87 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Int ), QgsVariantUtils::typeToDisplayString( QVariant::Int ), "integer" );
88 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Double ), QgsVariantUtils::typeToDisplayString( QVariant::Double ), "double" );
89 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Bool ), QgsVariantUtils::typeToDisplayString( QVariant::Bool ), "bool" );
90 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Date ), QgsVariantUtils::typeToDisplayString( QVariant::Date ), "date" );
91 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Time ), QgsVariantUtils::typeToDisplayString( QVariant::Time ), "time" );
92 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::DateTime ), QgsVariantUtils::typeToDisplayString( QVariant::DateTime ), "datetime" );
93 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::ByteArray ), QgsVariantUtils::typeToDisplayString( QVariant::ByteArray ), "binary" );
94 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::StringList ), QgsVariantUtils::typeToDisplayString( QVariant::StringList ), "stringlist" );
95 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::List, QVariant::Int ), QgsVariantUtils::typeToDisplayString( QVariant::List, QVariant::Int ), "integerlist" );
96 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::List, QVariant::Double ), QgsVariantUtils::typeToDisplayString( QVariant::List, QVariant::Double ), "doublelist" );
97 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::List, QVariant::LongLong ), QgsVariantUtils::typeToDisplayString( QVariant::List, QVariant::LongLong ), "integer64list" );
98 mTypeBox->addItem( QgsFields::iconForFieldType( QVariant::Map ), QgsVariantUtils::typeToDisplayString( QVariant::Map ), "map" );
99 mTypeBox_currentIndexChanged( 0 );
100
101 mWidth->setValidator( new QIntValidator( 1, 255, this ) );
102 mPrecision->setValidator( new QIntValidator( 0, 30, this ) );
103
104 mAddAttributeButton->setEnabled( false );
105 mRemoveAttributeButton->setEnabled( false );
106
107 mOkButton = mButtonBox->button( QDialogButtonBox::Ok );
108 mOkButton->setEnabled( false );
109
110 connect( mGeometryTypeBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNewMemoryLayerDialog::geometryTypeChanged );
111 connect( mFieldNameEdit, &QLineEdit::textChanged, this, &QgsNewMemoryLayerDialog::fieldNameChanged );
112 connect( mTypeBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNewMemoryLayerDialog::mTypeBox_currentIndexChanged );
113 connect( mAttributeView, &QTreeWidget::itemSelectionChanged, this, &QgsNewMemoryLayerDialog::selectionChanged );
114 connect( mAddAttributeButton, &QToolButton::clicked, this, &QgsNewMemoryLayerDialog::mAddAttributeButton_clicked );
115 connect( mRemoveAttributeButton, &QToolButton::clicked, this, &QgsNewMemoryLayerDialog::mRemoveAttributeButton_clicked );
116 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsNewMemoryLayerDialog::showHelp );
117
118 mNameLineEdit->selectAll();
119 mNameLineEdit->setFocus();
120}
121
123{
125 geomType = static_cast<QgsWkbTypes::Type>
126 ( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
127
128 if ( geomType != QgsWkbTypes::Unknown && geomType != QgsWkbTypes::NoGeometry )
129 {
130 if ( mGeometryWithZCheckBox->isChecked() )
131 geomType = QgsWkbTypes::addZ( geomType );
132 if ( mGeometryWithMCheckBox->isChecked() )
133 geomType = QgsWkbTypes::addM( geomType );
134 }
135
136 return geomType;
137}
138
139void QgsNewMemoryLayerDialog::geometryTypeChanged( int )
140{
141 const QgsWkbTypes::Type geomType = static_cast<QgsWkbTypes::Type>
142 ( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
143
144 const bool isSpatial = geomType != QgsWkbTypes::NoGeometry;
145 mGeometryWithZCheckBox->setEnabled( isSpatial );
146 mGeometryWithMCheckBox->setEnabled( isSpatial );
147 mCrsSelector->setEnabled( isSpatial );
148
149 const bool ok = ( !mNameLineEdit->text().isEmpty() && mGeometryTypeBox->currentIndex() != -1 );
150 mOkButton->setEnabled( ok );
151}
152
153void QgsNewMemoryLayerDialog::mTypeBox_currentIndexChanged( int index )
154{
155 switch ( index )
156 {
157 case 0: // Text data
158 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
159 mWidth->setText( QStringLiteral( "255" ) );
160 mPrecision->clear();
161 mPrecision->setEnabled( false );
162 mWidth->setValidator( new QIntValidator( 1, 255, this ) );
163 mWidth->setEnabled( true );
164 break;
165 case 1: // Whole number
166 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
167 mWidth->setText( QStringLiteral( "10" ) );
168 mPrecision->clear();
169 mPrecision->setEnabled( false );
170 mWidth->setValidator( new QIntValidator( 1, 10, this ) );
171 mWidth->setEnabled( true );
172 break;
173 case 2: // Decimal number
174 if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 30 )
175 mWidth->setText( QStringLiteral( "30" ) );
176 if ( mPrecision->text().toInt() < 1 || mPrecision->text().toInt() > 30 )
177 mPrecision->setText( QStringLiteral( "6" ) );
178 mPrecision->setEnabled( true );
179 mWidth->setValidator( new QIntValidator( 1, 20, this ) );
180 mWidth->setEnabled( true );
181 break;
182 case 3: // Boolean
183 mWidth->clear();
184 mWidth->setEnabled( false );
185 mPrecision->clear();
186 mPrecision->setEnabled( false );
187 break;
188 case 4: // Date
189 mWidth->clear();
190 mWidth->setEnabled( false );
191 mPrecision->clear();
192 mPrecision->setEnabled( false );
193 break;
194 case 5: // Time
195 mWidth->clear();
196 mWidth->setEnabled( false );
197 mPrecision->clear();
198 mPrecision->setEnabled( false );
199 break;
200 case 6: // Datetime
201 mWidth->clear();
202 mWidth->setEnabled( false );
203 mPrecision->clear();
204 mPrecision->setEnabled( false );
205 break;
206 case 7: // Binary
207 case 8: // Stringlist
208 case 9: // Integerlist
209 case 10: // Doublelist
210 case 11: // Integer64list
211 case 12: // Map
212 mWidth->clear();
213 mWidth->setEnabled( false );
214 mPrecision->clear();
215 mPrecision->setEnabled( false );
216 break;
217
218 default:
219 QgsDebugMsg( QStringLiteral( "unexpected index" ) );
220 break;
221 }
222}
223
225{
226 mCrsSelector->setCrs( crs );
227}
228
230{
231 return mCrsSelector->crs();
232}
233
235{
236 return mNameLineEdit->text();
237}
238
239void QgsNewMemoryLayerDialog::fieldNameChanged( const QString &name )
240{
241 mAddAttributeButton->setDisabled( name.isEmpty() || ! mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
242}
243
244void QgsNewMemoryLayerDialog::selectionChanged()
245{
246 mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
247}
248
250{
252
253 QTreeWidgetItemIterator it( mAttributeView );
254 while ( *it )
255 {
256 const QString name( ( *it )->text( 0 ) );
257 const QString typeName( ( *it )->text( 1 ) );
258 const int width = ( *it )->text( 2 ).toInt();
259 const int precision = ( *it )->text( 3 ).toInt();
260 QVariant::Type fieldType = QVariant::Invalid;
261 QVariant::Type fieldSubType = QVariant::Invalid;
262 if ( typeName == QLatin1String( "string" ) )
263 fieldType = QVariant::String;
264 else if ( typeName == QLatin1String( "integer" ) )
265 fieldType = QVariant::Int;
266 else if ( typeName == QLatin1String( "double" ) )
267 fieldType = QVariant::Double;
268 else if ( typeName == QLatin1String( "bool" ) )
269 fieldType = QVariant::Bool;
270 else if ( typeName == QLatin1String( "date" ) )
271 fieldType = QVariant::Date;
272 else if ( typeName == QLatin1String( "time" ) )
273 fieldType = QVariant::Time;
274 else if ( typeName == QLatin1String( "datetime" ) )
275 fieldType = QVariant::DateTime;
276 else if ( typeName == QLatin1String( "binary" ) )
277 fieldType = QVariant::ByteArray;
278 else if ( typeName == QLatin1String( "stringlist" ) )
279 {
280 fieldType = QVariant::StringList;
281 fieldSubType = QVariant::String;
282 }
283 else if ( typeName == QLatin1String( "integerlist" ) )
284 {
285 fieldType = QVariant::List;
286 fieldSubType = QVariant::Int;
287 }
288 else if ( typeName == QLatin1String( "doublelist" ) )
289 {
290 fieldType = QVariant::List;
291 fieldSubType = QVariant::Double;
292 }
293 else if ( typeName == QLatin1String( "integer64list" ) )
294 {
295 fieldType = QVariant::List;
296 fieldSubType = QVariant::LongLong;
297 }
298 else if ( typeName == QLatin1String( "map" ) )
299 fieldType = QVariant::Map;
300
301 const QgsField field = QgsField( name, fieldType, typeName, width, precision, QString(), fieldSubType );
303 ++it;
304 }
305
306 return fields;
307}
308
309void QgsNewMemoryLayerDialog::mAddAttributeButton_clicked()
310{
311 if ( !mFieldNameEdit->text().isEmpty() )
312 {
313 const QString fieldName = mFieldNameEdit->text();
314 const QString fieldType = mTypeBox->currentData( Qt::UserRole ).toString();
315 const QString width = mWidth->text();
316 const QString precision = mPrecision->text();
317 mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << fieldName << fieldType << width << precision ) );
318
319 mFieldNameEdit->clear();
320 }
321}
322
323void QgsNewMemoryLayerDialog::mRemoveAttributeButton_clicked()
324{
325 delete mAttributeView->currentItem();
326}
327
328void QgsNewMemoryLayerDialog::showHelp()
329{
330 QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-a-new-temporary-scratch-layer" ) );
331}
This class represents a coordinate reference system (CRS).
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:51
Container of fields for a vector layer.
Definition qgsfields.h:45
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition qgsfields.cpp:59
static QIcon iconForFieldType(QVariant::Type type, QVariant::Type subType=QVariant::Type::Invalid)
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...
Definition qgsgui.cpp:178
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:38
static QIcon iconForWkbType(QgsWkbTypes::Type type)
Returns the icon for a vector layer whose geometry type is provided.
static QgsVectorLayer * createMemoryLayer(const QString &name, const QgsFields &fields, QgsWkbTypes::Type geometryType=QgsWkbTypes::NoGeometry, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem()) SIP_FACTORY
Creates a new memory layer using the specified parameters.
QgsWkbTypes::Type selectedType() const
Returns the selected geometry type.
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.
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(QVariant::Type type, QVariant::Type subType=QVariant::Type::Invalid)
Returns a user-friendly translated string representing a QVariant type.
Represents a vector layer which manages a vector based data sets.
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
Type
The WKB type describes the number of dimensions a geometry has.
Definition qgswkbtypes.h:70
static QString translatedDisplayString(Type type)
Returns a translated display string type for a WKB type, e.g., the geometry name used in WKT geometry...
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
const QgsField & field
Definition qgsfield.h:476
#define QgsDebugMsg(str)
Definition qgslogger.h:38
const QgsCoordinateReferenceSystem & crs
const QString & typeName
int precision