24 const QMap<QString, QString> &expressions,
26 : QAbstractTableModel( parent )
27 , mSourceFields( sourceFields )
28 , mExpressionContextGenerator( new ExpressionContextGenerator( mSourceFields ) )
35 if ( role == Qt::DisplayRole )
37 switch ( orientation )
45 return tr(
"Source Expression" );
57 return tr(
"Length" );
61 return tr(
"Precision" );
65 return tr(
"Constraints" );
86 if ( parent.isValid() )
88 return mMapping.count();
93 if ( parent.isValid() )
100 if ( index.isValid() )
103 const Field &f { mMapping.at( index.row() ) };
105 const QgsFieldConstraints::Constraints constraints { fieldConstraints( f.field ) };
109 case Qt::DisplayRole:
120 return f.field.displayName();
124 return f.field.typeName();
128 return f.field.length();
132 return f.field.precision();
136 return constraints != 0 ? tr(
"Constraints active" ) : QString();
141 case Qt::ToolTipRole:
146 QStringList constraintDescription;
147 if ( constraints.testFlag( QgsFieldConstraints::Constraint::ConstraintUnique ) )
149 constraintDescription.push_back( tr(
"Unique" ) );
151 if ( constraints.testFlag( QgsFieldConstraints::Constraint::ConstraintNotNull ) )
153 constraintDescription.push_back( tr(
"Not null" ) );
155 if ( constraints.testFlag( QgsFieldConstraints::Constraint::ConstraintExpression ) )
157 constraintDescription.push_back( tr(
"Expression" ) );
159 return constraintDescription.join( QLatin1String(
"<br>" ) );
163 case Qt::BackgroundRole:
165 if ( constraints != 0 )
167 return QBrush( QColor( 255, 224, 178 ) );
178 if ( index.isValid() &&
182 return Qt::ItemFlags( Qt::ItemIsSelectable |
186 return Qt::ItemFlags();
191 if ( index.isValid() )
193 if ( role == Qt::EditRole )
195 Field &f = mMapping[index.row()];
211 setFieldTypeFromName( f.
field, value.toString() );
217 const int length { value.toInt( &ok ) };
225 const int precision { value.toInt( &ok ) };
235 emit dataChanged( index, index );
245 QgsFieldConstraints::Constraints QgsFieldMappingModel::fieldConstraints(
const QgsField &
field )
const
247 QgsFieldConstraints::Constraints constraints;
266 bool QgsFieldMappingModel::moveUpOrDown(
const QModelIndex &index,
bool up )
268 if ( ! index.isValid() && index.model() ==
this )
272 const int row { up ? index.row() - 1 : index.row() };
274 if ( row < 0 || row + 1 >=
rowCount( QModelIndex() ) )
278 beginMoveRows( QModelIndex( ), row, row, QModelIndex(), row + 2 );
279 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
280 mMapping.swap( row, row + 1 );
282 mMapping.swapItemsAt( row, row + 1 );
288 QString QgsFieldMappingModel::findExpressionForDestinationField(
const QgsFieldMappingModel::Field &f, QStringList &excludedFieldNames )
292 for (
const QgsField &sf : std::as_const( mSourceFields ) )
296 excludedFieldNames.push_back( sf.name() );
301 for (
const QgsField &sf : std::as_const( mSourceFields ) )
303 if ( excludedFieldNames.contains( sf.name() ) || sf.type() != f.
field.
type() )
305 excludedFieldNames.push_back( sf.name() );
314 if ( mExpressionContextGenerator )
315 mExpressionContextGenerator->setSourceFields( mSourceFields );
316 QStringList usedFields;
318 for (
const Field &f : std::as_const( mMapping ) )
325 for (
auto it = mMapping.begin(); it != mMapping.end(); ++it )
327 if ( it->expression.isEmpty() )
329 const QString expression { findExpressionForDestinationField( *it, usedFields ) };
330 if ( ! expression.isEmpty() )
331 it->expression = expression;
339 return mExpressionContextGenerator.get();
344 mExpressionContextGenerator->setBaseExpressionContextGenerator( generator );
348 const QMap<QString, QString> &expressions )
353 QStringList usedFields;
354 for (
const QgsField &df : destinationFields )
360 if ( expressions.contains( f.
field.
name() ) )
365 if ( exp.isField() &&
366 mSourceFields.
names().contains( qgis::setToList( exp.referencedColumns() ).first() ) )
368 usedFields.push_back( qgis::setToList( exp.referencedColumns() ).first() );
373 const QString expression { findExpressionForDestinationField( f, usedFields ) };
374 if ( ! expression.isEmpty() )
377 mMapping.push_back( f );
384 return mDestinationEditable;
394 static const QMap<QVariant::Type, QString> sDataTypes
411 static const QList<QgsVectorDataProvider::NativeType> sDataTypes =
428 const QString QgsFieldMappingModel::qgsFieldToTypeName(
const QgsField &
field )
431 for (
const auto &type : types )
435 return type.mTypeName;
441 void QgsFieldMappingModel::setFieldTypeFromName(
QgsField &
field,
const QString &name )
444 for (
const auto &type : types )
446 if ( type.mTypeName == name )
463 QMap< QString, QgsProperty > fieldMap;
467 const bool isField = exp.
isField();
468 fieldMap.insert(
field.originalName, isField
478 for (
int i = 0; i < mMapping.count(); ++i )
480 Field &f = mMapping[i];
513 const int lastRow {
rowCount( QModelIndex( ) ) };
514 beginInsertRows( QModelIndex(), lastRow, lastRow );
520 mMapping.push_back( f );
526 if ( index.isValid() && index.model() ==
this && index.row() <
rowCount( QModelIndex() ) )
528 beginRemoveRows( QModelIndex(), index.row(), index.row() );
529 mMapping.removeAt( index.row() );
541 return moveUpOrDown( index );
546 return moveUpOrDown( index,
false );
549 QgsFieldMappingModel::ExpressionContextGenerator::ExpressionContextGenerator(
const QgsFields &sourceFields )
550 : mSourceFields( sourceFields )
554 QgsExpressionContext QgsFieldMappingModel::ExpressionContextGenerator::createExpressionContext()
const
556 if ( mBaseGenerator )
559 std::unique_ptr< QgsExpressionContextScope > fieldMappingScope = std::make_unique< QgsExpressionContextScope >( tr(
"Field Mapping" ) );
560 fieldMappingScope->setFields( mSourceFields );
578 mBaseGenerator = generator;
581 void QgsFieldMappingModel::ExpressionContextGenerator::setSourceFields(
const QgsFields &fields )
583 mSourceFields = fields;