mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-12 00:06:54 -05:00
Adress PR review + model test + QgsExpression -> QString
This commit is contained in:
parent
4a33c75bc9
commit
a21800cf3e
@ -41,12 +41,12 @@ the mapping expression is editable.
|
|||||||
{
|
{
|
||||||
QString originalName;
|
QString originalName;
|
||||||
QgsField field;
|
QgsField field;
|
||||||
QgsExpression expression;
|
QString expression;
|
||||||
};
|
};
|
||||||
|
|
||||||
QgsFieldMappingModel( const QgsFields &sourceFields = QgsFields(),
|
QgsFieldMappingModel( const QgsFields &sourceFields = QgsFields(),
|
||||||
const QgsFields &destinationFields = QgsFields(),
|
const QgsFields &destinationFields = QgsFields(),
|
||||||
const QMap<QString, QgsExpression> &expressions = QMap<QString, QgsExpression>(),
|
const QMap<QString, QString> &expressions = QMap<QString, QString>(),
|
||||||
QObject *parent = 0 );
|
QObject *parent = 0 );
|
||||||
%Docstring
|
%Docstring
|
||||||
Constructs a QgsFieldMappingModel from a set of ``sourceFields``
|
Constructs a QgsFieldMappingModel from a set of ``sourceFields``
|
||||||
@ -54,11 +54,6 @@ and ``destinationFields``, initial values for the expressions can be
|
|||||||
optionally specified through ``expressions`` which is a map from the original
|
optionally specified through ``expressions`` which is a map from the original
|
||||||
field name to the corresponding expression. A ``parent`` object
|
field name to the corresponding expression. A ``parent`` object
|
||||||
can be also specified.
|
can be also specified.
|
||||||
%End
|
|
||||||
|
|
||||||
QgsExpressionContextGenerator *contextGenerator() const;
|
|
||||||
%Docstring
|
|
||||||
Returns the context generator with the source fields
|
|
||||||
%End
|
%End
|
||||||
|
|
||||||
bool destinationEditable() const;
|
bool destinationEditable() const;
|
||||||
@ -86,7 +81,7 @@ Returns a list of source fields
|
|||||||
Returns a list of Field objects representing the current status of the model
|
Returns a list of Field objects representing the current status of the model
|
||||||
%End
|
%End
|
||||||
|
|
||||||
void appendField( const QgsField &field, const QgsExpression &expression = QgsExpression() );
|
void appendField( const QgsField &field, const QString &expression = QString() );
|
||||||
%Docstring
|
%Docstring
|
||||||
Appends a new ``field`` to the model, with an optional ``expression``
|
Appends a new ``field`` to the model, with an optional ``expression``
|
||||||
%End
|
%End
|
||||||
@ -109,10 +104,15 @@ Moves up the field at ``index``
|
|||||||
void setSourceFields( const QgsFields &sourceFields );
|
void setSourceFields( const QgsFields &sourceFields );
|
||||||
%Docstring
|
%Docstring
|
||||||
Set source fields to ``sourceFields``
|
Set source fields to ``sourceFields``
|
||||||
|
%End
|
||||||
|
|
||||||
|
QgsExpressionContextGenerator *contextGenerator() const;
|
||||||
|
%Docstring
|
||||||
|
Returns the context generator with the source fields
|
||||||
%End
|
%End
|
||||||
|
|
||||||
void setDestinationFields( const QgsFields &destinationFields,
|
void setDestinationFields( const QgsFields &destinationFields,
|
||||||
const QMap<QString, QgsExpression> &expressions = QMap<QString, QgsExpression>() );
|
const QMap<QString, QString> &expressions = QMap<QString, QString>() );
|
||||||
%Docstring
|
%Docstring
|
||||||
Set destination fields to ``destinationFields``, initial values for the expressions can be
|
Set destination fields to ``destinationFields``, initial values for the expressions can be
|
||||||
optionally specified through ``expressions`` which is a map from the original
|
optionally specified through ``expressions`` which is a map from the original
|
||||||
@ -135,6 +135,8 @@ field name to the corresponding expression.
|
|||||||
public:
|
public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* This file has been generated automatically from *
|
* This file has been generated automatically from *
|
||||||
* *
|
* *
|
||||||
|
|||||||
@ -26,7 +26,7 @@ for each set of "destination" fields an expression defines how to obtain the val
|
|||||||
explicit QgsFieldMappingWidget( QWidget *parent = 0,
|
explicit QgsFieldMappingWidget( QWidget *parent = 0,
|
||||||
const QgsFields &sourceFields = QgsFields(),
|
const QgsFields &sourceFields = QgsFields(),
|
||||||
const QgsFields &destinationFields = QgsFields(),
|
const QgsFields &destinationFields = QgsFields(),
|
||||||
const QMap<QString, QgsExpression> &expressions = QMap<QString, QgsExpression>() );
|
const QMap<QString, QString> &expressions = QMap<QString, QString>() );
|
||||||
%Docstring
|
%Docstring
|
||||||
Constructs a QgsFieldMappingWidget from a set of ``sourceFields``
|
Constructs a QgsFieldMappingWidget from a set of ``sourceFields``
|
||||||
and ``destinationFields``, initial values for the expressions can be
|
and ``destinationFields``, initial values for the expressions can be
|
||||||
@ -66,7 +66,7 @@ Set source fields of the underlying mapping model to ``sourceFields``
|
|||||||
%End
|
%End
|
||||||
|
|
||||||
void setDestinationFields( const QgsFields &destinationFields,
|
void setDestinationFields( const QgsFields &destinationFields,
|
||||||
const QMap<QString, QgsExpression> &expressions = QMap<QString, QgsExpression>() );
|
const QMap<QString, QString> &expressions = QMap<QString, QString>() );
|
||||||
%Docstring
|
%Docstring
|
||||||
Set destination fields to ``destinationFields`` in the underlying model,
|
Set destination fields to ``destinationFields`` in the underlying model,
|
||||||
initial values for the expressions can be optionally specified through
|
initial values for the expressions can be optionally specified through
|
||||||
@ -81,7 +81,7 @@ Scroll the fields view to ``index``
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void appendField( const QgsField &field, const QgsExpression &expression = QgsExpression() );
|
void appendField( const QgsField &field, const QString &expression = QString() );
|
||||||
%Docstring
|
%Docstring
|
||||||
Appends a new ``field`` to the model, with an optional ``expression``
|
Appends a new ``field`` to the model, with an optional ``expression``
|
||||||
%End
|
%End
|
||||||
|
|||||||
@ -48,7 +48,6 @@ from qgis.core import (
|
|||||||
QgsVectorLayer,
|
QgsVectorLayer,
|
||||||
QgsField,
|
QgsField,
|
||||||
QgsFields,
|
QgsFields,
|
||||||
QgsExpression,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_MODELER
|
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_MODELER
|
||||||
@ -110,7 +109,7 @@ class FieldsMappingPanel(BASE, WIDGET):
|
|||||||
'type': f.field.type(),
|
'type': f.field.type(),
|
||||||
'length': f.field.length(),
|
'length': f.field.length(),
|
||||||
'precision': f.field.precision(),
|
'precision': f.field.precision(),
|
||||||
'expression': f.expression.expression(),
|
'expression': f.expression,
|
||||||
})
|
})
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@ -126,7 +125,7 @@ class FieldsMappingPanel(BASE, WIDGET):
|
|||||||
field_def.get('length', 0),
|
field_def.get('length', 0),
|
||||||
field_def.get('precision', 0))
|
field_def.get('precision', 0))
|
||||||
try:
|
try:
|
||||||
expressions[f.name()] = QgsExpression(field_def['expressions'])
|
expressions[f.name()] = field_def['expressions']
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
destinationFields.append(f)
|
destinationFields.append(f)
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
QgsFieldMappingModel::QgsFieldMappingModel( const QgsFields &sourceFields,
|
QgsFieldMappingModel::QgsFieldMappingModel( const QgsFields &sourceFields,
|
||||||
const QgsFields &destinationFields,
|
const QgsFields &destinationFields,
|
||||||
const QMap<QString, QgsExpression> &expressions,
|
const QMap<QString, QString> &expressions,
|
||||||
QObject *parent )
|
QObject *parent )
|
||||||
: QAbstractTableModel( parent )
|
: QAbstractTableModel( parent )
|
||||||
, mSourceFields( sourceFields )
|
, mSourceFields( sourceFields )
|
||||||
@ -35,29 +35,29 @@ QVariant QgsFieldMappingModel::headerData( int section, Qt::Orientation orientat
|
|||||||
{
|
{
|
||||||
if ( orientation == Qt::Horizontal )
|
if ( orientation == Qt::Horizontal )
|
||||||
{
|
{
|
||||||
switch ( section )
|
switch ( static_cast<ColumnDataIndex>( section ) )
|
||||||
{
|
{
|
||||||
case static_cast<int>( ColumnDataIndex::SourceExpression ):
|
case ColumnDataIndex::SourceExpression:
|
||||||
{
|
{
|
||||||
return tr( "Source expression" );
|
return tr( "Source expression" );
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationName ):
|
case ColumnDataIndex::DestinationName:
|
||||||
{
|
{
|
||||||
return tr( "Name" );
|
return tr( "Name" );
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationType ):
|
case ColumnDataIndex::DestinationType:
|
||||||
{
|
{
|
||||||
return tr( "Type" );
|
return tr( "Type" );
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationLength ):
|
case ColumnDataIndex::DestinationLength:
|
||||||
{
|
{
|
||||||
return tr( "Length" );
|
return tr( "Length" );
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationPrecision ):
|
case ColumnDataIndex::DestinationPrecision:
|
||||||
{
|
{
|
||||||
return tr( "Precision" );
|
return tr( "Precision" );
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationConstraints ):
|
case ColumnDataIndex::DestinationConstraints:
|
||||||
{
|
{
|
||||||
return tr( "Constraints" );
|
return tr( "Constraints" );
|
||||||
}
|
}
|
||||||
@ -78,13 +78,15 @@ QgsFields QgsFieldMappingModel::sourceFields() const
|
|||||||
|
|
||||||
int QgsFieldMappingModel::rowCount( const QModelIndex &parent ) const
|
int QgsFieldMappingModel::rowCount( const QModelIndex &parent ) const
|
||||||
{
|
{
|
||||||
Q_UNUSED( parent );
|
if ( parent.isValid() )
|
||||||
|
return 0;
|
||||||
return mMapping.count();
|
return mMapping.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
int QgsFieldMappingModel::columnCount( const QModelIndex &parent ) const
|
int QgsFieldMappingModel::columnCount( const QModelIndex &parent ) const
|
||||||
{
|
{
|
||||||
Q_UNUSED( parent );
|
if ( parent.isValid() )
|
||||||
|
return 0;
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,36 +101,34 @@ QVariant QgsFieldMappingModel::data( const QModelIndex &index, int role ) const
|
|||||||
|
|
||||||
if ( role == Qt::DisplayRole || role == Qt::EditRole )
|
if ( role == Qt::DisplayRole || role == Qt::EditRole )
|
||||||
{
|
{
|
||||||
switch ( col )
|
switch ( static_cast<ColumnDataIndex>( col ) )
|
||||||
{
|
{
|
||||||
|
case ColumnDataIndex::SourceExpression:
|
||||||
{
|
{
|
||||||
case static_cast<int>( ColumnDataIndex::SourceExpression ):
|
return f.expression;
|
||||||
{
|
|
||||||
return f.expression.expression();
|
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationName ):
|
case ColumnDataIndex::DestinationName:
|
||||||
{
|
{
|
||||||
return f.field.displayName();
|
return f.field.displayName();
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationType ):
|
case ColumnDataIndex::DestinationType:
|
||||||
{
|
{
|
||||||
return static_cast<int>( f.field.type() );
|
return static_cast<int>( f.field.type() );
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationLength ):
|
case ColumnDataIndex::DestinationLength:
|
||||||
{
|
{
|
||||||
return f.field.length();
|
return f.field.length();
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationPrecision ):
|
case ColumnDataIndex::DestinationPrecision:
|
||||||
{
|
{
|
||||||
return f.field.precision();
|
return f.field.precision();
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationConstraints ):
|
case ColumnDataIndex::DestinationConstraints:
|
||||||
{
|
{
|
||||||
return constraints != 0 ? tr( "Constraints active" ) : QString();
|
return constraints != 0 ? tr( "Constraints active" ) : QString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if ( role == Qt::ToolTipRole &&
|
else if ( role == Qt::ToolTipRole &&
|
||||||
col == static_cast<int>( ColumnDataIndex::DestinationConstraints ) &&
|
col == static_cast<int>( ColumnDataIndex::DestinationConstraints ) &&
|
||||||
constraints != 0 )
|
constraints != 0 )
|
||||||
@ -157,28 +157,6 @@ QVariant QgsFieldMappingModel::data( const QModelIndex &index, int role ) const
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsExpressionContextGenerator *QgsFieldMappingModel::contextGenerator() const
|
|
||||||
{
|
|
||||||
return mExpressionContextGenerator.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QgsFieldMappingModel::ExpressionContextGenerator::ExpressionContextGenerator( const QgsFields *sourceFields )
|
|
||||||
{
|
|
||||||
mSourceFields = sourceFields;
|
|
||||||
}
|
|
||||||
|
|
||||||
QgsExpressionContext QgsFieldMappingModel::ExpressionContextGenerator::createExpressionContext() const
|
|
||||||
{
|
|
||||||
QgsExpressionContext ctx;
|
|
||||||
ctx.appendScope( QgsExpressionContextUtils::globalScope() );
|
|
||||||
ctx.setFields( *mSourceFields );
|
|
||||||
QgsFeature feature { *mSourceFields };
|
|
||||||
feature.setValid( true );
|
|
||||||
ctx.setFeature( feature );
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::ItemFlags QgsFieldMappingModel::flags( const QModelIndex &index ) const
|
Qt::ItemFlags QgsFieldMappingModel::flags( const QModelIndex &index ) const
|
||||||
{
|
{
|
||||||
if ( index.isValid() &&
|
if ( index.isValid() &&
|
||||||
@ -199,25 +177,25 @@ bool QgsFieldMappingModel::setData( const QModelIndex &index, const QVariant &va
|
|||||||
if ( role == Qt::EditRole )
|
if ( role == Qt::EditRole )
|
||||||
{
|
{
|
||||||
Field &f = mMapping[index.row()];
|
Field &f = mMapping[index.row()];
|
||||||
switch ( index.column() )
|
switch ( static_cast<ColumnDataIndex>( index.column() ) )
|
||||||
{
|
{
|
||||||
case static_cast<int>( ColumnDataIndex::SourceExpression ):
|
case ColumnDataIndex::SourceExpression:
|
||||||
{
|
{
|
||||||
const QgsExpression exp { value.toString() };
|
const QgsExpression exp { value.toString() };
|
||||||
f.expression = exp;
|
f.expression = exp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationName ):
|
case ColumnDataIndex::DestinationName:
|
||||||
{
|
{
|
||||||
f.field.setName( value.toString() );
|
f.field.setName( value.toString() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationType ):
|
case ColumnDataIndex::DestinationType:
|
||||||
{
|
{
|
||||||
f.field.setType( static_cast<QVariant::Type>( value.toInt( ) ) );
|
f.field.setType( static_cast<QVariant::Type>( value.toInt( ) ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationLength ):
|
case ColumnDataIndex::DestinationLength:
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
const int length { value.toInt( &ok ) };
|
const int length { value.toInt( &ok ) };
|
||||||
@ -225,7 +203,7 @@ bool QgsFieldMappingModel::setData( const QModelIndex &index, const QVariant &va
|
|||||||
f.field.setLength( length );
|
f.field.setLength( length );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case static_cast<int>( ColumnDataIndex::DestinationPrecision ):
|
case ColumnDataIndex::DestinationPrecision:
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
const int precision { value.toInt( &ok ) };
|
const int precision { value.toInt( &ok ) };
|
||||||
@ -233,12 +211,20 @@ bool QgsFieldMappingModel::setData( const QModelIndex &index, const QVariant &va
|
|||||||
f.field.setPrecision( precision );
|
f.field.setPrecision( precision );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ColumnDataIndex::DestinationConstraints:
|
||||||
|
{
|
||||||
|
// Not editable: do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
emit dataChanged( index, index );
|
emit dataChanged( index, index );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QgsFieldConstraints::Constraints QgsFieldMappingModel::fieldConstraints( const QgsField &field ) const
|
QgsFieldConstraints::Constraints QgsFieldMappingModel::fieldConstraints( const QgsField &field ) const
|
||||||
{
|
{
|
||||||
@ -283,11 +269,11 @@ bool QgsFieldMappingModel::moveUpOrDown( const QModelIndex &index, bool up )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QgsFieldMappingModel::bestMatchforField( const QgsFieldMappingModel::Field &f, QStringList &excludedFieldNames )
|
QString QgsFieldMappingModel::findExpressionForDestinationField( const QgsFieldMappingModel::Field &f, QStringList &excludedFieldNames )
|
||||||
{
|
{
|
||||||
// Search for fields in the source
|
// Search for fields in the source
|
||||||
// 1. match by name
|
// 1. match by name
|
||||||
for ( const auto &sf : qgis::as_const( mSourceFields ) )
|
for ( const QgsField &sf : qgis::as_const( mSourceFields ) )
|
||||||
{
|
{
|
||||||
if ( sf.name() == f.field.name() )
|
if ( sf.name() == f.field.name() )
|
||||||
{
|
{
|
||||||
@ -295,7 +281,7 @@ QString QgsFieldMappingModel::bestMatchforField( const QgsFieldMappingModel::Fie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 2. match by type
|
// 2. match by type
|
||||||
for ( const auto &sf : qgis::as_const( mSourceFields ) )
|
for ( const QgsField &sf : qgis::as_const( mSourceFields ) )
|
||||||
{
|
{
|
||||||
if ( excludedFieldNames.contains( sf.name() ) || sf.type() != f.field.type() )
|
if ( excludedFieldNames.contains( sf.name() ) || sf.type() != f.field.type() )
|
||||||
continue;
|
continue;
|
||||||
@ -312,26 +298,30 @@ void QgsFieldMappingModel::setSourceFields( const QgsFields &sourceFields )
|
|||||||
beginResetModel();
|
beginResetModel();
|
||||||
for ( const Field &f : qgis::as_const( mMapping ) )
|
for ( const Field &f : qgis::as_const( mMapping ) )
|
||||||
{
|
{
|
||||||
if ( f.expression.isField() )
|
if ( QgsExpression( f.expression ).isField() )
|
||||||
{
|
{
|
||||||
usedFields.push_back( f.expression.expression().mid( 1, f.expression.expression().length() - 2 ) );
|
usedFields.push_back( f.expression.mid( 1, f.expression.length() - 2 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// not const on purpose
|
for ( auto it = mMapping.begin(); it != mMapping.end(); ++it )
|
||||||
for ( Field &f : mMapping )
|
|
||||||
{
|
{
|
||||||
if ( f.expression.expression().isEmpty() )
|
if ( it->expression.isEmpty() )
|
||||||
{
|
{
|
||||||
const QString expression { bestMatchforField( f, usedFields ) };
|
const QString expression { findExpressionForDestinationField( *it, usedFields ) };
|
||||||
if ( ! expression.isEmpty() )
|
if ( ! expression.isEmpty() )
|
||||||
f.expression = expression;
|
it->expression = expression;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QgsExpressionContextGenerator *QgsFieldMappingModel::contextGenerator() const
|
||||||
|
{
|
||||||
|
return mExpressionContextGenerator.get();
|
||||||
|
}
|
||||||
|
|
||||||
void QgsFieldMappingModel::setDestinationFields( const QgsFields &destinationFields,
|
void QgsFieldMappingModel::setDestinationFields( const QgsFields &destinationFields,
|
||||||
const QMap<QString, QgsExpression> &expressions )
|
const QMap<QString, QString> &expressions )
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
mMapping.clear();
|
mMapping.clear();
|
||||||
@ -345,16 +335,17 @@ void QgsFieldMappingModel::setDestinationFields( const QgsFields &destinationFie
|
|||||||
if ( expressions.contains( f.field.name() ) )
|
if ( expressions.contains( f.field.name() ) )
|
||||||
{
|
{
|
||||||
f.expression = expressions.value( f.field.name() );
|
f.expression = expressions.value( f.field.name() );
|
||||||
|
const QgsExpression exp { f.expression };
|
||||||
// if it's source field
|
// if it's source field
|
||||||
if ( f.expression.isField() &&
|
if ( exp.isField() &&
|
||||||
mSourceFields.names().contains( f.expression.referencedColumns().toList().first() ) )
|
mSourceFields.names().contains( exp.referencedColumns().toList().first() ) )
|
||||||
{
|
{
|
||||||
usedFields.push_back( f.expression.referencedColumns().toList().first() );
|
usedFields.push_back( exp.referencedColumns().toList().first() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const QString expression { bestMatchforField( f, usedFields ) };
|
const QString expression { findExpressionForDestinationField( f, usedFields ) };
|
||||||
if ( ! expression.isEmpty() )
|
if ( ! expression.isEmpty() )
|
||||||
f.expression = expression;
|
f.expression = expression;
|
||||||
}
|
}
|
||||||
@ -395,7 +386,7 @@ QList<QgsFieldMappingModel::Field> QgsFieldMappingModel::mapping() const
|
|||||||
return mMapping;
|
return mMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsFieldMappingModel::appendField( const QgsField &field, const QgsExpression &expression )
|
void QgsFieldMappingModel::appendField( const QgsField &field, const QString &expression )
|
||||||
{
|
{
|
||||||
const int lastRow { rowCount( QModelIndex( ) ) };
|
const int lastRow { rowCount( QModelIndex( ) ) };
|
||||||
beginInsertRows( QModelIndex(), lastRow, lastRow );
|
beginInsertRows( QModelIndex(), lastRow, lastRow );
|
||||||
@ -432,3 +423,18 @@ bool QgsFieldMappingModel::moveDown( const QModelIndex &index )
|
|||||||
return moveUpOrDown( index, false );
|
return moveUpOrDown( index, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QgsFieldMappingModel::ExpressionContextGenerator::ExpressionContextGenerator( const QgsFields *sourceFields )
|
||||||
|
: mSourceFields( sourceFields )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsExpressionContext QgsFieldMappingModel::ExpressionContextGenerator::createExpressionContext() const
|
||||||
|
{
|
||||||
|
QgsExpressionContext ctx;
|
||||||
|
ctx.appendScope( QgsExpressionContextUtils::globalScope() );
|
||||||
|
ctx.setFields( *mSourceFields );
|
||||||
|
QgsFeature feature { *mSourceFields };
|
||||||
|
feature.setValid( true );
|
||||||
|
ctx.setFeature( feature );
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|||||||
@ -20,7 +20,6 @@
|
|||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
#include "qgsfields.h"
|
#include "qgsfields.h"
|
||||||
#include "qgsexpression.h"
|
|
||||||
#include "qgsexpressioncontextgenerator.h"
|
#include "qgsexpressioncontextgenerator.h"
|
||||||
#include "qgsfieldconstraints.h"
|
#include "qgsfieldconstraints.h"
|
||||||
#include "qgis_gui.h"
|
#include "qgis_gui.h"
|
||||||
@ -68,7 +67,7 @@ class GUI_EXPORT QgsFieldMappingModel: public QAbstractTableModel
|
|||||||
//! The field in its current status (it might have been renamed)
|
//! The field in its current status (it might have been renamed)
|
||||||
QgsField field;
|
QgsField field;
|
||||||
//! The expression for the mapped field from the source fields
|
//! The expression for the mapped field from the source fields
|
||||||
QgsExpression expression;
|
QString expression;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,12 +79,9 @@ class GUI_EXPORT QgsFieldMappingModel: public QAbstractTableModel
|
|||||||
*/
|
*/
|
||||||
QgsFieldMappingModel( const QgsFields &sourceFields = QgsFields(),
|
QgsFieldMappingModel( const QgsFields &sourceFields = QgsFields(),
|
||||||
const QgsFields &destinationFields = QgsFields(),
|
const QgsFields &destinationFields = QgsFields(),
|
||||||
const QMap<QString, QgsExpression> &expressions = QMap<QString, QgsExpression>(),
|
const QMap<QString, QString> &expressions = QMap<QString, QString>(),
|
||||||
QObject *parent = nullptr );
|
QObject *parent = nullptr );
|
||||||
|
|
||||||
//! Returns the context generator with the source fields
|
|
||||||
QgsExpressionContextGenerator *contextGenerator() const;
|
|
||||||
|
|
||||||
//! Returns TRUE if the destination fields are editable
|
//! Returns TRUE if the destination fields are editable
|
||||||
bool destinationEditable() const;
|
bool destinationEditable() const;
|
||||||
|
|
||||||
@ -102,7 +98,7 @@ class GUI_EXPORT QgsFieldMappingModel: public QAbstractTableModel
|
|||||||
QList<QgsFieldMappingModel::Field> mapping() const;
|
QList<QgsFieldMappingModel::Field> mapping() const;
|
||||||
|
|
||||||
//! Appends a new \a field to the model, with an optional \a expression
|
//! Appends a new \a field to the model, with an optional \a expression
|
||||||
void appendField( const QgsField &field, const QgsExpression &expression = QgsExpression() );
|
void appendField( const QgsField &field, const QString &expression = QString() );
|
||||||
|
|
||||||
//! Removes the field at \a index from the model, returns TRUE on success
|
//! Removes the field at \a index from the model, returns TRUE on success
|
||||||
bool removeField( const QModelIndex &index );
|
bool removeField( const QModelIndex &index );
|
||||||
@ -116,13 +112,16 @@ class GUI_EXPORT QgsFieldMappingModel: public QAbstractTableModel
|
|||||||
//! Set source fields to \a sourceFields
|
//! Set source fields to \a sourceFields
|
||||||
void setSourceFields( const QgsFields &sourceFields );
|
void setSourceFields( const QgsFields &sourceFields );
|
||||||
|
|
||||||
|
//! Returns the context generator with the source fields
|
||||||
|
QgsExpressionContextGenerator *contextGenerator() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set destination fields to \a destinationFields, initial values for the expressions can be
|
* Set destination fields to \a destinationFields, initial values for the expressions can be
|
||||||
* optionally specified through \a expressions which is a map from the original
|
* optionally specified through \a expressions which is a map from the original
|
||||||
* field name to the corresponding expression.
|
* field name to the corresponding expression.
|
||||||
*/
|
*/
|
||||||
void setDestinationFields( const QgsFields &destinationFields,
|
void setDestinationFields( const QgsFields &destinationFields,
|
||||||
const QMap<QString, QgsExpression> &expressions = QMap<QString, QgsExpression>() );
|
const QMap<QString, QString> &expressions = QMap<QString, QString>() );
|
||||||
|
|
||||||
// QAbstractItemModel interface
|
// QAbstractItemModel interface
|
||||||
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
|
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
|
||||||
@ -150,16 +149,27 @@ class GUI_EXPORT QgsFieldMappingModel: public QAbstractTableModel
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
QgsFieldConstraints::Constraints fieldConstraints( const QgsField &field ) const;
|
QgsFieldConstraints::Constraints fieldConstraints( const QgsField &field ) const;
|
||||||
|
|
||||||
bool moveUpOrDown( const QModelIndex &index, bool up = true );
|
bool moveUpOrDown( const QModelIndex &index, bool up = true );
|
||||||
|
|
||||||
QString bestMatchforField( const QgsFieldMappingModel::Field &field, QStringList &excludedFieldNames );
|
/**
|
||||||
|
* Try to find the best expression for a destination \a field by searching in the
|
||||||
|
* source fields for fields with:
|
||||||
|
* - the same name
|
||||||
|
* - the same type
|
||||||
|
* Returns an expression containing a reference to the field that matches first.
|
||||||
|
*/
|
||||||
|
QString findExpressionForDestinationField( const QgsFieldMappingModel::Field &field, QStringList &excludedFieldNames );
|
||||||
|
|
||||||
QList<Field> mMapping;
|
QList<Field> mMapping;
|
||||||
bool mDestinationEditable = false;
|
bool mDestinationEditable = false;
|
||||||
QgsFields mSourceFields;
|
QgsFields mSourceFields;
|
||||||
std::unique_ptr<ExpressionContextGenerator> mExpressionContextGenerator;
|
std::unique_ptr<ExpressionContextGenerator> mExpressionContextGenerator;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // QGSFIELDMAPPINGMODEL_H
|
#endif // QGSFIELDMAPPINGMODEL_H
|
||||||
|
|||||||
@ -16,17 +16,27 @@
|
|||||||
|
|
||||||
#include "qgsfieldmappingwidget.h"
|
#include "qgsfieldmappingwidget.h"
|
||||||
#include "qgsfieldexpressionwidget.h"
|
#include "qgsfieldexpressionwidget.h"
|
||||||
|
#include "qgsexpression.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_MODELTEST
|
||||||
|
#include "modeltest.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
QgsFieldMappingWidget::QgsFieldMappingWidget( QWidget *parent,
|
QgsFieldMappingWidget::QgsFieldMappingWidget( QWidget *parent,
|
||||||
const QgsFields &sourceFields,
|
const QgsFields &sourceFields,
|
||||||
const QgsFields &destinationFields,
|
const QgsFields &destinationFields,
|
||||||
const QMap<QString, QgsExpression> &expressions )
|
const QMap<QString, QString> &expressions )
|
||||||
: QWidget( parent )
|
: QWidget( parent )
|
||||||
{
|
{
|
||||||
|
|
||||||
setupUi( this );
|
setupUi( this );
|
||||||
|
|
||||||
mModel = new QgsFieldMappingModel( sourceFields, destinationFields, expressions, this );
|
mModel = new QgsFieldMappingModel( sourceFields, destinationFields, expressions, this );
|
||||||
|
|
||||||
|
#ifdef ENABLE_MODELTEST
|
||||||
|
new ModelTest( mModel, this );
|
||||||
|
#endif
|
||||||
|
|
||||||
mTableView->setModel( mModel );
|
mTableView->setModel( mModel );
|
||||||
mTableView->setItemDelegateForColumn( static_cast<int>( QgsFieldMappingModel::ColumnDataIndex::SourceExpression ), new ExpressionDelegate( mTableView ) );
|
mTableView->setItemDelegateForColumn( static_cast<int>( QgsFieldMappingModel::ColumnDataIndex::SourceExpression ), new ExpressionDelegate( mTableView ) );
|
||||||
mTableView->setItemDelegateForColumn( static_cast<int>( QgsFieldMappingModel::ColumnDataIndex::DestinationType ), new TypeDelegate( mTableView ) );
|
mTableView->setItemDelegateForColumn( static_cast<int>( QgsFieldMappingModel::ColumnDataIndex::DestinationType ), new TypeDelegate( mTableView ) );
|
||||||
@ -67,7 +77,7 @@ void QgsFieldMappingWidget::setSourceFields( const QgsFields &sourceFields )
|
|||||||
model()->setSourceFields( sourceFields );
|
model()->setSourceFields( sourceFields );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsFieldMappingWidget::setDestinationFields( const QgsFields &destinationFields, const QMap<QString, QgsExpression> &expressions )
|
void QgsFieldMappingWidget::setDestinationFields( const QgsFields &destinationFields, const QMap<QString, QString> &expressions )
|
||||||
{
|
{
|
||||||
model()->setDestinationFields( destinationFields, expressions );
|
model()->setDestinationFields( destinationFields, expressions );
|
||||||
}
|
}
|
||||||
@ -77,7 +87,7 @@ void QgsFieldMappingWidget::scrollTo( const QModelIndex &index ) const
|
|||||||
mTableView->scrollTo( index );
|
mTableView->scrollTo( index );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsFieldMappingWidget::appendField( const QgsField &field, const QgsExpression &expression )
|
void QgsFieldMappingWidget::appendField( const QgsField &field, const QString &expression )
|
||||||
{
|
{
|
||||||
model()->appendField( field, expression );
|
model()->appendField( field, expression );
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ class GUI_EXPORT QgsFieldMappingWidget : public QWidget, private Ui::QgsFieldMap
|
|||||||
explicit QgsFieldMappingWidget( QWidget *parent = nullptr,
|
explicit QgsFieldMappingWidget( QWidget *parent = nullptr,
|
||||||
const QgsFields &sourceFields = QgsFields(),
|
const QgsFields &sourceFields = QgsFields(),
|
||||||
const QgsFields &destinationFields = QgsFields(),
|
const QgsFields &destinationFields = QgsFields(),
|
||||||
const QMap<QString, QgsExpression> &expressions = QMap<QString, QgsExpression>() );
|
const QMap<QString, QString> &expressions = QMap<QString, QString>() );
|
||||||
|
|
||||||
//! Sets the destination fields editable state to \a editable
|
//! Sets the destination fields editable state to \a editable
|
||||||
void setDestinationEditable( bool editable );
|
void setDestinationEditable( bool editable );
|
||||||
@ -74,7 +74,7 @@ class GUI_EXPORT QgsFieldMappingWidget : public QWidget, private Ui::QgsFieldMap
|
|||||||
* corresponding expression.
|
* corresponding expression.
|
||||||
*/
|
*/
|
||||||
void setDestinationFields( const QgsFields &destinationFields,
|
void setDestinationFields( const QgsFields &destinationFields,
|
||||||
const QMap<QString, QgsExpression> &expressions = QMap<QString, QgsExpression>() );
|
const QMap<QString, QString> &expressions = QMap<QString, QString>() );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll the fields view to \a index
|
* Scroll the fields view to \a index
|
||||||
@ -84,7 +84,7 @@ class GUI_EXPORT QgsFieldMappingWidget : public QWidget, private Ui::QgsFieldMap
|
|||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
//! Appends a new \a field to the model, with an optional \a expression
|
//! Appends a new \a field to the model, with an optional \a expression
|
||||||
void appendField( const QgsField &field, const QgsExpression &expression = QgsExpression() );
|
void appendField( const QgsField &field, const QString &expression = QString() );
|
||||||
|
|
||||||
//! Removes the currently selected field from the model
|
//! Removes the currently selected field from the model
|
||||||
bool removeSelectedFields( );
|
bool removeSelectedFields( );
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user