QGIS/python/plugins/processing/gui/ParametersPanel.py
2020-04-02 02:29:54 +10:00

196 lines
8.2 KiB
Python

# -*- coding: utf-8 -*-
"""
***************************************************************************
ParametersPanel.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
(C) 2013 by CS Systemes d'information (CS SI)
Email : volayaf at gmail dot com
otb at c-s dot fr (CS SI)
Contributors : Victor Olaya
***************************************************************************
* *
* 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. *
* *
***************************************************************************
"""
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
from qgis.core import (QgsProcessingParameterDefinition,
QgsProcessingParameterExtent,
QgsProject,
QgsProcessingModelAlgorithm)
from qgis.gui import (QgsProcessingContextGenerator,
QgsProcessingParameterWidgetContext,
QgsProcessingParametersWidget,
QgsGui,
QgsProcessingGui)
from qgis.utils import iface
from processing.gui.wrappers import WidgetWrapperFactory, WidgetWrapper
from processing.tools.dataobjects import createContext
class ParametersPanel(QgsProcessingParametersWidget):
def __init__(self, parent, alg, in_place=False):
super().__init__(alg, parent)
self.in_place = in_place
self.wrappers = {}
self.processing_context = createContext()
class ContextGenerator(QgsProcessingContextGenerator):
def __init__(self, context):
super().__init__()
self.processing_context = context
def processingContext(self):
return self.processing_context
self.context_generator = ContextGenerator(self.processing_context)
self.initWidgets()
QgsProject.instance().layerWasAdded.connect(self.layerRegistryChanged)
QgsProject.instance().layersWillBeRemoved.connect(self.layerRegistryChanged)
def layerRegistryChanged(self, layers):
for wrapper in list(self.wrappers.values()):
try:
wrapper.refresh()
except AttributeError:
pass
def initWidgets(self):
super().initWidgets()
widget_context = QgsProcessingParameterWidgetContext()
widget_context.setProject(QgsProject.instance())
if iface is not None:
widget_context.setMapCanvas(iface.mapCanvas())
widget_context.setBrowserModel(iface.browserModel())
widget_context.setActiveLayer(iface.activeLayer())
widget_context.setMessageBar(self.parent().messageBar())
if isinstance(self.algorithm(), QgsProcessingModelAlgorithm):
widget_context.setModel(self.algorithm())
# Create widgets and put them in layouts
for param in self.algorithm().parameterDefinitions():
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue
if param.isDestination():
continue
else:
wrapper = WidgetWrapperFactory.create_wrapper(param, self.parent())
wrapper.setWidgetContext(widget_context)
wrapper.registerProcessingContextGenerator(self.context_generator)
self.wrappers[param.name()] = wrapper
# For compatibility with 3.x API, we need to check whether the wrapper is
# the deprecated WidgetWrapper class. If not, it's the newer
# QgsAbstractProcessingParameterWidgetWrapper class
# TODO QGIS 4.0 - remove
is_python_wrapper = issubclass(wrapper.__class__, WidgetWrapper)
if not is_python_wrapper:
widget = wrapper.createWrappedWidget(self.processing_context)
else:
widget = wrapper.widget
if self.in_place and param.name() in ('INPUT', 'OUTPUT'):
# don't show the input/output parameter widgets in in-place mode
# we still need to CREATE them, because other wrappers may need to interact
# with them (e.g. those parameters which need the input layer for field
# selections/crs properties/etc)
continue
if widget is not None:
if is_python_wrapper:
widget.setToolTip(param.toolTip())
label = None
if not is_python_wrapper:
label = wrapper.createWrappedLabel()
else:
label = wrapper.label
if label is not None:
self.addParameterLabel(param, label)
elif is_python_wrapper:
desc = param.description()
if isinstance(param, QgsProcessingParameterExtent):
desc += self.tr(' (xmin, xmax, ymin, ymax)')
if param.flags() & QgsProcessingParameterDefinition.FlagOptional:
desc += self.tr(' [optional]')
widget.setText(desc)
self.addParameterWidget(param, widget)
for output in self.algorithm().destinationParameterDefinitions():
if output.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue
if self.in_place and output.name() in ('INPUT', 'OUTPUT'):
continue
wrapper = QgsGui.processingGuiRegistry().createParameterWidgetWrapper(output, QgsProcessingGui.Standard)
wrapper.setWidgetContext(widget_context)
wrapper.registerProcessingContextGenerator(self.context_generator)
self.wrappers[output.name()] = wrapper
label = wrapper.createWrappedLabel()
if label is not None:
self.addOutputLabel(label)
widget = wrapper.createWrappedWidget(self.processing_context)
self.addOutputWidget(widget)
# def skipOutputChanged(widget, checkbox, skipped):
# TODO
# enabled = not skipped
#
# # Do not try to open formats that are write-only.
# value = widget.value()
# if value and isinstance(value, QgsProcessingOutputLayerDefinition) and isinstance(output, (
# QgsProcessingParameterFeatureSink, QgsProcessingParameterVectorDestination)):
# filename = value.sink.staticValue()
# if filename not in ('memory:', ''):
# path, ext = os.path.splitext(filename)
# format = QgsVectorFileWriter.driverForExtension(ext)
# drv = gdal.GetDriverByName(format)
# if drv:
# if drv.GetMetadataItem(gdal.DCAP_OPEN) is None:
# enabled = False
#
# checkbox.setEnabled(enabled)
# checkbox.setChecked(enabled)
for wrapper in list(self.wrappers.values()):
wrapper.postInitialize(list(self.wrappers.values()))
def setParameters(self, parameters):
for param in self.algorithm().parameterDefinitions():
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue
if not param.name() in parameters:
continue
value = parameters[param.name()]
wrapper = self.wrappers[param.name()]
wrapper.setParameterValue(value, self.processing_context)