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