2727
2828from qgis .PyQt .QtWidgets import QComboBox
2929from qgis .core import (QgsProcessingParameterString ,
30- QgsProcessingOutputString )
30+ QgsProcessingOutputString ,
31+ QgsProcessingParameterDefinition )
32+ from qgis .gui import QgsProcessingModelerParameterWidget
3133from processing .gui .wrappers import (WidgetWrapper ,
3234 DIALOG_STANDARD ,
3335 DIALOG_BATCH ,
3436 DIALOG_MODELER )
3537
38+ # TODO: QGIS 3.8 move this class to processing/gui/
39+ # OtbChoiceWidget is a crucial parameter type in otb provider
40+ # It is the one that can handles required parameters are run-time depending on user input!.
41+ # This idea is indeed different from static list of required/optional parameters from a descriptor file.
42+ # So this class (if treated as first class citizen in processing/gui) have potential
43+ # to be reused in existing or future processing providers.
44+
3645
3746class OtbChoiceWidgetWrapper (WidgetWrapper ):
3847
48+ def __init__ (self , param , dialog , row = 0 , col = 0 , ** kwargs ):
49+ self .flagsModified = {}
50+ super ().__init__ (param , dialog , row = 0 , col = 0 , ** kwargs )
51+ self .updateAllParameters (None )
52+
3953 def createWidget (self ):
4054 widget = QComboBox ()
4155 widget .addItems (self .param .options )
4256 if self .dialogType in (DIALOG_MODELER , DIALOG_STANDARD ):
43- widget .currentIndexChanged .connect (self .valueChanged )
57+ widget .currentIndexChanged .connect (self .updateAllParameters )
4458 return widget
4559
4660 def get_algorithm (self ):
@@ -49,46 +63,59 @@ def get_algorithm(self):
4963 else :
5064 return self .dialog .algorithm ()
5165
52- def setWrapperVisible (self , name , visible ):
53- if self .dialogType == DIALOG_STANDARD :
66+ def __updateWrapper (self , name , visible ):
67+ if self .dialogType == DIALOG_BATCH :
68+ return
69+ elif self .dialogType == DIALOG_STANDARD :
5470 if self .dialog .mainWidget () is None :
5571 return
56- # For compatibility with 3.x API, we need to check whether the wrapper is
57- # the deprecated WidgetWrapper class. If not, it's the newer
58- # QgsAbstractProcessingParameterWidgetWrapper class
59- # TODO QGIS 4.0 - remove is_python_wrapper logic
60- is_python_wrapper = issubclass (self .dialog .mainWidget ().wrappers [name ].__class__ , WidgetWrapper )
61- if is_python_wrapper :
62- self .dialog .mainWidget ().wrappers [name ].widget .setVisible (visible )
63- if self .dialog .mainWidget ().wrappers [name ].label :
64- self .dialog .mainWidget ().wrappers [name ].label .setVisible (visible )
65- else :
66- self .dialog .mainWidget ().wrappers [name ].wrappedWidget ().setVisible (visible )
67- if self .dialog .mainWidget ().wrappers [name ].wrappedLabel ():
68- self .dialog .mainWidget ().wrappers [name ].wrappedLabel ().setVisible (visible )
72+ if name in self .dialog .mainWidget ().wrappers :
73+ self .__setWrapperVisibility (self .dialog .mainWidget ().wrappers [name ], visible )
74+
75+ #Fur Qgis modeler
6976 else :
70- # For compatibility with 3.x API, we need to check whether the wrapper is
71- # the deprecated WidgetWrapper class. If not, it's the newer
72- # QgsAbstractProcessingParameterWidgetWrapper class
73- # TODO QGIS 4.0 - remove is_python_wrapper logic
7477 if name in self .dialog .wrappers :
75- is_python_wrapper = issubclass (self .dialog .wrappers [name ].__class__ , WidgetWrapper )
76- if is_python_wrapper :
77- self .dialog .wrappers [name ].widget .setVisible (visible )
78- if self .dialog .wrappers [name ].label :
79- self .dialog .wrappers [name ].label .setVisible (visible )
80- else :
81- self .dialog .wrappers [name ].setVisible (visible )
82- if name in self .dialog .widget_labels :
83- self .dialog .widget_labels [name ].setVisible (visible )
78+ self .__setWrapperVisibility (self .dialog .wrappers [name ], visible )
79+ if name in self .dialog .widget_labels :
80+ self .dialog .widget_labels [name ].setVisible (visible )
81+
82+ def __setWrapperVisibility (self , wrapper , v ):
83+ # For compatibility with 3.x API, we need to check whether the wrapper is
84+ # the deprecated WidgetWrapper class. If not, it's the newer
85+ # QgsAbstractProcessingParameterWidgetWrapper class
86+ # TODO QGIS 4.0 - remove is_python_wrapper logic
87+ if issubclass (wrapper .__class__ , WidgetWrapper ):
88+ wrapper .widget .setVisible (v )
89+ if wrapper .label :
90+ wrapper .label .setVisible (v )
91+ elif issubclass (wrapper .__class__ , QgsProcessingModelerParameterWidget ):
92+ wrapper .setVisible (v )
93+ else :
94+ wrapper .wrappedWidget ().setVisible (v )
95+ if wrapper .wrappedLabel ():
96+ wrapper .wrappedLabel ().setVisible (v )
8497
85- def valueChanged (self , value ):
98+ def updateAllParameters (self , current_value ):
8699 for parameter in self .get_algorithm ().parameterDefinitions ():
87100 if not 'group_key' in parameter .metadata () or parameter .metadata ()['group_key' ] != self .param .name ():
88101 continue
89102 name = parameter .name ()
90- v = self .value () == parameter .metadata ()['group_value' ]
91- self .setWrapperVisible (name , v )
103+ choice_key = parameter .metadata ()['group_key' ]
104+ if choice_key and choice_key + "." in name :
105+ choice_param = self .get_algorithm ().parameterDefinition (choice_key )
106+ if current_value is None :
107+ current_value = choice_param .defaultValue ()
108+ pattern = "{}.{}." .format (choice_key , choice_param .getValueAsText (current_value ))
109+ if not pattern in name :
110+ flags = self .get_algorithm ().parameterDefinition (name ).flags ()
111+ if not flags & QgsProcessingParameterDefinition .FlagOptional :
112+ self .flagsModified [name ] = True
113+ self .get_algorithm ().parameterDefinition (name ).setFlags (QgsProcessingParameterDefinition .FlagOptional )
114+ self .__updateWrapper (name , False )
115+ else :
116+ if name in self .flagsModified .keys ():
117+ self .get_algorithm ().parameterDefinition (name ).setFlags (QgsProcessingParameterDefinition .FlagAdvanced )
118+ self .__updateWrapper (name , True )
92119
93120 def setValue (self , value ):
94121 if value in self .param .options :
@@ -101,29 +128,16 @@ def value(self):
101128 return self .widget .currentText ()
102129
103130 def postInitialize (self , wrappers ):
104- if self .dialogType == DIALOG_BATCH :
105- return
106-
131+ # if self.dialogType == DIALOG_BATCH:
132+ # return
133+ self . updateAllParameters ( current_value = None )
107134 for parameter in self .get_algorithm ().parameterDefinitions ():
108135 if not 'group_key' in parameter .metadata () or parameter .metadata ()['group_key' ] != self .param .name ():
109136 continue
110- name = parameter .name ()
111- v = self .value () == parameter .metadata ()['group_value' ]
112137 for wrapper in wrappers :
113- # For compatibility with 3.x API, we need to check whether the wrapper is
114- # the deprecated WidgetWrapper class. If not, it's the newer
115- # QgsAbstractProcessingParameterWidgetWrapper class
116- # TODO QGIS 4.0 - remove is_python_wrapper logic
117- is_python_wrapper = issubclass (wrapper .__class__ , WidgetWrapper )
118- if wrapper .param .name () == name :
119- if is_python_wrapper :
120- wrapper .widget .setVisible (v )
121- if wrapper .label :
122- wrapper .label .setVisible (v )
123- else :
124- wrapper .wrappedWidget ().setVisible (v )
125- if wrapper .wrappedLabel ():
126- wrapper .wrappedLabel ().setVisible (v )
138+ if wrapper .param .name () == parameter .name ():
139+ v = self .value () == parameter .metadata ()['group_value' ]
140+ self .__setWrapperVisibility (wrapper , v )
127141
128142
129143from qgis .core import QgsProcessingParameterDefinition
@@ -148,6 +162,11 @@ def __init__(self, name='', description='', options=[], default=None, isSource=F
148162 self .default = 0
149163 self .value = self .default
150164
165+ def getValueAsText (self , value ):
166+ if not value in self .options :
167+ value = self .options [int (value )]
168+ return value
169+
151170 def setValue (self , value ):
152171 if value is None :
153172 self .value = 0
0 commit comments