diff --git a/python/gui/auto_generated/processing/models/qgsmodeldesignerdialog.sip.in b/python/gui/auto_generated/processing/models/qgsmodeldesignerdialog.sip.in index 8358ac26899e..a33a91e06f7f 100644 --- a/python/gui/auto_generated/processing/models/qgsmodeldesignerdialog.sip.in +++ b/python/gui/auto_generated/processing/models/qgsmodeldesignerdialog.sip.in @@ -44,10 +44,16 @@ Model designer dialog base class QAction *actionEditHelp(); QAction *actionRun(); QAction *actionExportImage(); + QLineEdit *textName(); + QLineEdit *textGroup(); + QScrollArea *inputsScrollArea(); + QgsProcessingToolboxTreeView *algorithmsTree(); QgsMessageBar *messageBar(); QGraphicsView *view(); + void updateVariablesGui(); + }; diff --git a/python/plugins/processing/modeler/ModelerDialog.py b/python/plugins/processing/modeler/ModelerDialog.py index 4dd4faea3c48..0366a29c6e46 100644 --- a/python/plugins/processing/modeler/ModelerDialog.py +++ b/python/plugins/processing/modeler/ModelerDialog.py @@ -38,15 +38,9 @@ QMessageBox, QFileDialog, QTreeWidgetItem, - QSizePolicy, - QMainWindow, - QLabel, QDockWidget, QWidget, QVBoxLayout, - QGridLayout, - QFrame, - QLineEdit, QToolButton, QAction) from qgis.PyQt.QtGui import QIcon @@ -63,9 +57,6 @@ QgsExpressionContext ) from qgis.gui import (QgsDockWidget, - QgsScrollArea, - QgsFilterLineEdit, - QgsProcessingToolboxTreeView, QgsProcessingToolboxProxyModel, QgsProcessingParameterDefinitionDialog, QgsVariableEditorWidget, @@ -80,7 +71,6 @@ from processing.modeler.ModelerScene import ModelerScene from processing.modeler.ProjectProvider import PROJECT_PROVIDER_ID from processing.script.ScriptEditorDialog import ScriptEditorDialog -from processing.core.ProcessingConfig import ProcessingConfig from processing.tools.dataobjects import createContext from qgis.utils import iface @@ -132,65 +122,8 @@ def create(model=None): def __init__(self, model=None, parent=None): super().__init__(parent) - self._variables_scope = None self._model = None - # LOTS of bug reports when we include the dock creation in the UI file - # see e.g. #16428, #19068 - # So just roll it all by hand......! - self.propertiesDock = QgsDockWidget(self) - self.propertiesDock.setFeatures( - QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) - self.propertiesDock.setObjectName("propertiesDock") - propertiesDockContents = QWidget() - self.verticalDockLayout_1 = QVBoxLayout(propertiesDockContents) - self.verticalDockLayout_1.setContentsMargins(0, 0, 0, 0) - self.verticalDockLayout_1.setSpacing(0) - self.scrollArea_1 = QgsScrollArea(propertiesDockContents) - sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, - QSizePolicy.MinimumExpanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.scrollArea_1.sizePolicy().hasHeightForWidth()) - self.scrollArea_1.setSizePolicy(sizePolicy) - self.scrollArea_1.setFocusPolicy(Qt.WheelFocus) - self.scrollArea_1.setFrameShape(QFrame.NoFrame) - self.scrollArea_1.setFrameShadow(QFrame.Plain) - self.scrollArea_1.setWidgetResizable(True) - self.scrollAreaWidgetContents_1 = QWidget() - self.gridLayout = QGridLayout(self.scrollAreaWidgetContents_1) - self.gridLayout.setContentsMargins(6, 6, 6, 6) - self.gridLayout.setSpacing(4) - self.label_1 = QLabel(self.scrollAreaWidgetContents_1) - self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1) - self.textName = QLineEdit(self.scrollAreaWidgetContents_1) - self.gridLayout.addWidget(self.textName, 0, 1, 1, 1) - self.label_2 = QLabel(self.scrollAreaWidgetContents_1) - self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) - self.textGroup = QLineEdit(self.scrollAreaWidgetContents_1) - self.gridLayout.addWidget(self.textGroup, 1, 1, 1, 1) - self.label_1.setText(self.tr("Name")) - self.textName.setToolTip(self.tr("Enter model name here")) - self.label_2.setText(self.tr("Group")) - self.textGroup.setToolTip(self.tr("Enter group name here")) - self.scrollArea_1.setWidget(self.scrollAreaWidgetContents_1) - self.verticalDockLayout_1.addWidget(self.scrollArea_1) - self.propertiesDock.setWidget(propertiesDockContents) - self.propertiesDock.setWindowTitle(self.tr("Model Properties")) - - self.inputsDock = QgsDockWidget(self) - self.inputsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) - self.inputsDock.setObjectName("inputsDock") - self.inputsDockContents = QWidget() - self.verticalLayout_3 = QVBoxLayout(self.inputsDockContents) - self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) - self.scrollArea_2 = QgsScrollArea(self.inputsDockContents) - sizePolicy.setHeightForWidth(self.scrollArea_2.sizePolicy().hasHeightForWidth()) - self.scrollArea_2.setSizePolicy(sizePolicy) - self.scrollArea_2.setFocusPolicy(Qt.WheelFocus) - self.scrollArea_2.setFrameShape(QFrame.NoFrame) - self.scrollArea_2.setFrameShadow(QFrame.Plain) - self.scrollArea_2.setWidgetResizable(True) self.scrollAreaWidgetContents_2 = QWidget() self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents_2) self.verticalLayout.setContentsMargins(0, 0, 0, 0) @@ -199,64 +132,7 @@ def __init__(self, model=None, parent=None): self.inputsTree.setAlternatingRowColors(True) self.inputsTree.header().setVisible(False) self.verticalLayout.addWidget(self.inputsTree) - self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2) - self.verticalLayout_3.addWidget(self.scrollArea_2) - self.inputsDock.setWidget(self.inputsDockContents) - self.addDockWidget(Qt.DockWidgetArea(1), self.inputsDock) - self.inputsDock.setWindowTitle(self.tr("Inputs")) - - self.algorithmsDock = QgsDockWidget(self) - self.algorithmsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) - self.algorithmsDock.setObjectName("algorithmsDock") - self.algorithmsDockContents = QWidget() - self.verticalLayout_4 = QVBoxLayout(self.algorithmsDockContents) - self.verticalLayout_4.setContentsMargins(0, 0, 0, 0) - self.scrollArea_3 = QgsScrollArea(self.algorithmsDockContents) - sizePolicy.setHeightForWidth(self.scrollArea_3.sizePolicy().hasHeightForWidth()) - self.scrollArea_3.setSizePolicy(sizePolicy) - self.scrollArea_3.setFocusPolicy(Qt.WheelFocus) - self.scrollArea_3.setFrameShape(QFrame.NoFrame) - self.scrollArea_3.setFrameShadow(QFrame.Plain) - self.scrollArea_3.setWidgetResizable(True) - self.scrollAreaWidgetContents_3 = QWidget() - self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents_3) - self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) - self.verticalLayout_2.setSpacing(4) - self.searchBox = QgsFilterLineEdit(self.scrollAreaWidgetContents_3) - self.verticalLayout_2.addWidget(self.searchBox) - self.algorithmTree = QgsProcessingToolboxTreeView(None, - QgsApplication.processingRegistry()) - self.algorithmTree.setAlternatingRowColors(True) - self.algorithmTree.header().setVisible(False) - self.verticalLayout_2.addWidget(self.algorithmTree) - self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3) - self.verticalLayout_4.addWidget(self.scrollArea_3) - self.algorithmsDock.setWidget(self.algorithmsDockContents) - self.addDockWidget(Qt.DockWidgetArea(1), self.algorithmsDock) - self.algorithmsDock.setWindowTitle(self.tr("Algorithms")) - self.searchBox.setToolTip(self.tr("Enter algorithm name to filter list")) - self.searchBox.setShowSearchIcon(True) - - self.variables_dock = QgsDockWidget(self) - self.variables_dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) - self.variables_dock.setObjectName("variablesDock") - self.variables_dock_contents = QWidget() - vl_v = QVBoxLayout() - vl_v.setContentsMargins(0, 0, 0, 0) - self.variables_editor = QgsVariableEditorWidget() - vl_v.addWidget(self.variables_editor) - self.variables_dock_contents.setLayout(vl_v) - self.variables_dock.setWidget(self.variables_dock_contents) - self.addDockWidget(Qt.DockWidgetArea(1), self.variables_dock) - self.variables_dock.setWindowTitle(self.tr("Variables")) - self.addDockWidget(Qt.DockWidgetArea(1), self.propertiesDock) - self.tabifyDockWidget(self.propertiesDock, self.variables_dock) - self.variables_editor.scopeChanged.connect(self.variables_changed) - - try: - self.setDockOptions(self.dockOptions() | QMainWindow.GroupedDragging) - except: - pass + self.inputsScrollArea().setWidget(self.scrollAreaWidgetContents_2) if iface is not None: self.toolbar().setIconSize(iface.iconSize()) @@ -271,12 +147,6 @@ def __init__(self, model=None, parent=None): self.toolbar().insertWidget(self.actionExportImage(), self.toolbutton_export_to_script) self.export_to_script_algorithm_action.triggered.connect(self.export_as_script_algorithm) - self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock) - self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock) - self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock) - self.tabifyDockWidget(self.inputsDock, self.algorithmsDock) - self.inputsDock.raise_() - self.scene = ModelerScene(self) self.scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE)) self.scene.rebuildRequired.connect(self.repaintModel) @@ -298,26 +168,10 @@ def _mimeDataInput(items): self.inputsTree.setDropIndicatorShown(True) self.algorithms_model = ModelerToolboxModel(self, QgsApplication.processingRegistry()) - self.algorithmTree.setToolboxProxyModel(self.algorithms_model) - self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly) - self.algorithmTree.setDropIndicatorShown(True) - - filters = QgsProcessingToolboxProxyModel.Filters(QgsProcessingToolboxProxyModel.FilterModeler) - if ProcessingConfig.getSetting(ProcessingConfig.SHOW_ALGORITHMS_KNOWN_ISSUES): - filters |= QgsProcessingToolboxProxyModel.FilterShowKnownIssues - self.algorithmTree.setFilters(filters) - - if hasattr(self.searchBox, 'setPlaceholderText'): - self.searchBox.setPlaceholderText(QCoreApplication.translate('ModelerDialog', 'Search…')) - if hasattr(self.textName, 'setPlaceholderText'): - self.textName.setPlaceholderText(self.tr('Enter model name here')) - if hasattr(self.textGroup, 'setPlaceholderText'): - self.textGroup.setPlaceholderText(self.tr('Enter group name here')) + self.algorithmsTree().setToolboxProxyModel(self.algorithms_model) # Connect signals and slots self.inputsTree.doubleClicked.connect(self._addInput) - self.searchBox.textChanged.connect(self.algorithmTree.setFilterString) - self.algorithmTree.doubleClicked.connect(self._addAlgorithm) self.actionOpen().triggered.connect(self.openModel) self.actionSave().triggered.connect(self.save) @@ -332,14 +186,14 @@ def _mimeDataInput(items): if model is not None: self._model = model.create() self._model.setSourceFilePath(model.sourceFilePath()) - self.textGroup.setText(self._model.group()) - self.textName.setText(self._model.displayName()) + self.textGroup().setText(self._model.group()) + self.textName().setText(self._model.displayName()) self.repaintModel() else: self._model = QgsProcessingModelAlgorithm() self._model.setProvider(QgsApplication.processingRegistry().providerById('model')) - self.update_variables_gui() + self.updateVariablesGui() self.fillInputsTree() @@ -376,18 +230,6 @@ def editHelp(self): self.model().setHelpContent(dlg.descriptions) self.hasChanged = True - def update_variables_gui(self): - variables_scope = QgsExpressionContextScope(self.tr('Model Variables')) - for k, v in self.model().variables().items(): - variables_scope.setVariable(k, v) - variables_context = QgsExpressionContext() - variables_context.appendScope(variables_scope) - self.variables_editor.setContext(variables_context) - self.variables_editor.setEditableScopeIndex(0) - - def variables_changed(self): - self.model().setVariables(self.variables_editor.variablesInActiveScope()) - def runModel(self): if len(self.model().childAlgorithms()) == 0: self.messageBar().pushMessage("", self.tr( @@ -412,8 +254,8 @@ def saveInProject(self): if not self.can_save(): return - self.model().setName(str(self.textName.text())) - self.model().setGroup(str(self.textGroup.text())) + self.model().setName(str(self.textName().text())) + self.model().setGroup(str(self.textGroup().text())) self.model().setSourceFilePath(None) project_provider = QgsApplication.processingRegistry().providerById(PROJECT_PROVIDER_ID) @@ -431,7 +273,7 @@ def can_save(self): Tests whether a model can be saved, or if it is not yet valid :return: bool """ - if str(self.textName.text()).strip() == '': + if str(self.textName().text()).strip() == '': self.messageBar().pushWarning( "", self.tr('Please a enter model name before saving') ) @@ -442,8 +284,8 @@ def can_save(self): def saveModel(self, saveAs): if not self.can_save(): return - self.model().setName(str(self.textName.text())) - self.model().setGroup(str(self.textGroup.text())) + self.model().setName(str(self.textName().text())) + self.model().setGroup(str(self.textGroup().text())) if self.model().sourceFilePath() and not saveAs: filename = self.model().sourceFilePath() else: @@ -490,11 +332,11 @@ def loadModel(self, filename): if alg.fromFile(filename): self._model = alg self._model.setProvider(QgsApplication.processingRegistry().providerById('model')) - self.textGroup.setText(alg.group()) - self.textName.setText(alg.name()) + self.textGroup().setText(alg.group()) + self.textName().setText(alg.name()) self.repaintModel() - self.update_variables_gui() + self.updateVariablesGui() self.view().centerOn(0, 0) self.hasChanged = False @@ -626,9 +468,6 @@ def fillInputsTree(self): self.inputsTree.addTopLevelItem(parametersItem) parametersItem.setExpanded(True) - def _addAlgorithm(self): - self.addAlgorithm(self.algorithmTree.selectedAlgorithm()) - def addAlgorithm(self, alg_id, pos=None): alg = QgsApplication.processingRegistry().createAlgorithmById(alg_id) if not alg: @@ -637,7 +476,7 @@ def addAlgorithm(self, alg_id, pos=None): dlg = ModelerParametersDialog(alg, self.model()) if dlg.exec_(): alg = dlg.createAlgorithm() - if pos is None: + if pos is None or not pos: alg.setPosition(self.getPositionForAlgorithmItem()) else: alg.setPosition(pos) @@ -664,8 +503,8 @@ def getPositionForAlgorithmItem(self): maxX = max([alg.position().x() for alg in list(self.model().childAlgorithms().values())]) maxY = max([alg.position().y() for alg in list(self.model().childAlgorithms().values())]) newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH) - newY = min(MARGIN + BOX_HEIGHT + maxY, self.CANVAS_SIZE - - BOX_HEIGHT) + newY = min(MARGIN + BOX_HEIGHT + maxY, self.CANVAS_SIZE - + BOX_HEIGHT) else: newX = MARGIN + BOX_WIDTH / 2 newY = MARGIN * 2 + BOX_HEIGHT + BOX_HEIGHT / 2 diff --git a/src/gui/processing/models/qgsmodeldesignerdialog.cpp b/src/gui/processing/models/qgsmodeldesignerdialog.cpp index 67bbdd805968..04b5dc5f0d6f 100644 --- a/src/gui/processing/models/qgsmodeldesignerdialog.cpp +++ b/src/gui/processing/models/qgsmodeldesignerdialog.cpp @@ -39,9 +39,24 @@ QgsModelDesignerDialog::QgsModelDesignerDialog( QWidget *parent, Qt::WindowFlags QgsGui::enableAutoGeometryRestore( this ); setAttribute( Qt::WA_DeleteOnClose ); + setDockOptions( dockOptions() | QMainWindow::GroupedDragging ); setWindowFlags( Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint ); + + mPropertiesDock->setFeatures( QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable ); + mInputsDock->setFeatures( QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable ); + mAlgorithmsDock->setFeatures( QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable ); + mVariablesDock->setFeatures( QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable ); + + mAlgorithmsTree->header()->setVisible( false ); + mAlgorithmSearchEdit->setShowSearchIcon( true ); + mAlgorithmSearchEdit->setPlaceholderText( tr( "Search…" ) ); + connect( mAlgorithmSearchEdit, &QgsFilterLineEdit::textChanged, mAlgorithmsTree, &QgsProcessingToolboxTreeView::setFilterString ); + + mNameEdit->setPlaceholderText( tr( "Enter model name here" ) ); + mGroupEdit->setPlaceholderText( tr( "Enter group name here" ) ); + mMessageBar = new QgsMessageBar(); mMessageBar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ); mainLayout->insertWidget( 0, mMessageBar ); @@ -58,15 +73,56 @@ QgsModelDesignerDialog::QgsModelDesignerDialog( QWidget *parent, Qt::WindowFlags connect( mActionExportSvg, &QAction::triggered, this, &QgsModelDesignerDialog::exportToSvg ); connect( mActionExportPython, &QAction::triggered, this, &QgsModelDesignerDialog::exportAsPython ); + QgsSettings settings; + QgsProcessingToolboxProxyModel::Filters filters = QgsProcessingToolboxProxyModel::FilterModeler; + if ( settings.value( QStringLiteral( "Processing/Configuration/SHOW_ALGORITHMS_KNOWN_ISSUES" ), false ).toBool() ) + { + filters |= QgsProcessingToolboxProxyModel::FilterShowKnownIssues; + } + mAlgorithmsTree->setFilters( filters ); + mAlgorithmsTree->setDragDropMode( QTreeWidget::DragOnly ); + mAlgorithmsTree->setDropIndicatorShown( true ); + connect( mView, &QgsModelGraphicsView::algorithmDropped, this, [ = ]( const QString & algorithmId, const QPointF & pos ) { addAlgorithm( algorithmId, pos ); } ); + connect( mAlgorithmsTree, &QgsProcessingToolboxTreeView::doubleClicked, this, [ = ]() + { + if ( mAlgorithmsTree->selectedAlgorithm() ) + addAlgorithm( mAlgorithmsTree->selectedAlgorithm()->id(), QPointF() ); + } ); + + connect( mView, &QgsModelGraphicsView::inputDropped, this, &QgsModelDesignerDialog::addInput ); // Ctrl+= should also trigger a zoom in action QShortcut *ctrlEquals = new QShortcut( QKeySequence( QStringLiteral( "Ctrl+=" ) ), this ); connect( ctrlEquals, &QShortcut::activated, this, &QgsModelDesignerDialog::zoomIn ); + + tabifyDockWidget( mPropertiesDock, mVariablesDock ); + tabifyDockWidget( mInputsDock, mAlgorithmsDock ); + mInputsDock->raise(); + + connect( mVariablesEditor, &QgsVariableEditorWidget::scopeChanged, this, [ = ] + { + if ( model() ) + model()->setVariables( mVariablesEditor->variablesInActiveScope() ); + } ); +} + +void QgsModelDesignerDialog::updateVariablesGui() +{ + std::unique_ptr< QgsExpressionContextScope > variablesScope = qgis::make_unique< QgsExpressionContextScope >( tr( "Model Variables" ) ); + const QVariantMap modelVars = model()->variables(); + for ( auto it = modelVars.constBegin(); it != modelVars.constEnd(); ++it ) + { + variablesScope->setVariable( it.key(), it.value() ); + } + QgsExpressionContext variablesContext; + variablesContext.appendScope( variablesScope.release() ); + mVariablesEditor->setContext( &variablesContext ); + mVariablesEditor->setEditableScopeIndex( 0 ); } void QgsModelDesignerDialog::zoomIn() diff --git a/src/gui/processing/models/qgsmodeldesignerdialog.h b/src/gui/processing/models/qgsmodeldesignerdialog.h index 8eff83a9eb1c..bbd8ee3ff402 100644 --- a/src/gui/processing/models/qgsmodeldesignerdialog.h +++ b/src/gui/processing/models/qgsmodeldesignerdialog.h @@ -52,10 +52,16 @@ class GUI_EXPORT QgsModelDesignerDialog : public QMainWindow, public Ui::QgsMode QAction *actionEditHelp() { return mActionEditHelp; } QAction *actionRun() { return mActionRun; } QAction *actionExportImage() { return mActionExportImage; } + QLineEdit *textName() { return mNameEdit; } + QLineEdit *textGroup() { return mGroupEdit; } + QScrollArea *inputsScrollArea() { return mInputsScrollArea; } + QgsProcessingToolboxTreeView *algorithmsTree() { return mAlgorithmsTree; } QgsMessageBar *messageBar() { return mMessageBar; } QGraphicsView *view() { return mView; } + void updateVariablesGui(); + private slots: void zoomIn(); diff --git a/src/gui/processing/models/qgsmodelgraphicsview.cpp b/src/gui/processing/models/qgsmodelgraphicsview.cpp index 136c2ac88289..f59412645fa5 100644 --- a/src/gui/processing/models/qgsmodelgraphicsview.cpp +++ b/src/gui/processing/models/qgsmodelgraphicsview.cpp @@ -94,7 +94,7 @@ void QgsModelGraphicsView::wheelEvent( QWheelEvent *event ) //calculate zoom scale factor bool zoomIn = event->angleDelta().y() > 0; - double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor ); + double scaleFactor = ( !zoomIn ? 1 / zoomFactor : zoomFactor ); scale( scaleFactor, scaleFactor ); } diff --git a/src/ui/processing/qgsmodeldesignerdialogbase.ui b/src/ui/processing/qgsmodeldesignerdialogbase.ui index 30b109c3f241..c2691dc4c1eb 100644 --- a/src/ui/processing/qgsmodeldesignerdialogbase.ui +++ b/src/ui/processing/qgsmodeldesignerdialogbase.ui @@ -6,7 +6,7 @@ 0 0 - 891 + 786 596 @@ -40,7 +40,7 @@ 0 0 - 891 + 786 24 @@ -112,6 +112,245 @@ + + + Model Properties + + + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Plain + + + true + + + + + 0 + 0 + 256 + 128 + + + + + + + Enter model name here + + + + + + + Name + + + + + + + Group + + + + + + + Enter group name here + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Inputs + + + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Plain + + + true + + + + + 0 + 0 + 256 + 70 + + + + + + + + + + + Algorithms + + + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Plain + + + true + + + + + 0 + 0 + 256 + 231 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Enter algorithm name to filter list + + + + + + + true + + + + + + + + + + + + + Variables + + + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + @@ -324,6 +563,34 @@ QGraphicsView
qgsmodelgraphicsview.h
+ + QgsFilterLineEdit + QLineEdit +
qgsfilterlineedit.h
+
+ + QgsProcessingToolboxTreeView + QTreeView +
qgsprocessingtoolboxtreeview.h
+
+ + QgsVariableEditorWidget + QWidget +
qgsvariableeditorwidget.h
+ 1 +
+ + QgsDockWidget + QDockWidget +
qgsdockwidget.h
+ 1 +
+ + QgsScrollArea + QScrollArea +
qgsscrollarea.h
+ 1 +