Skip to content

Commit

Permalink
Move model child algorithm dependencies selection widget to c++, make…
Browse files Browse the repository at this point in the history
… inline panel
  • Loading branch information
nyalldawson committed Apr 16, 2020
1 parent e3955df commit 05bc716
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 50 deletions.
Expand Up @@ -110,6 +110,20 @@ Sets the inputs for child algorithms for the last run of the model through the d
};



class QgsModelChildDependenciesWidget : QWidget
{

%TypeHeaderCode
#include "qgsmodeldesignerdialog.h"
%End
public:

QgsModelChildDependenciesWidget( QWidget *parent, QgsProcessingModelAlgorithm *model, const QString &childId );
QList< QgsProcessingModelChildDependency > value() const;
void setValue( const QList< QgsProcessingModelChildDependency > &value );
};

/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
59 changes: 10 additions & 49 deletions python/plugins/processing/modeler/ModelerParametersDialog.py
Expand Up @@ -47,12 +47,12 @@
QgsProcessingParameterWidgetContext,
QgsPanelWidget,
QgsPanelWidgetStack,
QgsColorButton)
QgsColorButton,
QgsModelChildDependenciesWidget)
from qgis.utils import iface

from processing.gui.wrappers import WidgetWrapperFactory
from processing.gui.wrappers import InvalidParameterValue
from processing.gui.MultipleInputPanel import MultipleInputPanel
from processing.tools.dataobjects import createContext
from processing.gui.wrappers import WidgetWrapper

Expand Down Expand Up @@ -107,12 +107,6 @@ def commentColor(self):
def switchToCommentTab(self):
self.widget.switchToCommentTab()

def getAvailableDependencies(self):
return self.widget.getAvailableDependencies()

def getDependenciesPanel(self):
return self.widget.getDependenciesPanel()

def getAvailableValuesOfType(self, paramType, outTypes=[], dataTypes=[]):
return self.widget.getAvailableValuesOfType(paramType, outTypes, dataTypes)

Expand Down Expand Up @@ -279,10 +273,10 @@ def setupUi(self):

label = QLabel(' ')
self.verticalLayout.addWidget(label)
label = QLabel(self.tr('Parent algorithms'))
self.dependenciesPanel = self.getDependenciesPanel()
label = QLabel(self.tr('Dependencies'))
self.dependencies_panel = QgsModelChildDependenciesWidget(self, self.model, self.childId)
self.verticalLayout.addWidget(label)
self.verticalLayout.addWidget(self.dependenciesPanel)
self.verticalLayout.addWidget(self.dependencies_panel)
self.verticalLayout.addStretch(1000)

self.setPreviousValues()
Expand All @@ -304,21 +298,6 @@ def setupUi(self):
self.mainLayout.addWidget(w)
self.setLayout(self.mainLayout)

def getAvailableDependencies(self):
if self.childId is None:
dependent = []
else:
dependent = list(self.model.dependentChildAlgorithms(self.childId))
dependent.append(self.childId)
opts = []
for alg in list(self.model.childAlgorithms().values()):
if alg.childId() not in dependent:
opts.append(alg)
return opts

def getDependenciesPanel(self):
return MultipleInputPanel([alg.description() for alg in self.getAvailableDependencies()])

def showAdvancedParametersClicked(self):
self.showAdvanced = not self.showAdvanced
if self.showAdvanced:
Expand Down Expand Up @@ -430,13 +409,7 @@ def setPreviousValues(self):

wrapper.setWidgetValue(value)

selected = []
dependencies = self.getAvailableDependencies()
for idx, dependency in enumerate(dependencies):
if dependency.childId() in alg.dependencies():
selected.append(idx)

self.dependenciesPanel.setSelectedItems(selected)
self.dependencies_panel.setValue(alg.dependencies())

def createAlgorithm(self):
alg = QgsProcessingModelChildAlgorithm(self._alg.id())
Expand Down Expand Up @@ -470,9 +443,9 @@ def createAlgorithm(self):

valid = True
for subval in val:
if (isinstance(subval, QgsProcessingModelChildParameterSource) and
subval.source() == QgsProcessingModelChildParameterSource.StaticValue and
not param.checkValueIsAcceptable(subval.staticValue())) \
if (isinstance(subval, QgsProcessingModelChildParameterSource)
and subval.source() == QgsProcessingModelChildParameterSource.StaticValue
and not param.checkValueIsAcceptable(subval.staticValue())) \
or (subval is None and not param.flags() & QgsProcessingParameterDefinition.FlagOptional):
valid = False
break
Expand Down Expand Up @@ -508,13 +481,7 @@ def createAlgorithm(self):
outputs[output.name()] = model_output

alg.setModelOutputs(outputs)

selectedOptions = self.dependenciesPanel.selectedoptions
availableDependencies = self.getAvailableDependencies()
dep_ids = []
for selected in selectedOptions:
dep_ids.append(availableDependencies[selected].childId())
alg.setDependencies(dep_ids)
alg.setDependencies(self.dependencies_panel.value())

return alg

Expand Down Expand Up @@ -602,12 +569,6 @@ def setCommentColor(self, color):
def commentColor(self):
return self.comment_color_button.color() if not self.comment_color_button.isNull() else QColor()

def getAvailableDependencies(self):
return self.widget.getAvailableDependencies()

def getDependenciesPanel(self):
return self.widget.getDependenciesPanel()

def getAvailableValuesOfType(self, paramType, outTypes=[], dataTypes=[]):
return self.widget.getAvailableValuesOfType(paramType, outTypes, dataTypes)

Expand Down
85 changes: 84 additions & 1 deletion src/gui/processing/models/qgsmodeldesignerdialog.cpp
Expand Up @@ -31,6 +31,8 @@
#include "processing/models/qgsmodelinputreorderwidget.h"
#include "qgsmessageviewer.h"
#include "qgsmessagebaritem.h"
#include "qgspanelwidget.h"
#include "qgsprocessingmultipleselectiondialog.h"

#include <QShortcut>
#include <QDesktopWidget>
Expand Down Expand Up @@ -863,5 +865,86 @@ void QgsModelDesignerDialog::fillInputsTree()
}


///@endcond
//
// QgsModelChildDependenciesWidget
//

QgsModelChildDependenciesWidget::QgsModelChildDependenciesWidget( QWidget *parent, QgsProcessingModelAlgorithm *model, const QString &childId )
: QWidget( parent )
, mModel( model )
, mChildId( childId )
{
QHBoxLayout *hl = new QHBoxLayout();
hl->setMargin( 0 );
hl->setContentsMargins( 0, 0, 0, 0 );

mLineEdit = new QLineEdit();
mLineEdit->setEnabled( false );
hl->addWidget( mLineEdit, 1 );

mToolButton = new QToolButton();
mToolButton->setText( QString( QChar( 0x2026 ) ) );
hl->addWidget( mToolButton );

setLayout( hl );

mLineEdit->setText( tr( "%1 dependencies selected" ).arg( 0 ) );

connect( mToolButton, &QToolButton::clicked, this, &QgsModelChildDependenciesWidget::showDialog );
}

void QgsModelChildDependenciesWidget::setValue( const QList<QgsProcessingModelChildDependency> &value )
{
mValue = value;

updateSummaryText();
}

void QgsModelChildDependenciesWidget::showDialog()
{
const QList<QgsProcessingModelChildDependency> available = mModel->availableDependenciesForChildAlgorithm( mChildId );

QVariantList availableOptions;
for ( const QgsProcessingModelChildDependency &dep : available )
availableOptions << QVariant::fromValue( dep );
QVariantList selectedOptions;
for ( const QgsProcessingModelChildDependency &dep : mValue )
selectedOptions << QVariant::fromValue( dep );

QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( this );
if ( panel )
{
QgsProcessingMultipleSelectionPanelWidget *widget = new QgsProcessingMultipleSelectionPanelWidget( availableOptions, selectedOptions );
widget->setPanelTitle( tr( "Algorithm Dependencies" ) );

widget->setValueFormatter( [ = ]( const QVariant & v ) -> QString
{
const QgsProcessingModelChildDependency dep = v.value< QgsProcessingModelChildDependency >();

const QString description = mModel->childAlgorithm( dep.childId ).description();
if ( dep.conditionalBranch.isEmpty() )
return description;
else
return tr( "Condition “%1” from algorithm “%2”" ).arg( dep.conditionalBranch, description );
} );

connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged, this, [ = ]()
{
QList< QgsProcessingModelChildDependency > res;
for ( const QVariant &v : widget->selectedOptions() )
{
res << v.value< QgsProcessingModelChildDependency >();
}
setValue( res );
} );
connect( widget, &QgsProcessingMultipleSelectionPanelWidget::acceptClicked, widget, &QgsPanelWidget::acceptPanel );
panel->openPanel( widget );
}
}

void QgsModelChildDependenciesWidget::updateSummaryText()
{
mLineEdit->setText( tr( "%1 dependencies selected" ).arg( mValue.count() ) );
}

///@endcond
32 changes: 32 additions & 0 deletions src/gui/processing/models/qgsmodeldesignerdialog.h
Expand Up @@ -21,6 +21,7 @@
#include "ui_qgsmodeldesignerdialogbase.h"

#include "qgsprocessingtoolboxmodel.h"
#include "qgsprocessingmodelchilddependency.h"

class QgsMessageBar;
class QgsProcessingModelAlgorithm;
Expand All @@ -34,6 +35,7 @@ class QgsModelViewToolSelect;

class GUI_EXPORT QgsModelerToolboxModel : public QgsProcessingToolboxProxyModel
{
Q_OBJECT
public:
explicit QgsModelerToolboxModel( QObject *parent = nullptr );
Qt::ItemFlags flags( const QModelIndex &index ) const override;
Expand All @@ -51,6 +53,7 @@ class GUI_EXPORT QgsModelerToolboxModel : public QgsProcessingToolboxProxyModel
*/
class GUI_EXPORT QgsModelDesignerDialog : public QMainWindow, public Ui::QgsModelDesignerDialogBase
{
Q_OBJECT
public:

QgsModelDesignerDialog( QWidget *parent SIP_TRANSFERTHIS = nullptr, Qt::WindowFlags flags = nullptr );
Expand Down Expand Up @@ -191,6 +194,35 @@ class GUI_EXPORT QgsModelDesignerDialog : public QMainWindow, public Ui::QgsMode
void updateVariablesGui();
};



class GUI_EXPORT QgsModelChildDependenciesWidget : public QWidget
{
Q_OBJECT

public:

QgsModelChildDependenciesWidget( QWidget *parent, QgsProcessingModelAlgorithm *model, const QString &childId );
QList< QgsProcessingModelChildDependency > value() const { return mValue; }
void setValue( const QList< QgsProcessingModelChildDependency > &value );
private slots:

void showDialog();

private:

void updateSummaryText();

QLineEdit *mLineEdit = nullptr;
QToolButton *mToolButton = nullptr;

QgsProcessingModelAlgorithm *mModel = nullptr;
QString mChildId;

QList< QgsProcessingModelChildDependency > mValue;

friend class TestProcessingGui;
};
///@endcond

#endif // QGSMODELDESIGNERDIALOG_H

0 comments on commit 05bc716

Please sign in to comment.