Skip to content

Commit 35e7fc7

Browse files
committedJan 5, 2020
Add widget wrapper for processing map theme parameter type
1 parent 54629b8 commit 35e7fc7

File tree

4 files changed

+267
-0
lines changed

4 files changed

+267
-0
lines changed
 

‎src/gui/processing/qgsprocessingguiregistry.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ QgsProcessingGuiRegistry::QgsProcessingGuiRegistry()
4545
addParameterWidgetFactory( new QgsProcessingColorWidgetWrapper() );
4646
addParameterWidgetFactory( new QgsProcessingCoordinateOperationWidgetWrapper() );
4747
addParameterWidgetFactory( new QgsProcessingFieldWidgetWrapper() );
48+
addParameterWidgetFactory( new QgsProcessingMapThemeWidgetWrapper() );
4849
}
4950

5051
QgsProcessingGuiRegistry::~QgsProcessingGuiRegistry()

‎src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "qgscoordinateoperationwidget.h"
4747
#include "qgsdatumtransformdialog.h"
4848
#include "qgsfieldcombobox.h"
49+
#include "qgsmapthemecollection.h"
4950
#include <QToolButton>
5051
#include <QLabel>
5152
#include <QHBoxLayout>
@@ -3494,4 +3495,113 @@ QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingFieldWidgetWrapper::cr
34943495
return new QgsProcessingFieldWidgetWrapper( parameter, type );
34953496
}
34963497

3498+
//
3499+
// QgsProcessingMapThemeWidgetWrapper
3500+
//
3501+
3502+
QgsProcessingMapThemeWidgetWrapper::QgsProcessingMapThemeWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
3503+
: QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
3504+
{
3505+
3506+
}
3507+
3508+
QWidget *QgsProcessingMapThemeWidgetWrapper::createWidget()
3509+
{
3510+
const QgsProcessingParameterMapTheme *themeParam = dynamic_cast< const QgsProcessingParameterMapTheme *>( parameterDefinition() );
3511+
3512+
mComboBox = new QComboBox();
3513+
3514+
if ( themeParam->flags() & QgsProcessingParameterDefinition::FlagOptional )
3515+
mComboBox->addItem( tr( "[Not selected]" ), QVariant( -1 ) );
3516+
3517+
const QStringList mapThemes = widgetContext().project() ? widgetContext().project()->mapThemeCollection()->mapThemes() : QgsProject::instance()->mapThemeCollection()->mapThemes();
3518+
for ( const QString &theme : mapThemes )
3519+
{
3520+
mComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "/mActionShowAllLayers.svg" ) ), theme, theme );
3521+
}
3522+
3523+
switch ( type() )
3524+
{
3525+
case QgsProcessingGui::Standard:
3526+
case QgsProcessingGui::Batch:
3527+
break;
3528+
3529+
case QgsProcessingGui::Modeler:
3530+
mComboBox->setEditable( true );
3531+
break;
3532+
}
3533+
3534+
mComboBox->setToolTip( parameterDefinition()->toolTip() );
3535+
connect( mComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
3536+
{
3537+
emit widgetValueHasChanged( this );
3538+
} );
3539+
3540+
return mComboBox;
3541+
}
3542+
3543+
void QgsProcessingMapThemeWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
3544+
{
3545+
const QString v = QgsProcessingParameters::parameterAsString( parameterDefinition(), value, context );
3546+
3547+
if ( !value.isValid() )
3548+
mComboBox->setCurrentIndex( mComboBox->findData( QVariant( -1 ) ) );
3549+
else
3550+
{
3551+
if ( mComboBox->isEditable() && mComboBox->findData( v ) == -1 )
3552+
{
3553+
const QString prev = mComboBox->currentText();
3554+
mComboBox->setCurrentText( v );
3555+
if ( prev != v )
3556+
emit widgetValueHasChanged( this );
3557+
}
3558+
else
3559+
mComboBox->setCurrentIndex( mComboBox->findData( v ) );
3560+
}
3561+
}
3562+
3563+
QVariant QgsProcessingMapThemeWidgetWrapper::widgetValue() const
3564+
{
3565+
if ( mComboBox )
3566+
return mComboBox->currentData().toInt() == -1 ? QVariant() :
3567+
!mComboBox->currentData().isValid() && mComboBox->isEditable() ? mComboBox->currentText().isEmpty() ? QVariant() : QVariant( mComboBox->currentText() )
3568+
: mComboBox->currentData();
3569+
else
3570+
return QVariant();
3571+
}
3572+
3573+
QStringList QgsProcessingMapThemeWidgetWrapper::compatibleParameterTypes() const
3574+
{
3575+
return QStringList()
3576+
<< QgsProcessingParameterString::typeName()
3577+
<< QgsProcessingParameterExpression::typeName();
3578+
}
3579+
3580+
QStringList QgsProcessingMapThemeWidgetWrapper::compatibleOutputTypes() const
3581+
{
3582+
return QStringList()
3583+
<< QgsProcessingOutputString::typeName();
3584+
}
3585+
3586+
QList<int> QgsProcessingMapThemeWidgetWrapper::compatibleDataTypes() const
3587+
{
3588+
return QList< int >();
3589+
}
3590+
3591+
QString QgsProcessingMapThemeWidgetWrapper::modelerExpressionFormatString() const
3592+
{
3593+
return tr( "map theme as a string value (e.g. 'base maps')" );
3594+
}
3595+
3596+
QString QgsProcessingMapThemeWidgetWrapper::parameterType() const
3597+
{
3598+
return QgsProcessingParameterMapTheme::typeName();
3599+
}
3600+
3601+
QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingMapThemeWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
3602+
{
3603+
return new QgsProcessingMapThemeWidgetWrapper( parameter, type );
3604+
}
3605+
3606+
34973607
///@endcond PRIVATE

‎src/gui/processing/qgsprocessingwidgetwrapperimpl.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,42 @@ class GUI_EXPORT QgsProcessingFieldWidgetWrapper : public QgsAbstractProcessingP
10321032
};
10331033

10341034

1035+
1036+
class GUI_EXPORT QgsProcessingMapThemeWidgetWrapper : public QgsAbstractProcessingParameterWidgetWrapper, public QgsProcessingParameterWidgetFactoryInterface
1037+
{
1038+
Q_OBJECT
1039+
1040+
public:
1041+
1042+
QgsProcessingMapThemeWidgetWrapper( const QgsProcessingParameterDefinition *parameter = nullptr,
1043+
QgsProcessingGui::WidgetType type = QgsProcessingGui::Standard, QWidget *parent = nullptr );
1044+
1045+
// QgsProcessingParameterWidgetFactoryInterface
1046+
QString parameterType() const override;
1047+
QgsAbstractProcessingParameterWidgetWrapper *createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type ) override;
1048+
1049+
// QgsProcessingParameterWidgetWrapper interface
1050+
QWidget *createWidget() override SIP_FACTORY;
1051+
1052+
protected:
1053+
1054+
void setWidgetValue( const QVariant &value, QgsProcessingContext &context ) override;
1055+
QVariant widgetValue() const override;
1056+
1057+
QStringList compatibleParameterTypes() const override;
1058+
1059+
QStringList compatibleOutputTypes() const override;
1060+
1061+
QList< int > compatibleDataTypes() const override;
1062+
QString modelerExpressionFormatString() const override;
1063+
1064+
private:
1065+
1066+
QComboBox *mComboBox = nullptr;
1067+
1068+
friend class TestProcessingGui;
1069+
};
1070+
10351071
///@endcond PRIVATE
10361072

10371073
#endif // QGSPROCESSINGWIDGETWRAPPERIMPL_H

‎tests/src/gui/testprocessinggui.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#include "qgscoordinateoperationwidget.h"
6767
#include "qgsmessagebar.h"
6868
#include "qgsfieldcombobox.h"
69+
#include "qgsmapthemecollection.h"
6970

7071
class TestParamType : public QgsProcessingParameterDefinition
7172
{
@@ -195,6 +196,7 @@ class TestProcessingGui : public QObject
195196
void testCoordinateOperationWrapper();
196197
void mapLayerComboBox();
197198
void paramConfigWidget();
199+
void testMapThemeWrapper();
198200

199201
private:
200202

@@ -4254,6 +4256,124 @@ void TestProcessingGui::paramConfigWidget()
42544256
QVERIFY( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced );
42554257
}
42564258

4259+
void TestProcessingGui::testMapThemeWrapper()
4260+
{
4261+
// add some themes to the project
4262+
QgsProject p;
4263+
p.mapThemeCollection()->insert( QStringLiteral( "aa" ), QgsMapThemeCollection::MapThemeRecord() );
4264+
p.mapThemeCollection()->insert( QStringLiteral( "bb" ), QgsMapThemeCollection::MapThemeRecord() );
4265+
4266+
QCOMPARE( p.mapThemeCollection()->mapThemes(), QStringList() << QStringLiteral( "aa" ) << QStringLiteral( "bb" ) );
4267+
4268+
auto testWrapper = [&p]( QgsProcessingGui::WidgetType type )
4269+
{
4270+
// non optional, no existing themes
4271+
QgsProcessingParameterMapTheme param( QStringLiteral( "theme" ), QStringLiteral( "theme" ), false );
4272+
4273+
QgsProcessingMapThemeWidgetWrapper wrapper( &param, type );
4274+
4275+
QgsProcessingContext context;
4276+
QWidget *w = wrapper.createWrappedWidget( context );
4277+
4278+
QSignalSpy spy( &wrapper, &QgsProcessingEnumWidgetWrapper::widgetValueHasChanged );
4279+
wrapper.setWidgetValue( QStringLiteral( "bb" ), context );
4280+
4281+
switch ( type )
4282+
{
4283+
case QgsProcessingGui::Standard:
4284+
case QgsProcessingGui::Batch:
4285+
// batch or standard mode, only valid themes can be set!
4286+
QCOMPARE( spy.count(), 0 );
4287+
QVERIFY( !wrapper.widgetValue().isValid() );
4288+
QCOMPARE( static_cast< QComboBox * >( wrapper.wrappedWidget() )->currentIndex(), -1 );
4289+
wrapper.setWidgetValue( QStringLiteral( "aa" ), context );
4290+
QCOMPARE( spy.count(), 0 );
4291+
QVERIFY( !wrapper.widgetValue().isValid() );
4292+
QCOMPARE( static_cast< QComboBox * >( wrapper.wrappedWidget() )->currentIndex(), -1 );
4293+
break;
4294+
4295+
case QgsProcessingGui::Modeler:
4296+
QCOMPARE( spy.count(), 1 );
4297+
QCOMPARE( wrapper.widgetValue().toString(), QStringLiteral( "bb" ) );
4298+
QCOMPARE( static_cast< QComboBox * >( wrapper.wrappedWidget() )->currentText(), QStringLiteral( "bb" ) );
4299+
wrapper.setWidgetValue( QStringLiteral( "aa" ), context );
4300+
QCOMPARE( spy.count(), 2 );
4301+
QCOMPARE( wrapper.widgetValue().toString(), QStringLiteral( "aa" ) );
4302+
QCOMPARE( static_cast< QComboBox * >( wrapper.wrappedWidget() )->currentText(), QStringLiteral( "aa" ) );
4303+
break;
4304+
}
4305+
4306+
delete w;
4307+
4308+
// with project
4309+
QgsProcessingParameterWidgetContext widgetContext;
4310+
widgetContext.setProject( &p );
4311+
4312+
QgsProcessingMapThemeWidgetWrapper wrapper2( &param, type );
4313+
wrapper2.setWidgetContext( widgetContext );
4314+
w = wrapper2.createWrappedWidget( context );
4315+
4316+
QSignalSpy spy2( &wrapper2, &QgsProcessingEnumWidgetWrapper::widgetValueHasChanged );
4317+
wrapper2.setWidgetValue( QStringLiteral( "bb" ), context );
4318+
QCOMPARE( spy2.count(), 1 );
4319+
QCOMPARE( wrapper2.widgetValue().toString(), QStringLiteral( "bb" ) );
4320+
QCOMPARE( static_cast< QComboBox * >( wrapper2.wrappedWidget() )->currentText(), QStringLiteral( "bb" ) );
4321+
wrapper2.setWidgetValue( QStringLiteral( "aa" ), context );
4322+
QCOMPARE( spy2.count(), 2 );
4323+
QCOMPARE( wrapper2.widgetValue().toString(), QStringLiteral( "aa" ) );
4324+
QCOMPARE( static_cast< QComboBox * >( wrapper2.wrappedWidget() )->currentText(), QStringLiteral( "aa" ) );
4325+
4326+
// check signal
4327+
static_cast< QComboBox * >( wrapper2.wrappedWidget() )->setCurrentIndex( 2 );
4328+
QCOMPARE( spy2.count(), 3 );
4329+
4330+
delete w;
4331+
4332+
// optional
4333+
QgsProcessingParameterMapTheme param2( QStringLiteral( "theme" ), QStringLiteral( "theme" ), true );
4334+
QgsProcessingMapThemeWidgetWrapper wrapper3( &param2, type );
4335+
wrapper3.setWidgetContext( widgetContext );
4336+
w = wrapper3.createWrappedWidget( context );
4337+
4338+
QSignalSpy spy3( &wrapper3, &QgsProcessingEnumWidgetWrapper::widgetValueHasChanged );
4339+
wrapper3.setWidgetValue( QStringLiteral( "bb" ), context );
4340+
QCOMPARE( spy3.count(), 1 );
4341+
QCOMPARE( wrapper3.widgetValue().toString(), QStringLiteral( "bb" ) );
4342+
QCOMPARE( static_cast< QComboBox * >( wrapper3.wrappedWidget() )->currentText(), QStringLiteral( "bb" ) );
4343+
wrapper3.setWidgetValue( QStringLiteral( "aa" ), context );
4344+
QCOMPARE( spy3.count(), 2 );
4345+
QCOMPARE( wrapper3.widgetValue().toString(), QStringLiteral( "aa" ) );
4346+
QCOMPARE( static_cast< QComboBox * >( wrapper3.wrappedWidget() )->currentText(), QStringLiteral( "aa" ) );
4347+
wrapper3.setWidgetValue( QVariant(), context );
4348+
QCOMPARE( spy3.count(), 3 );
4349+
QVERIFY( !wrapper3.widgetValue().isValid() );
4350+
delete w;
4351+
4352+
4353+
QLabel *l = wrapper.createWrappedLabel();
4354+
if ( wrapper.type() != QgsProcessingGui::Batch )
4355+
{
4356+
QVERIFY( l );
4357+
QCOMPARE( l->text(), QStringLiteral( "theme" ) );
4358+
QCOMPARE( l->toolTip(), param.toolTip() );
4359+
delete l;
4360+
}
4361+
else
4362+
{
4363+
QVERIFY( !l );
4364+
}
4365+
};
4366+
4367+
// standard wrapper
4368+
testWrapper( QgsProcessingGui::Standard );
4369+
4370+
// batch wrapper
4371+
testWrapper( QgsProcessingGui::Batch );
4372+
4373+
// modeler wrapper
4374+
testWrapper( QgsProcessingGui::Modeler );
4375+
}
4376+
42574377
void TestProcessingGui::cleanupTempDir()
42584378
{
42594379
QDir tmpDir = QDir( mTempDir );

0 commit comments

Comments
 (0)
Please sign in to comment.