handle the actions

This commit is contained in:
Jakub Trllo 2025-08-25 11:22:22 +02:00
parent 856aa31231
commit 51beef8192
3 changed files with 154 additions and 35 deletions

View file

@ -124,12 +124,13 @@ class LoaderActionsModel:
self,
plugin_identifier: str,
identifier: str,
options: dict[str, Any],
project_name: str,
entity_ids: set[str],
entity_type: str,
selected_ids: set[str],
selected_entity_type: str,
options: dict[str, Any],
form_values: dict[str, Any],
):
"""Trigger action by identifier.
@ -142,17 +143,23 @@ class LoaderActionsModel:
Args:
plugin_identifier (str): Plugin identifier.
identifier (str): Action identifier.
options (dict[str, Any]): Loader option values.
project_name (str): Project name.
entity_ids (set[str]): Entity ids on action item.
entity_type (str): Entity type on action item.
selected_ids (set[str]): Selected entity ids.
selected_entity_type (str): Selected entity type.
options (dict[str, Any]): Loader option values.
form_values (dict[str, Any]): Form values.
"""
event_data = {
"plugin_identifier": plugin_identifier,
"identifier": identifier,
"project_name": project_name,
"entity_ids": list(entity_ids),
"entity_type": entity_type,
"selected_ids": list(selected_ids),
"selected_entity_type": selected_entity_type,
"id": uuid.uuid4().hex,
}
self._controller.emit_event(
@ -162,9 +169,10 @@ class LoaderActionsModel:
)
if plugin_identifier != LOADER_PLUGIN_ID:
# TODO fill error infor if any happens
error_info = []
result = None
crashed = False
try:
self._loader_actions.execute_action(
result = self._loader_actions.execute_action(
plugin_identifier,
identifier,
entity_ids,
@ -174,37 +182,47 @@ class LoaderActionsModel:
selected_ids,
selected_entity_type,
),
{},
form_values,
)
except Exception:
crashed = True
self._log.warning(
f"Failed to execute action '{identifier}'",
exc_info=True,
)
else:
loader = self._get_loader_by_identifier(
project_name, identifier
)
if entity_type == "version":
error_info = self._trigger_version_loader(
loader,
options,
project_name,
entity_ids,
)
elif entity_type == "representation":
error_info = self._trigger_representation_loader(
loader,
options,
project_name,
entity_ids,
)
else:
raise NotImplementedError(
f"Invalid entity type '{entity_type}' to trigger action item"
)
event_data["result"] = result
event_data["crashed"] = crashed
self._controller.emit_event(
"loader.action.finished",
event_data,
ACTIONS_MODEL_SENDER,
)
return
loader = self._get_loader_by_identifier(
project_name, identifier
)
if entity_type == "version":
error_info = self._trigger_version_loader(
loader,
options,
project_name,
entity_ids,
)
elif entity_type == "representation":
error_info = self._trigger_representation_loader(
loader,
options,
project_name,
entity_ids,
)
else:
raise NotImplementedError(
f"Invalid entity type '{entity_type}' to trigger action item"
)
event_data["error_info"] = error_info
self._controller.emit_event(
@ -334,8 +352,8 @@ class LoaderActionsModel:
label=label,
icon=self._get_action_icon(loader),
tooltip=self._get_action_tooltip(loader),
options=loader.get_options(contexts),
order=loader.order,
options=loader.get_options(contexts),
)
def _get_loaders(self, project_name):
@ -783,11 +801,11 @@ class LoaderActionsModel:
action.identifier,
action.entity_ids,
action.entity_type,
label,
action.icon,
None, # action.tooltip,
None, # action.options,
action.order,
label=label,
icon=action.icon,
tooltip=None, # action.tooltip,
order=action.order,
options=None, # action.options,
))
return items

View file

@ -493,10 +493,10 @@ class SiteSyncModel:
"color": "#999999"
},
tooltip=tooltip,
options={},
order=1,
entity_ids=representation_ids,
entity_type="representation",
options={},
)
def _add_site(self, project_name, repre_entity, site_name, product_type):

View file

@ -1,18 +1,24 @@
from __future__ import annotations
from typing import Optional
from qtpy import QtWidgets, QtCore, QtGui
from ayon_core.resources import get_ayon_icon_filepath
from ayon_core.style import load_stylesheet
from ayon_core.pipeline.actions import LoaderActionResult
from ayon_core.tools.utils import (
PlaceholderLineEdit,
MessageOverlayObject,
ErrorMessageBox,
ThumbnailPainterWidget,
RefreshButton,
GoToCurrentButton,
ProjectsCombobox,
get_qt_icon,
)
from ayon_core.tools.attribute_defs import AttributeDefinitionsDialog
from ayon_core.tools.utils.lib import center_window
from ayon_core.tools.utils import ProjectsCombobox
from ayon_core.tools.common_models import StatusItem
from ayon_core.tools.loader.abstract import ProductTypeItem
from ayon_core.tools.loader.control import LoaderController
@ -141,6 +147,8 @@ class LoaderWindow(QtWidgets.QWidget):
if controller is None:
controller = LoaderController()
overlay_object = MessageOverlayObject(self)
main_splitter = QtWidgets.QSplitter(self)
context_splitter = QtWidgets.QSplitter(main_splitter)
@ -294,6 +302,12 @@ class LoaderWindow(QtWidgets.QWidget):
"controller.reset.finished",
self._on_controller_reset_finish,
)
controller.register_event_callback(
"loader.action.finished",
self._on_loader_action_finished,
)
self._overlay_object = overlay_object
self._group_dialog = ProductGroupDialog(controller, self)
@ -406,6 +420,20 @@ class LoaderWindow(QtWidgets.QWidget):
if self._reset_on_show:
self.refresh()
def _show_toast_message(
self,
message: str,
success: bool = True,
message_id: Optional[str] = None,
):
message_type = None
if not success:
message_type = "error"
self._overlay_object.add_message(
message, message_type, message_id=message_id
)
def _show_group_dialog(self):
project_name = self._projects_combobox.get_selected_project_name()
if not project_name:
@ -494,6 +522,79 @@ class LoaderWindow(QtWidgets.QWidget):
box = LoadErrorMessageBox(error_info, self)
box.show()
def _on_loader_action_finished(self, event):
crashed = event["crashed"]
if crashed:
self._show_toast_message(
"Action failed",
success=False,
)
return
result: Optional[LoaderActionResult] = event["result"]
if result is None:
return
if result.message:
self._show_toast_message(
result.message, result.success
)
if result.form is None:
return
form = result.form
dialog = AttributeDefinitionsDialog(
form.fields,
title=form.title,
parent=self,
)
if result.form_values:
dialog.set_values(result.form_values)
submit_label = form.submit_label
submit_icon = form.submit_icon
cancel_label = form.cancel_label
cancel_icon = form.cancel_icon
if submit_icon:
submit_icon = get_qt_icon(submit_icon)
if cancel_icon:
cancel_icon = get_qt_icon(cancel_icon)
if submit_label:
dialog.set_submit_label(submit_label)
else:
dialog.set_submit_visible(False)
if submit_icon:
dialog.set_submit_icon(submit_icon)
if cancel_label:
dialog.set_cancel_label(cancel_label)
else:
dialog.set_cancel_visible(False)
if cancel_icon:
dialog.set_cancel_icon(cancel_icon)
dialog.setMinimumSize(300, 140)
result = dialog.exec_()
if result != QtWidgets.QDialog.Accepted:
return
form_data = dialog.get_values()
self._controller.trigger_action_item(
event["plugin_identifier"],
event["identifier"],
event["project_name"],
event["entity_ids"],
event["entity_type"],
event["selected_ids"],
event["selected_entity_type"],
{},
form_data,
)
def _on_project_selection_changed(self, event):
self._selected_project_name = event["project_name"]
self._update_filters()