QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsfield.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfield.cpp - Describes a field in a layer or table
3  --------------------------------------
4  Date : 01-Jan-2004
5  Copyright : (C) 2004 by Gary E.Sherman
6  email : sherman at mrcc.com
7 
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
17 #include "qgsfield_p.h"
18 #include "qgis.h"
19 #include "qgsapplication.h"
20 #include "qgsreferencedgeometry.h"
21 #include "qgsvariantutils.h"
22 
23 #include <QDataStream>
24 #include <QIcon>
25 #include <QLocale>
26 #include <QJsonDocument>
27 
28 /***************************************************************************
29  * This class is considered CRITICAL and any change MUST be accompanied with
30  * full unit tests in testqgsfield.cpp.
31  * See details in QEP #17
32  ****************************************************************************/
33 
34 #if 0
35 QgsField::QgsField( QString nam, QString typ, int len, int prec, bool num,
36  QString comment )
37  : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
38  , mComment( comment )
39 {
40  // This function used to lower case the field name since some stores
41  // use upper case (e.g., shapefiles), but that caused problems with
42  // attribute actions getting confused between uppercase and
43  // lowercase versions of the attribute names, so just leave the
44  // names how they are now.
45 }
46 #endif
47 QgsField::QgsField( const QString &name, QVariant::Type type,
48  const QString &typeName, int len, int prec, const QString &comment, QVariant::Type subType )
49 {
50  d = new QgsFieldPrivate( name, type, subType, typeName, len, prec, comment );
51 }
52 
53 QgsField::QgsField( const QgsField &other ) //NOLINT
54  : d( other.d )
55 {
56 
57 }
58 
59 QgsField::~QgsField() = default;
60 
61 /***************************************************************************
62  * This class is considered CRITICAL and any change MUST be accompanied with
63  * full unit tests in testqgsfield.cpp.
64  * See details in QEP #17
65  ****************************************************************************/
66 
67 QgsField &QgsField::operator =( const QgsField &other ) //NOLINT
68 {
69  d = other.d;
70  return *this;
71 }
72 
73 bool QgsField::operator==( const QgsField &other ) const
74 {
75  return *( other.d ) == *d;
76 }
77 
78 bool QgsField::operator!=( const QgsField &other ) const
79 {
80  return !( *this == other );
81 }
82 
83 QString QgsField::name() const
84 {
85  return d->name;
86 }
87 
88 QString QgsField::displayName() const
89 {
90  if ( !d->alias.isEmpty() )
91  return d->alias;
92  else
93  return d->name;
94 }
95 
97 {
98  if ( alias().isEmpty() )
99  {
100  return name();
101  }
102  return QStringLiteral( "%1 (%2)" ).arg( name(), alias() );
103 }
104 
105 QString QgsField::displayType( const bool showConstraints ) const
106 {
107  QString typeStr = typeName();
108 
109  if ( length() > 0 && precision() > 0 )
110  typeStr += QStringLiteral( "(%1, %2)" ).arg( length() ).arg( precision() );
111  else if ( length() > 0 )
112  typeStr += QStringLiteral( "(%1)" ).arg( length() );
113 
114  if ( showConstraints )
115  {
117  ? QStringLiteral( " NOT NULL" )
118  : QStringLiteral( " NULL" );
119 
121  ? QStringLiteral( " UNIQUE" )
122  : QString();
123  }
124 
125  return typeStr;
126 }
127 
129 {
130  if ( d->type == QVariant::UserType )
131  {
132  if ( d->typeName.compare( QLatin1String( "geometry" ), Qt::CaseInsensitive ) == 0 )
133  {
134  return QObject::tr( "Geometry" );
135  }
136  }
137  return QgsVariantUtils::typeToDisplayString( d->type, d->subType );
138 }
139 
140 QVariant::Type QgsField::type() const
141 {
142  return d->type;
143 }
144 
145 QVariant::Type QgsField::subType() const
146 {
147  return d->subType;
148 }
149 
150 QString QgsField::typeName() const
151 {
152  return d->typeName;
153 }
154 
155 int QgsField::length() const
156 {
157  return d->length;
158 }
159 
161 {
162  return d->precision;
163 }
164 
165 QString QgsField::comment() const
166 {
167  return d->comment;
168 }
169 
170 QVariant QgsField::metadata( int property ) const
171 {
172  return d->metadata.value( property );
173 }
174 
175 QMap<int, QVariant> QgsField::metadata() const
176 {
177  return d->metadata;
178 }
179 
181 {
182  return d->metadata.value( static_cast< int >( property ) );
183 }
184 
185 void QgsField::setMetadata( const QMap<int, QVariant> metadata )
186 {
187  d->metadata = metadata;
188 }
189 
190 void QgsField::setMetadata( Qgis::FieldMetadataProperty property, const QVariant &value )
191 {
192  d->metadata[ static_cast< int >( property )] = value;
193 }
194 
195 void QgsField::setMetadata( int property, const QVariant &value )
196 {
197  d->metadata[ property ] = value;
198 }
199 
201 {
202  return d->type == QVariant::Double || d->type == QVariant::Int || d->type == QVariant::UInt || d->type == QVariant::LongLong || d->type == QVariant::ULongLong;
203 }
204 
206 {
207  return d->type == QVariant::Date || d->type == QVariant::Time || d->type == QVariant::DateTime;
208 }
209 
210 /***************************************************************************
211  * This class is considered CRITICAL and any change MUST be accompanied with
212  * full unit tests in testqgsfield.cpp.
213  * See details in QEP #17
214  ****************************************************************************/
215 
216 void QgsField::setName( const QString &name )
217 {
218  d->name = name;
219 }
220 
221 void QgsField::setType( QVariant::Type type )
222 {
223  d->type = type;
224 }
225 
226 void QgsField::setSubType( QVariant::Type subType )
227 {
228  d->subType = subType;
229 }
230 
231 void QgsField::setTypeName( const QString &typeName )
232 {
233  d->typeName = typeName;
234 }
235 
236 void QgsField::setLength( int len )
237 {
238  d->length = len;
239 }
241 {
242  d->precision = precision;
243 }
244 
245 void QgsField::setComment( const QString &comment )
246 {
247  d->comment = comment;
248 }
249 
251 {
252  return d->defaultValueDefinition;
253 }
254 
255 void QgsField::setDefaultValueDefinition( const QgsDefaultValue &defaultValueDefinition )
256 {
257  d->defaultValueDefinition = defaultValueDefinition;
258 }
259 
261 {
262  d->constraints = constraints;
263 }
264 
266 {
267  return d->constraints;
268 }
269 
270 QString QgsField::alias() const
271 {
272  return d->alias;
273 }
274 
275 void QgsField::setAlias( const QString &alias )
276 {
277  d->alias = alias;
278 }
279 
281 {
282  return d->flags;
283 }
284 
286 {
287  d->flags = flags;
288 }
289 
290 /***************************************************************************
291  * This class is considered CRITICAL and any change MUST be accompanied with
292  * full unit tests in testqgsfield.cpp.
293  * See details in QEP #17
294  ****************************************************************************/
295 
296 QString QgsField::displayString( const QVariant &v ) const
297 {
298  if ( QgsVariantUtils::isNull( v ) )
299  {
301  }
302 
303  if ( v.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
304  {
305  QgsReferencedGeometry geom = qvariant_cast<QgsReferencedGeometry>( v );
306  if ( geom.isNull() )
308  else
309  {
310  QString wkt = geom.asWkt();
311  if ( wkt.length() >= 1050 )
312  {
313  wkt = wkt.left( MAX_WKT_LENGTH ) + QChar( 0x2026 );
314  }
315  QString formattedText = QStringLiteral( "%1 [%2]" ).arg( wkt, geom.crs().userFriendlyIdentifier() );
316  return formattedText;
317  }
318  }
319 
320  // Special treatment for numeric types if group separator is set or decimalPoint is not a dot
321  if ( d->type == QVariant::Double )
322  {
323  // if value doesn't contain a double (a default value expression for instance),
324  // apply no transformation
325  bool ok;
326  v.toDouble( &ok );
327  if ( !ok )
328  return v.toString();
329 
330  // Locales with decimal point != '.' or that require group separator: use QLocale
331  if ( QLocale().decimalPoint() != '.' ||
332  !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
333  {
334  if ( d->precision > 0 )
335  {
336  if ( -1 < v.toDouble() && v.toDouble() < 1 )
337  {
338  return QLocale().toString( v.toDouble(), 'g', d->precision );
339  }
340  else
341  {
342  return QLocale().toString( v.toDouble(), 'f', d->precision );
343  }
344  }
345  else
346  {
347  // Precision is not set, let's guess it from the
348  // standard conversion to string
349  const QString s( v.toString() );
350  const int dotPosition( s.indexOf( '.' ) );
351  int precision;
352  if ( dotPosition < 0 && s.indexOf( 'e' ) < 0 )
353  {
354  precision = 0;
355  return QLocale().toString( v.toDouble(), 'f', precision );
356  }
357  else
358  {
359  if ( dotPosition < 0 ) precision = 0;
360  else precision = s.length() - dotPosition - 1;
361 
362  if ( -1 < v.toDouble() && v.toDouble() < 1 )
363  {
364  return QLocale().toString( v.toDouble(), 'g', precision );
365  }
366  else
367  {
368  return QLocale().toString( v.toDouble(), 'f', precision );
369  }
370  }
371  }
372  }
373  // Default for doubles with precision
374  else if ( d->precision > 0 )
375  {
376  if ( -1 < v.toDouble() && v.toDouble() < 1 )
377  {
378  return QString::number( v.toDouble(), 'g', d->precision );
379  }
380  else
381  {
382  return QString::number( v.toDouble(), 'f', d->precision );
383  }
384  }
385  else
386  {
387  const double vDouble = v.toDouble();
388  // mimic Qt 5 handling of when to switch to exponential forms
389  if ( std::fabs( vDouble ) < 1e-04 )
390  return QString::number( vDouble, 'g', QLocale::FloatingPointShortest );
391  else
392  return QString::number( vDouble, 'f', QLocale::FloatingPointShortest );
393  }
394  }
395  // Other numeric types than doubles
396  else if ( isNumeric() &&
397  !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
398  {
399  bool ok;
400  const qlonglong converted( v.toLongLong( &ok ) );
401  if ( ok )
402  return QLocale().toString( converted );
403  }
404  else if ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String( "jsonb" ) )
405  {
406  const QJsonDocument doc = QJsonDocument::fromVariant( v );
407  return QString::fromUtf8( doc.toJson().constData() );
408  }
409  else if ( d->type == QVariant::ByteArray )
410  {
411  return QObject::tr( "BLOB" );
412  }
413  else if ( d->type == QVariant::StringList || d->type == QVariant::List )
414  {
415  QString result;
416  const QVariantList list = v.toList();
417  for ( const QVariant &var : list )
418  {
419  if ( !result.isEmpty() )
420  result.append( QStringLiteral( ", " ) );
421  result.append( var.toString() );
422  }
423  return result;
424  }
425 
426  // Fallback if special rules do not apply
427  return v.toString();
428 }
429 
431 {
432  switch ( flag )
433  {
435  return QObject::tr( "None" );
437  return QObject::tr( "Not searchable" );
439  return QObject::tr( "Do not expose via WMS" );
441  return QObject::tr( "Do not expose via WFS" );
442  }
443  return QString();
444 }
445 
446 /***************************************************************************
447  * This class is considered CRITICAL and any change MUST be accompanied with
448  * full unit tests in testqgsfield.cpp.
449  * See details in QEP #17
450  ****************************************************************************/
451 
452 bool QgsField::convertCompatible( QVariant &v, QString *errorMessage ) const
453 {
454  const QVariant original = v;
455  if ( errorMessage )
456  errorMessage->clear();
457 
458  if ( QgsVariantUtils::isNull( v ) )
459  {
460  v.convert( d->type );
461  return true;
462  }
463 
464  if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
465  {
466  v = QVariant( d->type );
467  if ( errorMessage )
468  *errorMessage = QObject::tr( "Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
469  return false;
470  }
471 
472  // Give it a chance to convert to double since for not '.' locales
473  // we accept both comma and dot as decimal point
474  if ( d->type == QVariant::Double && v.type() == QVariant::String )
475  {
476  QVariant tmp( v );
477  if ( !tmp.convert( d->type ) )
478  {
479  // This might be a string with thousand separator: use locale to convert
480  bool ok = false;
481  double d = qgsPermissiveToDouble( v.toString(), ok );
482  if ( ok )
483  {
484  v = QVariant( d );
485  return true;
486  }
487  // For not 'dot' locales, we also want to accept '.'
488  if ( QLocale().decimalPoint() != '.' )
489  {
490  d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
491  if ( ok )
492  {
493  v = QVariant( d );
494  return true;
495  }
496  }
497  }
498  }
499 
500  // For string representation of an int we also might have thousand separator
501  if ( d->type == QVariant::Int && v.type() == QVariant::String )
502  {
503  QVariant tmp( v );
504  if ( !tmp.convert( d->type ) )
505  {
506  // This might be a string with thousand separator: use locale to convert
507  bool ok;
508  const int i = qgsPermissiveToInt( v.toString(), ok );
509  if ( ok )
510  {
511  v = QVariant( i );
512  return true;
513  }
514  }
515  }
516 
517  // For string representation of a long we also might have thousand separator
518  if ( d->type == QVariant::LongLong && v.type() == QVariant::String )
519  {
520  QVariant tmp( v );
521  if ( !tmp.convert( d->type ) )
522  {
523  // This might be a string with thousand separator: use locale to convert
524  bool ok;
525  const qlonglong l = qgsPermissiveToLongLong( v.toString(), ok );
526  if ( ok )
527  {
528  v = QVariant( l );
529  return true;
530  }
531  }
532  }
533 
534  //String representations of doubles in QVariant will return false to convert( QVariant::Int )
535  //work around this by first converting to double, and then checking whether the double is convertible to int
536  if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
537  {
538  bool ok = false;
539  const double dbl = v.toDouble( &ok );
540  if ( !ok )
541  {
542  //couldn't convert to number
543  v = QVariant( d->type );
544 
545  if ( errorMessage )
546  *errorMessage = QObject::tr( "Value \"%1\" is not a number" ).arg( original.toString() );
547 
548  return false;
549  }
550 
551  const double round = std::round( dbl );
552  if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
553  {
554  //double too large to fit in int
555  v = QVariant( d->type );
556 
557  if ( errorMessage )
558  *errorMessage = QObject::tr( "Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
559 
560  return false;
561  }
562  v = QVariant( static_cast< int >( std::round( dbl ) ) );
563  return true;
564  }
565 
566  //String representations of doubles in QVariant will return false to convert( QVariant::LongLong )
567  //work around this by first converting to double, and then checking whether the double is convertible to longlong
568  if ( d->type == QVariant::LongLong && v.canConvert( QVariant::Double ) )
569  {
570  //firstly test the conversion to longlong because conversion to double will rounded the value
571  QVariant tmp( v );
572  if ( !tmp.convert( d->type ) )
573  {
574  bool ok = false;
575  const double dbl = v.toDouble( &ok );
576  if ( !ok )
577  {
578  //couldn't convert to number
579  v = QVariant( d->type );
580 
581  if ( errorMessage )
582  *errorMessage = QObject::tr( "Value \"%1\" is not a number" ).arg( original.toString() );
583 
584  return false;
585  }
586 
587  const double round = std::round( dbl );
588  if ( round > static_cast<double>( std::numeric_limits<long long>::max() ) || round < static_cast<double>( -std::numeric_limits<long long>::max() ) )
589  {
590  //double too large to fit in longlong
591  v = QVariant( d->type );
592 
593  if ( errorMessage )
594  *errorMessage = QObject::tr( "Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
595 
596  return false;
597  }
598  v = QVariant( static_cast< long long >( std::round( dbl ) ) );
599  return true;
600  }
601  }
602 
603  if ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName.compare( QLatin1String( "jsonb" ), Qt::CaseInsensitive ) == 0 )
604  {
605  if ( d->type == QVariant::String )
606  {
607  const QJsonDocument doc = QJsonDocument::fromVariant( v );
608  if ( !doc.isNull() )
609  {
610  v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
611  return true;
612  }
613  v = QVariant( d->type );
614  return false;
615  }
616  else if ( d->type == QVariant::Map )
617  {
618  if ( v.type() == QVariant::StringList || v.type() == QVariant::List || v.type() == QVariant::Map )
619  {
620  return true;
621  }
622  v = QVariant( d->type );
623  return false;
624  }
625  }
626 
627  if ( ( d->type == QVariant::StringList || ( d->type == QVariant::List && d->subType == QVariant::String ) )
628  && ( v.type() == QVariant::String ) )
629  {
630  v = QStringList( { v.toString() } );
631  return true;
632  }
633 
634  if ( ( d->type == QVariant::StringList || d->type == QVariant::List ) && !( v.type() == QVariant::StringList || v.type() == QVariant::List ) )
635  {
636  v = QVariant( d->type );
637 
638  if ( errorMessage )
639  *errorMessage = QObject::tr( "Could not convert value \"%1\" to target list type" ).arg( original.toString() );
640 
641  return false;
642  }
643 
644  // Handle referenced geometries (e.g. from additional geometry fields)
645  if ( d->type == QVariant::String && v.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
646  {
647  const QgsReferencedGeometry geom { v.value<QgsReferencedGeometry>( ) };
648  if ( geom.isNull() )
649  {
650  v = QVariant( d->type );
651  }
652  else
653  {
654  v = QVariant( geom.asWkt() );
655  }
656  return true;
657  }
658  else if ( d->type == QVariant::UserType && d->typeName.compare( QLatin1String( "geometry" ), Qt::CaseInsensitive ) == 0 )
659  {
660  if ( v.userType() == QMetaType::type( "QgsReferencedGeometry" ) || v.userType() == QMetaType::type( "QgsGeometry" ) )
661  {
662  return true;
663  }
664  else if ( v.type() == QVariant::String )
665  {
666  const QgsGeometry geom = QgsGeometry::fromWkt( v.toString() );
667  if ( !geom.isNull() )
668  {
669  v = QVariant::fromValue( geom );
670  return true;
671  }
672  }
673  return false;
674  }
675  else if ( !v.convert( d->type ) )
676  {
677  v = QVariant( d->type );
678 
679  if ( errorMessage )
680  *errorMessage = QObject::tr( "Could not convert value \"%1\" to target type \"%2\"" )
681  .arg( original.toString(),
682  d->typeName );
683 
684  return false;
685  }
686 
687  if ( d->type == QVariant::Double && d->precision > 0 )
688  {
689  const double s = std::pow( 10, d->precision );
690  const double d = v.toDouble() * s;
691  v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
692  return true;
693  }
694 
695  if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
696  {
697  const int length = v.toString().length();
698  v = v.toString().left( d->length );
699 
700  if ( errorMessage )
701  *errorMessage = QObject::tr( "String of length %1 exceeds maximum field length (%2)" ).arg( length ).arg( d->length );
702 
703  return false;
704  }
705 
706  return true;
707 }
708 
710 {
711  d->editorWidgetSetup = v;
712 }
713 
715 {
716  return d->editorWidgetSetup;
717 }
718 
719 void QgsField::setReadOnly( bool readOnly )
720 {
721  d->isReadOnly = readOnly;
722 }
723 
725 {
726  return d->isReadOnly;
727 }
728 
730 {
731  return d->splitPolicy;
732 }
733 
735 {
736  d->splitPolicy = policy;
737 }
738 
739 /***************************************************************************
740  * This class is considered CRITICAL and any change MUST be accompanied with
741  * full unit tests in testqgsfield.cpp.
742  * See details in QEP #17
743  ****************************************************************************/
744 
745 QDataStream &operator<<( QDataStream &out, const QgsField &field )
746 {
747  out << field.name();
748  out << static_cast< quint32 >( field.type() );
749  out << field.typeName();
750  out << field.length();
751  out << field.precision();
752  out << field.comment();
753  out << field.alias();
754  out << field.defaultValueDefinition().expression();
755  out << field.defaultValueDefinition().applyOnUpdate();
756  out << field.constraints().constraints();
757  out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintNotNull ) );
758  out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintUnique ) );
759  out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintExpression ) );
760  out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintNotNull ) );
761  out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintUnique ) );
762  out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintExpression ) );
763  out << field.constraints().constraintExpression();
764  out << field.constraints().constraintDescription();
765  out << static_cast< quint32 >( field.subType() );
766  out << static_cast< int >( field.splitPolicy() );
767  out << field.metadata();
768  return out;
769 }
770 
771 QDataStream &operator>>( QDataStream &in, QgsField &field )
772 {
773  quint32 type;
774  quint32 subType;
775  quint32 length;
776  quint32 precision;
777  quint32 constraints;
778  quint32 originNotNull;
779  quint32 originUnique;
780  quint32 originExpression;
781  quint32 strengthNotNull;
782  quint32 strengthUnique;
783  quint32 strengthExpression;
784  int splitPolicy;
785 
786  bool applyOnUpdate;
787 
788  QString name;
789  QString typeName;
790  QString comment;
791  QString alias;
792  QString defaultValueExpression;
793  QString constraintExpression;
794  QString constraintDescription;
795  QMap< int, QVariant > metadata;
796 
797  in >> name >> type >> typeName >> length >> precision >> comment >> alias
798  >> defaultValueExpression >> applyOnUpdate >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
799  constraintExpression >> constraintDescription >> subType >> splitPolicy >> metadata;
800  field.setName( name );
801  field.setType( static_cast< QVariant::Type >( type ) );
802  field.setTypeName( typeName );
803  field.setLength( static_cast< int >( length ) );
804  field.setPrecision( static_cast< int >( precision ) );
805  field.setComment( comment );
806  field.setAlias( alias );
807  field.setDefaultValueDefinition( QgsDefaultValue( defaultValueExpression, applyOnUpdate ) );
808  field.setSplitPolicy( static_cast< Qgis::FieldDomainSplitPolicy >( splitPolicy ) );
809  QgsFieldConstraints fieldConstraints;
810  if ( constraints & QgsFieldConstraints::ConstraintNotNull )
811  {
812  fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintOrigin>( originNotNull ) );
814  }
815  else
817  if ( constraints & QgsFieldConstraints::ConstraintUnique )
818  {
819  fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintOrigin>( originUnique ) );
821  }
822  else
824  if ( constraints & QgsFieldConstraints::ConstraintExpression )
825  {
826  fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintOrigin>( originExpression ) );
828  }
829  else
831  fieldConstraints.setConstraintExpression( constraintExpression, constraintDescription );
832  field.setConstraints( fieldConstraints );
833  field.setSubType( static_cast< QVariant::Type >( subType ) );
834  field.setMetadata( metadata );
835  return in;
836 }
FieldDomainSplitPolicy
Split policy for field domains.
Definition: qgis.h:3162
FieldMetadataProperty
Standard field metadata values.
Definition: qgis.h:1313
FieldConfigurationFlag
Configuration flags for fields These flags are meant to be user-configurable and are not describing a...
Definition: qgis.h:1289
@ HideFromWfs
Field is not available if layer is served as WFS from QGIS server.
@ NoFlag
No flag is defined.
@ NotSearchable
Defines if the field is searchable (used in the locator search for instance)
@ HideFromWms
Field is not available if layer is served as WMS from QGIS server.
QFlags< FieldConfigurationFlag > FieldConfigurationFlags
Configuration flags for fields These flags are meant to be user-configurable and are not describing a...
Definition: qgis.h:1304
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
QString userFriendlyIdentifier(Qgis::CrsIdentifierType type=Qgis::CrsIdentifierType::MediumString) const
Returns a user friendly identifier for the CRS.
The QgsDefaultValue class provides a container for managing client side default values for fields.
Q_GADGET QString expression
Holder for the widget type and its configuration for a field.
Stores information about constraints which may be present on a field.
ConstraintStrength
Strength of constraints.
void setConstraintStrength(Constraint constraint, ConstraintStrength strength)
Sets the strength of a constraint.
void setConstraintExpression(const QString &expression, const QString &description=QString())
Set the constraint expression for the field.
ConstraintOrigin
Origin of constraints.
ConstraintStrength constraintStrength(Constraint constraint) const
Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint is not pres...
ConstraintOrigin constraintOrigin(Constraint constraint) const
Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint is not present ...
QString constraintExpression() const
Returns the constraint expression for the field, if set.
@ ConstraintNotNull
Field may not be null.
@ ConstraintUnique
Field must have a unique value.
@ ConstraintExpression
Field has an expression constraint set. See constraintExpression().
void removeConstraint(Constraint constraint)
Removes a constraint from the field.
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
Q_GADGET Constraints constraints
void setConstraint(Constraint constraint, ConstraintOrigin origin=ConstraintOriginLayer)
Sets a constraint on the field.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:53
void setSplitPolicy(Qgis::FieldDomainSplitPolicy policy)
Sets the field's split policy, which indicates how field values should be handled during a split oper...
Definition: qgsfield.cpp:734
bool isDateOrTime
Definition: qgsfield.h:57
void setEditorWidgetSetup(const QgsEditorWidgetSetup &v)
Set the editor widget setup for the field.
Definition: qgsfield.cpp:709
QString typeName() const
Gets the field type.
Definition: qgsfield.cpp:150
void setConstraints(const QgsFieldConstraints &constraints)
Sets constraints which are present for the field.
Definition: qgsfield.cpp:260
void setAlias(const QString &alias)
Sets the alias for the field (the friendly displayed name of the field ).
Definition: qgsfield.cpp:275
QString name
Definition: qgsfield.h:62
bool operator!=(const QgsField &other) const
Definition: qgsfield.cpp:78
bool operator==(const QgsField &other) const
Definition: qgsfield.cpp:73
int precision
Definition: qgsfield.h:59
int length
Definition: qgsfield.h:58
QgsField & operator=(const QgsField &other)
Assignment operator.
Definition: qgsfield.cpp:67
QString displayString(const QVariant &v) const
Formats string for display.
Definition: qgsfield.cpp:296
void setPrecision(int precision)
Set the field precision.
Definition: qgsfield.cpp:240
QString displayNameWithAlias() const
Returns the name to use when displaying this field and adds the alias in parenthesis if it is defined...
Definition: qgsfield.cpp:96
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:452
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:216
void setComment(const QString &comment)
Set the field comment.
Definition: qgsfield.cpp:245
QString displayType(bool showConstraints=false) const
Returns the type to use when displaying this field, including the length and precision of the datatyp...
Definition: qgsfield.cpp:105
void setConfigurationFlags(Qgis::FieldConfigurationFlags flags)
Sets the Flags for the field (searchable, …).
Definition: qgsfield.cpp:285
Qgis::FieldDomainSplitPolicy splitPolicy() const
Returns the field's split policy, which indicates how field values should be handled during a split o...
Definition: qgsfield.cpp:729
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:236
QString displayName() const
Returns the name to use when displaying this field.
Definition: qgsfield.cpp:88
void setDefaultValueDefinition(const QgsDefaultValue &defaultValueDefinition)
Sets an expression to use when calculating the default value for the field.
Definition: qgsfield.cpp:255
Q_GADGET bool isNumeric
Definition: qgsfield.h:56
QString friendlyTypeString() const
Returns a user friendly, translated representation of the field type.
Definition: qgsfield.cpp:128
void setReadOnly(bool readOnly)
Make field read-only if readOnly is set to true.
Definition: qgsfield.cpp:719
QMap< int, QVariant > metadata() const
Returns the map of field metadata.
Definition: qgsfield.cpp:175
QVariant::Type type
Definition: qgsfield.h:60
static QString readableConfigurationFlag(Qgis::FieldConfigurationFlag flag)
Returns the readable and translated value of the configuration flag.
Definition: qgsfield.cpp:430
QVariant::Type subType() const
If the field is a collection, gets its element's type.
Definition: qgsfield.cpp:145
Qgis::FieldConfigurationFlags configurationFlags
Definition: qgsfield.h:66
QString alias
Definition: qgsfield.h:63
QgsField(const QString &name=QString(), QVariant::Type type=QVariant::Invalid, const QString &typeName=QString(), int len=0, int prec=0, const QString &comment=QString(), QVariant::Type subType=QVariant::Invalid)
Constructor.
Definition: qgsfield.cpp:47
static constexpr int MAX_WKT_LENGTH
Definition: qgsfield.h:509
QgsDefaultValue defaultValueDefinition
Definition: qgsfield.h:64
void setSubType(QVariant::Type subType)
If the field is a collection, set its element's type.
Definition: qgsfield.cpp:226
void setMetadata(const QMap< int, QVariant > metadata)
Sets the map of field metadata.
Definition: qgsfield.cpp:185
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:221
QString comment
Definition: qgsfield.h:61
virtual ~QgsField()
QgsFieldConstraints constraints
Definition: qgsfield.h:65
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Definition: qgsfield.cpp:714
bool isReadOnly
Definition: qgsfield.h:67
void setTypeName(const QString &typeName)
Set the field type.
Definition: qgsfield.cpp:231
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:162
Q_GADGET bool isNull
Definition: qgsgeometry.h:164
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QString asWkt(int precision=17) const
Exports the geometry to WKT.
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
A QgsGeometry with associated coordinate reference system.
static QString typeToDisplayString(QVariant::Type type, QVariant::Type subType=QVariant::Type::Invalid)
Returns a user-friendly translated string representing a QVariant type.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
qlonglong qgsPermissiveToLongLong(QString string, bool &ok)
Converts a string to an qlonglong in a permissive way, e.g., allowing for incorrect numbers of digits...
Definition: qgis.cpp:86
double qgsPermissiveToDouble(QString string, bool &ok)
Converts a string to a double in a permissive way, e.g., allowing for incorrect numbers of digits bet...
Definition: qgis.cpp:72
int qgsPermissiveToInt(QString string, bool &ok)
Converts a string to an integer in a permissive way, e.g., allowing for incorrect numbers of digits b...
Definition: qgis.cpp:79
QDataStream & operator>>(QDataStream &in, QgsField &field)
Reads a field from stream in into field. QGIS version compatibility is not guaranteed.
Definition: qgsfield.cpp:771
QDataStream & operator<<(QDataStream &out, const QgsField &field)
Writes the field to stream out. QGIS version compatibility is not guaranteed.
Definition: qgsfield.cpp:745
const QString & typeName
int precision