QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsaddattrdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsaddattrdialog.h - description
3  -------------------
4  begin : January 2005
5  copyright : (C) 2005 by Marco Hugentobler
6  email : [email protected]
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 
18 #include "qgsaddattrdialog.h"
19 #include "qgsvectorlayer.h"
20 #include "qgsvectordataprovider.h"
21 #include "qgslogger.h"
22 
23 #include <QMessageBox>
24 
25 QgsAddAttrDialog::QgsAddAttrDialog( QgsVectorLayer *vlayer, QWidget *parent, Qt::WindowFlags fl )
26  : QDialog( parent, fl )
27  , mIsShapeFile( vlayer && vlayer->providerType() == QLatin1String( "ogr" ) && vlayer->storageType() == QLatin1String( "ESRI Shapefile" ) )
28 {
29  setupUi( this );
30  connect( mTypeBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsAddAttrDialog::mTypeBox_currentIndexChanged );
31  connect( mLength, &QSpinBox::editingFinished, this, &QgsAddAttrDialog::mLength_editingFinished );
32 
33  if ( !vlayer )
34  return;
35 
36  //fill data types into the combo box
37  const QList< QgsVectorDataProvider::NativeType > &typelist = vlayer->dataProvider()->nativeTypes();
38  for ( int i = 0; i < typelist.size(); i++ )
39  {
40  QgsDebugMsg( QStringLiteral( "name:%1 type:%2 typeName:%3 length:%4-%5 prec:%6-%7" )
41  .arg( typelist[i].mTypeDesc )
42  .arg( typelist[i].mType )
43  .arg( typelist[i].mTypeName )
44  .arg( typelist[i].mMinLen ).arg( typelist[i].mMaxLen )
45  .arg( typelist[i].mMinPrec ).arg( typelist[i].mMaxPrec ) );
46 
47  whileBlocking( mTypeBox )->addItem( typelist[i].mTypeDesc );
48  mTypeBox->setItemData( i, static_cast<int>( typelist[i].mType ), Qt::UserRole );
49  mTypeBox->setItemData( i, typelist[i].mTypeName, Qt::UserRole + 1 );
50  mTypeBox->setItemData( i, typelist[i].mMinLen, Qt::UserRole + 2 );
51  mTypeBox->setItemData( i, typelist[i].mMaxLen, Qt::UserRole + 3 );
52  mTypeBox->setItemData( i, typelist[i].mMinPrec, Qt::UserRole + 4 );
53  mTypeBox->setItemData( i, typelist[i].mMaxPrec, Qt::UserRole + 5 );
54  }
55 
56  //default values for field width and precision
57  mLength->setValue( 10 );
58  mPrec->setValue( 3 );
59  mTypeBox_currentIndexChanged( 0 );
60 
61  if ( mIsShapeFile )
62  mNameEdit->setMaxLength( 10 );
63 
64  mNameEdit->setFocus();
65 }
66 
67 void QgsAddAttrDialog::mTypeBox_currentIndexChanged( int idx )
68 {
69  mTypeName->setText( mTypeBox->itemData( idx, Qt::UserRole + 1 ).toString() );
70 
71  mLength->setMinimum( mTypeBox->itemData( idx, Qt::UserRole + 2 ).toInt() );
72  mLength->setMaximum( mTypeBox->itemData( idx, Qt::UserRole + 3 ).toInt() );
73  mLength->setVisible( mLength->minimum() < mLength->maximum() );
74  mLengthLabel->setVisible( mLength->minimum() < mLength->maximum() );
75  if ( mLength->value() < mLength->minimum() )
76  mLength->setValue( mLength->minimum() );
77  if ( mLength->value() > mLength->maximum() )
78  mLength->setValue( mLength->maximum() );
79  setPrecisionMinMax();
80 }
81 
82 void QgsAddAttrDialog::mLength_editingFinished()
83 {
84  setPrecisionMinMax();
85 }
86 
87 void QgsAddAttrDialog::setPrecisionMinMax()
88 {
89  int idx = mTypeBox->currentIndex();
90  int minPrecType = mTypeBox->itemData( idx, Qt::UserRole + 4 ).toInt();
91  int maxPrecType = mTypeBox->itemData( idx, Qt::UserRole + 5 ).toInt();
92  bool precisionIsEnabled = minPrecType < maxPrecType;
93  mPrec->setVisible( precisionIsEnabled );
94  mPrecLabel->setVisible( precisionIsEnabled );
95 
96  // Do not set min/max if it's disabled or we'll loose the default value,
97  // see https://github.com/qgis/QGIS/issues/26880 - QGIS saves integer field when
98  // I create a new real field through field calculator (Update field works as intended)
99  if ( precisionIsEnabled )
100  {
101  mPrec->setMinimum( minPrecType );
102  mPrec->setMaximum( std::max( minPrecType, std::min( maxPrecType, mLength->value() ) ) );
103  }
104 }
105 
106 void QgsAddAttrDialog::accept()
107 {
108  if ( mIsShapeFile && mNameEdit->text().compare( QLatin1String( "shape" ), Qt::CaseInsensitive ) == 0 )
109  {
110  QMessageBox::warning( this, tr( "Add Field" ),
111  tr( "Invalid field name. This field name is reserved and cannot be used." ) );
112  return;
113  }
114  if ( mNameEdit->text().isEmpty() )
115  {
116  QMessageBox::warning( this, tr( "Add Field" ),
117  tr( "No name specified. Please specify a name to create a new field." ) );
118  return;
119  }
120 
121  QDialog::accept();
122 }
123 
125 {
126 
127  QgsDebugMsg( QStringLiteral( "idx:%1 name:%2 type:%3 typeName:%4 length:%5 prec:%6 comment:%7" )
128  .arg( mTypeBox->currentIndex() )
129  .arg( mNameEdit->text() )
130  .arg( mTypeBox->currentData( Qt::UserRole ).toInt() )
131  .arg( mTypeBox->currentData( Qt::UserRole + 1 ).toString() )
132  .arg( mLength->value() )
133  .arg( mPrec->value() )
134  .arg( mCommentEdit->text() ) );
135 
136  return QgsField(
137  mNameEdit->text(),
138  ( QVariant::Type ) mTypeBox->currentData( Qt::UserRole ).toInt(),
139  mTypeBox->currentData( Qt::UserRole + 1 ).toString(),
140  mLength->value(),
141  mPrec->value(),
142  mCommentEdit->text(),
143  static_cast<QVariant::Type>( mTypeBox->currentData( Qt::UserRole ).toInt() ) == QVariant::Map ? QVariant::String : QVariant::Invalid
144  );
145 }
QgsVectorLayer::dataProvider
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectorlayer.cpp:627
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsAddAttrDialog::field
QgsField field() const
Returns a field for the configured attribute.
Definition: qgsaddattrdialog.cpp:124
qgsaddattrdialog.h
QgsVectorDataProvider::nativeTypes
QList< QgsVectorDataProvider::NativeType > nativeTypes() const
Returns the names of the supported types.
Definition: qgsvectordataprovider.cpp:338
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:262
qgsvectordataprovider.h
QgsAddAttrDialog::QgsAddAttrDialog
QgsAddAttrDialog(QgsVectorLayer *vlayer, QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
constructor
Definition: qgsaddattrdialog.cpp:25
qgsvectorlayer.h
QgsVectorLayer
Definition: qgsvectorlayer.h:385
qgslogger.h
QgsField
Definition: qgsfield.h:49