QGIS/python/plugins/otbprovider/OtbChoiceWidget.py
2021-06-21 07:17:36 +03:00

180 lines
7.5 KiB
Python

# -*- coding: utf-8 -*-
"""
***************************************************************************
OtbChoiceWidget.py
------------------
Date : June 2017
Copyright : (C) 2017 by CS Systemes d'Information (CS SI)
Email : rashad dot kanavath at c-s fr
***************************************************************************
* *
* 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__ = 'Rashad Kanavath'
__date__ = 'June 2017'
__copyright__ = "(C) 2017,2018 by CS Systemes d'information (CS SI)"
from qgis.PyQt.QtWidgets import QComboBox
from qgis.core import (QgsProcessingParameterString,
QgsProcessingOutputString,
QgsProcessingParameterDefinition)
from qgis.gui import QgsProcessingModelerParameterWidget
from processing.gui.wrappers import (WidgetWrapper,
DIALOG_STANDARD,
DIALOG_BATCH,
DIALOG_MODELER)
# TODO: QGIS 3.8 move this class to processing/gui/
# OtbChoiceWidget is a crucial parameter type in otb provider
# It is the one that can handles required parameters are run-time depending on user input!.
# This idea is indeed different from static list of required/optional parameters from a descriptor file.
# So this class (if treated as first class citizen in processing/gui) have potential
# to be reused in existing or future processing providers.
class OtbChoiceWidgetWrapper(WidgetWrapper):
def __init__(self, param, dialog, row=0, col=0, **kwargs):
self.flagsModified = {}
super().__init__(param, dialog, row=0, col=0, **kwargs)
self.updateAllParameters(None)
def createWidget(self):
widget = QComboBox()
widget.addItems(self.param.options)
if self.dialogType in (DIALOG_MODELER, DIALOG_STANDARD):
widget.currentIndexChanged.connect(self.updateAllParameters)
return widget
def get_algorithm(self):
if self.dialogType == DIALOG_MODELER:
return self.dialog._alg
else:
return self.dialog.algorithm()
def __updateWrapper(self, name, visible):
if self.dialogType == DIALOG_BATCH:
return
elif self.dialogType == DIALOG_STANDARD:
if self.dialog.mainWidget() is None:
return
if name in self.dialog.mainWidget().wrappers:
self.__setWrapperVisibility(self.dialog.mainWidget().wrappers[name], visible)
# For QGIS modeler
else:
try:
if name in self.dialog.widget.widget.wrappers:
self.__setWrapperVisibility(self.dialog.widget.widget.wrappers[name], visible)
if name in self.dialog.widget.widget.widget_labels:
self.dialog.widget.widget.widget_labels[name].setVisible(visible)
except AttributeError:
pass
def __setWrapperVisibility(self, wrapper, v):
# 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 logic
if issubclass(wrapper.__class__, WidgetWrapper):
wrapper.widget.setVisible(v)
if wrapper.label:
wrapper.label.setVisible(v)
elif issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget):
wrapper.setVisible(v)
else:
wrapper.wrappedWidget().setVisible(v)
if wrapper.wrappedLabel():
wrapper.wrappedLabel().setVisible(v)
def updateAllParameters(self, current_value):
for parameter in self.get_algorithm().parameterDefinitions():
if 'group_key' not in parameter.metadata() or parameter.metadata()['group_key'] != self.param.name():
continue
name = parameter.name()
choice_key = parameter.metadata()['group_key']
if choice_key and choice_key + "." in name:
choice_param = self.get_algorithm().parameterDefinition(choice_key)
if current_value is None:
current_value = choice_param.defaultValue()
pattern = "{}.{}.".format(choice_key, choice_param.getValueAsText(current_value))
if pattern not in name:
flags = self.get_algorithm().parameterDefinition(name).flags()
if not flags & QgsProcessingParameterDefinition.FlagOptional:
self.flagsModified[name] = True
self.get_algorithm().parameterDefinition(name).setFlags(QgsProcessingParameterDefinition.FlagOptional)
self.__updateWrapper(name, False)
else:
if name in self.flagsModified.keys():
self.get_algorithm().parameterDefinition(name).setFlags(QgsProcessingParameterDefinition.FlagAdvanced)
self.__updateWrapper(name, True)
def setValue(self, value):
if value in self.param.options:
index = self.param.options.index(value)
else:
index = int(value)
self.widget.setCurrentIndex(index)
def value(self):
return self.widget.currentText()
def postInitialize(self, wrappers):
# if self.dialogType == DIALOG_BATCH:
# return
self.updateAllParameters(current_value=None)
for parameter in self.get_algorithm().parameterDefinitions():
if 'group_key' not in parameter.metadata() or parameter.metadata()['group_key'] != self.param.name():
continue
for wrapper in wrappers:
if wrapper.param.name() == parameter.name():
v = self.value() == parameter.metadata()['group_value']
self.__setWrapperVisibility(wrapper, v)
from qgis.core import QgsProcessingParameterDefinition
class OtbParameterChoice(QgsProcessingParameterDefinition):
def __init__(self, name='', description='', options=[], default=None, isSource=False,
multiple=False, optional=False):
QgsProcessingParameterDefinition.__init__(self, name, description, default, optional)
self.setMetadata({
'widget_wrapper': {
'class': 'otbprovider.OtbChoiceWidget.OtbChoiceWidgetWrapper'}})
self.options = options
if default is not None:
try:
self.default = int(default)
except Exception:
self.default = 0
self.value = self.default
def getValueAsText(self, value):
if value not in self.options:
value = self.options[int(value)]
return value
def setValue(self, value):
if value is None:
self.value = 0
else:
self.value = int(value)
return True
def type(self):
# This value is written by otbQgisDescriptor.
return 'OTBParameterChoice'