mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
Move processing algorithm configuration widget to gui library
This way we can also use all the fancy widgets like a QgsExpressionLineEdit.
This commit is contained in:
parent
10db1c8f0e
commit
3be4324d60
@ -349,12 +349,6 @@ If an algorithm subclass implements a custom parameters widget, a copy of this w
|
||||
should be constructed and returned by this method.
|
||||
The base class implementation returns None, which indicates that an autogenerated
|
||||
parameters widget should be used.
|
||||
%End
|
||||
|
||||
virtual QgsProcessingAlgorithmConfigurationWidget *createModelerWidget() const /Factory/;
|
||||
%Docstring
|
||||
If an algorithm subclass implements a configuration widget for the algorithm itself,
|
||||
a new instance of this widget should be returned by this method.
|
||||
%End
|
||||
|
||||
QgsExpressionContext createExpressionContext( const QVariantMap ¶meters,
|
||||
|
||||
@ -9,19 +9,68 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsProcessingAlgorithmConfigurationWidget : QWidget
|
||||
{
|
||||
%Docstring
|
||||
A configuration widget for processing algorithms allows to provide additional
|
||||
configuration options directly on algorithm level, in addition to parameters.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingalgorithmconfigurationwidget.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsProcessingAlgorithmConfigurationWidget( QWidget *parent = 0 );
|
||||
%Docstring
|
||||
Creates a new QgsProcessingAlgorithmConfigurationWidget
|
||||
%End
|
||||
virtual ~QgsProcessingAlgorithmConfigurationWidget();
|
||||
|
||||
virtual QVariantMap configuration() const = 0;
|
||||
%Docstring
|
||||
Read the current configuration from this widget.
|
||||
%End
|
||||
|
||||
virtual void setConfiguration( const QVariantMap &configuration ) = 0;
|
||||
%Docstring
|
||||
Set the configuration which this widget should represent.
|
||||
%End
|
||||
};
|
||||
|
||||
|
||||
class QgsProcessingAlgorithmConfigurationWidgetFactory
|
||||
{
|
||||
%Docstring
|
||||
Interface base class for factories for algorithm configuration widgets.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingalgorithmconfigurationwidget.h"
|
||||
%End
|
||||
public:
|
||||
virtual ~QgsProcessingAlgorithmConfigurationWidgetFactory();
|
||||
|
||||
virtual QgsProcessingAlgorithmConfigurationWidget *create( QgsProcessingAlgorithm *algorithm ) const = 0 /Factory/;
|
||||
%Docstring
|
||||
Create a new configuration widget for ``algorithm``.
|
||||
%End
|
||||
|
||||
virtual bool canCreateFor( QgsProcessingAlgorithm *algorithm ) const = 0;
|
||||
%Docstring
|
||||
Check if this factory can create widgets for ``algorithm``.
|
||||
%End
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
|
||||
@ -143,6 +143,29 @@ Return a list with all known parameter types.
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void addAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory /Transfer/ );
|
||||
%Docstring
|
||||
Add a new configuration widget factory for customized algorithm configuration
|
||||
widgets. Ownership is taken.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void removeAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory );
|
||||
%Docstring
|
||||
Remove a configuration widget factory for customized algorithm configuration
|
||||
widgets.
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
QgsProcessingAlgorithmConfigurationWidget *algorithmConfigurationWidget( QgsProcessingAlgorithm *algorithm ) const;
|
||||
%Docstring
|
||||
algorithmConfigurationWidget
|
||||
@param algorithm
|
||||
@return
|
||||
%End
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
|
||||
@ -312,4 +312,5 @@
|
||||
%Include layout/qgslayoutviewtoolzoom.sip
|
||||
%Include locator/qgslocatorwidget.sip
|
||||
%Include processing/qgsprocessingalgorithmdialogbase.sip
|
||||
%Include processing/qgsprocessingconfigurationwidgets.sip
|
||||
%Include qgsadvanceddigitizingcanvasitem.sip
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/processing/qgsprocessingconfigurationwidgets.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsProcessingConfigurationWidgets
|
||||
{
|
||||
%Docstring
|
||||
This class is responsible for the management of processing widgets which
|
||||
QGIS internally.
|
||||
|
||||
Standalone applications that require to show configuration widgets for processing
|
||||
algorithms will need to execute the following code to have the configuration
|
||||
interfaces available.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# At startup time
|
||||
QgsApplicationProcessingConfigurationWidgets.initialize()
|
||||
|
||||
# At exit time
|
||||
QgsApplicationProcessingConfigurationWidgets.cleanup()
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingconfigurationwidgets.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
static void initialize();
|
||||
%Docstring
|
||||
Initialize native configuration widgets.
|
||||
%End
|
||||
|
||||
static void cleanup();
|
||||
%Docstring
|
||||
Cleanup native configuration widgets.
|
||||
%End
|
||||
|
||||
private:
|
||||
QgsProcessingConfigurationWidgets();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/processing/qgsprocessingconfigurationwidgets.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
@ -36,6 +36,7 @@ from qgis.PyQt.QtWidgets import (QDialog, QDialogButtonBox, QLabel, QLineEdit,
|
||||
QHBoxLayout, QWidget)
|
||||
|
||||
from qgis.core import (Qgis,
|
||||
QgsApplication,
|
||||
QgsProcessingParameterDefinition,
|
||||
QgsProcessingParameterPoint,
|
||||
QgsProcessingParameterExtent,
|
||||
@ -118,7 +119,7 @@ class ModelerParametersDialog(QDialog):
|
||||
line.setFrameShape(QFrame.HLine)
|
||||
line.setFrameShadow(QFrame.Sunken)
|
||||
self.verticalLayout.addWidget(line)
|
||||
self.algorithmItem = self._alg.createModelerWidget()
|
||||
self.algorithmItem = QgsApplication.instance().processingRegistry().algorithmConfigurationWidget(self._alg)
|
||||
if self.configuration:
|
||||
self.algorithmItem.setConfiguration(self.configuration)
|
||||
self.verticalLayout.addWidget(self.algorithmItem)
|
||||
@ -330,6 +331,7 @@ class ModelerParametersDialog(QDialog):
|
||||
output.setChildId(alg.childId())
|
||||
output.setChildOutputName(dest.name())
|
||||
outputs[name] = output
|
||||
|
||||
alg.setModelOutputs(outputs)
|
||||
|
||||
selectedOptions = self.dependenciesPanel.selectedoptions
|
||||
|
||||
@ -140,7 +140,6 @@ SET(QGIS_ANALYSIS_MOC_HDRS
|
||||
network/qgsvectorlayerdirector.h
|
||||
|
||||
processing/qgsalgorithmfiledownloader.h
|
||||
processing/qgsalgorithmfilter.h
|
||||
|
||||
vector/geometry_checker/qgsfeaturepool.h
|
||||
vector/geometry_checker/qgsgeometrychecker.h
|
||||
|
||||
@ -18,12 +18,6 @@
|
||||
#include "qgsalgorithmfilter.h"
|
||||
#include "qgsapplication.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QGridLayout>
|
||||
#include <QTableWidget>
|
||||
#include <QHeaderView>
|
||||
#include <QToolButton>
|
||||
|
||||
///@cond PRIVATE
|
||||
|
||||
QString QgsFilterAlgorithm::name() const
|
||||
@ -66,11 +60,6 @@ QgsFilterAlgorithm *QgsFilterAlgorithm::createInstance() const
|
||||
return new QgsFilterAlgorithm();
|
||||
}
|
||||
|
||||
QgsProcessingAlgorithmConfigurationWidget *QgsFilterAlgorithm::createModelerWidget() const
|
||||
{
|
||||
return new QgsFilterAlgorithmConfigurationWidget();
|
||||
}
|
||||
|
||||
QgsFilterAlgorithm::~QgsFilterAlgorithm()
|
||||
{
|
||||
qDeleteAll( mOutputs );
|
||||
@ -93,60 +82,6 @@ void QgsFilterAlgorithm::initAlgorithm( const QVariantMap &configuration )
|
||||
}
|
||||
|
||||
|
||||
QgsFilterAlgorithmConfigurationWidget::QgsFilterAlgorithmConfigurationWidget( QWidget *parent )
|
||||
: QgsProcessingAlgorithmConfigurationWidget( parent )
|
||||
{
|
||||
setContentsMargins( 0, 0, 0, 0 );
|
||||
|
||||
mOutputExpressionWidget = new QTableWidget();
|
||||
mOutputExpressionWidget->setColumnCount( 2 );
|
||||
mOutputExpressionWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "Output Name" ) ) );
|
||||
mOutputExpressionWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "Filter Expression" ) ) );
|
||||
mOutputExpressionWidget->horizontalHeader()->setStretchLastSection( true );
|
||||
QGridLayout *layout = new QGridLayout();
|
||||
setLayout( layout );
|
||||
|
||||
layout->addWidget( new QLabel( tr( "Outputs and filters" ) ), 0, 0, 1, 2 );
|
||||
layout->addWidget( mOutputExpressionWidget, 1, 0, 4, 1 );
|
||||
QToolButton *addOutputButton = new QToolButton();
|
||||
addOutputButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLayer.svg" ) ) );
|
||||
addOutputButton->setText( tr( "Add Output" ) );
|
||||
|
||||
QToolButton *removeOutputButton = new QToolButton();
|
||||
removeOutputButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRemoveLayer.svg" ) ) );
|
||||
removeOutputButton->setToolTip( tr( "Remove Selected Outputs" ) );
|
||||
|
||||
layout->addWidget( addOutputButton, 2, 1, 1, 1 );
|
||||
layout->addWidget( removeOutputButton, 3, 1, 1, 1 );
|
||||
|
||||
connect( addOutputButton, &QToolButton::clicked, this, &QgsFilterAlgorithmConfigurationWidget::addOutput );
|
||||
connect( removeOutputButton, &QToolButton::clicked, this, &QgsFilterAlgorithmConfigurationWidget::removeSelectedOutputs );
|
||||
|
||||
connect( mOutputExpressionWidget->selectionModel(), &QItemSelectionModel::selectionChanged, [removeOutputButton, this]
|
||||
{
|
||||
removeOutputButton->setEnabled( !mOutputExpressionWidget->selectionModel()->selectedIndexes().isEmpty() );
|
||||
} );
|
||||
}
|
||||
|
||||
QVariantMap QgsFilterAlgorithmConfigurationWidget::configuration() const
|
||||
{
|
||||
QVariantList outputs;
|
||||
|
||||
for ( int i = 0; i < mOutputExpressionWidget->rowCount(); ++i )
|
||||
{
|
||||
QVariantMap output;
|
||||
output.insert( QStringLiteral( "name" ), mOutputExpressionWidget->item( i, 0 )->text() );
|
||||
output.insert( QStringLiteral( "expression" ), mOutputExpressionWidget->item( i, 1 )->text() );
|
||||
outputs.append( output );
|
||||
}
|
||||
|
||||
QVariantMap map;
|
||||
map.insert( "outputs", outputs );
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
QVariantMap QgsFilterAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
|
||||
{
|
||||
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
|
||||
@ -195,53 +130,3 @@ QVariantMap QgsFilterAlgorithm::processAlgorithm( const QVariantMap ¶meters,
|
||||
return outputs;
|
||||
}
|
||||
|
||||
|
||||
void QgsFilterAlgorithmConfigurationWidget::setConfiguration( const QVariantMap &configuration )
|
||||
{
|
||||
mOutputExpressionWidget->setRowCount( 0 );
|
||||
int currentRow = 0;
|
||||
const QVariantList outputs = configuration.value( "outputs" ).toList();
|
||||
|
||||
for ( const QVariant &outputvar : outputs )
|
||||
{
|
||||
const QVariantMap output = outputvar.toMap();
|
||||
mOutputExpressionWidget->insertRow( currentRow );
|
||||
mOutputExpressionWidget->setItem( currentRow, 0, new QTableWidgetItem( output.value( "name" ).toString() ) );
|
||||
mOutputExpressionWidget->setItem( currentRow, 1, new QTableWidgetItem( output.value( "expression" ).toString() ) );
|
||||
|
||||
currentRow++;
|
||||
}
|
||||
|
||||
if ( outputs.isEmpty() )
|
||||
addOutput();
|
||||
}
|
||||
|
||||
void QgsFilterAlgorithmConfigurationWidget::removeSelectedOutputs()
|
||||
{
|
||||
QItemSelection selection( mOutputExpressionWidget->selectionModel()->selection() );
|
||||
|
||||
QList<int> rows;
|
||||
const QModelIndexList indexes = selection.indexes();
|
||||
for ( const QModelIndex &index : indexes )
|
||||
{
|
||||
rows.append( index.row() );
|
||||
}
|
||||
|
||||
qSort( rows );
|
||||
|
||||
int prev = -1;
|
||||
for ( int i = rows.count() - 1; i >= 0; i -= 1 )
|
||||
{
|
||||
int current = rows[i];
|
||||
if ( current != prev )
|
||||
{
|
||||
mOutputExpressionWidget->removeRow( current );
|
||||
prev = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFilterAlgorithmConfigurationWidget::addOutput()
|
||||
{
|
||||
mOutputExpressionWidget->setRowCount( mOutputExpressionWidget->rowCount() + 1 );
|
||||
}
|
||||
|
||||
@ -22,38 +22,18 @@
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgsprocessingalgorithm.h"
|
||||
#include "qgsprocessingalgorithmconfigurationwidget.h"
|
||||
|
||||
class QgsProcessingModelAlgorithm;
|
||||
class QTableWidget;
|
||||
|
||||
///@cond PRIVATE
|
||||
|
||||
|
||||
class QgsFilterAlgorithmConfigurationWidget : public QgsProcessingAlgorithmConfigurationWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsFilterAlgorithmConfigurationWidget( QWidget *parent = nullptr );
|
||||
|
||||
QVariantMap configuration() const override;
|
||||
|
||||
void setConfiguration( const QVariantMap &configuration ) override;
|
||||
|
||||
private slots:
|
||||
void removeSelectedOutputs();
|
||||
void addOutput();
|
||||
|
||||
private:
|
||||
QTableWidget *mOutputExpressionWidget;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Feature filter algorithm for modeler.
|
||||
* Accepts a list of expressions and names and creates outputs where
|
||||
* matching features are sent to.
|
||||
*
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
class QgsFilterAlgorithm : public QgsProcessingAlgorithm
|
||||
{
|
||||
@ -70,7 +50,6 @@ class QgsFilterAlgorithm : public QgsProcessingAlgorithm
|
||||
virtual Flags flags() const override;
|
||||
QString shortHelpString() const override;
|
||||
QgsFilterAlgorithm *createInstance() const override SIP_FACTORY;
|
||||
QgsProcessingAlgorithmConfigurationWidget *createModelerWidget() const override SIP_FACTORY;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@ -608,6 +608,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/gui/attributetable
|
||||
${CMAKE_SOURCE_DIR}/src/gui/auth
|
||||
${CMAKE_SOURCE_DIR}/src/gui/ogr
|
||||
${CMAKE_SOURCE_DIR}/src/gui/processing
|
||||
${CMAKE_SOURCE_DIR}/src/gui/raster
|
||||
${CMAKE_SOURCE_DIR}/src/gui/editorwidgets
|
||||
${CMAKE_SOURCE_DIR}/src/gui/editorwidgets/core
|
||||
|
||||
@ -246,6 +246,7 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
|
||||
#include "qgsruntimeprofiler.h"
|
||||
#include "qgshandlebadlayers.h"
|
||||
#include "qgsprintlayout.h"
|
||||
#include "qgsprocessingconfigurationwidgets.h"
|
||||
#include "qgsprocessingregistry.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsprojectlayergroupdialog.h"
|
||||
@ -1457,6 +1458,7 @@ QgisApp::~QgisApp()
|
||||
|
||||
// cancel request for FileOpen events
|
||||
QgsApplication::setFileOpenEventReceiver( nullptr );
|
||||
QgsProcessingConfigurationWidgets::cleanup();
|
||||
|
||||
unregisterCustomLayoutDropHandler( mLayoutQptDropHandler );
|
||||
|
||||
@ -10495,6 +10497,7 @@ void QgisApp::initNativeProcessing()
|
||||
#ifdef HAVE_3D
|
||||
QgsApplication::processingRegistry()->addProvider( new Qgs3DAlgorithms( QgsApplication::processingRegistry() ) );
|
||||
#endif
|
||||
QgsProcessingConfigurationWidgets::initialize();
|
||||
}
|
||||
|
||||
void QgisApp::initLayouts()
|
||||
|
||||
@ -64,6 +64,7 @@ const QgsProcessingAlgorithm *QgsProcessingModelChildAlgorithm::algorithm() cons
|
||||
void QgsProcessingModelChildAlgorithm::setModelOutputs( const QMap<QString, QgsProcessingModelOutput> &modelOutputs )
|
||||
{
|
||||
mModelOutputs = modelOutputs;
|
||||
|
||||
QMap<QString, QgsProcessingModelOutput>::iterator outputIt = mModelOutputs.begin();
|
||||
for ( ; outputIt != mModelOutputs.end(); ++outputIt )
|
||||
{
|
||||
|
||||
@ -131,11 +131,6 @@ QWidget *QgsProcessingAlgorithm::createCustomParametersWidget( QWidget * ) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsProcessingAlgorithmConfigurationWidget *QgsProcessingAlgorithm::createModelerWidget() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsExpressionContext QgsProcessingAlgorithm::createExpressionContext( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context, QgsProcessingFeatureSource *source ) const
|
||||
{
|
||||
|
||||
@ -356,12 +356,6 @@ class CORE_EXPORT QgsProcessingAlgorithm
|
||||
*/
|
||||
virtual QWidget *createCustomParametersWidget( QWidget *parent = nullptr ) const SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* If an algorithm subclass implements a configuration widget for the algorithm itself,
|
||||
* a new instance of this widget should be returned by this method.
|
||||
*/
|
||||
virtual QgsProcessingAlgorithmConfigurationWidget *createModelerWidget() const SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Creates an expression context relating to the algorithm. This can be called by algorithms
|
||||
* to create a new expression context ready for evaluating expressions within the algorithm.
|
||||
|
||||
@ -24,6 +24,10 @@
|
||||
#include <QVariantMap>
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis_sip.h"
|
||||
|
||||
class QgsProcessingAlgorithm;
|
||||
class QgsProcessingAlgorithmConfigurationWidget;
|
||||
|
||||
/**
|
||||
* A configuration widget for processing algorithms allows to provide additional
|
||||
@ -37,6 +41,7 @@ class CORE_EXPORT QgsProcessingAlgorithmConfigurationWidget : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new QgsProcessingAlgorithmConfigurationWidget
|
||||
*/
|
||||
@ -54,4 +59,28 @@ class CORE_EXPORT QgsProcessingAlgorithmConfigurationWidget : public QWidget
|
||||
virtual void setConfiguration( const QVariantMap &configuration ) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Interface base class for factories for algorithm configuration widgets.
|
||||
*
|
||||
* \since QGIS 3.2
|
||||
* \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT QgsProcessingAlgorithmConfigurationWidgetFactory
|
||||
{
|
||||
public:
|
||||
virtual ~QgsProcessingAlgorithmConfigurationWidgetFactory() = default;
|
||||
|
||||
/**
|
||||
* Create a new configuration widget for \a algorithm.
|
||||
*/
|
||||
virtual QgsProcessingAlgorithmConfigurationWidget *create( QgsProcessingAlgorithm *algorithm ) const = 0 SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Check if this factory can create widgets for \a algorithm.
|
||||
*/
|
||||
virtual bool canCreateFor( QgsProcessingAlgorithm *algorithm ) const = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // QGSPROCESSINGALGORITHMCONFIGURATIONWIDGET_H
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "qgsprocessingregistry.h"
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include "qgsprocessingparametertypeimpl.h"
|
||||
#include "qgsprocessingalgorithmconfigurationwidget.h"
|
||||
|
||||
QgsProcessingRegistry::QgsProcessingRegistry( QObject *parent SIP_TRANSFERTHIS )
|
||||
: QObject( parent )
|
||||
@ -189,3 +190,27 @@ QList<QgsProcessingParameterType *> QgsProcessingRegistry::parameterTypes() cons
|
||||
return mParameterTypes.values();
|
||||
}
|
||||
|
||||
void QgsProcessingRegistry::addAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory )
|
||||
{
|
||||
mAlgorithmConfigurationWidgetFactories.append( factory );
|
||||
}
|
||||
|
||||
void QgsProcessingRegistry::removeAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory )
|
||||
{
|
||||
mAlgorithmConfigurationWidgetFactories.removeAll( factory );
|
||||
delete factory;
|
||||
}
|
||||
|
||||
QgsProcessingAlgorithmConfigurationWidget *QgsProcessingRegistry::algorithmConfigurationWidget( QgsProcessingAlgorithm *algorithm ) const
|
||||
{
|
||||
for ( const auto *factory : mAlgorithmConfigurationWidgetFactories )
|
||||
{
|
||||
if ( factory->canCreateFor( algorithm ) )
|
||||
{
|
||||
return factory->create( algorithm );
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <QMap>
|
||||
|
||||
class QgsProcessingParameterType;
|
||||
class QgsProcessingAlgorithmConfigurationWidgetFactory;
|
||||
|
||||
/**
|
||||
* \class QgsProcessingRegistry
|
||||
@ -168,6 +169,29 @@ class CORE_EXPORT QgsProcessingRegistry : public QObject
|
||||
*/
|
||||
QList<QgsProcessingParameterType *> parameterTypes() const;
|
||||
|
||||
/**
|
||||
* Add a new configuration widget factory for customized algorithm configuration
|
||||
* widgets. Ownership is taken.
|
||||
*
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
void addAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory SIP_TRANSFER );
|
||||
|
||||
/**
|
||||
* Remove a configuration widget factory for customized algorithm configuration
|
||||
* widgets.
|
||||
*
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
void removeAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory );
|
||||
|
||||
/**
|
||||
* @brief algorithmConfigurationWidget
|
||||
* @param algorithm
|
||||
* @return
|
||||
*/
|
||||
QgsProcessingAlgorithmConfigurationWidget *algorithmConfigurationWidget( QgsProcessingAlgorithm *algorithm ) const;
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
@ -200,6 +224,8 @@ class CORE_EXPORT QgsProcessingRegistry : public QObject
|
||||
//! Hash of available parameter types by id. This object owns the pointers.
|
||||
QMap<QString, QgsProcessingParameterType *> mParameterTypes;
|
||||
|
||||
QList <QgsProcessingAlgorithmConfigurationWidgetFactory *> mAlgorithmConfigurationWidgetFactories;
|
||||
|
||||
#ifdef SIP_RUN
|
||||
QgsProcessingRegistry( const QgsProcessingRegistry &other );
|
||||
#endif
|
||||
|
||||
@ -193,6 +193,7 @@ SET(QGIS_GUI_SRCS
|
||||
ogr/qgsvectorlayersaveasdialog.cpp
|
||||
|
||||
processing/qgsprocessingalgorithmdialogbase.cpp
|
||||
processing/qgsprocessingconfigurationwidgets.cpp
|
||||
|
||||
qgisinterface.cpp
|
||||
qgsactionmenu.cpp
|
||||
@ -710,6 +711,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
locator/qgslocatorwidget.h
|
||||
|
||||
processing/qgsprocessingalgorithmdialogbase.h
|
||||
processing/qgsprocessingconfigurationwidgets.h
|
||||
)
|
||||
SET_PROPERTY(GLOBAL PROPERTY QGIS_GUI_MOC_HDRS ${QGIS_GUI_MOC_HDRS})
|
||||
|
||||
@ -881,6 +883,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/core/layout
|
||||
${CMAKE_SOURCE_DIR}/src/core/locator
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/processing
|
||||
${CMAKE_SOURCE_DIR}/src/core/providers/memory
|
||||
${CMAKE_SOURCE_DIR}/src/core/raster
|
||||
${CMAKE_SOURCE_DIR}/src/core/scalebar
|
||||
|
||||
187
src/gui/processing/qgsprocessingconfigurationwidgets.cpp
Normal file
187
src/gui/processing/qgsprocessingconfigurationwidgets.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/***************************************************************************
|
||||
qgsprocessingconfigurationwidgets.cpp
|
||||
---------------------
|
||||
begin : April 2018
|
||||
copyright : (C) 2018 by Matthias Kuhn
|
||||
email : matthias@opengis.ch
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "qgsprocessingconfigurationwidgets.h"
|
||||
#include "qgsprocessingalgorithm.h"
|
||||
#include "qgsexpressionlineedit.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsprocessingregistry.h"
|
||||
|
||||
#include <QTableWidget>
|
||||
#include <QGridLayout>
|
||||
#include <QToolButton>
|
||||
#include <QLabel>
|
||||
#include <QCheckBox>
|
||||
#include <QHeaderView>
|
||||
|
||||
QList<QgsProcessingAlgorithmConfigurationWidgetFactory *> QgsProcessingConfigurationWidgets::sProcessingAlgorithmConfigurationWidgetFactories;
|
||||
|
||||
QgsProcessingConfigurationWidgets::QgsProcessingConfigurationWidgets()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QgsProcessingConfigurationWidgets::initialize()
|
||||
{
|
||||
if ( !sProcessingAlgorithmConfigurationWidgetFactories.isEmpty() )
|
||||
{
|
||||
QgsDebugMsg( "QgsProcessingConfigurationWidgets::initialize() called more than once. Exiting now." );
|
||||
return;
|
||||
}
|
||||
QgsProcessingAlgorithmConfigurationWidgetFactory *factory = new QgsFilterAlgorithmConfigurationWidgetFactory();
|
||||
sProcessingAlgorithmConfigurationWidgetFactories.append( factory );
|
||||
QgsApplication::instance()->processingRegistry()->addAlgorithmConfigurationWidgetFactory( factory );
|
||||
}
|
||||
|
||||
void QgsProcessingConfigurationWidgets::cleanup()
|
||||
{
|
||||
for ( QgsProcessingAlgorithmConfigurationWidgetFactory *factory : qgis::as_const( sProcessingAlgorithmConfigurationWidgetFactories ) )
|
||||
QgsApplication::instance()->processingRegistry()->removeAlgorithmConfigurationWidgetFactory( factory );
|
||||
sProcessingAlgorithmConfigurationWidgetFactories.clear();
|
||||
}
|
||||
|
||||
QgsFilterAlgorithmConfigurationWidget::QgsFilterAlgorithmConfigurationWidget( QWidget *parent )
|
||||
: QgsProcessingAlgorithmConfigurationWidget( parent )
|
||||
{
|
||||
setContentsMargins( 0, 0, 0, 0 );
|
||||
|
||||
mOutputExpressionWidget = new QTableWidget();
|
||||
mOutputExpressionWidget->setColumnCount( 3 );
|
||||
mOutputExpressionWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "Output Name" ) ) );
|
||||
mOutputExpressionWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "Filter Expression" ) ) );
|
||||
mOutputExpressionWidget->setHorizontalHeaderItem( 2, new QTableWidgetItem( tr( "Final Output" ) ) );
|
||||
mOutputExpressionWidget->horizontalHeader()->setResizeMode( 1, QHeaderView::Stretch );
|
||||
QGridLayout *layout = new QGridLayout();
|
||||
setLayout( layout );
|
||||
|
||||
layout->addWidget( new QLabel( tr( "Outputs and filters" ) ), 0, 0, 1, 2 );
|
||||
layout->addWidget( mOutputExpressionWidget, 1, 0, 4, 1 );
|
||||
QToolButton *addOutputButton = new QToolButton();
|
||||
addOutputButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLayer.svg" ) ) );
|
||||
addOutputButton->setText( tr( "Add Output" ) );
|
||||
|
||||
QToolButton *removeOutputButton = new QToolButton();
|
||||
removeOutputButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRemoveLayer.svg" ) ) );
|
||||
removeOutputButton->setToolTip( tr( "Remove Selected Outputs" ) );
|
||||
|
||||
layout->addWidget( addOutputButton, 2, 1, 1, 1 );
|
||||
layout->addWidget( removeOutputButton, 3, 1, 1, 1 );
|
||||
|
||||
connect( addOutputButton, &QToolButton::clicked, this, &QgsFilterAlgorithmConfigurationWidget::addOutput );
|
||||
connect( removeOutputButton, &QToolButton::clicked, this, &QgsFilterAlgorithmConfigurationWidget::removeSelectedOutputs );
|
||||
|
||||
connect( mOutputExpressionWidget->selectionModel(), &QItemSelectionModel::selectionChanged, [removeOutputButton, this]
|
||||
{
|
||||
removeOutputButton->setEnabled( !mOutputExpressionWidget->selectionModel()->selectedIndexes().isEmpty() );
|
||||
} );
|
||||
}
|
||||
|
||||
QVariantMap QgsFilterAlgorithmConfigurationWidget::configuration() const
|
||||
{
|
||||
QVariantList outputs;
|
||||
|
||||
for ( int i = 0; i < mOutputExpressionWidget->rowCount(); ++i )
|
||||
{
|
||||
QVariantMap output;
|
||||
output.insert( QStringLiteral( "name" ), mOutputExpressionWidget->item( i, 0 )->text() );
|
||||
output.insert( QStringLiteral( "expression" ), qobject_cast<QgsExpressionLineEdit *>( mOutputExpressionWidget->cellWidget( i, 1 ) )->expression() );
|
||||
output.insert( QStringLiteral( "isModelOutput" ), qobject_cast<QCheckBox *>( mOutputExpressionWidget->cellWidget( i, 2 ) )->isChecked() );
|
||||
outputs.append( output );
|
||||
}
|
||||
|
||||
QVariantMap map;
|
||||
map.insert( "outputs", outputs );
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
void QgsFilterAlgorithmConfigurationWidget::setConfiguration( const QVariantMap &configuration )
|
||||
{
|
||||
mOutputExpressionWidget->setRowCount( 0 );
|
||||
int currentRow = 0;
|
||||
const QVariantList outputs = configuration.value( "outputs" ).toList();
|
||||
|
||||
for ( const QVariant &outputvar : outputs )
|
||||
{
|
||||
const QVariantMap output = outputvar.toMap();
|
||||
mOutputExpressionWidget->insertRow( currentRow );
|
||||
mOutputExpressionWidget->setItem( currentRow, 0, new QTableWidgetItem( output.value( "name" ).toString() ) );
|
||||
QgsExpressionLineEdit *expressionBuilder = new QgsExpressionLineEdit();
|
||||
expressionBuilder->setExpression( output.value( "expression" ).toString() );
|
||||
mOutputExpressionWidget->setCellWidget( currentRow, 1, expressionBuilder );
|
||||
QCheckBox *isModelOutput = new QCheckBox();
|
||||
isModelOutput->setChecked( output.value( "isModelOutput" ).toBool() );
|
||||
mOutputExpressionWidget->setCellWidget( currentRow, 2, isModelOutput );
|
||||
|
||||
currentRow++;
|
||||
}
|
||||
|
||||
if ( outputs.isEmpty() )
|
||||
addOutput();
|
||||
}
|
||||
|
||||
void QgsFilterAlgorithmConfigurationWidget::removeSelectedOutputs()
|
||||
{
|
||||
QItemSelection selection( mOutputExpressionWidget->selectionModel()->selection() );
|
||||
|
||||
QList<int> rows;
|
||||
const QModelIndexList indexes = selection.indexes();
|
||||
for ( const QModelIndex &index : indexes )
|
||||
{
|
||||
rows.append( index.row() );
|
||||
}
|
||||
|
||||
qSort( rows );
|
||||
|
||||
int prev = -1;
|
||||
for ( int i = rows.count() - 1; i >= 0; i -= 1 )
|
||||
{
|
||||
int current = rows[i];
|
||||
if ( current != prev )
|
||||
{
|
||||
mOutputExpressionWidget->removeRow( current );
|
||||
prev = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFilterAlgorithmConfigurationWidget::addOutput()
|
||||
{
|
||||
int rowIndex = mOutputExpressionWidget->rowCount() + 1;
|
||||
mOutputExpressionWidget->setRowCount( rowIndex );
|
||||
QgsExpressionLineEdit *expressionBuilder = new QgsExpressionLineEdit();
|
||||
mOutputExpressionWidget->setCellWidget( rowIndex, 1, expressionBuilder );
|
||||
mOutputExpressionWidget->setCellWidget( rowIndex, 2, new QCheckBox() );
|
||||
}
|
||||
|
||||
QgsProcessingAlgorithmConfigurationWidget *QgsFilterAlgorithmConfigurationWidgetFactory::create( QgsProcessingAlgorithm *algorithm ) const
|
||||
{
|
||||
if ( algorithm->name() == QStringLiteral( "filter" ) )
|
||||
return new QgsFilterAlgorithmConfigurationWidget();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool QgsFilterAlgorithmConfigurationWidgetFactory::canCreateFor( QgsProcessingAlgorithm *algorithm ) const
|
||||
{
|
||||
if ( algorithm->name() == QStringLiteral( "filter" ) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
97
src/gui/processing/qgsprocessingconfigurationwidgets.h
Normal file
97
src/gui/processing/qgsprocessingconfigurationwidgets.h
Normal file
@ -0,0 +1,97 @@
|
||||
/***************************************************************************
|
||||
qgsprocessingconfigurationwidgets.h
|
||||
---------------------
|
||||
begin : April 2018
|
||||
copyright : (C) 2018 by Matthias Kuhn
|
||||
email : matthias@opengis.ch
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef QGSPROCESSINGCONFIGURATIONWIDGETS_H
|
||||
#define QGSPROCESSINGCONFIGURATIONWIDGETS_H
|
||||
|
||||
#include "qgsprocessingalgorithmconfigurationwidget.h"
|
||||
#include "qgis_gui.h"
|
||||
#include "qgis_sip.h"
|
||||
|
||||
class QTableWidget;
|
||||
|
||||
/**
|
||||
* This class is responsible for the management of processing widgets which
|
||||
* QGIS internally.
|
||||
*
|
||||
* Standalone applications that require to show configuration widgets for processing
|
||||
* algorithms will need to execute the following code to have the configuration
|
||||
* interfaces available.
|
||||
*
|
||||
* \code{.py}
|
||||
* # At startup time
|
||||
* QgsApplicationProcessingConfigurationWidgets.initialize()
|
||||
*
|
||||
* # At exit time
|
||||
* QgsApplicationProcessingConfigurationWidgets.cleanup()
|
||||
* \endcode
|
||||
*/
|
||||
class GUI_EXPORT QgsProcessingConfigurationWidgets
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Initialize native configuration widgets.
|
||||
*/
|
||||
static void initialize();
|
||||
|
||||
/**
|
||||
* Cleanup native configuration widgets.
|
||||
*/
|
||||
static void cleanup();
|
||||
|
||||
private:
|
||||
QgsProcessingConfigurationWidgets() SIP_FORCE;
|
||||
static QList<QgsProcessingAlgorithmConfigurationWidgetFactory *> sProcessingAlgorithmConfigurationWidgetFactories;
|
||||
};
|
||||
|
||||
///@cond PRIVATE
|
||||
|
||||
#ifndef SIP_RUN
|
||||
|
||||
class QgsFilterAlgorithmConfigurationWidget : public QgsProcessingAlgorithmConfigurationWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsFilterAlgorithmConfigurationWidget( QWidget *parent = nullptr );
|
||||
|
||||
QVariantMap configuration() const override;
|
||||
|
||||
void setConfiguration( const QVariantMap &configuration ) override;
|
||||
|
||||
private slots:
|
||||
void removeSelectedOutputs();
|
||||
void addOutput();
|
||||
|
||||
private:
|
||||
QTableWidget *mOutputExpressionWidget;
|
||||
};
|
||||
|
||||
class QgsFilterAlgorithmConfigurationWidgetFactory : public QgsProcessingAlgorithmConfigurationWidgetFactory
|
||||
{
|
||||
public:
|
||||
virtual QgsProcessingAlgorithmConfigurationWidget *create( QgsProcessingAlgorithm *algorithm ) const override;
|
||||
virtual bool canCreateFor( QgsProcessingAlgorithm *algorithm ) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
///@endcond
|
||||
|
||||
#endif // QGSPROCESSINGCONFIGURATIONWIDGETS_H
|
||||
Loading…
x
Reference in New Issue
Block a user