23 const QMap<QString, QString> &expressions,
25 : QAbstractTableModel( parent )
26 , mSourceFields( sourceFields )
27 , mExpressionContextGenerator( new ExpressionContextGenerator( mSourceFields ) )
34 if ( role == Qt::DisplayRole )
36 switch ( orientation )
44 return tr(
"Source Expression" );
56 return tr(
"Length" );
60 return tr(
"Precision" );
64 return tr(
"Constraints" );
85 if ( parent.isValid() )
87 return mMapping.count();
92 if ( parent.isValid() )
99 if ( index.isValid() )
102 const Field &f { mMapping.at( index.row() ) };
104 const QgsFieldConstraints::Constraints constraints { fieldConstraints( f.field ) };
108 case Qt::DisplayRole:
119 return f.field.displayName();
123 return static_cast<int>( f.field.type() );
127 return f.field.length();
131 return f.field.precision();
135 return constraints != 0 ? tr(
"Constraints active" ) : QString();
140 case Qt::ToolTipRole:
145 QStringList constraintDescription;
146 if ( constraints.testFlag( QgsFieldConstraints::Constraint::ConstraintUnique ) )
148 constraintDescription.push_back( tr(
"Unique" ) );
150 if ( constraints.testFlag( QgsFieldConstraints::Constraint::ConstraintNotNull ) )
152 constraintDescription.push_back( tr(
"Not null" ) );
154 if ( constraints.testFlag( QgsFieldConstraints::Constraint::ConstraintExpression ) )
156 constraintDescription.push_back( tr(
"Expression" ) );
158 return constraintDescription.join( QLatin1String(
"<br>" ) );
162 case Qt::BackgroundRole:
164 if ( constraints != 0 )
166 return QBrush( QColor( 255, 224, 178 ) );
177 if ( index.isValid() &&
181 return Qt::ItemFlags( Qt::ItemIsSelectable |
185 return Qt::ItemFlags();
190 if ( index.isValid() )
192 if ( role == Qt::EditRole )
194 Field &f = mMapping[index.row()];
210 f.
field.
setType(
static_cast<QVariant::Type
>( value.toInt( ) ) );
216 const int length { value.toInt( &ok ) };
224 const int precision { value.toInt( &ok ) };
234 emit dataChanged( index, index );
244 QgsFieldConstraints::Constraints QgsFieldMappingModel::fieldConstraints(
const QgsField &
field )
const
246 QgsFieldConstraints::Constraints constraints;
265 bool QgsFieldMappingModel::moveUpOrDown(
const QModelIndex &index,
bool up )
267 if ( ! index.isValid() && index.model() ==
this )
271 const int row { up ? index.row() - 1 : index.row() };
273 if ( row < 0 || row + 1 >=
rowCount( QModelIndex() ) )
277 beginMoveRows( QModelIndex( ), row, row, QModelIndex(), row + 2 );
278 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
279 mMapping.swap( row, row + 1 );
281 mMapping.swapItemsAt( row, row + 1 );
287 QString QgsFieldMappingModel::findExpressionForDestinationField(
const QgsFieldMappingModel::Field &f, QStringList &excludedFieldNames )
291 for (
const QgsField &sf : qgis::as_const( mSourceFields ) )
295 excludedFieldNames.push_back( sf.name() );
300 for (
const QgsField &sf : qgis::as_const( mSourceFields ) )
302 if ( excludedFieldNames.contains( sf.name() ) || sf.type() != f.
field.
type() )
304 excludedFieldNames.push_back( sf.name() );
313 if ( mExpressionContextGenerator )
314 mExpressionContextGenerator->setSourceFields( mSourceFields );
315 QStringList usedFields;
317 for (
const Field &f : qgis::as_const( mMapping ) )
324 for (
auto it = mMapping.begin(); it != mMapping.end(); ++it )
326 if ( it->expression.isEmpty() )
328 const QString expression { findExpressionForDestinationField( *it, usedFields ) };
329 if ( ! expression.isEmpty() )
330 it->expression = expression;
338 return mExpressionContextGenerator.get();
343 mExpressionContextGenerator->setBaseExpressionContextGenerator( generator );
347 const QMap<QString, QString> &expressions )
352 QStringList usedFields;
353 for (
const QgsField &df : destinationFields )
358 if ( expressions.contains( f.
field.
name() ) )
363 if ( exp.isField() &&
364 mSourceFields.
names().contains( qgis::setToList( exp.referencedColumns() ).first() ) )
366 usedFields.push_back( qgis::setToList( exp.referencedColumns() ).first() );
371 const QString expression { findExpressionForDestinationField( f, usedFields ) };
372 if ( ! expression.isEmpty() )
375 mMapping.push_back( f );
382 return mDestinationEditable;
392 static const QMap<QVariant::Type, QString> sDataTypes
394 { QVariant::Type::Int, tr(
"Whole number (integer - 32bit)" ) },
395 { QVariant::Type::LongLong, tr(
"Whole number (integer - 64bit)" ) },
396 { QVariant::Type::Double, tr(
"Decimal number (double)" ) },
397 { QVariant::Type::String, tr(
"Text (string)" ) },
398 { QVariant::Type::Date, tr(
"Date" ) },
399 { QVariant::Type::Time, tr(
"Time" ) },
400 { QVariant::Type::DateTime, tr(
"Date & Time" ) },
401 { QVariant::Type::Bool, tr(
"Boolean" ) },
402 { QVariant::Type::ByteArray, tr(
"Binary object (BLOB)" ) },
414 QMap< QString, QgsProperty > fieldMap;
418 const bool isField = exp.
isField();
419 fieldMap.insert(
field.originalName, isField
429 for (
int i = 0; i < mMapping.count(); ++i )
431 Field &f = mMapping[i];
464 const int lastRow {
rowCount( QModelIndex( ) ) };
465 beginInsertRows( QModelIndex(), lastRow, lastRow );
470 mMapping.push_back( f );
476 if ( index.isValid() && index.model() ==
this && index.row() <
rowCount( QModelIndex() ) )
478 beginRemoveRows( QModelIndex(), index.row(), index.row() );
479 mMapping.removeAt( index.row() );
491 return moveUpOrDown( index );
496 return moveUpOrDown( index,
false );
499 QgsFieldMappingModel::ExpressionContextGenerator::ExpressionContextGenerator(
const QgsFields &sourceFields )
500 : mSourceFields( sourceFields )
504 QgsExpressionContext QgsFieldMappingModel::ExpressionContextGenerator::createExpressionContext()
const
506 if ( mBaseGenerator )
509 std::unique_ptr< QgsExpressionContextScope > fieldMappingScope = qgis::make_unique< QgsExpressionContextScope >( tr(
"Field Mapping" ) );
510 fieldMappingScope->setFields( mSourceFields );
528 mBaseGenerator = generator;
531 void QgsFieldMappingModel::ExpressionContextGenerator::setSourceFields(
const QgsFields &fields )
533 mSourceFields = fields;