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;
321 if ( v.userType() == qMetaTypeId<QgsReferencedGeometry>() )
328 QString wkt = geom.
asWkt();
329 if ( wkt.length() >= 1050 )
334 return formattedText;
339 if ( d->type == QMetaType::Type::Double )
349 if ( QLocale().decimalPoint() !=
'.' || !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
351 if ( d->precision > 0 )
353 if ( -1 < v.toDouble() && v.toDouble() < 1 )
355 return QLocale().toString( v.toDouble(),
'g', d->precision );
359 return QLocale().toString( v.toDouble(),
'f', d->precision );
366 const QString s( v.toString() );
367 const int dotPosition( s.indexOf(
'.' ) );
369 if ( dotPosition < 0 && s.indexOf(
'e' ) < 0 )
372 return QLocale().toString( v.toDouble(),
'f',
precision );
376 if ( dotPosition < 0 )
379 precision = s.length() - dotPosition - 1;
381 if ( -1 < v.toDouble() && v.toDouble() < 1 )
383 return QLocale().toString( v.toDouble(),
'g',
precision );
387 return QLocale().toString( v.toDouble(),
'f',
precision );
393 else if ( d->precision > 0 )
395 if ( -1 < v.toDouble() && v.toDouble() < 1 )
397 return QString::number( v.toDouble(),
'g', d->precision );
401 return QString::number( v.toDouble(),
'f', d->precision );
406 const double vDouble = v.toDouble();
408 if ( std::fabs( vDouble ) < 1e-04 )
409 return QString::number( vDouble,
'g', QLocale::FloatingPointShortest );
411 return QString::number( vDouble,
'f', QLocale::FloatingPointShortest );
415 else if (
isNumeric() && !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
418 const qlonglong converted( v.toLongLong( &ok ) );
420 return QLocale().toString( converted );
422 else if ( d->typeName.compare(
"json"_L1, Qt::CaseInsensitive ) == 0 || d->typeName ==
"jsonb"_L1 )
424 const QJsonDocument doc = QJsonDocument::fromVariant( v );
425 return QString::fromUtf8( doc.toJson().constData() );
427 else if ( d->type == QMetaType::Type::QByteArray )
429 return QObject::tr(
"BLOB" );
431 else if ( d->type == QMetaType::Type::QStringList || d->type == QMetaType::Type::QVariantList )
434 const QVariantList list = v.toList();
435 for (
const QVariant &var : list )
437 if ( !result.isEmpty() )
438 result.append( u
", "_s );
439 result.append( var.toString() );
453 return QObject::tr(
"None" );
455 return QObject::tr(
"Not searchable" );
457 return QObject::tr(
"Do not expose via WMS" );
459 return QObject::tr(
"Do not expose via WFS" );
472 const QVariant original = v;
474 errorMessage->clear();
478 ( void ) v.convert( d->type );
487 if ( d->type == QMetaType::Type::Int && v.toInt() != v.toLongLong() )
491 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
497 if ( d->type == QMetaType::Type::Double && v.userType() == QMetaType::Type::QString )
500 if ( !tmp.convert( d->type ) )
511 if ( QLocale().decimalPoint() !=
'.' )
513 d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
524 if ( d->type == QMetaType::Type::Int && v.userType() == QMetaType::Type::QString )
527 if ( !tmp.convert( d->type ) )
541 if ( d->type == QMetaType::Type::LongLong && v.userType() == QMetaType::Type::QString )
544 if ( !tmp.convert( d->type ) )
559 if ( d->type == QMetaType::Type::Int && v.canConvert( QMetaType::Type::Double ) )
562 const double dbl = v.toDouble( &ok );
569 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
574 const double round = std::round( dbl );
575 if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
581 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
585 v = QVariant(
static_cast< int >( std::round( dbl ) ) );
591 if ( d->type == QMetaType::Type::LongLong && v.canConvert( QMetaType::Type::Double ) )
595 if ( !tmp.convert( d->type ) )
598 const double dbl = v.toDouble( &ok );
605 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
610 const double round = std::round( dbl );
611 if ( round >
static_cast<double>( std::numeric_limits<long long>::max() ) || round <
static_cast<double>( -std::numeric_limits<long long>::max() ) )
617 *errorMessage = QObject::tr(
"Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
621 v = QVariant(
static_cast< long long >( std::round( dbl ) ) );
626 if ( d->typeName.compare(
"json"_L1, Qt::CaseInsensitive ) == 0 || d->typeName.compare(
"jsonb"_L1, Qt::CaseInsensitive ) == 0 )
628 if ( d->type == QMetaType::Type::QString )
630 const QJsonDocument doc = QJsonDocument::fromVariant( v );
633 v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
639 else if ( d->type == QMetaType::Type::QVariantMap )
641 if ( v.userType() == QMetaType::Type::QStringList || v.userType() == QMetaType::Type::QVariantList || v.userType() == QMetaType::Type::QVariantMap )
650 if ( ( d->type == QMetaType::Type::QStringList || ( d->type == QMetaType::Type::QVariantList && d->subType == QMetaType::Type::QString ) ) && ( v.userType() == QMetaType::Type::QString ) )
652 v = QStringList( { v.toString() } );
656 if ( ( d->type == QMetaType::Type::QStringList || d->type == QMetaType::Type::QVariantList ) && !( v.userType() == QMetaType::Type::QStringList || v.userType() == QMetaType::Type::QVariantList ) )
661 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target list type" ).arg( original.toString() );
667 if ( d->type == QMetaType::Type::QString && v.userType() == qMetaTypeId<QgsReferencedGeometry>() )
676 v = QVariant( geom.
asWkt() );
680 else if ( d->type == QMetaType::Type::User && d->typeName.compare(
"geometry"_L1, Qt::CaseInsensitive ) == 0 )
682 if ( v.userType() == qMetaTypeId<QgsReferencedGeometry>() || v.userType() == qMetaTypeId< QgsGeometry>() )
686 else if ( v.userType() == QMetaType::Type::QString )
691 v = QVariant::fromValue( geom );
697 else if ( !v.convert( d->type ) )
702 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target type \"%2\"" ).arg( original.toString(), d->typeName );
707 if ( d->type == QMetaType::Type::Double && d->precision > 0 )
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 );
715 if ( d->type == QMetaType::Type::QString && d->length > 0 && v.toString().length() > d->length )
717 const int length = v.toString().length();
718 v = v.toString().left( d->length );
721 *errorMessage = QObject::tr(
"String of length %1 exceeds maximum field length (%2)" ).arg(
length ).arg( d->length );
729QgsField::operator QVariant()
const
731 return QVariant::fromValue( *
this );
736 d->editorWidgetSetup = v;
741 return d->editorWidgetSetup;
746 d->isReadOnly = readOnly;
751 return d->isReadOnly;
756 return d->splitPolicy;
761 d->splitPolicy = policy;
766 return d->duplicatePolicy;
771 d->duplicatePolicy = policy;
776 return d->mergePolicy;
781 d->mergePolicy = policy;
793 out << static_cast< quint32 >( field.
type() );
798 out << field.
alias();
810 out << static_cast< quint32 >( field.
subType() );
824 quint32 originNotNull;
825 quint32 originUnique;
826 quint32 originExpression;
827 quint32 strengthNotNull;
828 quint32 strengthUnique;
829 quint32 strengthExpression;
839 QString defaultValueExpression;
840 QString constraintExpression;
841 QString constraintDescription;
842 QMap< int, QVariant > metadata;
852 >> defaultValueExpression
860 >> strengthExpression
861 >> constraintExpression
862 >> constraintDescription
868 field.
setType(
static_cast< QMetaType::Type
>( type ) );
870 field.
setLength(
static_cast< int >( length ) );
901 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.