Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

dataladcmd_ui.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. from typing import (
  2. Dict,
  3. )
  4. from PySide6.QtCore import (
  5. QObject,
  6. Signal,
  7. Slot,
  8. )
  9. from PySide6.QtGui import QAction
  10. from PySide6.QtWidgets import (
  11. QDialogButtonBox,
  12. QFormLayout,
  13. QLabel,
  14. QScrollArea,
  15. QWidget,
  16. )
  17. from .param_form_utils import populate_form_w_params
  18. from .api_utils import get_cmd_displayname
  19. from .active_api import api
  20. class GooeyDataladCmdUI(QObject):
  21. configured_dataladcmd = Signal(str, dict)
  22. def __init__(self, app, ui_parent: QWidget):
  23. super().__init__()
  24. self._app = app
  25. self._ui_parent = ui_parent
  26. # start out disabled, there will be no populated form
  27. self._ui_parent.setDisabled(True)
  28. self._pform = None
  29. self._cmd_title = None
  30. @property
  31. def pwidget(self):
  32. return self._ui_parent
  33. @property
  34. def pform(self):
  35. if self._pform is None:
  36. pw = self.pwidget
  37. # make sure all expected UI blocks are present
  38. self._cmd_title = pw.findChild(QLabel, 'cmdTabTitle')
  39. scrollarea_content = pw.findChild(QScrollArea).widget()
  40. buttonbox = pw.findChild(QDialogButtonBox, 'cmdTabButtonBox')
  41. for w in (self._cmd_title, scrollarea_content, buttonbox):
  42. assert w
  43. # create main form layout for the parameters to appear in
  44. form_layout = QFormLayout(scrollarea_content)
  45. form_layout.setObjectName('cmdTabFormLayout')
  46. self._pform = form_layout
  47. # connect the dialog interaction with slots in this instance
  48. # we run the retrieval helper on ok/run
  49. buttonbox.accepted.connect(self._retrieve_input)
  50. # we disable the UI (however that might look like) on cancel
  51. buttonbox.rejected.connect(self.disable)
  52. return self._pform
  53. @Slot(str, dict)
  54. def configure(
  55. self,
  56. cmdname: str = None,
  57. cmdkwargs: Dict or None = None):
  58. if cmdkwargs is None:
  59. cmdkwargs = dict()
  60. # figure out the object that emitted the signal triggering
  61. # this slot execution. Will be None for a regular method call.
  62. # we can use this to update the method parameter values
  63. # with information from menu-items, or tree nodes clicked
  64. sender = self.sender()
  65. if sender is not None:
  66. if cmdname is None and isinstance(sender, QAction):
  67. cmdname = sender.data().get('__cmd_name__')
  68. # pull in any signal-provided kwargs for the command
  69. # unless they have been also specified directly to the method
  70. cmdkwargs = {
  71. k: v for k, v in sender.data().items()
  72. if k != '__cmd_name__' and k not in cmdkwargs
  73. }
  74. assert cmdname is not None, \
  75. "GooeyDataladCmdUI.configure() called without command name"
  76. self._app.get_widget('contextTabs').setCurrentWidget(self.pwidget)
  77. self.reset_form()
  78. populate_form_w_params(
  79. self._app.rootpath,
  80. self.pform,
  81. cmdname,
  82. cmdkwargs,
  83. )
  84. # set title afterwards, form might just have been created first, lazily
  85. self._cmd_title.setText(get_cmd_displayname(api, cmdname))
  86. self._cmd_title.setToolTip(f'API command: `{cmdname}`')
  87. # make sure the UI is visible
  88. self.pwidget.setEnabled(True)
  89. @Slot()
  90. def _retrieve_input(self):
  91. params = dict()
  92. for i in range(self.pform.rowCount()):
  93. # the things is wrapped into a QWidgetItem layout class, hence .wid
  94. field_widget = self.pform.itemAt(i, QFormLayout.FieldRole).wid
  95. # _get_datalad_param_spec() is our custom private adhoc method
  96. # expected to return a dict with a parameter setting, or an
  97. # empty dict, when the default shall be used.
  98. params.update(field_widget.get_gooey_param_spec())
  99. # take a peek, TODO remove
  100. from pprint import pprint
  101. pprint(params)
  102. self.configured_dataladcmd.emit(
  103. self.pform.datalad_cmd_name,
  104. params,
  105. )
  106. self.disable()
  107. @Slot()
  108. def disable(self):
  109. """Disable UI when no longer needed for configuration"""
  110. # only disaable, not hide, to keep the info what ran (was configured)
  111. # accessible. Widget empties itself on reconfigure
  112. self.pwidget.setDisabled(True)
  113. def reset_form(self):
  114. if self._cmd_title:
  115. self._cmd_title.setText('')
  116. for i in range(self.pform.rowCount() - 1, -1, -1):
  117. # empty the form layout (deletes all widgets)
  118. self.pform.removeRow(i)
  119. self.disable()