QGIS API Documentation 3.39.0-Master (52f98f8c831)
Loading...
Searching...
No Matches
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"
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
35QgsField::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
47QgsField::QgsField( const QString &name, QMetaType::Type type,
48 const QString &typeName, int len, int prec, const QString &comment, QMetaType::Type subType )
49{
50 d = new QgsFieldPrivate( name, type, subType, typeName, len, prec, comment );
51}
52
53QgsField::QgsField( const QString &name, QVariant::Type type,
54 const QString &typeName, int len, int prec, const QString &comment, QVariant::Type subType )
55 : QgsField( name, QgsVariantUtils::variantTypeToMetaType( type ), typeName, len, prec, comment, QgsVariantUtils::variantTypeToMetaType( subType ) )
56{
57}
58
59QgsField::QgsField( const QgsField &other ) //NOLINT
60 : d( other.d )
61{
62
63}
64
65QgsField::~QgsField() = default;
66
67/***************************************************************************
68 * This class is considered CRITICAL and any change MUST be accompanied with
69 * full unit tests in testqgsfield.cpp.
70 * See details in QEP #17
71 ****************************************************************************/
72
73QgsField &QgsField::operator =( const QgsField &other ) //NOLINT
74{
75 d = other.d;
76 return *this;
77}
78
79bool QgsField::operator==( const QgsField &other ) const
80{
81 return *( other.d ) == *d;
82}
83
84bool QgsField::operator!=( const QgsField &other ) const
85{
86 return !( *this == other );
87}
88
89QString QgsField::name() const
90{
91 return d->name;
92}
93
94QString QgsField::displayName() const
95{
96 if ( !d->alias.isEmpty() )
97 return d->alias;
98 else
99 return d->name;
100}
101
103{
104 if ( alias().isEmpty() )
105 {
106 return name();
107 }
108 return QStringLiteral( "%1 (%2)" ).arg( name(), alias() );
109}
110
111QString QgsField::displayType( const bool showConstraints ) const
112{
113 QString typeStr = typeName();
114 if ( typeStr.isEmpty() )
115 {
117 }
118
119 if ( length() > 0 && precision() > 0 )
120 typeStr += QStringLiteral( "(%1, %2)" ).arg( length() ).arg( precision() );
121 else if ( length() > 0 )
122 typeStr += QStringLiteral( "(%1)" ).arg( length() );
123
124 if ( showConstraints )
125 {
127 ? QStringLiteral( " NOT NULL" )
128 : QStringLiteral( " NULL" );
129
131 ? QStringLiteral( " UNIQUE" )
132 : QString();
133 }
134
135 return typeStr;
136}
137
139{
140 if ( d->type == QMetaType::Type::User )
141 {
142 if ( d->typeName.compare( QLatin1String( "geometry" ), Qt::CaseInsensitive ) == 0 )
143 {
144 return QObject::tr( "Geometry" );
145 }
146 }
147 return QgsVariantUtils::typeToDisplayString( d->type, d->subType );
148}
149
150QMetaType::Type QgsField::type() const
151{
152 return d->type;
153}
154
155QMetaType::Type QgsField::subType() const
156{
157 return d->subType;
158}
159
160QString QgsField::typeName() const
161{
162 return d->typeName;
163}
164
166{
167 return d->length;
168}
169
171{
172 return d->precision;
173}
174
175QString QgsField::comment() const
176{
177 return d->comment;
178}
179
180QVariant QgsField::metadata( int property ) const
181{
182 return d->metadata.value( property );
183}
184
185QMap<int, QVariant> QgsField::metadata() const
186{
187 return d->metadata;
188}
189
191{
192 return d->metadata.value( static_cast< int >( property ) );
193}
194
195void QgsField::setMetadata( const QMap<int, QVariant> metadata )
196{
197 d->metadata = metadata;
198}
199
200void QgsField::setMetadata( Qgis::FieldMetadataProperty property, const QVariant &value )
201{
202 d->metadata[ static_cast< int >( property )] = value;
203}
204
205void QgsField::setMetadata( int property, const QVariant &value )
206{
207 d->metadata[ property ] = value;
208}
209
211{
212 return d->type == QMetaType::Type::Double || d->type == QMetaType::Type::Int || d->type == QMetaType::Type::UInt || d->type == QMetaType::Type::LongLong || d->type == QMetaType::Type::ULongLong;
213}
214
216{
217 return d->type == QMetaType::Type::QDate || d->type == QMetaType::Type::QTime || d->type == QMetaType::Type::QDateTime;
218}
219
220/***************************************************************************
221 * This class is considered CRITICAL and any change MUST be accompanied with
222 * full unit tests in testqgsfield.cpp.
223 * See details in QEP #17
224 ****************************************************************************/
225
226void QgsField::setName( const QString &name )
227{
228 d->name = name;
229}
230
231void QgsField::setType( QMetaType::Type type )
232{
233 d->type = type;
234}
235
236void QgsField::setType( QVariant::Type type )
237{
239}
240
241void QgsField::setSubType( QMetaType::Type subType )
242{
243 d->subType = subType;
244}
245
246void QgsField::setSubType( QVariant::Type subType )
247{
249}
250
251void QgsField::setTypeName( const QString &typeName )
252{
253 d->typeName = typeName;
254}
255
256void QgsField::setLength( int len )
257{
258 d->length = len;
259}
261{
262 d->precision = precision;
263}
264
265void QgsField::setComment( const QString &comment )
266{
267 d->comment = comment;
268}
269
271{
272 return d->defaultValueDefinition;
273}
274
275void QgsField::setDefaultValueDefinition( const QgsDefaultValue &defaultValueDefinition )
276{
277 d->defaultValueDefinition = defaultValueDefinition;
278}
279
281{
282 d->constraints = constraints;
283}
284
286{
287 return d->constraints;
288}
289
290QString QgsField::alias() const
291{
292 return d->alias;
293}
294
295void QgsField::setAlias( const QString &alias )
296{
297 d->alias = alias;
298}
299
301{
302 return d->flags;
303}
304
306{
307 d->flags = flags;
308}
309
310/***************************************************************************
311 * This class is considered CRITICAL and any change MUST be accompanied with
312 * full unit tests in testqgsfield.cpp.
313 * See details in QEP #17
314 ****************************************************************************/
315
316QString QgsField::displayString( const QVariant &v ) const
317{
318 if ( QgsVariantUtils::isNull( v ) )
319 {
321 }
322
323 if ( v.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
324 {
325 QgsReferencedGeometry geom = qvariant_cast<QgsReferencedGeometry>( v );
326 if ( geom.isNull() )
328 else
329 {
330 QString wkt = geom.asWkt();
331 if ( wkt.length() >= 1050 )
332 {
333 wkt = wkt.left( MAX_WKT_LENGTH ) + QChar( 0x2026 );
334 }
335 QString formattedText = QStringLiteral( "%1 [%2]" ).arg( wkt, geom.crs().userFriendlyIdentifier() );
336 return formattedText;
337 }
338 }
339
340 // Special treatment for numeric types if group separator is set or decimalPoint is not a dot
341 if ( d->type == QMetaType::Type::Double )
342 {
343 // if value doesn't contain a double (a default value expression for instance),
344 // apply no transformation
345 bool ok;
346 v.toDouble( &ok );
347 if ( !ok )
348 return v.toString();
349
350 // Locales with decimal point != '.' or that require group separator: use QLocale
351 if ( QLocale().decimalPoint() != '.' ||
352 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
353 {
354 if ( d->precision > 0 )
355 {
356 if ( -1 < v.toDouble() && v.toDouble() < 1 )
357 {
358 return QLocale().toString( v.toDouble(), 'g', d->precision );
359 }
360 else
361 {
362 return QLocale().toString( v.toDouble(), 'f', d->precision );
363 }
364 }
365 else
366 {
367 // Precision is not set, let's guess it from the
368 // standard conversion to string
369 const QString s( v.toString() );
370 const int dotPosition( s.indexOf( '.' ) );
371 int precision;
372 if ( dotPosition < 0 && s.indexOf( 'e' ) < 0 )
373 {
374 precision = 0;
375 return QLocale().toString( v.toDouble(), 'f', precision );
376 }
377 else
378 {
379 if ( dotPosition < 0 ) precision = 0;
380 else precision = s.length() - dotPosition - 1;
381
382 if ( -1 < v.toDouble() && v.toDouble() < 1 )
383 {
384 return QLocale().toString( v.toDouble(), 'g', precision );
385 }
386 else
387 {
388 return QLocale().toString( v.toDouble(), 'f', precision );
389 }
390 }
391 }
392 }
393 // Default for doubles with precision
394 else if ( d->precision > 0 )
395 {
396 if ( -1 < v.toDouble() && v.toDouble() < 1 )
397 {
398 return QString::number( v.toDouble(), 'g', d->precision );
399 }
400 else
401 {
402 return QString::number( v.toDouble(), 'f', d->precision );
403 }
404 }
405 else
406 {
407 const double vDouble = v.toDouble();
408 // mimic Qt 5 handling of when to switch to exponential forms
409 if ( std::fabs( vDouble ) < 1e-04 )
410 return QString::number( vDouble, 'g', QLocale::FloatingPointShortest );
411 else
412 return QString::number( vDouble, 'f', QLocale::FloatingPointShortest );
413 }
414 }
415 // Other numeric types than doubles
416 else if ( isNumeric() &&
417 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
418 {
419 bool ok;
420 const qlonglong converted( v.toLongLong( &ok ) );
421 if ( ok )
422 return QLocale().toString( converted );
423 }
424 else if ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String( "jsonb" ) )
425 {
426 const QJsonDocument doc = QJsonDocument::fromVariant( v );
427 return QString::fromUtf8( doc.toJson().constData() );
428 }
429 else if ( d->type == QMetaType::Type::QByteArray )
430 {
431 return QObject::tr( "BLOB" );
432 }
433 else if ( d->type == QMetaType::Type::QStringList || d->type == QMetaType::Type::QVariantList )
434 {
435 QString result;
436 const QVariantList list = v.toList();
437 for ( const QVariant &var : list )
438 {
439 if ( !result.isEmpty() )
440 result.append( QStringLiteral( ", " ) );
441 result.append( var.toString() );
442 }
443 return result;
444 }
445
446 // Fallback if special rules do not apply
447 return v.toString();
448}
449
451{
452 switch ( flag )
453 {
455 return QObject::tr( "None" );
457 return QObject::tr( "Not searchable" );
459 return QObject::tr( "Do not expose via WMS" );
461 return QObject::tr( "Do not expose via WFS" );
462 }
463 return QString();
464}
465
466/***************************************************************************
467 * This class is considered CRITICAL and any change MUST be accompanied with
468 * full unit tests in testqgsfield.cpp.
469 * See details in QEP #17
470 ****************************************************************************/
471
472bool QgsField::convertCompatible( QVariant &v, QString *errorMessage ) const
473{
474 const QVariant original = v;
475 if ( errorMessage )
476 errorMessage->clear();
477
478 if ( QgsVariantUtils::isNull( v ) )
479 {
480 v.convert( d->type );
481 return true;
482 }
483
484 if ( d->type == QMetaType::Type::Int && v.toInt() != v.toLongLong() )
485 {
487 if ( errorMessage )
488 *errorMessage = QObject::tr( "Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
489 return false;
490 }
491
492 // Give it a chance to convert to double since for not '.' locales
493 // we accept both comma and dot as decimal point
494 if ( d->type == QMetaType::Type::Double && v.userType() == QMetaType::Type::QString )
495 {
496 QVariant tmp( v );
497 if ( !tmp.convert( d->type ) )
498 {
499 // This might be a string with thousand separator: use locale to convert
500 bool ok = false;
501 double d = qgsPermissiveToDouble( v.toString(), ok );
502 if ( ok )
503 {
504 v = QVariant( d );
505 return true;
506 }
507 // For not 'dot' locales, we also want to accept '.'
508 if ( QLocale().decimalPoint() != '.' )
509 {
510 d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
511 if ( ok )
512 {
513 v = QVariant( d );
514 return true;
515 }
516 }
517 }
518 }
519
520 // For string representation of an int we also might have thousand separator
521 if ( d->type == QMetaType::Type::Int && v.userType() == QMetaType::Type::QString )
522 {
523 QVariant tmp( v );
524 if ( !tmp.convert( d->type ) )
525 {
526 // This might be a string with thousand separator: use locale to convert
527 bool ok;
528 const int i = qgsPermissiveToInt( v.toString(), ok );
529 if ( ok )
530 {
531 v = QVariant( i );
532 return true;
533 }
534 }
535 }
536
537 // For string representation of a long we also might have thousand separator
538 if ( d->type == QMetaType::Type::LongLong && v.userType() == QMetaType::Type::QString )
539 {
540 QVariant tmp( v );
541 if ( !tmp.convert( d->type ) )
542 {
543 // This might be a string with thousand separator: use locale to convert
544 bool ok;
545 const qlonglong l = qgsPermissiveToLongLong( v.toString(), ok );
546 if ( ok )
547 {
548 v = QVariant( l );
549 return true;
550 }
551 }
552 }
553
554 //String representations of doubles in QVariant will return false to convert( QVariant::Int )
555 //work around this by first converting to double, and then checking whether the double is convertible to int
556 if ( d->type == QMetaType::Type::Int && v.canConvert( QMetaType::Type::Double ) )
557 {
558 bool ok = false;
559 const double dbl = v.toDouble( &ok );
560 if ( !ok )
561 {
562 //couldn't convert to number
564
565 if ( errorMessage )
566 *errorMessage = QObject::tr( "Value \"%1\" is not a number" ).arg( original.toString() );
567
568 return false;
569 }
570
571 const double round = std::round( dbl );
572 if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
573 {
574 //double too large to fit in int
576
577 if ( errorMessage )
578 *errorMessage = QObject::tr( "Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
579
580 return false;
581 }
582 v = QVariant( static_cast< int >( std::round( dbl ) ) );
583 return true;
584 }
585
586 //String representations of doubles in QVariant will return false to convert( QVariant::LongLong )
587 //work around this by first converting to double, and then checking whether the double is convertible to longlong
588 if ( d->type == QMetaType::Type::LongLong && v.canConvert( QMetaType::Type::Double ) )
589 {
590 //firstly test the conversion to longlong because conversion to double will rounded the value
591 QVariant tmp( v );
592 if ( !tmp.convert( d->type ) )
593 {
594 bool ok = false;
595 const double dbl = v.toDouble( &ok );
596 if ( !ok )
597 {
598 //couldn't convert to number
600
601 if ( errorMessage )
602 *errorMessage = QObject::tr( "Value \"%1\" is not a number" ).arg( original.toString() );
603
604 return false;
605 }
606
607 const double round = std::round( dbl );
608 if ( round > static_cast<double>( std::numeric_limits<long long>::max() ) || round < static_cast<double>( -std::numeric_limits<long long>::max() ) )
609 {
610 //double too large to fit in longlong
612
613 if ( errorMessage )
614 *errorMessage = QObject::tr( "Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
615
616 return false;
617 }
618 v = QVariant( static_cast< long long >( std::round( dbl ) ) );
619 return true;
620 }
621 }
622
623 if ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName.compare( QLatin1String( "jsonb" ), Qt::CaseInsensitive ) == 0 )
624 {
625 if ( d->type == QMetaType::Type::QString )
626 {
627 const QJsonDocument doc = QJsonDocument::fromVariant( v );
628 if ( !doc.isNull() )
629 {
630 v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
631 return true;
632 }
634 return false;
635 }
636 else if ( d->type == QMetaType::Type::QVariantMap )
637 {
638 if ( v.userType() == QMetaType::Type::QStringList || v.userType() == QMetaType::Type::QVariantList || v.userType() == QMetaType::Type::QVariantMap )
639 {
640 return true;
641 }
643 return false;
644 }
645 }
646
647 if ( ( d->type == QMetaType::Type::QStringList || ( d->type == QMetaType::Type::QVariantList && d->subType == QMetaType::Type::QString ) )
648 && ( v.userType() == QMetaType::Type::QString ) )
649 {
650 v = QStringList( { v.toString() } );
651 return true;
652 }
653
654 if ( ( d->type == QMetaType::Type::QStringList || d->type == QMetaType::Type::QVariantList ) && !( v.userType() == QMetaType::Type::QStringList || v.userType() == QMetaType::Type::QVariantList ) )
655 {
657
658 if ( errorMessage )
659 *errorMessage = QObject::tr( "Could not convert value \"%1\" to target list type" ).arg( original.toString() );
660
661 return false;
662 }
663
664 // Handle referenced geometries (e.g. from additional geometry fields)
665 if ( d->type == QMetaType::Type::QString && v.userType() == QMetaType::type( "QgsReferencedGeometry" ) )
666 {
667 const QgsReferencedGeometry geom { v.value<QgsReferencedGeometry>( ) };
668 if ( geom.isNull() )
669 {
671 }
672 else
673 {
674 v = QVariant( geom.asWkt() );
675 }
676 return true;
677 }
678 else if ( d->type == QMetaType::Type::User && d->typeName.compare( QLatin1String( "geometry" ), Qt::CaseInsensitive ) == 0 )
679 {
680 if ( v.userType() == QMetaType::type( "QgsReferencedGeometry" ) || v.userType() == QMetaType::type( "QgsGeometry" ) )
681 {
682 return true;
683 }
684 else if ( v.userType() == QMetaType::Type::QString )
685 {
686 const QgsGeometry geom = QgsGeometry::fromWkt( v.toString() );
687 if ( !geom.isNull() )
688 {
689 v = QVariant::fromValue( geom );
690 return true;
691 }
692 }
693 return false;
694 }
695 else if ( !v.convert( d->type ) )
696 {
698
699 if ( errorMessage )
700 *errorMessage = QObject::tr( "Could not convert value \"%1\" to target type \"%2\"" )
701 .arg( original.toString(),
702 d->typeName );
703
704 return false;
705 }
706
707 if ( d->type == QMetaType::Type::Double && d->precision > 0 )
708 {
709 const double s = std::pow( 10, d->precision );
710 const double d = v.toDouble() * s;
711 v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
712 return true;
713 }
714
715 if ( d->type == QMetaType::Type::QString && d->length > 0 && v.toString().length() > d->length )
716 {
717 const int length = v.toString().length();
718 v = v.toString().left( d->length );
719
720 if ( errorMessage )
721 *errorMessage = QObject::tr( "String of length %1 exceeds maximum field length (%2)" ).arg( length ).arg( d->length );
722
723 return false;
724 }
725
726 return true;
727}
728
729QgsField::operator QVariant() const
730{
731 return QVariant::fromValue( *this );
732}
733
735{
736 d->editorWidgetSetup = v;
737}
738
740{
741 return d->editorWidgetSetup;
742}
743
744void QgsField::setReadOnly( bool readOnly )
745{
746 d->isReadOnly = readOnly;
747}
748
750{
751 return d->isReadOnly;
752}
753
755{
756 return d->splitPolicy;
757}
758
760{
761 d->splitPolicy = policy;
762}
763
765{
766 return d->duplicatePolicy;
767}
768
770{
771 d->duplicatePolicy = policy;
772}
773
774/***************************************************************************
775 * This class is considered CRITICAL and any change MUST be accompanied with
776 * full unit tests in testqgsfield.cpp.
777 * See details in QEP #17
778 ****************************************************************************/
779
780QDataStream &operator<<( QDataStream &out, const QgsField &field )
781{
782 out << field.name();
783 out << static_cast< quint32 >( field.type() );
784 out << field.typeName();
785 out << field.length();
786 out << field.precision();
787 out << field.comment();
788 out << field.alias();
789 out << field.defaultValueDefinition().expression();
790 out << field.defaultValueDefinition().applyOnUpdate();
791 out << field.constraints().constraints();
792 out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintNotNull ) );
793 out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintUnique ) );
794 out << static_cast< quint32 >( field.constraints().constraintOrigin( QgsFieldConstraints::ConstraintExpression ) );
795 out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintNotNull ) );
796 out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintUnique ) );
797 out << static_cast< quint32 >( field.constraints().constraintStrength( QgsFieldConstraints::ConstraintExpression ) );
798 out << field.constraints().constraintExpression();
799 out << field.constraints().constraintDescription();
800 out << static_cast< quint32 >( field.subType() );
801 out << static_cast< int >( field.splitPolicy() );
802 out << static_cast< int >( field.duplicatePolicy() );
803 out << field.metadata();
804 return out;
805}
806
807QDataStream &operator>>( QDataStream &in, QgsField &field )
808{
809 quint32 type;
810 quint32 subType;
811 quint32 length;
812 quint32 precision;
813 quint32 constraints;
814 quint32 originNotNull;
815 quint32 originUnique;
816 quint32 originExpression;
817 quint32 strengthNotNull;
818 quint32 strengthUnique;
819 quint32 strengthExpression;
820 int splitPolicy;
821 int duplicatePolicy;
822
823 bool applyOnUpdate;
824
825 QString name;
826 QString typeName;
827 QString comment;
828 QString alias;
829 QString defaultValueExpression;
830 QString constraintExpression;
831 QString constraintDescription;
832 QMap< int, QVariant > metadata;
833
834 in >> name >> type >> typeName >> length >> precision >> comment >> alias
835 >> defaultValueExpression >> applyOnUpdate >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
836 constraintExpression >> constraintDescription >> subType >> splitPolicy >> duplicatePolicy >> metadata;
837 field.setName( name );
838 field.setType( static_cast< QMetaType::Type >( type ) );
839 field.setTypeName( typeName );
840 field.setLength( static_cast< int >( length ) );
841 field.setPrecision( static_cast< int >( precision ) );
842 field.setComment( comment );
843 field.setAlias( alias );
844 field.setDefaultValueDefinition( QgsDefaultValue( defaultValueExpression, applyOnUpdate ) );
845 field.setSplitPolicy( static_cast< Qgis::FieldDomainSplitPolicy >( splitPolicy ) );
846 field.setDuplicatePolicy( static_cast< Qgis::FieldDuplicatePolicy >( duplicatePolicy ) );
847 QgsFieldConstraints fieldConstraints;
848 if ( constraints & QgsFieldConstraints::ConstraintNotNull )
849 {
850 fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintNotNull, static_cast< QgsFieldConstraints::ConstraintOrigin>( originNotNull ) );
852 }
853 else
855 if ( constraints & QgsFieldConstraints::ConstraintUnique )
856 {
857 fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintUnique, static_cast< QgsFieldConstraints::ConstraintOrigin>( originUnique ) );
859 }
860 else
863 {
864 fieldConstraints.setConstraint( QgsFieldConstraints::ConstraintExpression, static_cast< QgsFieldConstraints::ConstraintOrigin>( originExpression ) );
866 }
867 else
869 fieldConstraints.setConstraintExpression( constraintExpression, constraintDescription );
870 field.setConstraints( fieldConstraints );
871 field.setSubType( static_cast< QMetaType::Type >( subType ) );
872 field.setMetadata( metadata );
873 return in;
874}
FieldDomainSplitPolicy
Split policy for field domains.
Definition qgis.h:3337
FieldDuplicatePolicy
Duplicate policy for fields.
Definition qgis.h:3369
FieldMetadataProperty
Standard field metadata values.
Definition qgis.h:1415
FieldConfigurationFlag
Configuration flags for fields These flags are meant to be user-configurable and are not describing a...
Definition qgis.h:1391
@ 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:1406
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.
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.
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:759
QMetaType::Type type
Definition qgsfield.h:60
bool isDateOrTime
Definition qgsfield.h:57
void setEditorWidgetSetup(const QgsEditorWidgetSetup &v)
Set the editor widget setup for the field.
Definition qgsfield.cpp:734
QString typeName() const
Gets the field type.
Definition qgsfield.cpp:160
void setConstraints(const QgsFieldConstraints &constraints)
Sets constraints which are present for the field.
Definition qgsfield.cpp:280
void setAlias(const QString &alias)
Sets the alias for the field (the friendly displayed name of the field ).
Definition qgsfield.cpp:295
QString name
Definition qgsfield.h:62
bool operator!=(const QgsField &other) const
Definition qgsfield.cpp:84
bool operator==(const QgsField &other) const
Definition qgsfield.cpp:79
int precision
Definition qgsfield.h:59
int length
Definition qgsfield.h:58
QgsField & operator=(const QgsField &other)
Assignment operator.
Definition qgsfield.cpp:73
QString displayString(const QVariant &v) const
Formats string for display.
Definition qgsfield.cpp:316
void setPrecision(int precision)
Set the field precision.
Definition qgsfield.cpp:260
void setDuplicatePolicy(Qgis::FieldDuplicatePolicy policy)
Sets the field's duplicate policy, which indicates how field values should be handled during a duplic...
Definition qgsfield.cpp:769
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:102
QgsField(const QString &name=QString(), QMetaType::Type type=QMetaType::Type::UnknownType, const QString &typeName=QString(), int len=0, int prec=0, const QString &comment=QString(), QMetaType::Type subType=QMetaType::Type::UnknownType)
Constructor.
Definition qgsfield.cpp:47
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
Definition qgsfield.cpp:472
void setSubType(QMetaType::Type subType)
If the field is a collection, set its element's type.
Definition qgsfield.cpp:241
void setName(const QString &name)
Set the field name.
Definition qgsfield.cpp:226
void setComment(const QString &comment)
Set the field comment.
Definition qgsfield.cpp:265
void setType(QMetaType::Type type)
Set variant type.
Definition qgsfield.cpp:231
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:111
void setConfigurationFlags(Qgis::FieldConfigurationFlags flags)
Sets the Flags for the field (searchable, …).
Definition qgsfield.cpp:305
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:754
void setLength(int len)
Set the field length.
Definition qgsfield.cpp:256
QString displayName() const
Returns the name to use when displaying this field.
Definition qgsfield.cpp:94
void setDefaultValueDefinition(const QgsDefaultValue &defaultValueDefinition)
Sets an expression to use when calculating the default value for the field.
Definition qgsfield.cpp:275
QString friendlyTypeString() const
Returns a user friendly, translated representation of the field type.
Definition qgsfield.cpp:138
void setReadOnly(bool readOnly)
Make field read-only if readOnly is set to true.
Definition qgsfield.cpp:744
QMap< int, QVariant > metadata() const
Returns the map of field metadata.
Definition qgsfield.cpp:185
static QString readableConfigurationFlag(Qgis::FieldConfigurationFlag flag)
Returns the readable and translated value of the configuration flag.
Definition qgsfield.cpp:450
Qgis::FieldConfigurationFlags configurationFlags
Definition qgsfield.h:66
QMetaType::Type subType() const
If the field is a collection, gets its element's type.
Definition qgsfield.cpp:155
QString alias
Definition qgsfield.h:63
Qgis::FieldDuplicatePolicy duplicatePolicy() const
Returns the field's duplicate policy, which indicates how field values should be handled during a dup...
Definition qgsfield.cpp:764
static constexpr int MAX_WKT_LENGTH
Definition qgsfield.h:564
QgsDefaultValue defaultValueDefinition
Definition qgsfield.h:64
bool isNumeric
Definition qgsfield.h:56
void setMetadata(const QMap< int, QVariant > metadata)
Sets the map of field metadata.
Definition qgsfield.cpp:195
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:739
bool isReadOnly
Definition qgsfield.h:67
void setTypeName(const QString &typeName)
Set the field type.
Definition qgsfield.cpp:251
A geometry is the spatial representation of a feature.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
Q_INVOKABLE 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.
Contains utility functions for working with QVariants and QVariant types.
static QMetaType::Type variantTypeToMetaType(QVariant::Type variantType)
Converts a QVariant::Type to a QMetaType::Type.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QString typeToDisplayString(QMetaType::Type type, QMetaType::Type subType=QMetaType::Type::UnknownType)
Returns a user-friendly translated string representing a QVariant type.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
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:807
QDataStream & operator<<(QDataStream &out, const QgsField &field)
Writes the field to stream out. QGIS version compatibility is not guaranteed.
Definition qgsfield.cpp:780
const QString & typeName
int precision