Source code for ooodev.gui.menu.context.context_processor

from __future__ import annotations
from typing import cast, Any, Union, TYPE_CHECKING
from ooodev.events.args.cancel_event_args import CancelEventArgs
from ooodev.events.args.event_args import EventArgs
from ooodev.events.partial.events_partial import EventsPartial
from ooodev.gui.commands.cmd_data import CmdData
from ooodev.gui.commands.cmd_info import CmdInfo
from ooodev.gui.menu.context.action_trigger_item import ActionTriggerItem
from ooodev.gui.menu.context.action_trigger_sep import ActionTriggerSep
from ooodev.gui.menu.context.action_trigger_container import ActionTriggerContainer
from ooodev.gui.menu.shortcuts import Shortcuts
from ooodev.utils.helper.dot_dict import DotDict
from ooodev.utils.kind.module_names_kind import ModuleNamesKind

if TYPE_CHECKING:
    from ooodev.gui.menu.common.command_dict import CommandDict


[docs]class ContextProcessor(EventsPartial): """ Class for processing context menus for interception. Does not process submenus. See Also: - :ref:`help_menu_context_incept` - :ref:`help_menu_context_incept_class_ex` """
[docs] def __init__(self, container: ActionTriggerContainer) -> None: """ Constructor Args: item (ActionTriggerItem): Menu item data. """ EventsPartial.__init__(self) self._init_events() self._container = container self._cmd_info = CmdInfo() self._cmd_info.subscribe_on_command_found(self._fn_on_command_found)
def _init_events(self) -> None: self._fn_on_command_found = self._on_command_found def _on_command_found(self, source: Any, event: CancelEventArgs) -> None: """Command found event""" pass # cmd_data = cast(CmdData, event.event_data["cmd_data"]) # if not cmd_data.global_hotkey: # event.cancel = True def _process_command(self, pop: ActionTriggerItem) -> None: """Process command""" if not pop.CommandURL: return pop.CommandURL = Shortcuts.get_url_script(pop.CommandURL) def _get_action_from_module(self, menu: dict, index: int) -> ActionTriggerItem | ActionTriggerSep | None: """ Gets the Action Trigger item and looks up the command data from the command info. Args: menu (dict): Menu Data index (int): Current Index Raises: ValueError: If no text is found for the command Returns: ActionTriggerItem | ActionTriggerSep | None: Action Item if found, otherwise None Note: If the menu text is not found then the event ``action_item_module_no_text_found`` is raised. The event data is a dictionary with keys: - ``module_kind``: ModuleNamesKind - ``cmd``: Command as a string. - ``index``: Index as an integer. - ``menu``: Menu Data as a dictionary. The caller can set ``menu["text"]`` to provide a valid menu text. If the caller cancels the event then the menu item is not created and None is returned. """ def _get_command_data(kind: ModuleNamesKind, cmd: str) -> CmdData | None: if kind == ModuleNamesKind.NONE: # get from global data = self._cmd_info.find_command(cmd) if cmd not in data: return None c_infos = data[cmd] if not c_infos: return None return c_infos[0] return self._cmd_info.get_cmd_data(kind, cmd) def get_cmd_text(data: CmdData) -> str: return data.label or data.name module_kind = ModuleNamesKind(menu["module"]) cmd = cast(str, menu["command"]) command_data = _get_command_data(module_kind, cmd) if command_data is None: cmd_text = "" else: cmd_text = get_cmd_text(command_data) if not cmd_text: # check if a label has bee provided: if "text" in menu: cmd_text = menu["text"] else: # no valid menu text found # raise an event to allow the caller to provide a valid menu text cargs = CancelEventArgs(self) event_data = DotDict(module_kind=module_kind, cmd=cmd, index=index, menu=menu) cargs.event_data = event_data self.trigger_event("action_item_module_no_text_found", cargs) if cargs.cancel: return None if "text" in cargs.event_data.menu: cmd_text = cargs.event_data.menu["text"] if not cmd_text: raise ValueError(f"No text for command: {module_kind} {cmd}") menu_data = { "command": cmd, } menu_data.update(menu) # set the text back to the found command text menu_data["text"] = cmd_text return self._get_action_item(menu_data, index) def _get_action_item(self, menu: dict, index: int) -> ActionTriggerItem: """Get popup item data""" eargs = EventArgs(self) eargs.event_data = DotDict(**menu) eargs.event_data.index = index self.trigger_event("before_get_action_item", eargs) menu_data = cast(DotDict, eargs.event_data) text = menu_data.text command = cast(Union[str, "CommandDict"], menu_data.get("command", "")) help_command = menu_data.get("help_command", "") return ActionTriggerItem(command_url=Shortcuts.get_url_script(command), text=text, help_url=help_command)
[docs] def get_action_item(self, menu: dict, index: int) -> ActionTriggerItem | ActionTriggerSep | None: """Get Action item""" if "module" in menu: item = self._get_action_from_module(menu, index) elif "text" in menu: text = menu["text"] if text == "-": item = ActionTriggerSep(int(menu.get("separator_type", 0))) else: item = self._get_action_item(menu, index) else: item = self._get_action_item(menu, index) return item
[docs] def process(self, menu: dict, index: int) -> ActionTriggerItem | ActionTriggerSep | None: """Process menu item""" item = self.get_action_item(menu, index) if item is None: return None cargs = CancelEventArgs(source=self) cargs.event_data = DotDict(container=self._container, action_item=item) self.trigger_event("before_process", cargs) if cargs.cancel: return item self._container.insertByIndex(index, item) if isinstance(item, ActionTriggerSep): return item self._process_command(item) eargs = EventArgs.from_args(cargs) self.trigger_event("after_process", eargs) return item