Skip to content

Commit

Permalink
Add methods to QgsFieldMappingModel to retrieve/set QgsProperty based…
Browse files Browse the repository at this point in the history
… definitions
  • Loading branch information
nyalldawson committed Apr 7, 2020
1 parent 8050612 commit a3c7a05
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 1 deletion.
15 changes: 15 additions & 0 deletions python/gui/auto_generated/qgsfieldmappingmodel.sip.in
Expand Up @@ -79,6 +79,21 @@ Returns a list of source fields
QList<QgsFieldMappingModel::Field> mapping() const;
%Docstring
Returns a list of Field objects representing the current status of the model
%End

QMap< QString, QgsProperty > fieldPropertyMap() const;
%Docstring
Returns a map of destination field name to QgsProperty definition for field value,
representing the current status of the model.

.. seealso:: :py:func:`setFieldPropertyMap`
%End

void setFieldPropertyMap( const QMap< QString, QgsProperty > &map );
%Docstring
Sets a map of destination field name to QgsProperty definition for field value.

.. seealso:: :py:func:`fieldPropertyMap`
%End

void appendField( const QgsField &field, const QString &expression = QString() );
Expand Down
15 changes: 15 additions & 0 deletions python/gui/auto_generated/qgsfieldmappingwidget.sip.in
Expand Up @@ -53,6 +53,21 @@ Returns the underlying mapping model
QList<QgsFieldMappingModel::Field> mapping() const;
%Docstring
Returns a list of Field objects representing the current status of the underlying mapping model
%End

QMap< QString, QgsProperty > fieldPropertyMap() const;
%Docstring
Returns a map of destination field name to QgsProperty definition for field value,
representing the current status of the widget.

.. seealso:: :py:func:`setFieldPropertyMap`
%End

void setFieldPropertyMap( const QMap< QString, QgsProperty > &map );
%Docstring
Sets a map of destination field name to QgsProperty definition for field value.

.. seealso:: :py:func:`fieldPropertyMap`
%End

QItemSelectionModel *selectionModel();
Expand Down
52 changes: 51 additions & 1 deletion src/gui/qgsfieldmappingmodel.cpp
Expand Up @@ -16,7 +16,7 @@

#include "qgsfieldmappingmodel.h"
#include "qgsexpressioncontextutils.h"

#include "qgsexpressionnodeimpl.h"

QgsFieldMappingModel::QgsFieldMappingModel( const QgsFields &sourceFields,
const QgsFields &destinationFields,
Expand Down Expand Up @@ -402,6 +402,56 @@ QList<QgsFieldMappingModel::Field> QgsFieldMappingModel::mapping() const
return mMapping;
}

QMap<QString, QgsProperty> QgsFieldMappingModel::fieldPropertyMap() const
{
QMap< QString, QgsProperty > fieldMap;
for ( const QgsFieldMappingModel::Field &field : mMapping )
{
const QgsExpression exp( field.expression );
const bool isField = exp.isField();
fieldMap.insert( field.originalName, isField
? QgsProperty::fromField( static_cast<const QgsExpressionNodeColumnRef *>( exp.rootNode() )->name() )
: QgsProperty::fromExpression( field.expression ) );
}
return fieldMap;
}

void QgsFieldMappingModel::setFieldPropertyMap( const QMap<QString, QgsProperty> &map )
{
beginResetModel();
for ( int i = 0; i < mMapping.count(); ++i )
{
Field &f = mMapping[i];
if ( map.contains( f.field.name() ) )
{
const QgsProperty prop = map.value( f.field.name() );
switch ( prop.propertyType() )
{
case QgsProperty::StaticProperty:
f.expression = QgsExpression::quotedValue( prop.staticValue() );
break;

case QgsProperty::FieldBasedProperty:
f.expression = prop.field();
break;

case QgsProperty::ExpressionBasedProperty:
f.expression = prop.expressionString();
break;

case QgsProperty::InvalidProperty:
f.expression.clear();
break;
}
}
else
{
f.expression.clear();
}
}
endResetModel();
}

void QgsFieldMappingModel::appendField( const QgsField &field, const QString &expression )
{
const int lastRow { rowCount( QModelIndex( ) ) };
Expand Down
16 changes: 16 additions & 0 deletions src/gui/qgsfieldmappingmodel.h
Expand Up @@ -22,6 +22,7 @@
#include "qgsfields.h"
#include "qgsexpressioncontextgenerator.h"
#include "qgsfieldconstraints.h"
#include "qgsproperty.h"
#include "qgis_gui.h"


Expand Down Expand Up @@ -97,6 +98,21 @@ class GUI_EXPORT QgsFieldMappingModel: public QAbstractTableModel
//! Returns a list of Field objects representing the current status of the model
QList<QgsFieldMappingModel::Field> mapping() const;

/**
* Returns a map of destination field name to QgsProperty definition for field value,
* representing the current status of the model.
*
* \see setFieldPropertyMap()
*/
QMap< QString, QgsProperty > fieldPropertyMap() const;

/**
* Sets a map of destination field name to QgsProperty definition for field value.
*
* \see fieldPropertyMap()
*/
void setFieldPropertyMap( const QMap< QString, QgsProperty > &map );

//! Appends a new \a field to the model, with an optional \a expression
void appendField( const QgsField &field, const QString &expression = QString() );

Expand Down
10 changes: 10 additions & 0 deletions src/gui/qgsfieldmappingwidget.cpp
Expand Up @@ -67,6 +67,16 @@ QList<QgsFieldMappingModel::Field> QgsFieldMappingWidget::mapping() const
return model()->mapping();
}

QMap<QString, QgsProperty> QgsFieldMappingWidget::fieldPropertyMap() const
{
return model()->fieldPropertyMap();
}

void QgsFieldMappingWidget::setFieldPropertyMap( const QMap<QString, QgsProperty> &map )
{
model()->setFieldPropertyMap( map );
}

QItemSelectionModel *QgsFieldMappingWidget::selectionModel()
{
return mTableView->selectionModel();
Expand Down
15 changes: 15 additions & 0 deletions src/gui/qgsfieldmappingwidget.h
Expand Up @@ -61,6 +61,21 @@ class GUI_EXPORT QgsFieldMappingWidget : public QgsPanelWidget, private Ui::QgsF
//! Returns a list of Field objects representing the current status of the underlying mapping model
QList<QgsFieldMappingModel::Field> mapping() const;

/**
* Returns a map of destination field name to QgsProperty definition for field value,
* representing the current status of the widget.
*
* \see setFieldPropertyMap()
*/
QMap< QString, QgsProperty > fieldPropertyMap() const;

/**
* Sets a map of destination field name to QgsProperty definition for field value.
*
* \see fieldPropertyMap()
*/
void setFieldPropertyMap( const QMap< QString, QgsProperty > &map );

//! Returns the selection model
QItemSelectionModel *selectionModel();

Expand Down
37 changes: 37 additions & 0 deletions tests/src/python/test_qgsfieldmappingwidget.py
Expand Up @@ -17,6 +17,7 @@
QgsFields,
QgsField,
QgsFieldConstraints,
QgsProperty
)
from qgis.gui import (
QgsFieldMappingWidget,
Expand Down Expand Up @@ -173,6 +174,42 @@ def testSetSourceFields(self):
self.assertEqual(model.data(model.index(2, 0), Qt.DisplayRole), '"source_field3"')
self.assertEqual(model.data(model.index(2, 1), Qt.DisplayRole), 'destination_field3')

def testProperties(self):
model = QgsFieldMappingModel(self.source_fields, self.destination_fields)
model.setDestinationFields(self.destination_fields, {'destination_field1': '5',
'destination_field2': 'source_field2',
'destination_field3': 'source_field2 * @myvar'})

mapping = model.mapping()
self.assertEqual(mapping[0].field.name(), 'destination_field1')
self.assertEqual(mapping[1].field.name(), 'destination_field2')
self.assertEqual(mapping[2].field.name(), 'destination_field3')
self.assertEqual(mapping[0].expression, '5')
self.assertEqual(mapping[1].expression, 'source_field2')
self.assertEqual(mapping[2].expression, 'source_field2 * @myvar')

self.assertEqual(model.fieldPropertyMap(), {'destination_field1': QgsProperty.fromExpression('5'),
'destination_field2': QgsProperty.fromField('source_field2'),
'destination_field3': QgsProperty.fromExpression('source_field2 * @myvar'),
})

model = QgsFieldMappingModel(self.source_fields, self.destination_fields)
self.assertEqual(model.fieldPropertyMap(), {'destination_field1': QgsProperty.fromField('source_field2'),
'destination_field2': QgsProperty.fromField('source_field1'),
'destination_field3': QgsProperty.fromExpression(''),
})

model.setFieldPropertyMap({
'destination_field1': QgsProperty.fromField('source_field1'),
'destination_field2': QgsProperty.fromExpression('55*6'),
'destination_field3': QgsProperty.fromValue(6),
})
self.assertEqual(model.fieldPropertyMap(), {
'destination_field1': QgsProperty.fromField('source_field1'),
'destination_field2': QgsProperty.fromExpression('55*6'),
'destination_field3': QgsProperty.fromExpression('6'),
})

def testWidget(self):
"""Test widget operations"""

Expand Down

0 comments on commit a3c7a05

Please sign in to comment.