Source code for ooodev.adapter.beans.vetoable_change_collection

from __future__ import annotations
from typing import Dict, TypedDict
from com.sun.star.beans import XPropertySet

from ooodev.events.args.generic_args import GenericArgs
from ooodev.adapter.beans.vetoable_change_events import VetoableChangeEvents


class _PropertyDict(TypedDict):
    property_name: str
    ref_count: int
    event: VetoableChangeEvents


[docs]class VetoableChangeCollection: """ Class for managing Adding and removing Vetoable Change Listeners. """
[docs] def __init__(self, component: XPropertySet, generic_args: GenericArgs | None = None) -> None: """ Constructor Args: component (Any): UNO Component that implements ``com.sun.star.beans.XPropertySet``. generic_args (Dict[str, Any], optional): Generic Arguments to pass to instances of ``PropertyChangeEvents`` when they are created. Defaults to None. """ self.__events: Dict[str, _PropertyDict] = {} self.__component = component self.__generic_args = generic_args
[docs] def create_vetoable_change_events(self, name: str, **kwargs) -> VetoableChangeEvents: """ Creates a vetoable change events that can be used to add/remove listeners. Any generic args passed into the constructor are also passed into the constructor of the ``VetoableChangeEvents``. Args: name (str): Property Name kwargs (Any): Keyword Arguments to pass to the ``GenericArgs`` constructor. Raises: ValueError: If name is empty Returns: VetoableChangeEvents: Vetoable Change Events """ if self.__generic_args is None: extra = {} else: extra = self.__generic_args.kwargs.copy() extra.update(kwargs) if not name: raise ValueError("name cannot be empty") args = GenericArgs(component=self.__component, property_name=name, **extra) return VetoableChangeEvents(trigger_args=args)
[docs] def add_vetoable_listener(self, name: str, events: VetoableChangeEvents | None = None) -> VetoableChangeEvents: """ Add vetoable property listener Args: name (str): Property Name events (VetoableChangeEvents | None, optional): Instance to pass to UNO. Defaults to None. Raises: ValueError: If name is empty. ValueError: If name has already been added for the current listener. Returns: VetoableChangeEvents: Vetoable Change Events Note: The returned instance, in most cases, would be used to subscribe to callbacks. """ if not name: raise ValueError("name cannot be empty") if not events: events = self.create_vetoable_change_events(name) # get the name from mangling events_name: str = events._VetoableChangeEvents__name # type: ignore if events_name in self.__events: # increment the reference count current = self.__events[events_name] if current["property_name"] == name: raise ValueError(f'The property "{name}" is already being listened to.') current_events = current["event"] self.__component.addVetoableChangeListener(name, current_events.events_listener_vetoable_change) current["ref_count"] += 1 else: # add the listener self.__component.addVetoableChangeListener(name, events.events_listener_vetoable_change) self.__events[events_name] = {"property_name": name, "ref_count": 1, "event": events} return self.__events[events_name]["event"]
[docs] def remove_vetoable_listener(self, name: str, events: VetoableChangeEvents) -> bool: """ Remove Property Listener Args: name (str): Property Name events (VetoableChangeEvents): Property Change Events Raises: ValueError: If name is empty Returns: bool: ``True`` on success; Otherwise, ``False``. """ if not name: raise ValueError("name cannot be empty") # get the name from mangling events_name: str = events._VetoableChangeEvents__name # type: ignore if events_name not in self.__events: return False current = self.__events[events_name] ref_count = current["ref_count"] result = False if ref_count > 1: current["ref_count"] -= 1 self.__component.removeVetoableChangeListener(name, current["event"].events_listener_vetoable_change) result = True else: self.__component.removeVetoableChangeListener(name, current["event"].events_listener_vetoable_change) _ = self.__events.pop(events_name) result = True return result