QGIS API Documentation 3.27.0-Master (1d7a28cfd2)
qgsfieldmappingmodel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsfieldmappingmodel.cpp - QgsFieldMappingModel
3
4 ---------------------
5 begin : 17.3.2020
6 copyright : (C) 2020 by Alessandro Pasotti
7 email : elpaso at itopen dot it
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
20#include "qgsvariantutils.h"
21
23 const QgsFields &destinationFields,
24 const QMap<QString, QString> &expressions,
25 QObject *parent )
26 : QAbstractTableModel( parent )
27 , mSourceFields( sourceFields )
28 , mExpressionContextGenerator( new ExpressionContextGenerator( mSourceFields ) )
29{
30 setDestinationFields( destinationFields, expressions );
31}
32
33QVariant QgsFieldMappingModel::headerData( int section, Qt::Orientation orientation, int role ) const
34{
35 if ( role == Qt::DisplayRole )
36 {
37 switch ( orientation )
38 {
39 case Qt::Horizontal:
40 {
41 switch ( static_cast<ColumnDataIndex>( section ) )
42 {
44 {
45 return tr( "Source Expression" );
46 }
48 {
49 return tr( "Name" );
50 }
52 {
53 return tr( "Type" );
54 }
56 {
57 return tr( "Length" );
58 }
60 {
61 return tr( "Precision" );
62 }
64 {
65 return tr( "Constraints" );
66 }
67 }
68 break;
69 }
70 case Qt::Vertical:
71 {
72 return section;
73 }
74 }
75 }
76 return QVariant();
77}
78
80{
81 return mSourceFields;
82}
83
84int QgsFieldMappingModel::rowCount( const QModelIndex &parent ) const
85{
86 if ( parent.isValid() )
87 return 0;
88 return mMapping.count();
89}
90
91int QgsFieldMappingModel::columnCount( const QModelIndex &parent ) const
92{
93 if ( parent.isValid() )
94 return 0;
95 return 6;
96}
97
98QVariant QgsFieldMappingModel::data( const QModelIndex &index, int role ) const
99{
100 if ( index.isValid() )
101 {
102 const ColumnDataIndex col { static_cast<ColumnDataIndex>( index.column() ) };
103 const Field &f { mMapping.at( index.row() ) };
104
105 const QgsFieldConstraints::Constraints constraints { fieldConstraints( f.field ) };
106
107 switch ( role )
108 {
109 case Qt::DisplayRole:
110 case Qt::EditRole:
111 {
112 switch ( col )
113 {
115 {
116 return f.expression;
117 }
119 {
120 return f.field.displayName();
121 }
123 {
124 return f.field.typeName();
125 }
127 {
128 return f.field.length();
129 }
131 {
132 return f.field.precision();
133 }
135 {
136 return constraints != 0 ? tr( "Constraints active" ) : QString();
137 }
138 }
139 break;
140 }
141 case Qt::ToolTipRole:
142 {
144 constraints != 0 )
145 {
146 QStringList constraintDescription;
147 if ( constraints.testFlag( QgsFieldConstraints::Constraint::ConstraintUnique ) )
148 {
149 constraintDescription.push_back( tr( "Unique" ) );
150 }
151 if ( constraints.testFlag( QgsFieldConstraints::Constraint::ConstraintNotNull ) )
152 {
153 constraintDescription.push_back( tr( "Not null" ) );
154 }
155 if ( constraints.testFlag( QgsFieldConstraints::Constraint::ConstraintExpression ) )
156 {
157 constraintDescription.push_back( tr( "Expression" ) );
158 }
159 return constraintDescription.join( QLatin1String( "<br>" ) );
160 }
161 break;
162 }
163 case Qt::BackgroundRole:
164 {
165 if ( constraints != 0 )
166 {
167 return QBrush( QColor( 255, 224, 178 ) );
168 }
169 break;
170 }
171 }
172 }
173 return QVariant();
174}
175
176Qt::ItemFlags QgsFieldMappingModel::flags( const QModelIndex &index ) const
177{
178 if ( index.isValid() &&
179 index.column() != static_cast<int>( ColumnDataIndex::DestinationConstraints ) &&
180 ( index.column() == static_cast<int>( ColumnDataIndex::SourceExpression ) || destinationEditable() ) )
181 {
182 return Qt::ItemFlags( Qt::ItemIsSelectable |
183 Qt::ItemIsEditable |
184 Qt::ItemIsEnabled );
185 }
186 return Qt::ItemFlags();
187}
188
189bool QgsFieldMappingModel::setData( const QModelIndex &index, const QVariant &value, int role )
190{
191 if ( index.isValid() )
192 {
193 if ( role == Qt::EditRole )
194 {
195 Field &f = mMapping[index.row()];
196 switch ( static_cast<ColumnDataIndex>( index.column() ) )
197 {
199 {
200 const QgsExpression exp { value.toString() };
201 f.expression = exp;
202 break;
203 }
205 {
206 f.field.setName( value.toString() );
207 break;
208 }
210 {
211 setFieldTypeFromName( f.field, value.toString() );
212 break;
213 }
215 {
216 bool ok;
217 const int length { value.toInt( &ok ) };
218 if ( ok )
219 f.field.setLength( length );
220 break;
221 }
223 {
224 bool ok;
225 const int precision { value.toInt( &ok ) };
226 if ( ok )
228 break;
229 }
231 {
232 // Not editable: do nothing
233 }
234 }
235 emit dataChanged( index, index );
236 }
237 return true;
238 }
239 else
240 {
241 return false;
242 }
243}
244
245QgsFieldConstraints::Constraints QgsFieldMappingModel::fieldConstraints( const QgsField &field ) const
246{
247 QgsFieldConstraints::Constraints constraints;
248
249 const QgsFieldConstraints fieldConstraints { field.constraints() };
250
251 if ( fieldConstraints.constraints() & QgsFieldConstraints::ConstraintNotNull &&
253 constraints.setFlag( QgsFieldConstraints::ConstraintNotNull );
254
255 if ( fieldConstraints.constraints() & QgsFieldConstraints::ConstraintUnique &&
257 constraints.setFlag( QgsFieldConstraints::ConstraintUnique );
258
259 if ( fieldConstraints.constraints() & QgsFieldConstraints::ConstraintExpression &&
261 constraints.setFlag( QgsFieldConstraints::ConstraintExpression );
262
263 return constraints;
264}
265
266bool QgsFieldMappingModel::moveUpOrDown( const QModelIndex &index, bool up )
267{
268 if ( ! index.isValid() && index.model() == this )
269 return false;
270
271 // Always swap down
272 const int row { up ? index.row() - 1 : index.row() };
273 // Range checking
274 if ( row < 0 || row + 1 >= rowCount( QModelIndex() ) )
275 {
276 return false;
277 }
278 beginMoveRows( QModelIndex( ), row, row, QModelIndex(), row + 2 );
279 mMapping.swapItemsAt( row, row + 1 );
280 endMoveRows();
281 return true;
282}
283
284QString QgsFieldMappingModel::findExpressionForDestinationField( const QgsFieldMappingModel::Field &f, QStringList &excludedFieldNames )
285{
286 // Search for fields in the source
287 // 1. match by name
288 for ( const QgsField &sf : std::as_const( mSourceFields ) )
289 {
290 if ( sf.name() == f.field.name() )
291 {
292 excludedFieldNames.push_back( sf.name() );
293 return QgsExpression::quotedColumnRef( sf.name() );
294 }
295 }
296 // 2. match by type
297 for ( const QgsField &sf : std::as_const( mSourceFields ) )
298 {
299 if ( excludedFieldNames.contains( sf.name() ) || sf.type() != f.field.type() )
300 continue;
301 excludedFieldNames.push_back( sf.name() );
302 return QgsExpression::quotedColumnRef( sf.name() );
303 }
304 return QString();
305}
306
308{
309 mSourceFields = sourceFields;
310 if ( mExpressionContextGenerator )
311 mExpressionContextGenerator->setSourceFields( mSourceFields );
312 QStringList usedFields;
313 beginResetModel();
314 for ( const Field &f : std::as_const( mMapping ) )
315 {
316 if ( QgsExpression( f.expression ).isField() )
317 {
318 usedFields.push_back( f.expression.mid( 1, f.expression.length() - 2 ) );
319 }
320 }
321 for ( auto it = mMapping.begin(); it != mMapping.end(); ++it )
322 {
323 if ( it->expression.isEmpty() )
324 {
325 const QString expression { findExpressionForDestinationField( *it, usedFields ) };
326 if ( ! expression.isEmpty() )
327 it->expression = expression;
328 }
329 }
330 endResetModel();
331}
332
334{
335 return mExpressionContextGenerator.get();
336}
337
339{
340 mExpressionContextGenerator->setBaseExpressionContextGenerator( generator );
341}
342
344 const QMap<QString, QString> &expressions )
345{
346 beginResetModel();
347 mMapping.clear();
348 // Prepare the model data
349 QStringList usedFields;
350 for ( const QgsField &df : destinationFields )
351 {
352 Field f;
353 f.field = df;
354 f.field.setTypeName( qgsFieldToTypeName( df ) );
355 f.originalName = df.name();
356 if ( expressions.contains( f.field.name() ) )
357 {
358 f.expression = expressions.value( f.field.name() );
359 const QgsExpression exp { f.expression };
360 // if it's source field
361 if ( exp.isField() &&
362 mSourceFields.names().contains( qgis::setToList( exp.referencedColumns() ).first() ) )
363 {
364 usedFields.push_back( qgis::setToList( exp.referencedColumns() ).first() );
365 }
366 }
367 else
368 {
369 const QString expression { findExpressionForDestinationField( f, usedFields ) };
370 if ( ! expression.isEmpty() )
371 f.expression = expression;
372 }
373 mMapping.push_back( f );
374 }
375 endResetModel();
376}
377
379{
380 return mDestinationEditable;
381}
382
383void QgsFieldMappingModel::setDestinationEditable( bool destinationEditable )
384{
385 mDestinationEditable = destinationEditable;
386}
387
388const QMap<QVariant::Type, QString> QgsFieldMappingModel::dataTypes()
389{
390 static const QMap<QVariant::Type, QString> sDataTypes
391 {
392 { QVariant::Type::Int, QgsVariantUtils::typeToDisplayString( QVariant::Type::Int ) },
393 { QVariant::Type::LongLong, QgsVariantUtils::typeToDisplayString( QVariant::Type::LongLong ) },
394 { QVariant::Type::Double, QgsVariantUtils::typeToDisplayString( QVariant::Type::Double ) },
395 { QVariant::Type::String, QgsVariantUtils::typeToDisplayString( QVariant::Type::String ) },
396 { QVariant::Type::Date, QgsVariantUtils::typeToDisplayString( QVariant::Type::Date ) },
397 { QVariant::Type::Time, QgsVariantUtils::typeToDisplayString( QVariant::Type::Time ) },
398 { QVariant::Type::DateTime, QgsVariantUtils::typeToDisplayString( QVariant::Type::DateTime ) },
399 { QVariant::Type::Bool, QgsVariantUtils::typeToDisplayString( QVariant::Type::Bool ) },
400 { QVariant::Type::ByteArray, QgsVariantUtils::typeToDisplayString( QVariant::Type::ByteArray ) },
401 };
402 return sDataTypes;
403}
404
405const QList<QgsVectorDataProvider::NativeType> QgsFieldMappingModel::supportedDataTypes()
406{
407 static const QList<QgsVectorDataProvider::NativeType> sDataTypes =
408 QList<QgsVectorDataProvider::NativeType>() << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::Int ), QStringLiteral( "integer" ), QVariant::Int )
409 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::LongLong ), QStringLiteral( "int8" ), QVariant::LongLong )
410 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::Double ), QStringLiteral( "double precision" ), QVariant::Double )
411 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::String ), QStringLiteral( "text" ), QVariant::String )
412 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::Date ), QStringLiteral( "date" ), QVariant::Date )
413 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::Time ), QStringLiteral( "time" ), QVariant::Time )
414 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::DateTime ), QStringLiteral( "datetime" ), QVariant::DateTime )
415 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::Bool ), QStringLiteral( "boolean" ), QVariant::Bool )
416 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::ByteArray ), QStringLiteral( "binary" ), QVariant::ByteArray )
417 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::StringList ), QStringLiteral( "stringlist" ), QVariant::StringList, 0, 0, 0, 0, QVariant::String )
418 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::List, QVariant::Type::Int ), QStringLiteral( "integerlist" ), QVariant::List, 0, 0, 0, 0, QVariant::Int )
419 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::List, QVariant::Type::Double ), QStringLiteral( "doublelist" ), QVariant::List, 0, 0, 0, 0, QVariant::Double )
420 << QgsVectorDataProvider::NativeType( QgsVariantUtils::typeToDisplayString( QVariant::Type::List, QVariant::Type::LongLong ), QStringLiteral( "integer64list" ), QVariant::List, 0, 0, 0, 0, QVariant::LongLong );
421 return sDataTypes;
422}
423
424const QString QgsFieldMappingModel::qgsFieldToTypeName( const QgsField &field )
425{
426 const QList<QgsVectorDataProvider::NativeType> types = supportedDataTypes();
427 for ( const auto &type : types )
428 {
429 if ( type.mType == field.type() && type.mSubType == field.subType() )
430 {
431 return type.mTypeName;
432 }
433 }
434 return QString();
435}
436
437void QgsFieldMappingModel::setFieldTypeFromName( QgsField &field, const QString &name )
438{
439 const QList<QgsVectorDataProvider::NativeType> types = supportedDataTypes();
440 for ( const auto &type : types )
441 {
442 if ( type.mTypeName == name )
443 {
444 field.setType( type.mType );
445 field.setTypeName( type.mTypeName );
446 field.setSubType( type.mSubType );
447 return;
448 }
449 }
450}
451
452QList<QgsFieldMappingModel::Field> QgsFieldMappingModel::mapping() const
453{
454 return mMapping;
455}
456
457QMap<QString, QgsProperty> QgsFieldMappingModel::fieldPropertyMap() const
458{
459 QMap< QString, QgsProperty > fieldMap;
460 for ( const QgsFieldMappingModel::Field &field : mMapping )
461 {
462 const QgsExpression exp( field.expression );
463 const bool isField = exp.isField();
464 fieldMap.insert( field.originalName, isField
465 ? QgsProperty::fromField( static_cast<const QgsExpressionNodeColumnRef *>( exp.rootNode() )->name() )
466 : QgsProperty::fromExpression( field.expression ) );
467 }
468 return fieldMap;
469}
470
471void QgsFieldMappingModel::setFieldPropertyMap( const QMap<QString, QgsProperty> &map )
472{
473 beginResetModel();
474 for ( int i = 0; i < mMapping.count(); ++i )
475 {
476 Field &f = mMapping[i];
477 if ( map.contains( f.field.name() ) )
478 {
479 const QgsProperty prop = map.value( f.field.name() );
480 switch ( prop.propertyType() )
481 {
484 break;
485
487 f.expression = prop.field();
488 break;
489
491 f.expression = prop.expressionString();
492 break;
493
495 f.expression.clear();
496 break;
497 }
498 }
499 else
500 {
501 f.expression.clear();
502 }
503 }
504 endResetModel();
505}
506
507void QgsFieldMappingModel::appendField( const QgsField &field, const QString &expression )
508{
509 const int lastRow { rowCount( QModelIndex( ) ) };
510 beginInsertRows( QModelIndex(), lastRow, lastRow );
511 Field f;
512 f.field = field;
513 f.field.setTypeName( qgsFieldToTypeName( field ) );
514 f.expression = expression;
515 f.originalName = field.name();
516 mMapping.push_back( f );
517 endInsertRows( );
518}
519
520bool QgsFieldMappingModel::removeField( const QModelIndex &index )
521{
522 if ( index.isValid() && index.model() == this && index.row() < rowCount( QModelIndex() ) )
523 {
524 beginRemoveRows( QModelIndex(), index.row(), index.row() );
525 mMapping.removeAt( index.row() );
526 endRemoveRows();
527 return true;
528 }
529 else
530 {
531 return false;
532 }
533}
534
535bool QgsFieldMappingModel::moveUp( const QModelIndex &index )
536{
537 return moveUpOrDown( index );
538}
539
540bool QgsFieldMappingModel::moveDown( const QModelIndex &index )
541{
542 return moveUpOrDown( index, false );
543}
544
545QgsFieldMappingModel::ExpressionContextGenerator::ExpressionContextGenerator( const QgsFields &sourceFields )
546 : mSourceFields( sourceFields )
547{
548}
549
550QgsExpressionContext QgsFieldMappingModel::ExpressionContextGenerator::createExpressionContext() const
551{
552 if ( mBaseGenerator )
553 {
554 QgsExpressionContext ctx = mBaseGenerator->createExpressionContext();
555 std::unique_ptr< QgsExpressionContextScope > fieldMappingScope = std::make_unique< QgsExpressionContextScope >( tr( "Field Mapping" ) );
556 fieldMappingScope->setFields( mSourceFields );
557 ctx.appendScope( fieldMappingScope.release() );
558 return ctx;
559 }
560 else
561 {
564 ctx.setFields( mSourceFields );
565 QgsFeature feature { mSourceFields };
566 feature.setValid( true );
567 ctx.setFeature( feature );
568 return ctx;
569 }
570}
571
572void QgsFieldMappingModel::ExpressionContextGenerator::setBaseExpressionContextGenerator( const QgsExpressionContextGenerator *generator )
573{
574 mBaseGenerator = generator;
575}
576
577void QgsFieldMappingModel::ExpressionContextGenerator::setSourceFields( const QgsFields &fields )
578{
579 mSourceFields = fields;
580}
Abstract interface for generating an expression context.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
An expression node which takes it value from a feature's field.
QString name() const
The name of the column.
Class for parsing and evaluation of expressions (formerly called "search strings").
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
bool isField() const
Checks whether an expression consists only of a single field reference.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
const QgsExpressionNode * rootNode() const
Returns the root node of the expression.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
void setValid(bool validity)
Sets the validity of the feature.
Definition: qgsfeature.cpp:221
Stores information about constraints which may be present on a field.
@ ConstraintStrengthHard
Constraint must be honored before feature can be accepted.
@ ConstraintNotNull
Field may not be null.
@ ConstraintUnique
Field must have a unique value.
@ ConstraintExpression
Field has an expression constraint set. See constraintExpression().
void setDestinationEditable(bool editable)
Sets the destination fields editable state to editable.
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
ColumnDataIndex
The ColumnDataIndex enum represents the column index for the view.
@ DestinationPrecision
Destination field precision.
@ DestinationConstraints
Destination field constraints.
@ DestinationName
Destination field name.
@ DestinationType
Destination field type string.
@ DestinationLength
Destination field length.
Qt::ItemFlags flags(const QModelIndex &index) const override
static Q_DECL_DEPRECATED const QMap< QVariant::Type, QString > dataTypes()
Returns a static map of supported data types.
QgsFields sourceFields() const
Returns a list of source fields.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
bool removeField(const QModelIndex &index)
Removes the field at index from the model, returns true on success.
void appendField(const QgsField &field, const QString &expression=QString())
Appends a new field to the model, with an optional expression.
QMap< QString, QgsProperty > fieldPropertyMap() const
Returns a map of destination field name to QgsProperty definition for field value,...
QList< QgsFieldMappingModel::Field > mapping() const
Returns a list of Field objects representing the current status of the model.
QgsFieldMappingModel(const QgsFields &sourceFields=QgsFields(), const QgsFields &destinationFields=QgsFields(), const QMap< QString, QString > &expressions=QMap< QString, QString >(), QObject *parent=nullptr)
Constructs a QgsFieldMappingModel from a set of sourceFields and destinationFields,...
bool moveDown(const QModelIndex &index)
Moves up the field at index.
bool moveUp(const QModelIndex &index)
Moves down the field at index.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
void setBaseExpressionContextGenerator(const QgsExpressionContextGenerator *generator)
Sets the base expression context generator, which will generate the expression contexts for expressio...
static const QList< QgsVectorDataProvider::NativeType > supportedDataTypes()
Returns a static list of supported data types.
QgsExpressionContextGenerator * contextGenerator() const
Returns the context generator with the source fields.
void setDestinationFields(const QgsFields &destinationFields, const QMap< QString, QString > &expressions=QMap< QString, QString >())
Set destination fields to destinationFields, initial values for the expressions can be optionally spe...
void setSourceFields(const QgsFields &sourceFields)
Set source fields to sourceFields.
bool setData(const QModelIndex &index, const QVariant &value, int role) override
bool destinationEditable() const
Returns true if the destination fields are editable.
void setFieldPropertyMap(const QMap< QString, QgsProperty > &map)
Sets a map of destination field name to QgsProperty definition for field value.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
QString name
Definition: qgsfield.h:60
void setPrecision(int precision)
Set the field precision.
Definition: qgsfield.cpp:200
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:176
void setLength(int len)
Set the field length.
Definition: qgsfield.cpp:196
QVariant::Type type
Definition: qgsfield.h:58
QVariant::Type subType() const
If the field is a collection, gets its element's type.
Definition: qgsfield.cpp:135
void setSubType(QVariant::Type subType)
If the field is a collection, set its element's type.
Definition: qgsfield.cpp:186
void setType(QVariant::Type type)
Set variant type.
Definition: qgsfield.cpp:181
QgsFieldConstraints constraints
Definition: qgsfield.h:63
void setTypeName(const QString &typeName)
Set the field type.
Definition: qgsfield.cpp:191
Container of fields for a vector layer.
Definition: qgsfields.h:45
QStringList names() const
Returns a list with field names.
Definition: qgsfields.cpp:143
A store for object properties.
Definition: qgsproperty.h:231
@ ExpressionBasedProperty
Expression based property (QgsExpressionBasedProperty)
Definition: qgsproperty.h:240
@ StaticProperty
Static property (QgsStaticProperty)
Definition: qgsproperty.h:238
@ FieldBasedProperty
Field based property (QgsFieldBasedProperty)
Definition: qgsproperty.h:239
@ InvalidProperty
Invalid (not set) property.
Definition: qgsproperty.h:237
QString expressionString() const
Returns the expression used for the property value.
QString field() const
Returns the current field name the property references.
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
QVariant staticValue() const
Returns the current static value for the property.
Type propertyType() const
Returns the property type.
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
static QString typeToDisplayString(QVariant::Type type, QVariant::Type subType=QVariant::Type::Invalid)
Returns a user-friendly translated string representing a QVariant type.
const QgsField & field
Definition: qgsfield.h:463
int precision
The Field struct holds information about a mapped field.
QgsField field
The field in its current status (it might have been renamed)
QString expression
The expression for the mapped field from the source fields.
QString originalName
The original name of the field.