26#include <QJsonDocument>
37 : mName( nam ), mType( typ ), mLength( len ), mPrecision( prec ), mNumeric( num )
48 const QString &
typeName,
int len,
int prec,
const QString &comment, QVariant::Type subType )
75 return *( other.d ) == *d;
80 return !( *
this == other );
90 if ( !d->alias.isEmpty() )
98 if (
alias().isEmpty() )
102 return QStringLiteral(
"%1 (%2)" ).arg(
name(),
alias() );
110 typeStr += QStringLiteral(
"(%1, %2)" ).arg(
length() ).arg(
precision() );
112 typeStr += QStringLiteral(
"(%1)" ).arg(
length() );
114 if ( showConstraints )
117 ? QStringLiteral(
" NOT NULL" )
118 : QStringLiteral(
" NULL" );
121 ? QStringLiteral(
" UNIQUE" )
130 if ( d->type == QVariant::UserType )
132 if ( d->typeName.compare( QLatin1String(
"geometry" ), Qt::CaseInsensitive ) == 0 )
134 return QObject::tr(
"Geometry" );
172 return d->type == QVariant::Double || d->type == QVariant::Int || d->type == QVariant::UInt || d->type == QVariant::LongLong || d->type == QVariant::ULongLong;
177 return d->type == QVariant::Date || d->type == QVariant::Time || d->type == QVariant::DateTime;
222 return d->defaultValueDefinition;
237 return d->constraints;
273 if ( v.userType() == QMetaType::type(
"QgsReferencedGeometry" ) )
280 QString wkt = geom.
asWkt();
281 if ( wkt.length() >= 1050 )
286 return formattedText;
291 if ( d->type == QVariant::Double )
301 if ( QLocale().decimalPoint() !=
'.' ||
302 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
304 if ( d->precision > 0 )
306 if ( -1 < v.toDouble() && v.toDouble() < 1 )
308 return QLocale().toString( v.toDouble(),
'g', d->precision );
312 return QLocale().toString( v.toDouble(),
'f', d->precision );
319 const QString s( v.toString() );
320 const int dotPosition( s.indexOf(
'.' ) );
322 if ( dotPosition < 0 && s.indexOf(
'e' ) < 0 )
325 return QLocale().toString( v.toDouble(),
'f',
precision );
330 else precision = s.length() - dotPosition - 1;
332 if ( -1 < v.toDouble() && v.toDouble() < 1 )
334 return QLocale().toString( v.toDouble(),
'g',
precision );
338 return QLocale().toString( v.toDouble(),
'f',
precision );
344 else if ( d->precision > 0 )
346 if ( -1 < v.toDouble() && v.toDouble() < 1 )
348 return QString::number( v.toDouble(),
'g', d->precision );
352 return QString::number( v.toDouble(),
'f', d->precision );
357 const double vDouble = v.toDouble();
359 if ( std::fabs( vDouble ) < 1e-04 )
360 return QString::number( vDouble,
'g', QLocale::FloatingPointShortest );
362 return QString::number( vDouble,
'f', QLocale::FloatingPointShortest );
367 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
370 const qlonglong converted( v.toLongLong( &ok ) );
372 return QLocale().toString( converted );
374 else if ( d->typeName.compare( QLatin1String(
"json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String(
"jsonb" ) )
376 const QJsonDocument doc = QJsonDocument::fromVariant( v );
377 return QString::fromUtf8( doc.toJson().data() );
379 else if ( d->type == QVariant::ByteArray )
381 return QObject::tr(
"BLOB" );
383 else if ( d->type == QVariant::StringList || d->type == QVariant::List )
386 const QVariantList list = v.toList();
387 for (
const QVariant &var : list )
389 if ( !result.isEmpty() )
390 result.append( QStringLiteral(
", " ) );
391 result.append( var.toString() );
405 return QObject::tr(
"None" );
407 return QObject::tr(
"Not searchable" );
409 return QObject::tr(
"Do not expose via WMS" );
411 return QObject::tr(
"Do not expose via WFS" );
424 const QVariant original = v;
426 errorMessage->clear();
430 v.convert( d->type );
434 if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
436 v = QVariant( d->type );
438 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
444 if ( d->type == QVariant::Double && v.type() == QVariant::String )
447 if ( !tmp.convert( d->type ) )
458 if ( QLocale().decimalPoint() !=
'.' )
460 d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
471 if ( d->type == QVariant::Int && v.type() == QVariant::String )
474 if ( !tmp.convert( d->type ) )
488 if ( d->type == QVariant::LongLong && v.type() == QVariant::String )
491 if ( !tmp.convert( d->type ) )
506 if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
509 const double dbl = v.toDouble( &ok );
513 v = QVariant( d->type );
516 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
521 const double round = std::round( dbl );
522 if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
525 v = QVariant( d->type );
528 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
532 v = QVariant(
static_cast< int >( std::round( dbl ) ) );
538 if ( d->type == QVariant::LongLong && v.canConvert( QVariant::Double ) )
542 if ( !tmp.convert( d->type ) )
545 const double dbl = v.toDouble( &ok );
549 v = QVariant( d->type );
552 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
557 const double round = std::round( dbl );
558 if ( round >
static_cast<double>( std::numeric_limits<long long>::max() ) || round <
static_cast<double>( -std::numeric_limits<long long>::max() ) )
561 v = QVariant( d->type );
564 *errorMessage = QObject::tr(
"Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
568 v = QVariant(
static_cast< long long >( std::round( dbl ) ) );
573 if ( d->type == QVariant::String && ( d->typeName.compare( QLatin1String(
"json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String(
"jsonb" ) ) )
575 const QJsonDocument doc = QJsonDocument::fromVariant( v );
578 v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
581 v = QVariant( d->type );
585 if ( ( d->type == QVariant::StringList || ( d->type == QVariant::List && d->subType == QVariant::String ) )
586 && ( v.type() == QVariant::String ) )
588 v = QStringList( { v.toString() } );
592 if ( ( d->type == QVariant::StringList || d->type == QVariant::List ) && !( v.type() == QVariant::StringList || v.type() == QVariant::List ) )
594 v = QVariant( d->type );
597 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target list type" ).arg( original.toString() );
603 if ( d->type == QVariant::String && v.userType() == QMetaType::type(
"QgsReferencedGeometry" ) )
608 v = QVariant( d->type );
612 v = QVariant( geom.asWkt() );
616 else if ( d->type == QVariant::UserType && d->typeName.compare( QLatin1String(
"geometry" ), Qt::CaseInsensitive ) == 0 )
618 if ( v.userType() == QMetaType::type(
"QgsReferencedGeometry" ) || v.userType() == QMetaType::type(
"QgsGeometry" ) )
622 else if ( v.type() == QVariant::String )
627 v = QVariant::fromValue( geom );
633 else if ( !v.convert( d->type ) )
635 v = QVariant( d->type );
638 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target type \"%2\"" )
639 .arg( original.toString(),
645 if ( d->type == QVariant::Double && d->precision > 0 )
647 const double s = std::pow( 10, d->precision );
648 const double d = v.toDouble() * s;
649 v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
653 if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
655 const int length = v.toString().length();
656 v = v.toString().left( d->length );
659 *errorMessage = QObject::tr(
"String of length %1 exceeds maximum field length (%2)" ).arg(
length ).arg( d->length );
669 d->editorWidgetSetup = v;
674 return d->editorWidgetSetup;
679 d->isReadOnly = readOnly;
684 return d->isReadOnly;
689 return d->splitPolicy;
694 d->splitPolicy = policy;
706 out << static_cast< quint32 >(
field.
type() );
735 quint32 originNotNull;
736 quint32 originUnique;
737 quint32 originExpression;
738 quint32 strengthNotNull;
739 quint32 strengthUnique;
740 quint32 strengthExpression;
749 QString defaultValueExpression;
750 QString constraintExpression;
751 QString constraintDescription;
754 >> defaultValueExpression >> applyOnUpdate >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
755 constraintExpression >> constraintDescription >> subType >> splitPolicy;
FieldDomainSplitPolicy
Split policy for field domains.
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
QString userFriendlyIdentifier(IdentifierType type=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
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.
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
static QString readableConfigurationFlag(QgsField::ConfigurationFlag flag)
Returns the readable and translated value of the configuration flag.
QgsField & operator=(const QgsField &other)
Assignment operator.
QString displayString(const QVariant &v) const
Formats string for display.
void setPrecision(int precision)
Set the field precision.
QString displayNameWithAlias() const
Returns the name to use when displaying this field and adds the alias in parenthesis if it is defined...
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
void setName(const QString &name)
Set the field name.
void setComment(const QString &comment)
Set the field comment.
QString displayType(bool showConstraints=false) const
Returns the type to use when displaying this field, including the length and precision of the datatyp...
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.
void setConfigurationFlags(QgsField::ConfigurationFlags configurationFlags)
Sets the Flags for the field (searchable, …)
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.
ConfigurationFlags configurationFlags
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.
QVariant::Type subType() const
If the field is a collection, gets its element's type.
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.
static constexpr int MAX_WKT_LENGTH
QgsDefaultValue defaultValueDefinition
void setSubType(QVariant::Type subType)
If the field is a collection, set its element's type.
void setType(QVariant::Type type)
Set variant type.
QgsFieldConstraints constraints
ConfigurationFlag
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.
@ NotSearchable
Defines if the field is searchable (used in the locator search for instance)
@ None
No flag is defined.
@ HideFromWms
Field is not available if layer is served as WMS from QGIS server.
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 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)
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...
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)