Skip to content

Commit 33eb295

Browse files
committedSep 21, 2018
Distance parameter unit tests
1 parent 1166768 commit 33eb295

File tree

3 files changed

+216
-35
lines changed

3 files changed

+216
-35
lines changed
 

‎src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -659,47 +659,65 @@ QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingDistanceWidgetWrapper:
659659
QWidget *QgsProcessingDistanceWidgetWrapper::createWidget()
660660
{
661661
QWidget *spin = QgsProcessingNumericWidgetWrapper::createWidget();
662+
switch ( type() )
663+
{
664+
case QgsProcessingGui::Standard:
665+
{
666+
mLabel = new QLabel();
667+
mUnitsCombo = new QComboBox();
668+
669+
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceMeters ), QgsUnitTypes::DistanceMeters );
670+
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceKilometers ), QgsUnitTypes::DistanceKilometers );
671+
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceFeet ), QgsUnitTypes::DistanceFeet );
672+
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceMiles ), QgsUnitTypes::DistanceMiles );
673+
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceYards ), QgsUnitTypes::DistanceYards );
674+
675+
const int labelMargin = static_cast< int >( std::round( mUnitsCombo->fontMetrics().width( 'X' ) ) );
676+
QHBoxLayout *layout = new QHBoxLayout();
677+
layout->addWidget( spin, 1 );
678+
layout->insertSpacing( 1, labelMargin / 2 );
679+
layout->insertWidget( 2, mLabel );
680+
layout->insertWidget( 3, mUnitsCombo );
681+
682+
// bit of fiddlyness here -- we want the initial spacing to only be visible
683+
// when the warning label is shown, so it's embedded inside mWarningLabel
684+
// instead of outside it
685+
mWarningLabel = new QWidget();
686+
QHBoxLayout *warningLayout = new QHBoxLayout();
687+
warningLayout->setMargin( 0 );
688+
warningLayout->setContentsMargins( 0, 0, 0, 0 );
689+
QLabel *warning = new QLabel();
690+
QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "mIconWarning.svg" ) );
691+
const int size = static_cast< int >( std::max( 24.0, spin->minimumSize().height() * 0.5 ) );
692+
warning->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
693+
warning->setToolTip( tr( "Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results." ) );
694+
warningLayout->insertSpacing( 0, labelMargin / 2 );
695+
warningLayout->insertWidget( 1, warning );
696+
mWarningLabel->setLayout( warningLayout );
697+
layout->insertWidget( 4, mWarningLabel );
698+
699+
setUnits( QgsUnitTypes::DistanceUnknownUnit );
662700

663-
mLabel = new QLabel();
664-
mUnitsCombo = new QComboBox();
665-
666-
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceMeters ), QgsUnitTypes::DistanceMeters );
667-
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceKilometers ), QgsUnitTypes::DistanceKilometers );
668-
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceFeet ), QgsUnitTypes::DistanceFeet );
669-
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceMiles ), QgsUnitTypes::DistanceMiles );
670-
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceYards ), QgsUnitTypes::DistanceYards );
671-
672-
const double labelMargin = mUnitsCombo->fontMetrics().width( 'X' );
673-
QHBoxLayout *layout = new QHBoxLayout();
674-
layout->addWidget( spin, 1 );
675-
layout->insertSpacing( 1, labelMargin / 2 );
676-
layout->insertWidget( 2, mLabel );
677-
layout->insertWidget( 3, mUnitsCombo );
678-
layout->insertSpacing( 4, labelMargin / 2 );
679-
680-
mWarningLabel = new QLabel();
681-
QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "mIconWarning.svg" ) );
682-
const int size = static_cast< int >( std::max( 24.0, spin->height() * 0.5 ) );
683-
mWarningLabel->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
684-
mWarningLabel->setToolTip( tr( "Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results." ) );
685-
layout->insertWidget( 4, mWarningLabel );
686-
layout->insertSpacing( 5, labelMargin );
701+
QWidget *w = new QWidget();
702+
layout->setMargin( 0 );
703+
layout->setContentsMargins( 0, 0, 0, 0 );
704+
w->setLayout( layout );
705+
return w;
706+
}
687707

688-
setUnits( QgsUnitTypes::DistanceUnknownUnit );
708+
case QgsProcessingGui::Batch:
709+
case QgsProcessingGui::Modeler:
710+
return spin;
689711

690-
QWidget *w = new QWidget();
691-
layout->setMargin( 0 );
692-
layout->setContentsMargins( 0, 0, 0, 0 );
693-
w->setLayout( layout );
694-
return w;
712+
}
713+
return nullptr;
695714
}
696715

697716
void QgsProcessingDistanceWidgetWrapper::postInitialize( const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
698717
{
699718
QgsProcessingNumericWidgetWrapper::postInitialize( wrappers );
700719
switch ( type() )
701720
{
702-
case QgsProcessingGui::Batch:
703721
case QgsProcessingGui::Standard:
704722
{
705723
for ( const QgsAbstractProcessingParameterWidgetWrapper *wrapper : wrappers )
@@ -717,6 +735,7 @@ void QgsProcessingDistanceWidgetWrapper::postInitialize( const QList<QgsAbstract
717735
break;
718736
}
719737

738+
case QgsProcessingGui::Batch:
720739
case QgsProcessingGui::Modeler:
721740
break;
722741
}
@@ -760,15 +779,15 @@ void QgsProcessingDistanceWidgetWrapper::setUnits( const QgsUnitTypes::DistanceU
760779
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( units ) );
761780
mUnitsCombo->show();
762781
mLabel->hide();
763-
mWarningLabel->setVisible( units == QgsUnitTypes::DistanceDegrees );
764-
mBaseUnit = units;
765782
}
783+
mWarningLabel->setVisible( units == QgsUnitTypes::DistanceDegrees );
784+
mBaseUnit = units;
766785
}
767786

768787
QVariant QgsProcessingDistanceWidgetWrapper::widgetValue() const
769788
{
770789
const QVariant val = QgsProcessingNumericWidgetWrapper::widgetValue();
771-
if ( val.type() == QVariant::Double && mUnitsCombo->isVisible() )
790+
if ( val.type() == QVariant::Double && mUnitsCombo && mUnitsCombo->isVisible() )
772791
{
773792
QgsUnitTypes::DistanceUnit displayUnit = static_cast<QgsUnitTypes::DistanceUnit >( mUnitsCombo->currentData().toInt() );
774793
return val.toDouble() * QgsUnitTypes::fromUnitToUnitFactor( displayUnit, mBaseUnit );

‎src/gui/processing/qgsprocessingwidgetwrapperimpl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ class GUI_EXPORT QgsProcessingDistanceWidgetWrapper : public QgsProcessingNumeri
209209

210210
QgsUnitTypes::DistanceUnit mBaseUnit = QgsUnitTypes::DistanceUnknownUnit;
211211
QLabel *mLabel = nullptr;
212-
QLabel *mWarningLabel = nullptr;
212+
QWidget *mWarningLabel = nullptr;
213213
QComboBox *mUnitsCombo = nullptr;
214214

215215
friend class TestProcessingGui;

‎tests/src/gui/testprocessinggui.cpp

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ class TestProcessingGui : public QObject
147147
void testCrsWrapper();
148148
void testNumericWrapperDouble();
149149
void testNumericWrapperInt();
150+
void testDistanceWrapper();
150151
};
151152

152153
void TestProcessingGui::initTestCase()
@@ -1149,5 +1150,166 @@ void TestProcessingGui::testNumericWrapperInt()
11491150
testWrapper( QgsProcessingGui::Modeler );
11501151
}
11511152

1153+
void TestProcessingGui::testDistanceWrapper()
1154+
{
1155+
QgsProcessingParameterDistance param( QStringLiteral( "distance" ), QStringLiteral( "distance" ) );
1156+
1157+
// standard wrapper
1158+
QgsProcessingDistanceWidgetWrapper wrapper( &param );
1159+
1160+
QgsProcessingContext context;
1161+
QWidget *w = wrapper.createWrappedWidget( context );
1162+
1163+
QSignalSpy spy( &wrapper, &QgsProcessingDistanceWidgetWrapper::widgetValueHasChanged );
1164+
wrapper.setWidgetValue( 55.5, context );
1165+
QCOMPARE( spy.count(), 1 );
1166+
QCOMPARE( wrapper.widgetValue().toDouble(), 55.5 );
1167+
QCOMPARE( wrapper.mDoubleSpinBox->value(), 55.5 );
1168+
wrapper.setWidgetValue( -34.0, context );
1169+
QCOMPARE( spy.count(), 2 );
1170+
QCOMPARE( wrapper.widgetValue().toDouble(), -34.0 );
1171+
QCOMPARE( wrapper.mDoubleSpinBox->value(), -34.0 );
1172+
1173+
QLabel *l = wrapper.createWrappedLabel();
1174+
QVERIFY( l );
1175+
QCOMPARE( l->text(), QStringLiteral( "distance" ) );
1176+
QCOMPARE( l->toolTip(), param.toolTip() );
1177+
delete l;
1178+
1179+
// check signal
1180+
wrapper.mDoubleSpinBox->setValue( 43.0 );
1181+
QCOMPARE( spy.count(), 3 );
1182+
1183+
// test unit handling
1184+
w->show();
1185+
1186+
// crs values
1187+
wrapper.setUnitParameterValue( QStringLiteral( "EPSG:3111" ) );
1188+
QCOMPARE( wrapper.mLabel->text(), QStringLiteral( "meters" ) );
1189+
QVERIFY( !wrapper.mWarningLabel->isVisible() );
1190+
QVERIFY( wrapper.mUnitsCombo->isVisible() );
1191+
QVERIFY( !wrapper.mLabel->isVisible() );
1192+
QCOMPARE( wrapper.mUnitsCombo->currentData().toInt(), static_cast< int >( QgsUnitTypes::DistanceMeters ) );
1193+
1194+
wrapper.setUnitParameterValue( QStringLiteral( "EPSG:4326" ) );
1195+
QCOMPARE( wrapper.mLabel->text(), QStringLiteral( "degrees" ) );
1196+
QVERIFY( wrapper.mWarningLabel->isVisible() );
1197+
QVERIFY( !wrapper.mUnitsCombo->isVisible() );
1198+
QVERIFY( wrapper.mLabel->isVisible() );
1199+
1200+
wrapper.setUnitParameterValue( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3111" ) ) );
1201+
QCOMPARE( wrapper.mLabel->text(), QStringLiteral( "meters" ) );
1202+
QVERIFY( !wrapper.mWarningLabel->isVisible() );
1203+
QVERIFY( wrapper.mUnitsCombo->isVisible() );
1204+
QVERIFY( !wrapper.mLabel->isVisible() );
1205+
QCOMPARE( wrapper.mUnitsCombo->currentData().toInt(), static_cast< int >( QgsUnitTypes::DistanceMeters ) );
1206+
1207+
wrapper.setUnitParameterValue( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) );
1208+
QCOMPARE( wrapper.mLabel->text(), QStringLiteral( "degrees" ) );
1209+
QVERIFY( wrapper.mWarningLabel->isVisible() );
1210+
QVERIFY( !wrapper.mUnitsCombo->isVisible() );
1211+
QVERIFY( wrapper.mLabel->isVisible() );
1212+
1213+
// layer values
1214+
std::unique_ptr< QgsVectorLayer > vl = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "Polygon?crs=epsg:3111&field=pk:int" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) );
1215+
wrapper.setUnitParameterValue( QVariant::fromValue( vl.get() ) );
1216+
QCOMPARE( wrapper.mLabel->text(), QStringLiteral( "meters" ) );
1217+
QVERIFY( !wrapper.mWarningLabel->isVisible() );
1218+
QVERIFY( wrapper.mUnitsCombo->isVisible() );
1219+
QVERIFY( !wrapper.mLabel->isVisible() );
1220+
QCOMPARE( wrapper.mUnitsCombo->currentData().toInt(), static_cast< int >( QgsUnitTypes::DistanceMeters ) );
1221+
1222+
std::unique_ptr< QgsVectorLayer > vl2 = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "Polygon?crs=epsg:4326&field=pk:int" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) );
1223+
wrapper.setUnitParameterValue( QVariant::fromValue( vl2.get() ) );
1224+
QCOMPARE( wrapper.mLabel->text(), QStringLiteral( "degrees" ) );
1225+
QVERIFY( wrapper.mWarningLabel->isVisible() );
1226+
QVERIFY( !wrapper.mUnitsCombo->isVisible() );
1227+
QVERIFY( wrapper.mLabel->isVisible() );
1228+
1229+
// unresolvable values
1230+
wrapper.setUnitParameterValue( QStringLiteral( "blah" ) );
1231+
QCOMPARE( wrapper.mLabel->text(), QStringLiteral( "<unknown>" ) );
1232+
QVERIFY( !wrapper.mWarningLabel->isVisible() );
1233+
QVERIFY( !wrapper.mUnitsCombo->isVisible() );
1234+
QVERIFY( wrapper.mLabel->isVisible() );
1235+
1236+
// resolvable text value
1237+
const QString id = vl->id();
1238+
QgsProject::instance()->addMapLayer( vl.release() );
1239+
context.setProject( QgsProject::instance() );
1240+
1241+
TestProcessingContextGenerator generator( context );
1242+
wrapper.registerProcessingContextGenerator( &generator );
1243+
wrapper.setUnitParameterValue( id );
1244+
QCOMPARE( wrapper.mLabel->text(), QStringLiteral( "meters" ) );
1245+
QVERIFY( !wrapper.mWarningLabel->isVisible() );
1246+
QVERIFY( wrapper.mUnitsCombo->isVisible() );
1247+
QVERIFY( !wrapper.mLabel->isVisible() );
1248+
QCOMPARE( wrapper.mUnitsCombo->currentData().toInt(), static_cast< int >( QgsUnitTypes::DistanceMeters ) );
1249+
1250+
// using unit choice
1251+
wrapper.setParameterValue( 5, context );
1252+
QCOMPARE( wrapper.parameterValue().toDouble(), 5.0 );
1253+
wrapper.mUnitsCombo->setCurrentIndex( wrapper.mUnitsCombo->findData( QgsUnitTypes::DistanceKilometers ) );
1254+
QCOMPARE( wrapper.parameterValue().toDouble(), 5000.0 );
1255+
wrapper.setParameterValue( 2, context );
1256+
QCOMPARE( wrapper.parameterValue().toDouble(), 2000.0 );
1257+
1258+
wrapper.setUnitParameterValue( id );
1259+
QCOMPARE( wrapper.parameterValue().toDouble(), 2 );
1260+
wrapper.setParameterValue( 5, context );
1261+
QCOMPARE( wrapper.parameterValue().toDouble(), 5.0 );
1262+
1263+
delete w;
1264+
1265+
// batch wrapper
1266+
QgsProcessingDistanceWidgetWrapper wrapperB( &param, QgsProcessingGui::Batch );
1267+
1268+
w = wrapperB.createWrappedWidget( context );
1269+
QSignalSpy spy2( &wrapperB, &QgsProcessingDistanceWidgetWrapper::widgetValueHasChanged );
1270+
wrapperB.setWidgetValue( 34, context );
1271+
QCOMPARE( spy2.count(), 1 );
1272+
QCOMPARE( wrapperB.widgetValue().toDouble(), 34.0 );
1273+
QCOMPARE( wrapperB.mDoubleSpinBox->value(), 34.0 );
1274+
wrapperB.setWidgetValue( -57, context );
1275+
QCOMPARE( spy2.count(), 2 );
1276+
QCOMPARE( wrapperB.widgetValue().toDouble(), -57.0 );
1277+
QCOMPARE( wrapperB.mDoubleSpinBox->value(), -57.0 );
1278+
1279+
// check signal
1280+
static_cast< QgsDoubleSpinBox * >( w )->setValue( 29 );
1281+
QCOMPARE( spy2.count(), 3 );
1282+
1283+
// should be no label in batch mode
1284+
QVERIFY( !wrapperB.createWrappedLabel() );
1285+
delete w;
1286+
1287+
// modeler wrapper
1288+
QgsProcessingDistanceWidgetWrapper wrapperM( &param, QgsProcessingGui::Modeler );
1289+
1290+
w = wrapperM.createWrappedWidget( context );
1291+
QSignalSpy spy3( &wrapperM, &QgsProcessingDistanceWidgetWrapper::widgetValueHasChanged );
1292+
wrapperM.setWidgetValue( 29, context );
1293+
QCOMPARE( wrapperM.widgetValue().toDouble(), 29 );
1294+
QCOMPARE( spy3.count(), 1 );
1295+
QCOMPARE( wrapperM.mDoubleSpinBox->value(), 29 );
1296+
wrapperM.setWidgetValue( -29, context );
1297+
QCOMPARE( wrapperM.widgetValue().toDouble(), -29 );
1298+
QCOMPARE( spy3.count(), 2 );
1299+
QCOMPARE( wrapperM.mDoubleSpinBox->value(), -29 );
1300+
1301+
// check signal
1302+
wrapperM.mDoubleSpinBox->setValue( 33 );
1303+
QCOMPARE( spy3.count(), 3 );
1304+
1305+
// should be a label in modeler mode
1306+
l = wrapperM.createWrappedLabel();
1307+
QVERIFY( l );
1308+
QCOMPARE( l->text(), QStringLiteral( "distance" ) );
1309+
QCOMPARE( l->toolTip(), param.toolTip() );
1310+
delete w;
1311+
delete l;
1312+
}
1313+
11521314
QGSTEST_MAIN( TestProcessingGui )
11531315
#include "testprocessinggui.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.