QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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"
23 #include "qgsvectordataprovider.h"
24 #include "qgsvectorlayer.h"
25 #include "qgsfield.h"
26 #include "qgsfields.h"
27 #include "qgssettings.h"
28 #include "qgsmemoryproviderutils.h"
29 #include "qgsgui.h"
30 
31 #include <QPushButton>
32 #include <QComboBox>
33 #include <QUuid>
34 #include <QFileDialog>
35 
37 {
38  QgsNewMemoryLayerDialog dialog( parent );
39  dialog.setCrs( defaultCrs );
40  if ( dialog.exec() == QDialog::Rejected )
41  {
42  return nullptr;
43  }
44 
45  QgsWkbTypes::Type geometrytype = dialog.selectedType();
46  QgsFields fields = dialog.fields();
47  QString name = dialog.layerName().isEmpty() ? tr( "New scratch layer" ) : dialog.layerName();
48  QgsVectorLayer *newLayer = QgsMemoryProviderUtils::createMemoryLayer( name, fields, geometrytype, dialog.crs() );
49  return newLayer;
50 }
51 
52 QgsNewMemoryLayerDialog::QgsNewMemoryLayerDialog( QWidget *parent, Qt::WindowFlags fl )
53  : QDialog( parent, fl )
54 {
55  setupUi( this );
57 
58  mNameLineEdit->setText( tr( "New scratch layer" ) );
59 
60  mGeometryTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconTableLayer.svg" ) ), tr( "No Geometry" ), QgsWkbTypes::NoGeometry );
61  mGeometryTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconPointLayer.svg" ) ), tr( "Point" ), QgsWkbTypes::Point );
62  mGeometryTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconLineLayer.svg" ) ), tr( "LineString / CompoundCurve" ), QgsWkbTypes::LineString );
63  mGeometryTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconPolygonLayer.svg" ) ), tr( "Polygon / CurvePolygon" ), QgsWkbTypes::Polygon );
64  mGeometryTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconPointLayer.svg" ) ), tr( "MultiPoint" ), QgsWkbTypes::MultiPoint );
65  mGeometryTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconLineLayer.svg" ) ), tr( "MultiLineString / MultiCurve" ), QgsWkbTypes::MultiLineString );
66  mGeometryTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconPolygonLayer.svg" ) ), tr( "MultiPolygon / MultiSurface" ), QgsWkbTypes::MultiPolygon );
67  mGeometryTypeBox->setCurrentIndex( -1 );
68 
69  mGeometryWithZCheckBox->setEnabled( false );
70  mGeometryWithMCheckBox->setEnabled( false );
71  mCrsSelector->setEnabled( false );
72 
73  mTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFieldText.svg" ) ), tr( "Text" ), "string" );
74  mTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFieldInteger.svg" ) ), tr( "Whole Number" ), "integer" );
75  mTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFieldFloat.svg" ) ), tr( "Decimal Number" ), "double" );
76  mTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFieldBool.svg" ) ), tr( "Boolean" ), "bool" );
77  mTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFieldDate.svg" ) ), tr( "Date" ), "date" );
78  mTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFieldTime.svg" ) ), tr( "Time" ), "time" );
79  mTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFieldDateTime.svg" ) ), tr( "Date and Time" ), "datetime" );
80  mTypeBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mIconFieldBinary.svg" ) ), tr( "Binary (BLOB)" ), "binary" );
81  mTypeBox_currentIndexChanged( 1 );
82 
83  mWidth->setValidator( new QIntValidator( 1, 255, this ) );
84  mPrecision->setValidator( new QIntValidator( 0, 30, this ) );
85 
86  mAddAttributeButton->setEnabled( false );
87  mRemoveAttributeButton->setEnabled( false );
88 
89  mOkButton = mButtonBox->button( QDialogButtonBox::Ok );
90  mOkButton->setEnabled( false );
91 
92  connect( mGeometryTypeBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNewMemoryLayerDialog::geometryTypeChanged );
93  connect( mFieldNameEdit, &QLineEdit::textChanged, this, &QgsNewMemoryLayerDialog::fieldNameChanged );
94  connect( mTypeBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNewMemoryLayerDialog::mTypeBox_currentIndexChanged );
95  connect( mAttributeView, &QTreeWidget::itemSelectionChanged, this, &QgsNewMemoryLayerDialog::selectionChanged );
96  connect( mAddAttributeButton, &QToolButton::clicked, this, &QgsNewMemoryLayerDialog::mAddAttributeButton_clicked );
97  connect( mRemoveAttributeButton, &QToolButton::clicked, this, &QgsNewMemoryLayerDialog::mRemoveAttributeButton_clicked );
98  connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsNewMemoryLayerDialog::showHelp );
99 }
100 
102 {
104  geomType = static_cast<QgsWkbTypes::Type>
105  ( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
106 
107  if ( geomType != QgsWkbTypes::Unknown && geomType != QgsWkbTypes::NoGeometry )
108  {
109  if ( mGeometryWithZCheckBox->isChecked() )
110  geomType = QgsWkbTypes::addZ( geomType );
111  if ( mGeometryWithMCheckBox->isChecked() )
112  geomType = QgsWkbTypes::addM( geomType );
113  }
114 
115  return geomType;
116 }
117 
118 void QgsNewMemoryLayerDialog::geometryTypeChanged( int )
119 {
120  QgsWkbTypes::Type geomType = static_cast<QgsWkbTypes::Type>
121  ( mGeometryTypeBox->currentData( Qt::UserRole ).toInt() );
122 
123  bool isSpatial = geomType != QgsWkbTypes::NoGeometry;
124  mGeometryWithZCheckBox->setEnabled( isSpatial );
125  mGeometryWithMCheckBox->setEnabled( isSpatial );
126  mCrsSelector->setEnabled( isSpatial );
127 
128  bool ok = ( !mNameLineEdit->text().isEmpty() && mGeometryTypeBox->currentIndex() != -1 );
129  mOkButton->setEnabled( ok );
130 }
131 
132 void QgsNewMemoryLayerDialog::mTypeBox_currentIndexChanged( int index )
133 {
134  switch ( index )
135  {
136  case 0: // Text data
137  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 255 )
138  mWidth->setText( QStringLiteral( "255" ) );
139  mPrecision->clear();
140  mPrecision->setEnabled( false );
141  mWidth->setValidator( new QIntValidator( 1, 255, this ) );
142  break;
143  case 1: // Whole number
144  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 10 )
145  mWidth->setText( QStringLiteral( "10" ) );
146  mPrecision->clear();
147  mPrecision->setEnabled( false );
148  mWidth->setValidator( new QIntValidator( 1, 10, this ) );
149  break;
150  case 2: // Decimal number
151  if ( mWidth->text().toInt() < 1 || mWidth->text().toInt() > 30 )
152  mWidth->setText( QStringLiteral( "30" ) );
153  if ( mPrecision->text().toInt() < 1 || mPrecision->text().toInt() > 30 )
154  mPrecision->setText( QStringLiteral( "6" ) );
155  mPrecision->setEnabled( true );
156  mWidth->setValidator( new QIntValidator( 1, 20, this ) );
157  break;
158  case 3: // Boolean
159  mWidth->clear();
160  mWidth->setEnabled( false );
161  mPrecision->clear();
162  mPrecision->setEnabled( false );
163  break;
164  case 4: // Date
165  mWidth->clear();
166  mWidth->setEnabled( false );
167  mPrecision->clear();
168  mPrecision->setEnabled( false );
169  break;
170  case 5: // Time
171  mWidth->clear();
172  mWidth->setEnabled( false );
173  mPrecision->clear();
174  mPrecision->setEnabled( false );
175  break;
176  case 6: // Datetime
177  mWidth->clear();
178  mWidth->setEnabled( false );
179  mPrecision->clear();
180  mPrecision->setEnabled( false );
181  break;
182  case 7: // Binary
183  mWidth->clear();
184  mWidth->setEnabled( false );
185  mPrecision->clear();
186  mPrecision->setEnabled( false );
187  break;
188 
189  default:
190  QgsDebugMsg( QStringLiteral( "unexpected index" ) );
191  break;
192  }
193 }
194 
196 {
197  mCrsSelector->setCrs( crs );
198 }
199 
201 {
202  return mCrsSelector->crs();
203 }
204 
206 {
207  return mNameLineEdit->text();
208 }
209 
210 void QgsNewMemoryLayerDialog::fieldNameChanged( const QString &name )
211 {
212  mAddAttributeButton->setDisabled( name.isEmpty() || ! mAttributeView->findItems( name, Qt::MatchExactly ).isEmpty() );
213 }
214 
215 void QgsNewMemoryLayerDialog::selectionChanged()
216 {
217  mRemoveAttributeButton->setDisabled( mAttributeView->selectedItems().isEmpty() );
218 }
219 
221 {
223 
224  QTreeWidgetItemIterator it( mAttributeView );
225  while ( *it )
226  {
227  QString name( ( *it )->text( 0 ) );
228  QString typeName( ( *it )->text( 1 ) );
229  int width = ( *it )->text( 2 ).toInt();
230  int precision = ( *it )->text( 3 ).toInt();
231  QVariant::Type fieldType = QVariant::Invalid;
232  if ( typeName == QLatin1String( "string" ) )
233  fieldType = QVariant::String;
234  else if ( typeName == QLatin1String( "integer" ) )
235  fieldType = QVariant::Int;
236  else if ( typeName == QLatin1String( "double" ) )
237  fieldType = QVariant::Double;
238  else if ( typeName == QLatin1String( "bool" ) )
239  fieldType = QVariant::Bool;
240  else if ( typeName == QLatin1String( "date" ) )
241  fieldType = QVariant::Date;
242  else if ( typeName == QLatin1String( "time" ) )
243  fieldType = QVariant::Time;
244  else if ( typeName == QLatin1String( "datetime" ) )
245  fieldType = QVariant::DateTime;
246 
247  QgsField field = QgsField( name, fieldType, typeName, width, precision );
248  fields.append( field );
249  ++it;
250  }
251 
252  return fields;
253 }
254 
255 void QgsNewMemoryLayerDialog::mAddAttributeButton_clicked()
256 {
257  if ( !mFieldNameEdit->text().isEmpty() )
258  {
259  QString fieldName = mFieldNameEdit->text();
260  QString fieldType = mTypeBox->currentData( Qt::UserRole ).toString();
261  QString width = mWidth->text();
262  QString precision = mPrecision->text();
263  mAttributeView->addTopLevelItem( new QTreeWidgetItem( QStringList() << fieldName << fieldType << width << precision ) );
264 
265  mFieldNameEdit->clear();
266  }
267 }
268 
269 void QgsNewMemoryLayerDialog::mRemoveAttributeButton_clicked()
270 {
271  delete mAttributeView->currentItem();
272 }
273 
274 void QgsNewMemoryLayerDialog::showHelp()
275 {
276  QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-a-new-temporary-scratch-layer" ) );
277 }
qgsfields.h
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:605
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:71
QgsNewMemoryLayerDialog::crs
QgsCoordinateReferenceSystem crs() const
Returns the selected CRS for the new layer.
Definition: qgsnewmemorylayerdialog.cpp:200
QgsWkbTypes::MultiPolygon
@ MultiPolygon
Definition: qgswkbtypes.h:77
QgsNewMemoryLayerDialog::QgsNewMemoryLayerDialog
QgsNewMemoryLayerDialog(QWidget *parent SIP_TRANSFERTHIS=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
New dialog constructor.
Definition: qgsnewmemorylayerdialog.cpp:52
QgsNewMemoryLayerDialog::layerName
QString layerName() const
Returns the layer name.
Definition: qgsnewmemorylayerdialog.cpp:205
qgsgui.h
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsWkbTypes::LineString
@ LineString
Definition: qgswkbtypes.h:72
QgsFields
Definition: qgsfields.h:44
qgis.h
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsFields::append
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
QgsWkbTypes::addM
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1163
qgsapplication.h
QgsNewMemoryLayerDialog
Definition: qgsnewmemorylayerdialog.h:33
QgsGui::enableAutoGeometryRestore
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:133
precision
int precision
Definition: qgswfsgetfeature.cpp:103
QgsWkbTypes::MultiLineString
@ MultiLineString
Definition: qgswkbtypes.h:76
QgsMemoryProviderUtils::createMemoryLayer
static QgsVectorLayer * createMemoryLayer(const QString &name, const QgsFields &fields, QgsWkbTypes::Type geometryType=QgsWkbTypes::NoGeometry, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Creates a new memory layer using the specified parameters.
Definition: qgsmemoryproviderutils.cpp:59
QgsWkbTypes::Unknown
@ Unknown
Definition: qgswkbtypes.h:70
qgsproviderregistry.h
qgsvectordataprovider.h
typeName
const QString & typeName
Definition: qgswfsgetfeature.cpp:109
QgsNewMemoryLayerDialog::setCrs
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the crs value for the new layer in the dialog.
Definition: qgsnewmemorylayerdialog.cpp:195
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:206
QgsWkbTypes::addZ
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1138
qgsvectorlayer.h
QgsNewMemoryLayerDialog::runAndCreateLayer
static QgsVectorLayer * runAndCreateLayer(QWidget *parent=nullptr, const QgsCoordinateReferenceSystem &defaultCrs=QgsCoordinateReferenceSystem())
Runs the dialog and creates a new memory layer.
Definition: qgsnewmemorylayerdialog.cpp:36
QgsWkbTypes::NoGeometry
@ NoGeometry
Definition: qgswkbtypes.h:84
QgsHelp::openHelp
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsVectorLayer
Definition: qgsvectorlayer.h:385
qgsfield.h
QgsWkbTypes::Polygon
@ Polygon
Definition: qgswkbtypes.h:73
QgsWkbTypes::MultiPoint
@ MultiPoint
Definition: qgswkbtypes.h:75
qgssettings.h
QgsNewMemoryLayerDialog::fields
QgsFields fields() const
Returns attributes for the new layer.
Definition: qgsnewmemorylayerdialog.cpp:220
qgsmemoryproviderutils.h
QgsNewMemoryLayerDialog::selectedType
QgsWkbTypes::Type selectedType() const
Returns the selected geometry type.
Definition: qgsnewmemorylayerdialog.cpp:101
qgscoordinatereferencesystem.h
qgsnewmemorylayerdialog.h
QgsField
Definition: qgsfield.h:49