Bläddra i källkod

Merge pull request #170 from datalad/cfgproc

Dedicated cfg_proc parameter input widget
Michael Hanke 2 år sedan
förälder
incheckning
c86e40fe32
2 ändrade filer med 50 tillägg och 8 borttagningar
  1. 6 2
      datalad_gooey/param_form_utils.py
  2. 44 6
      datalad_gooey/param_widgets.py

+ 6 - 2
datalad_gooey/param_form_utils.py

@@ -187,15 +187,19 @@ def _get_parameter_widget_factory(
 
     # if we have no idea, use a simple line edit
     type_widget = pw.StrParamWidget
+    # no some parameters where we can derive semantics from their name
     if name == 'dataset':
         type_widget = functools.partial(
             pw.PathParamWidget,
             pathtype=QFileDialog.Directory,
             basedir=basedir)
-    if name == 'path':
+    elif name == 'path':
         type_widget = functools.partial(
             pw.PathParamWidget, basedir=basedir)
-    if argparse_action in ('store_true', 'store_false'):
+    elif name == 'cfg_proc':
+        type_widget = pw.CfgProcParamWidget
+    # now parameters where we make decisions based on their configuration
+    elif argparse_action in ('store_true', 'store_false'):
         type_widget = pw.BoolParamWidget
     elif isinstance(constraints, EnsureChoice) and argparse_action is None:
         type_widget = functools.partial(

+ 44 - 6
datalad_gooey/param_widgets.py

@@ -183,17 +183,17 @@ class ChoiceParamWidget(QComboBox, GooeyParamWidgetMixin):
         super().__init__(parent)
         self.setInsertPolicy(QComboBox.NoInsert)
         if choices:
-            self._add_items(choices)
+            for c in choices:
+                self._add_item(c)
         else:
             # avoid making the impression something could be selected
             self.setPlaceholderText('No known choices')
             self.setDisabled(True)
 
-    def _add_items(self, values: List) -> None:
-        for v in values:
-            # we add items, and we stick their real values in too
-            # to avoid tricky conversion via str
-            self.addItem(self._gooey_map_val2label(v), userData=v)
+    def _add_item(self, value) -> None:
+        # we add items, and we stick their real values in too
+        # to avoid tricky conversion via str
+        self.addItem(self._gooey_map_val2label(value), userData=value)
 
     def _set_gooey_param_value(self, value):
         self.setCurrentText(self._gooey_map_val2label(value))
@@ -395,3 +395,41 @@ class PathParamWidget(QWidget, GooeyParamWidgetMixin):
 
         if 'dataset' in spec:
             self._basedir = spec['dataset']
+
+
+class CfgProcParamWidget(ChoiceParamWidget):
+    """Choice widget with items from `run_procedure(discover=True)`"""
+    def __init__(self, choices=None, parent=None):
+        super().__init__(parent=parent)
+        self.init_gooey_from_other_param({})
+
+    def init_gooey_from_other_param(self, spec: Dict) -> None:
+        if self.count() and 'dataset' not in spec:
+            # we have items and no context change is required
+            return
+
+        # we have no items yet, or the dataset has changed: query!
+        # reset first
+        while self.count():
+            self.removeItem(0)
+        from datalad.local.run_procedure import RunProcedure
+        for res in RunProcedure.__call__(
+            dataset=spec.get('dataset'),
+            discover=True,
+            return_type='generator',
+            result_renderer='disabled',
+            on_failure='ignore',
+        ):
+            proc_name = res.get('procedure_name', '')
+            if res.get('status') != 'ok' \
+                    or not proc_name.startswith('cfg_'):
+                # not a good config procedure
+                continue
+            self._add_item(proc_name)
+        if self.count():
+            self.setEnabled(True)
+            self.setPlaceholderText('Select procedure')
+
+    def _gooey_map_val2label(self, val):
+        # strip 'cfg_' prefix
+        return val[4:].replace('cfg_', '') if val else ''