1#include "moc_qgsfield.cpp"
29#include <QJsonDocument>
40 : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
84 return *( other.d ) == *d;
89 return !( *
this == other );
99 if ( !d->alias.isEmpty() )
107 if (
alias().isEmpty() )
111 return QStringLiteral(
"%1 (%2)" ).arg(
name(),
alias() );
117 if ( typeStr.isEmpty() )
123 typeStr += QStringLiteral(
"(%1, %2)" ).arg(
length() ).arg(
precision() );
125 typeStr += QStringLiteral(
"(%1)" ).arg(
length() );
127 if ( showConstraints )
130 ? QStringLiteral(
" NOT NULL" )
131 : QStringLiteral(
" NULL" );
134 ? QStringLiteral(
" UNIQUE" )
143 if ( d->type == QMetaType::Type::User )
145 if ( d->typeName.compare( QLatin1String(
"geometry" ), Qt::CaseInsensitive ) == 0 )
147 return QObject::tr(
"Geometry" );
185 return d->metadata.value( property );
195 return d->metadata.value(
static_cast< int >( property ) );
205 d->metadata[
static_cast< int >( property )] = value;
210 d->metadata[ property ] = value;
215 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;
220 return d->type == QMetaType::Type::QDate || d->type == QMetaType::Type::QTime || d->type == QMetaType::Type::QDateTime;
275 return d->defaultValueDefinition;
326 if ( v.userType() == qMetaTypeId<QgsReferencedGeometry>() )
333 QString wkt = geom.
asWkt();
334 if ( wkt.length() >= 1050 )
339 return formattedText;
344 if ( d->type == QMetaType::Type::Double )
354 if ( QLocale().decimalPoint() !=
'.' ||
355 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
357 if ( d->precision > 0 )
359 if ( -1 < v.toDouble() && v.toDouble() < 1 )
361 return QLocale().toString( v.toDouble(),
'g', d->precision );
365 return QLocale().toString( v.toDouble(),
'f', d->precision );
372 const QString s( v.toString() );
373 const int dotPosition( s.indexOf(
'.' ) );
375 if ( dotPosition < 0 && s.indexOf(
'e' ) < 0 )
378 return QLocale().toString( v.toDouble(),
'f',
precision );
383 else precision = s.length() - dotPosition - 1;
385 if ( -1 < v.toDouble() && v.toDouble() < 1 )
387 return QLocale().toString( v.toDouble(),
'g',
precision );
391 return QLocale().toString( v.toDouble(),
'f',
precision );
397 else if ( d->precision > 0 )
399 if ( -1 < v.toDouble() && v.toDouble() < 1 )
401 return QString::number( v.toDouble(),
'g', d->precision );
405 return QString::number( v.toDouble(),
'f', d->precision );
410 const double vDouble = v.toDouble();
412 if ( std::fabs( vDouble ) < 1e-04 )
413 return QString::number( vDouble,
'g', QLocale::FloatingPointShortest );
415 return QString::number( vDouble,
'f', QLocale::FloatingPointShortest );
420 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
423 const qlonglong converted( v.toLongLong( &ok ) );
425 return QLocale().toString( converted );
427 else if ( d->typeName.compare( QLatin1String(
"json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String(
"jsonb" ) )
429 const QJsonDocument doc = QJsonDocument::fromVariant( v );
430 return QString::fromUtf8( doc.toJson().constData() );
432 else if ( d->type == QMetaType::Type::QByteArray )
434 return QObject::tr(
"BLOB" );
436 else if ( d->type == QMetaType::Type::QStringList || d->type == QMetaType::Type::QVariantList )
439 const QVariantList list = v.toList();
440 for (
const QVariant &var : list )
442 if ( !result.isEmpty() )
443 result.append( QStringLiteral(
", " ) );
444 result.append( var.toString() );
458 return QObject::tr(
"None" );
460 return QObject::tr(
"Not searchable" );
462 return QObject::tr(
"Do not expose via WMS" );
464 return QObject::tr(
"Do not expose via WFS" );
477 const QVariant original = v;
479 errorMessage->clear();
483 v.convert( d->type );
492 if ( d->type == QMetaType::Type::Int && v.toInt() != v.toLongLong() )
496 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
502 if ( d->type == QMetaType::Type::Double && v.userType() == QMetaType::Type::QString )
505 if ( !tmp.convert( d->type ) )
516 if ( QLocale().decimalPoint() !=
'.' )
518 d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
529 if ( d->type == QMetaType::Type::Int && v.userType() == QMetaType::Type::QString )
532 if ( !tmp.convert( d->type ) )
546 if ( d->type == QMetaType::Type::LongLong && v.userType() == QMetaType::Type::QString )
549 if ( !tmp.convert( d->type ) )
564 if ( d->type == QMetaType::Type::Int && v.canConvert( QMetaType::Type::Double ) )
567 const double dbl = v.toDouble( &ok );
574 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
579 const double round = std::round( dbl );
580 if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
586 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
590 v = QVariant(
static_cast< int >( std::round( dbl ) ) );
596 if ( d->type == QMetaType::Type::LongLong && v.canConvert( QMetaType::Type::Double ) )
600 if ( !tmp.convert( d->type ) )
603 const double dbl = v.toDouble( &ok );
610 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
615 const double round = std::round( dbl );
616 if ( round >
static_cast<double>( std::numeric_limits<long long>::max() ) || round <
static_cast<double>( -std::numeric_limits<long long>::max() ) )
622 *errorMessage = QObject::tr(
"Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
626 v = QVariant(
static_cast< long long >( std::round( dbl ) ) );
631 if ( d->typeName.compare( QLatin1String(
"json" ), Qt::CaseInsensitive ) == 0 || d->typeName.compare( QLatin1String(
"jsonb" ), Qt::CaseInsensitive ) == 0 )
633 if ( d->type == QMetaType::Type::QString )
635 const QJsonDocument doc = QJsonDocument::fromVariant( v );
638 v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
644 else if ( d->type == QMetaType::Type::QVariantMap )
646 if ( v.userType() == QMetaType::Type::QStringList || v.userType() == QMetaType::Type::QVariantList || v.userType() == QMetaType::Type::QVariantMap )
655 if ( ( d->type == QMetaType::Type::QStringList || ( d->type == QMetaType::Type::QVariantList && d->subType == QMetaType::Type::QString ) )
656 && ( v.userType() == QMetaType::Type::QString ) )
658 v = QStringList( { v.toString() } );
662 if ( ( d->type == QMetaType::Type::QStringList || d->type == QMetaType::Type::QVariantList ) && !( v.userType() == QMetaType::Type::QStringList || v.userType() == QMetaType::Type::QVariantList ) )
667 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target list type" ).arg( original.toString() );
673 if ( d->type == QMetaType::Type::QString && v.userType() == qMetaTypeId<QgsReferencedGeometry>() )
682 v = QVariant( geom.
asWkt() );
686 else if ( d->type == QMetaType::Type::User && d->typeName.compare( QLatin1String(
"geometry" ), Qt::CaseInsensitive ) == 0 )
688 if ( v.userType() == qMetaTypeId<QgsReferencedGeometry>() || v.userType() == qMetaTypeId< QgsGeometry>() )
692 else if ( v.userType() == QMetaType::Type::QString )
697 v = QVariant::fromValue( geom );
703 else if ( !v.convert( d->type ) )
708 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target type \"%2\"" )
709 .arg( original.toString(),
715 if ( d->type == QMetaType::Type::Double && d->precision > 0 )
717 const double s = std::pow( 10, d->precision );
718 const double d = v.toDouble() * s;
719 v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
723 if ( d->type == QMetaType::Type::QString && d->length > 0 && v.toString().length() > d->length )
725 const int length = v.toString().length();
726 v = v.toString().left( d->length );
729 *errorMessage = QObject::tr(
"String of length %1 exceeds maximum field length (%2)" ).arg(
length ).arg( d->length );
737QgsField::operator QVariant()
const
739 return QVariant::fromValue( *
this );
744 d->editorWidgetSetup = v;
749 return d->editorWidgetSetup;
754 d->isReadOnly = readOnly;
759 return d->isReadOnly;
764 return d->splitPolicy;
769 d->splitPolicy = policy;
774 return d->duplicatePolicy;
779 d->duplicatePolicy = policy;
784 return d->mergePolicy;
789 d->mergePolicy = policy;
801 out << static_cast< quint32 >( field.
type() );
806 out << field.
alias();
818 out << static_cast< quint32 >( field.
subType() );
832 quint32 originNotNull;
833 quint32 originUnique;
834 quint32 originExpression;
835 quint32 strengthNotNull;
836 quint32 strengthUnique;
837 quint32 strengthExpression;
847 QString defaultValueExpression;
848 QString constraintExpression;
849 QString constraintDescription;
850 QMap< int, QVariant > metadata;
852 in >> name >> type >> typeName >> length >> precision >> comment >> alias
853 >> defaultValueExpression >> applyOnUpdate >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
854 constraintExpression >> constraintDescription >> subType >> splitPolicy >> duplicatePolicy >> metadata;
856 field.
setType(
static_cast< QMetaType::Type
>( type ) );
858 field.
setLength(
static_cast< int >( length ) );
889 field.
setSubType(
static_cast< QMetaType::Type
>( subType ) );
FieldDomainMergePolicy
Merge policy for field domains.
FieldDomainSplitPolicy
Split policy for field domains.
FieldDuplicatePolicy
Duplicate policy for fields.
FieldMetadataProperty
Standard field metadata values.
FieldConfigurationFlag
Configuration flags for fields These flags are meant to be user-configurable and are not describing a...
@ 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...
static QString nullRepresentation()
Returns the string 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.
Provides a container for managing client side default values for fields.
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.
void setSplitPolicy(Qgis::FieldDomainSplitPolicy policy)
Sets the field's split policy, which indicates how field values should be handled during a split oper...
void setEditorWidgetSetup(const QgsEditorWidgetSetup &v)
Set the editor widget setup for the field.
QString typeName() const
Gets the field type.
void setConstraints(const QgsFieldConstraints &constraints)
Sets constraints which are present for the field.
void setAlias(const QString &alias)
Sets the alias for the field (the friendly displayed name of the field ).
bool operator!=(const QgsField &other) const
bool operator==(const QgsField &other) const
QgsField & operator=(const QgsField &other)
QString displayString(const QVariant &v) const
Formats string for display.
void setPrecision(int precision)
Set the field precision.
void setDuplicatePolicy(Qgis::FieldDuplicatePolicy policy)
Sets the field's duplicate policy, which indicates how field values should be handled during a duplic...
QString displayNameWithAlias() const
Returns the name to use when displaying this field and adds the alias in parenthesis if it is defined...
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.
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
void setMergePolicy(Qgis::FieldDomainMergePolicy policy)
Sets the field's merge policy, which indicates how field values should be handled during a merge oper...
void setSubType(QMetaType::Type subType)
If the field is a collection, set its element's type.
void setName(const QString &name)
Set the field name.
void setComment(const QString &comment)
Set the field comment.
void setType(QMetaType::Type type)
Set variant type.
QString displayType(bool showConstraints=false) const
Returns the type to use when displaying this field, including the length and precision of the datatyp...
void setConfigurationFlags(Qgis::FieldConfigurationFlags flags)
Sets the Flags for the field (searchable, …).
Qgis::FieldDomainSplitPolicy splitPolicy() const
Returns the field's split policy, which indicates how field values should be handled during a split o...
void setLength(int len)
Set the field length.
QString displayName() const
Returns the name to use when displaying this field.
void setDefaultValueDefinition(const QgsDefaultValue &defaultValueDefinition)
Sets an expression to use when calculating the default value for the field.
QString friendlyTypeString() const
Returns a user friendly, translated representation of the field type.
void setReadOnly(bool readOnly)
Make field read-only if readOnly is set to true.
QMap< int, QVariant > metadata() const
Returns the map of field metadata.
static QString readableConfigurationFlag(Qgis::FieldConfigurationFlag flag)
Returns the readable and translated value of the configuration flag.
Qgis::FieldConfigurationFlags configurationFlags
QMetaType::Type subType() const
If the field is a collection, gets its element's type.
Qgis::FieldDuplicatePolicy duplicatePolicy() const
Returns the field's duplicate policy, which indicates how field values should be handled during a dup...
static constexpr int MAX_WKT_LENGTH
QgsDefaultValue defaultValueDefinition
Qgis::FieldDomainMergePolicy mergePolicy() const
Returns the field's merge policy, which indicates how field values should be handled during a merge o...
void setMetadata(const QMap< int, QVariant > metadata)
Sets the map of field metadata.
QgsFieldConstraints constraints
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
void setTypeName(const QString &typeName)
Set the field type.
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.
static bool isUnsetAttributeValue(const QVariant &variant)
Check if the variant is a QgsUnsetAttributeValue.
qlonglong qgsPermissiveToLongLong(QString string, bool &ok)
Converts a string to an qlonglong in a permissive way, e.g., allowing for incorrect numbers of digits...
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...
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...
QDataStream & operator>>(QDataStream &in, QgsField &field)
Reads a field from stream in into field. QGIS version compatibility is not guaranteed.
QDataStream & operator<<(QDataStream &out, const QgsField &field)
Writes the field to stream out. QGIS version compatibility is not guaranteed.