|
15 | 15 | from qtpy import QtWidgets |
16 | 16 | from qtpy.QtCore import Qt # type: ignore[attr-defined] |
17 | 17 |
|
| 18 | +from deadline.client.config import get_setting, str2bool |
18 | 19 | from deadline.client.dataclasses import SubmitterInfo |
19 | | -from deadline.client.exceptions import DeadlineOperationError |
| 20 | +from deadline.client.exceptions import DeadlineOperationCanceled, DeadlineOperationError |
20 | 21 | from deadline.client.job_bundle._yaml import deadline_yaml_dump |
21 | 22 | from deadline.client.job_bundle.parameters import JobParameter |
22 | 23 | from deadline.client.job_bundle.submission import AssetReferences |
23 | 24 | from deadline.client.ui.dialogs.submit_job_to_deadline_dialog import ( # pylint: disable=import-error |
24 | 25 | JobBundlePurpose, |
25 | 26 | SubmitJobToDeadlineDialog, |
26 | 27 | ) |
| 28 | +from deadline.client.ui.pre_gui_hooks import ( |
| 29 | + PreGuiHookContext, |
| 30 | + apply_pre_gui_output, |
| 31 | + qt_hook_confirmation, |
| 32 | + run_pre_gui_hooks, |
| 33 | +) |
27 | 34 |
|
28 | 35 | from ._version import version_tuple as adaptor_version_tuple |
29 | 36 | from .assets import AssetIntrospector |
@@ -111,6 +118,10 @@ def show_submitter(): |
111 | 118 | ) |
112 | 119 | else: |
113 | 120 | w = _show_submitter(temp_dir, None) |
| 121 | + # _show_submitter returns None when the user declines the pre-GUI hook confirmation |
| 122 | + # prompt; treat that as a normal cancellation and skip showing the dialog. |
| 123 | + if w is None: |
| 124 | + return |
114 | 125 | w.setStyleSheet(C4D_STYLE) |
115 | 126 | w.exec_() |
116 | 127 | except Exception: |
@@ -933,6 +944,19 @@ def export_to_temp_folder(temp_dir: str, asset_references: AssetReferences) -> N |
933 | 944 | asset_references.input_filenames = temp_assets |
934 | 945 |
|
935 | 946 |
|
| 947 | +def _pre_gui_hook_confirm_callback(parent): |
| 948 | + """Choose the confirmation callback for pre-GUI hooks based on the auto_accept setting. |
| 949 | +
|
| 950 | + Returns ``None`` (run hooks without prompting) when ``settings.auto_accept`` is enabled, |
| 951 | + otherwise the standard Qt confirmation dialog from ``qt_hook_confirmation``. Kept as a small |
| 952 | + helper so the auto_accept branch can be unit-tested headlessly. |
| 953 | + """ |
| 954 | + if str2bool(get_setting("settings.auto_accept")): |
| 955 | + return None |
| 956 | + |
| 957 | + return qt_hook_confirmation(parent) |
| 958 | + |
| 959 | + |
936 | 960 | def _show_submitter(temp_dir: str, parent=None, f=Qt.WindowType.Tool): # type: ignore[call-overload] |
937 | 961 | """ |
938 | 962 | Creates and returns a submission dialog for rendering jobs. |
@@ -1018,12 +1042,41 @@ def on_create_job_bundle_callback( |
1018 | 1042 | host_requirements, |
1019 | 1043 | ) |
1020 | 1044 |
|
| 1045 | + shared_parameter_values = { |
| 1046 | + "CondaPackages": conda_packages, |
| 1047 | + } |
| 1048 | + |
| 1049 | + # Run pre-GUI hooks so studios can pre-populate dialog fields before it opens. Cinema 4D has |
| 1050 | + # no on-disk job bundle at this point, so hooks are sourced from DEADLINE_HOOKS_DIR only |
| 1051 | + # (bundle_dir=None), gated by settings.allow_environment_hooks. The confirmation prompt is |
| 1052 | + # skipped when auto_accept is set; otherwise the standard dialog is shown. |
| 1053 | + try: |
| 1054 | + pre_gui_output = run_pre_gui_hooks( |
| 1055 | + PreGuiHookContext( |
| 1056 | + bundle_dir=None, |
| 1057 | + job_name=render_settings.name, |
| 1058 | + submitter_name="cinema4d", |
| 1059 | + parameters=dict(shared_parameter_values), |
| 1060 | + ), |
| 1061 | + confirm_callback=_pre_gui_hook_confirm_callback(parent), |
| 1062 | + ) |
| 1063 | + except DeadlineOperationCanceled: |
| 1064 | + # The user declined the hook confirmation prompt. This is a normal cancellation, not an |
| 1065 | + # error, so abort opening the submitter silently by returning None; show_submitter skips |
| 1066 | + # the dialog. Without this, the exception would surface as a spurious "Deadline UI launch |
| 1067 | + # failed" error for what is a deliberate "No" click. |
| 1068 | + return None |
| 1069 | + # RenderSubmitterUISettings has no `.parameters` list, so apply_pre_gui_output routes |
| 1070 | + # name/description onto it and every hook parameter into shared_parameter_values. |
| 1071 | + # run_pre_gui_hooks returns {} when no hooks run (and raises DeadlineOperationCanceled, handled |
| 1072 | + # above, if the user declines); `or {}` is defensive against any future contract change so the |
| 1073 | + # common no-hooks path can never pass a falsy value into apply_pre_gui_output. |
| 1074 | + apply_pre_gui_output(pre_gui_output or {}, render_settings, shared_parameter_values) |
| 1075 | + |
1021 | 1076 | submitter_dialog = SubmitJobToDeadlineDialog( |
1022 | 1077 | job_setup_widget_type=SceneSettingsWidget, |
1023 | 1078 | initial_job_settings=render_settings, |
1024 | | - initial_shared_parameter_values={ |
1025 | | - "CondaPackages": conda_packages, |
1026 | | - }, |
| 1079 | + initial_shared_parameter_values=shared_parameter_values, |
1027 | 1080 | auto_detected_attachments=auto_detected_attachments, |
1028 | 1081 | attachments=attachments, |
1029 | 1082 | on_create_job_bundle_callback=on_create_job_bundle_callback, |
|
0 commit comments