Skip to content

Commit

Permalink
Port extent parameter to new c++ API widget wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Mar 25, 2020
1 parent 945ab52 commit 1915a16
Show file tree
Hide file tree
Showing 13 changed files with 429 additions and 7 deletions.
Expand Up @@ -1080,6 +1080,14 @@ Returns the coordinate reference system associated with an extent parameter valu
.. seealso:: :py:func:`parameterAsExtent`
%End

static QgsCoordinateReferenceSystem parameterAsExtentCrs( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context );
%Docstring
Returns the coordinate reference system associated with an extent parameter value.

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


static QgsPointXY parameterAsPoint( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context,
const QgsCoordinateReferenceSystem &crs = QgsCoordinateReferenceSystem() );
%Docstring
Expand Down
6 changes: 6 additions & 0 deletions python/gui/auto_generated/qgsextentwidget.sip.in
Expand Up @@ -219,6 +219,12 @@ Emitted when the widget's extent is changed.
void validationChanged( bool valid );
%Docstring
Emitted when the widget's validation state changes.
%End

void toggleDialogVisibility( bool visible );
%Docstring
Emitted when the parent dialog visibility must be changed (e.g.
to permit access to the map canvas)
%End

protected:
Expand Down
11 changes: 11 additions & 0 deletions python/plugins/processing/gui/wrappers.py
Expand Up @@ -405,6 +405,16 @@ def value(self):
class ExtentWidgetWrapper(WidgetWrapper):
USE_MIN_COVERING_EXTENT = "[Use min covering extent]"

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
"""
.. deprecated:: 3.4
Do not use, will be removed in QGIS 4.0
"""

from warnings import warn
warn("ExtentWidgetWrapper is deprecated and will be removed in QGIS 4.0", DeprecationWarning)

def createWidget(self):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH):
widget = ExtentSelectionPanel(self.dialog, self.parameterDefinition())
Expand Down Expand Up @@ -1819,6 +1829,7 @@ def create_wrapper_from_class(param, dialog, row=0, col=0):
# deprecated, moved to c++
wrapper = CrsWidgetWrapper
elif param.type() == 'extent':
# deprecated, moved to c++
wrapper = ExtentWidgetWrapper
elif param.type() == 'point':
# deprecated, moved to c++
Expand Down
Expand Up @@ -46,7 +46,6 @@
QgsProcessingParameterDefinition,
QgsProcessingParameterCrs,
QgsProcessingParameterMapLayer,
QgsProcessingParameterExtent,
QgsProcessingParameterMatrix,
QgsProcessingParameterMultipleLayers,
QgsProcessingParameterNumber,
Expand Down Expand Up @@ -487,9 +486,6 @@ def accept(self):
QMessageBox.warning(self, self.tr('Unable to define parameter'),
self.tr('Wrong or missing parameter values'))
return
elif (self.paramType == parameters.PARAMETER_EXTENT
or isinstance(self.param, QgsProcessingParameterExtent)):
self.param = QgsProcessingParameterExtent(name, description)
elif (self.paramType == parameters.PARAMETER_ENUM
or isinstance(self.param, QgsProcessingParameterEnum)):
self.param = QgsProcessingParameterEnum(name, description, self.widget.options(), self.widget.allowMultiple(), self.widget.defaultOptions())
Expand Down
5 changes: 5 additions & 0 deletions src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -1181,7 +1181,12 @@ QgsGeometry QgsProcessingParameters::parameterAsExtentGeometry( const QgsProcess
QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsExtentCrs( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context )
{
QVariant val = parameters.value( definition->name() );
return parameterAsExtentCrs( definition, val, context );
}

QgsCoordinateReferenceSystem QgsProcessingParameters::parameterAsExtentCrs( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context )
{
QVariant val = value;
if ( val.canConvert< QgsReferencedRectangle >() )
{
QgsReferencedRectangle rr = val.value<QgsReferencedRectangle>();
Expand Down
8 changes: 8 additions & 0 deletions src/core/processing/qgsprocessingparameters.h
Expand Up @@ -1155,6 +1155,14 @@ class CORE_EXPORT QgsProcessingParameters
*/
static QgsCoordinateReferenceSystem parameterAsExtentCrs( const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, QgsProcessingContext &context );

/**
* Returns the coordinate reference system associated with an extent parameter value.
*
* \see parameterAsExtent()
*/
static QgsCoordinateReferenceSystem parameterAsExtentCrs( const QgsProcessingParameterDefinition *definition, const QVariant &value, QgsProcessingContext &context );


/**
* Evaluates the parameter with matching \a definition to a point.
*
Expand Down
1 change: 1 addition & 0 deletions src/gui/processing/qgsprocessingguiregistry.cpp
Expand Up @@ -50,6 +50,7 @@ QgsProcessingGuiRegistry::QgsProcessingGuiRegistry()
addParameterWidgetFactory( new QgsProcessingProviderConnectionWidgetWrapper() );
addParameterWidgetFactory( new QgsProcessingDatabaseSchemaWidgetWrapper() );
addParameterWidgetFactory( new QgsProcessingDatabaseTableWidgetWrapper() );
addParameterWidgetFactory( new QgsProcessingExtentWidgetWrapper() );
}

QgsProcessingGuiRegistry::~QgsProcessingGuiRegistry()
Expand Down
189 changes: 189 additions & 0 deletions src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp
Expand Up @@ -51,6 +51,7 @@
#include "qgsproviderconnectioncombobox.h"
#include "qgsdatabaseschemacombobox.h"
#include "qgsdatabasetablecombobox.h"
#include "qgsextentwidget.h"
#include <QToolButton>
#include <QLabel>
#include <QHBoxLayout>
Expand Down Expand Up @@ -4716,6 +4717,194 @@ void QgsProcessingDatabaseTableWidgetWrapper::postInitialize( const QList<QgsAbs
}


//
// QgsProcessingExtentWidgetWrapper
//

QgsProcessingExtentParameterDefinitionWidget::QgsProcessingExtentParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm, QWidget *parent )
: QgsProcessingAbstractParameterDefinitionWidget( context, widgetContext, definition, algorithm, parent )
{
QVBoxLayout *vlayout = new QVBoxLayout();
vlayout->setMargin( 0 );
vlayout->setContentsMargins( 0, 0, 0, 0 );

vlayout->addWidget( new QLabel( tr( "Default value" ) ) );

mDefaultWidget = new QgsExtentWidget();
mDefaultWidget->setNullValueAllowed( true, tr( "Not set" ) );
if ( const QgsProcessingParameterExtent *extentParam = dynamic_cast<const QgsProcessingParameterExtent *>( definition ) )
{
if ( extentParam->defaultValue().isValid() )
{
QgsRectangle rect = QgsProcessingParameters::parameterAsExtent( extentParam, extentParam->defaultValue(), context );
QgsCoordinateReferenceSystem crs = QgsProcessingParameters::parameterAsExtentCrs( extentParam, extentParam->defaultValue(), context );
mDefaultWidget->setCurrentExtent( rect, crs );
mDefaultWidget->setOutputExtentFromCurrent();
}
else
{
mDefaultWidget->clear();
}
}

vlayout->addWidget( mDefaultWidget );
setLayout( vlayout );
}

QgsProcessingParameterDefinition *QgsProcessingExtentParameterDefinitionWidget::createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const
{
const QString defaultVal = mDefaultWidget->isValid() ? QStringLiteral( "%1,%2,%3,%4%5" ).arg(
QString::number( mDefaultWidget->outputExtent().xMinimum(), 'f', 9 ),
QString::number( mDefaultWidget->outputExtent().xMaximum(), 'f', 9 ),
QString::number( mDefaultWidget->outputExtent().yMinimum(), 'f', 9 ),
QString::number( mDefaultWidget->outputExtent().yMaximum(), 'f', 9 ),
mDefaultWidget->outputCrs().isValid() ? QStringLiteral( " [%1]" ).arg( mDefaultWidget->outputCrs().authid() ) : QString()
) : QString();
auto param = qgis::make_unique< QgsProcessingParameterExtent >( name, description, !defaultVal.isEmpty() ? QVariant( defaultVal ) : QVariant() );
param->setFlags( flags );
return param.release();
}



QgsProcessingExtentWidgetWrapper::QgsProcessingExtentWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type, QWidget *parent )
: QgsAbstractProcessingParameterWidgetWrapper( parameter, type, parent )
{

}

QWidget *QgsProcessingExtentWidgetWrapper::createWidget()
{
const QgsProcessingParameterExtent *extentParam = dynamic_cast< const QgsProcessingParameterExtent *>( parameterDefinition() );
switch ( type() )
{
case QgsProcessingGui::Standard:
case QgsProcessingGui::Batch:
case QgsProcessingGui::Modeler:
{
mExtentWidget = new QgsExtentWidget( nullptr );
if ( widgetContext().mapCanvas() )
mExtentWidget->setMapCanvas( widgetContext().mapCanvas() );

if ( extentParam->flags() & QgsProcessingParameterDefinition::FlagOptional )
mExtentWidget->setNullValueAllowed( true, tr( "Not set" ) );

mExtentWidget->setToolTip( parameterDefinition()->toolTip() );

connect( mExtentWidget, &QgsExtentWidget::extentChanged, this, [ = ]
{
emit widgetValueHasChanged( this );
} );

if ( mDialog && type() != QgsProcessingGui::Modeler )
setDialog( mDialog ); // setup connections to panel - dialog was previously set before the widget was created

return mExtentWidget;
}
}
return nullptr;
}

void QgsProcessingExtentWidgetWrapper::setWidgetContext( const QgsProcessingParameterWidgetContext &context )
{
QgsAbstractProcessingParameterWidgetWrapper::setWidgetContext( context );
if ( mExtentWidget && context.mapCanvas() && type() != QgsProcessingGui::Modeler )
mExtentWidget->setMapCanvas( context.mapCanvas() );
}

void QgsProcessingExtentWidgetWrapper::setDialog( QDialog *dialog )
{
mDialog = dialog;
if ( mExtentWidget && mDialog && type() != QgsProcessingGui::Modeler )
{
connect( mExtentWidget, &QgsExtentWidget::toggleDialogVisibility, mDialog, [ = ]( bool visible )
{
if ( !visible )
mDialog->showMinimized();
else
{
mDialog->showNormal();
mDialog->raise();
mDialog->activateWindow();
}
} );
}
QgsAbstractProcessingParameterWidgetWrapper::setDialog( dialog );
}

void QgsProcessingExtentWidgetWrapper::setWidgetValue( const QVariant &value, QgsProcessingContext &context )
{
if ( mExtentWidget )
{
if ( !value.isValid() || ( value.type() == QVariant::String && value.toString().isEmpty() ) )
mExtentWidget->clear();
else
{
QgsRectangle r = QgsProcessingParameters::parameterAsExtent( parameterDefinition(), value, context );
QgsCoordinateReferenceSystem crs = QgsProcessingParameters::parameterAsPointCrs( parameterDefinition(), value, context );
mExtentWidget->setCurrentExtent( r, crs );
mExtentWidget->setOutputExtentFromCurrent();
}
}
}

QVariant QgsProcessingExtentWidgetWrapper::widgetValue() const
{
if ( mExtentWidget )
{
const QString val = mExtentWidget->isValid() ? QStringLiteral( "%1,%2,%3,%4%5" ).arg(
QString::number( mExtentWidget->outputExtent().xMinimum(), 'f', 9 ),
QString::number( mExtentWidget->outputExtent().xMaximum(), 'f', 9 ),
QString::number( mExtentWidget->outputExtent().yMinimum(), 'f', 9 ),
QString::number( mExtentWidget->outputExtent().yMaximum(), 'f', 9 ),
mExtentWidget->outputCrs().isValid() ? QStringLiteral( " [%1]" ).arg( mExtentWidget->outputCrs().authid() ) : QString()
) : QString();

return val.isEmpty() ? QVariant() : QVariant( val );
}
else
return QVariant();
}

QStringList QgsProcessingExtentWidgetWrapper::compatibleParameterTypes() const
{
return QStringList()
<< QgsProcessingParameterExtent::typeName()
<< QgsProcessingParameterString::typeName();
}

QStringList QgsProcessingExtentWidgetWrapper::compatibleOutputTypes() const
{
return QStringList()
<< QgsProcessingOutputString::typeName();
}

QList<int> QgsProcessingExtentWidgetWrapper::compatibleDataTypes() const
{
return QList<int>();
}

QString QgsProcessingExtentWidgetWrapper::modelerExpressionFormatString() const
{
return tr( "string of the format 'x min,x max,y min,y max' or a geometry value (bounding box is used)" );
}

QString QgsProcessingExtentWidgetWrapper::parameterType() const
{
return QgsProcessingParameterExtent::typeName();
}

QgsAbstractProcessingParameterWidgetWrapper *QgsProcessingExtentWidgetWrapper::createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type )
{
return new QgsProcessingExtentWidgetWrapper( parameter, type );
}

QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingExtentWidgetWrapper::createParameterDefinitionWidget( QgsProcessingContext &context, const QgsProcessingParameterWidgetContext &widgetContext, const QgsProcessingParameterDefinition *definition, const QgsProcessingAlgorithm *algorithm )
{
return new QgsProcessingExtentParameterDefinitionWidget( context, widgetContext, definition, algorithm );
}



///@endcond PRIVATE

62 changes: 62 additions & 0 deletions src/gui/processing/qgsprocessingwidgetwrapperimpl.h
Expand Up @@ -57,6 +57,7 @@ class QgsTimeEdit;
class QgsProviderConnectionComboBox;
class QgsDatabaseSchemaComboBox;
class QgsDatabaseTableComboBox;
class QgsExtentWidget;

///@cond PRIVATE

Expand Down Expand Up @@ -894,6 +895,67 @@ class GUI_EXPORT QgsProcessingPointWidgetWrapper : public QgsAbstractProcessingP
};




class GUI_EXPORT QgsProcessingExtentParameterDefinitionWidget : public QgsProcessingAbstractParameterDefinitionWidget
{
Q_OBJECT
public:

QgsProcessingExtentParameterDefinitionWidget( QgsProcessingContext &context,
const QgsProcessingParameterWidgetContext &widgetContext,
const QgsProcessingParameterDefinition *definition = nullptr,
const QgsProcessingAlgorithm *algorithm = nullptr, QWidget *parent SIP_TRANSFERTHIS = nullptr );
QgsProcessingParameterDefinition *createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const override;

private:

QgsExtentWidget *mDefaultWidget = nullptr;

};

class GUI_EXPORT QgsProcessingExtentWidgetWrapper : public QgsAbstractProcessingParameterWidgetWrapper, public QgsProcessingParameterWidgetFactoryInterface
{
Q_OBJECT

public:

QgsProcessingExtentWidgetWrapper( const QgsProcessingParameterDefinition *parameter = nullptr,
QgsProcessingGui::WidgetType type = QgsProcessingGui::Standard, QWidget *parent = nullptr );

// QgsProcessingParameterWidgetFactoryInterface
QString parameterType() const override;
QgsAbstractProcessingParameterWidgetWrapper *createWidgetWrapper( const QgsProcessingParameterDefinition *parameter, QgsProcessingGui::WidgetType type ) override;
QgsProcessingAbstractParameterDefinitionWidget *createParameterDefinitionWidget(
QgsProcessingContext &context,
const QgsProcessingParameterWidgetContext &widgetContext,
const QgsProcessingParameterDefinition *definition = nullptr,
const QgsProcessingAlgorithm *algorithm = nullptr ) override;

// QgsProcessingParameterWidgetWrapper interface
QWidget *createWidget() override SIP_FACTORY;
void setWidgetContext( const QgsProcessingParameterWidgetContext &context ) override;
void setDialog( QDialog *dialog ) override;

protected:

void setWidgetValue( const QVariant &value, QgsProcessingContext &context ) override;
QVariant widgetValue() const override;

QStringList compatibleParameterTypes() const override;

QStringList compatibleOutputTypes() const override;

QList< int > compatibleDataTypes() const override;
QString modelerExpressionFormatString() const override;
private:

QgsExtentWidget *mExtentWidget = nullptr;
QDialog *mDialog = nullptr;

friend class TestProcessingGui;
};

class GUI_EXPORT QgsProcessingColorParameterDefinitionWidget : public QgsProcessingAbstractParameterDefinitionWidget
{
Q_OBJECT
Expand Down
5 changes: 5 additions & 0 deletions src/gui/qgsextentgroupbox.cpp
Expand Up @@ -28,6 +28,11 @@ QgsExtentGroupBox::QgsExtentGroupBox( QWidget *parent )
connect( this, &QGroupBox::toggled, this, &QgsExtentGroupBox::groupBoxClicked );
connect( mWidget, &QgsExtentWidget::extentChanged, this, &QgsExtentGroupBox::widgetExtentChanged );
connect( mWidget, &QgsExtentWidget::validationChanged, this, &QgsExtentGroupBox::validationChanged );

connect( mWidget, &QgsExtentWidget::toggleDialogVisibility, this, [ = ]( bool visible )
{
window()->setVisible( visible );
} );
}

void QgsExtentGroupBox::setOriginalExtent( const QgsRectangle &originalExtent, const QgsCoordinateReferenceSystem &originalCrs )
Expand Down

0 comments on commit 1915a16

Please sign in to comment.