3#include "moc_qgsfield.cpp"
5using namespace Qt::StringLiterals;
33#include <QJsonDocument>
44 : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
83 return *( other.d ) == *d;
88 return !( *
this == other );
98 if ( !d->alias.isEmpty() )
106 if (
alias().isEmpty() )
110 return u
"%1 (%2)"_s.arg(
name(),
alias() );
116 if ( typeStr.isEmpty() )
124 typeStr += u
"(%1)"_s.arg(
length() );
126 if ( showConstraints )
138 if ( d->type == QMetaType::Type::User )
140 if ( d->typeName.compare(
"geometry"_L1, Qt::CaseInsensitive ) == 0 )
142 return QObject::tr(
"Geometry" );
180 return d->metadata.value( property );
190 return d->metadata.value(
static_cast< int >( property ) );
200 d->metadata[
static_cast< int >( property )] = value;
205 d->metadata[property] = value;
210 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;
215 return d->type == QMetaType::Type::QDate || d->type == QMetaType::Type::QTime || d->type == QMetaType::Type::QDateTime;
270 return d->defaultValueDefinition;
300 return d->customComment;
331 if ( v.userType() == qMetaTypeId<QgsReferencedGeometry>() )
338 QString wkt = geom.
asWkt();
339 if ( wkt.length() >= 1050 )
344 return formattedText;
349 if ( d->type == QMetaType::Type::Double )
359 if ( QLocale().decimalPoint() !=
'.' || !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
361 if ( d->precision > 0 )
363 if ( -1 < v.toDouble() && v.toDouble() < 1 )
365 return QLocale().toString( v.toDouble(),
'g', d->precision );
369 return QLocale().toString( v.toDouble(),
'f', d->precision );
376 const QString s( v.toString() );
377 const int dotPosition( s.indexOf(
'.' ) );
379 if ( dotPosition < 0 && s.indexOf(
'e' ) < 0 )
382 return QLocale().toString( v.toDouble(),
'f',
precision );
386 if ( dotPosition < 0 )
389 precision = s.length() - dotPosition - 1;
391 if ( -1 < v.toDouble() && v.toDouble() < 1 )
393 return QLocale().toString( v.toDouble(),
'g',
precision );
397 return QLocale().toString( v.toDouble(),
'f',
precision );
403 else if ( d->precision > 0 )
405 if ( -1 < v.toDouble() && v.toDouble() < 1 )
407 return QString::number( v.toDouble(),
'g', d->precision );
411 return QString::number( v.toDouble(),
'f', d->precision );
416 const double vDouble = v.toDouble();
418 if ( std::fabs( vDouble ) < 1e-04 )
419 return QString::number( vDouble,
'g', QLocale::FloatingPointShortest );
421 return QString::number( vDouble,
'f', QLocale::FloatingPointShortest );
425 else if (
isNumeric() && !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
428 const qlonglong converted( v.toLongLong( &ok ) );
430 return QLocale().toString( converted );
432 else if ( d->typeName.compare(
"json"_L1, Qt::CaseInsensitive ) == 0 || d->typeName ==
"jsonb"_L1 )
434 const QJsonDocument doc = QJsonDocument::fromVariant( v );
435 return QString::fromUtf8( doc.toJson().constData() );
437 else if ( d->type == QMetaType::Type::QByteArray )
439 return QObject::tr(
"BLOB" );
441 else if ( d->type == QMetaType::Type::QStringList || d->type == QMetaType::Type::QVariantList )
444 const QVariantList list = v.toList();
445 for (
const QVariant &var : list )
447 if ( !result.isEmpty() )
448 result.append( u
", "_s );
449 result.append( var.toString() );
463 return QObject::tr(
"None" );
465 return QObject::tr(
"Not searchable" );
467 return QObject::tr(
"Do not expose via WMS" );
469 return QObject::tr(
"Do not expose via WFS" );
482 const QVariant original = v;
484 errorMessage->clear();
488 ( void ) v.convert( d->type );
497 if ( d->type == QMetaType::Type::Int && v.toInt() != v.toLongLong() )
501 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
507 if ( d->type == QMetaType::Type::Double && v.userType() == QMetaType::Type::QString )
510 if ( !tmp.convert( d->type ) )
521 if ( QLocale().decimalPoint() !=
'.' )
523 d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
534 if ( d->type == QMetaType::Type::Int && v.userType() == QMetaType::Type::QString )
537 if ( !tmp.convert( d->type ) )
551 if ( d->type == QMetaType::Type::LongLong && v.userType() == QMetaType::Type::QString )
554 if ( !tmp.convert( d->type ) )
569 if ( d->type == QMetaType::Type::Int && v.canConvert( QMetaType::Type::Double ) )
572 const double dbl = v.toDouble( &ok );
579 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
584 const double round = std::round( dbl );
585 if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
591 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
595 v = QVariant(
static_cast< int >( std::round( dbl ) ) );
601 if ( d->type == QMetaType::Type::LongLong && v.canConvert( QMetaType::Type::Double ) )
605 if ( !tmp.convert( d->type ) )
608 const double dbl = v.toDouble( &ok );
615 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
620 const double round = std::round( dbl );
621 if ( round >
static_cast<double>( std::numeric_limits<long long>::max() ) || round <
static_cast<double>( -std::numeric_limits<long long>::max() ) )
627 *errorMessage = QObject::tr(
"Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
631 v = QVariant(
static_cast< long long >( std::round( dbl ) ) );
636 if ( d->typeName.compare(
"json"_L1, Qt::CaseInsensitive ) == 0 || d->typeName.compare(
"jsonb"_L1, Qt::CaseInsensitive ) == 0 )
638 if ( d->type == QMetaType::Type::QString )
640 const QJsonDocument doc = QJsonDocument::fromVariant( v );
643 v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
649 else if ( d->type == QMetaType::Type::QVariantMap )
651 if ( v.userType() == QMetaType::Type::QStringList || v.userType() == QMetaType::Type::QVariantList || v.userType() == QMetaType::Type::QVariantMap )
660 if ( ( d->type == QMetaType::Type::QStringList || ( d->type == QMetaType::Type::QVariantList && d->subType == QMetaType::Type::QString ) ) && ( v.userType() == QMetaType::Type::QString ) )
662 v = QStringList( { v.toString() } );
666 if ( ( d->type == QMetaType::Type::QStringList || d->type == QMetaType::Type::QVariantList ) && !( v.userType() == QMetaType::Type::QStringList || v.userType() == QMetaType::Type::QVariantList ) )
671 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target list type" ).arg( original.toString() );
677 if ( d->type == QMetaType::Type::QString && v.userType() == qMetaTypeId<QgsReferencedGeometry>() )
686 v = QVariant( geom.
asWkt() );
690 else if ( d->type == QMetaType::Type::User && d->typeName.compare(
"geometry"_L1, Qt::CaseInsensitive ) == 0 )
692 if ( v.userType() == qMetaTypeId<QgsReferencedGeometry>() || v.userType() == qMetaTypeId< QgsGeometry>() )
696 else if ( v.userType() == QMetaType::Type::QString )
701 v = QVariant::fromValue( geom );
707 else if ( !v.convert( d->type ) )
712 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target type \"%2\"" ).arg( original.toString(), d->typeName );
717 if ( d->type == QMetaType::Type::Double && d->precision > 0 )
719 const double s = std::pow( 10, d->precision );
720 const double d = v.toDouble() * s;
721 v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
725 if ( d->type == QMetaType::Type::QString && d->length > 0 && v.toString().length() > d->length )
727 const int length = v.toString().length();
728 v = v.toString().left( d->length );
731 *errorMessage = QObject::tr(
"String of length %1 exceeds maximum field length (%2)" ).arg(
length ).arg( d->length );
739QgsField::operator QVariant()
const
741 return QVariant::fromValue( *
this );
746 d->editorWidgetSetup = v;
751 return d->editorWidgetSetup;
756 d->isReadOnly = readOnly;
761 return d->isReadOnly;
766 return d->splitPolicy;
771 d->splitPolicy = policy;
776 return d->duplicatePolicy;
781 d->duplicatePolicy = policy;
786 return d->mergePolicy;
791 d->mergePolicy = policy;
803 out << static_cast< quint32 >( field.
type() );
808 out << field.
alias();
820 out << static_cast< quint32 >( field.
subType() );
834 quint32 originNotNull;
835 quint32 originUnique;
836 quint32 originExpression;
837 quint32 strengthNotNull;
838 quint32 strengthUnique;
839 quint32 strengthExpression;
849 QString defaultValueExpression;
850 QString constraintExpression;
851 QString constraintDescription;
852 QMap< int, QVariant > metadata;
862 >> defaultValueExpression
870 >> strengthExpression
871 >> constraintExpression
872 >> constraintDescription
878 field.
setType(
static_cast< QMetaType::Type
>( type ) );
880 field.
setLength(
static_cast< int >( length ) );
911 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.
void setCustomComment(const QString &customComment)
Sets the custom comment for the field.
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.