23 #include <QDataStream>
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() ).arg(
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" )
160 return d->type == QVariant::Double || d->type == QVariant::Int || d->type == QVariant::UInt || d->type == QVariant::LongLong || d->type == QVariant::ULongLong;
165 return d->type == QVariant::Date || d->type == QVariant::Time || d->type == QVariant::DateTime;
210 return d->defaultValueDefinition;
225 return d->constraints;
262 if ( d->type == QVariant::Double )
272 if ( QLocale().decimalPoint() !=
'.' ||
273 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
275 if ( d->precision > 0 )
277 if ( -1 < v.toDouble() && v.toDouble() < 1 )
279 return QLocale().toString( v.toDouble(),
'g', d->precision );
283 return QLocale().toString( v.toDouble(),
'f', d->precision );
290 const QString s( v.toString() );
291 const int dotPosition( s.indexOf(
'.' ) );
293 if ( dotPosition < 0 && s.indexOf(
'e' ) < 0 )
296 return QLocale().toString( v.toDouble(),
'f',
precision );
301 else precision = s.length() - dotPosition - 1;
303 if ( -1 < v.toDouble() && v.toDouble() < 1 )
305 return QLocale().toString( v.toDouble(),
'g',
precision );
309 return QLocale().toString( v.toDouble(),
'f',
precision );
315 else if ( d->precision > 0 )
317 if ( -1 < v.toDouble() && v.toDouble() < 1 )
319 return QString::number( v.toDouble(),
'g', d->precision );
323 return QString::number( v.toDouble(),
'f', d->precision );
329 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
332 const qlonglong converted( v.toLongLong( &ok ) );
334 return QLocale().toString( converted );
336 else if ( d->typeName.compare( QLatin1String(
"json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String(
"jsonb" ) )
338 const QJsonDocument doc = QJsonDocument::fromVariant( v );
339 return QString::fromUtf8( doc.toJson().data() );
341 else if ( d->type == QVariant::ByteArray )
343 return QObject::tr(
"BLOB" );
345 else if ( d->type == QVariant::StringList || d->type == QVariant::List )
348 const QVariantList list = v.toList();
349 for (
const QVariant &var : list )
351 if ( !result.isEmpty() )
352 result.append( QStringLiteral(
", " ) );
353 result.append( var.toString() );
367 return QObject::tr(
"None" );
369 return QObject::tr(
"Not searchable" );
371 return QObject::tr(
"Do not expose via WMS" );
373 return QObject::tr(
"Do not expose via WFS" );
386 const QVariant original = v;
388 errorMessage->clear();
392 v.convert( d->type );
396 if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
398 v = QVariant( d->type );
400 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toLongLong() );
406 if ( d->type == QVariant::Double && v.type() == QVariant::String )
409 if ( !tmp.convert( d->type ) )
420 if ( QLocale().decimalPoint() !=
'.' )
422 d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
433 if ( d->type == QVariant::Int && v.type() == QVariant::String )
436 if ( !tmp.convert( d->type ) )
450 if ( d->type == QVariant::LongLong && v.type() == QVariant::String )
453 if ( !tmp.convert( d->type ) )
468 if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
471 const double dbl = v.toDouble( &ok );
475 v = QVariant( d->type );
478 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
483 const double round = std::round( dbl );
484 if ( round > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
487 v = QVariant( d->type );
490 *errorMessage = QObject::tr(
"Value \"%1\" is too large for integer field" ).arg( original.toDouble() );
494 v = QVariant(
static_cast< int >( std::round( dbl ) ) );
500 if ( d->type == QVariant::LongLong && v.canConvert( QVariant::Double ) )
504 if ( !tmp.convert( d->type ) )
507 const double dbl = v.toDouble( &ok );
511 v = QVariant( d->type );
514 *errorMessage = QObject::tr(
"Value \"%1\" is not a number" ).arg( original.toString() );
519 const double round = std::round( dbl );
520 if ( round >
static_cast<double>( std::numeric_limits<long long>::max() ) || round <
static_cast<double>( -std::numeric_limits<long long>::max() ) )
523 v = QVariant( d->type );
526 *errorMessage = QObject::tr(
"Value \"%1\" is too large for long long field" ).arg( original.toDouble() );
530 v = QVariant(
static_cast< long long >( std::round( dbl ) ) );
535 if ( !v.convert( d->type ) )
537 v = QVariant( d->type );
540 *errorMessage = QObject::tr(
"Could not convert value \"%1\" to target type" ).arg( original.toString() );
545 if ( d->type == QVariant::Double && d->precision > 0 )
547 const double s = std::pow( 10, d->precision );
548 const double d = v.toDouble() * s;
549 v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
553 if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
555 const int length = v.toString().length();
556 v = v.toString().left( d->length );
559 *errorMessage = QObject::tr(
"String of length %1 exceeds maximum field length (%2)" ).arg(
length ).arg( d->length );
569 d->editorWidgetSetup = v;
574 return d->editorWidgetSetup;
579 d->isReadOnly = readOnly;
584 return d->isReadOnly;
597 out << static_cast< quint32 >(
field.
type() );
625 quint32 originNotNull;
626 quint32 originUnique;
627 quint32 originExpression;
628 quint32 strengthNotNull;
629 quint32 strengthUnique;
630 quint32 strengthExpression;
638 QString defaultValueExpression;
639 QString constraintExpression;
640 QString constraintDescription;
643 >> defaultValueExpression >> applyOnUpdate >> constraints >> originNotNull >> originUnique >> originExpression >> strengthNotNull >> strengthUnique >> strengthExpression >>
644 constraintExpression >> constraintDescription >> subType;
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
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 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 reabable 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...
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
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.
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
Fields is 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
Fields is 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.
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)