Source code for ooodev.format.inner.direct.structs.line_spacing_struct

"""
Module for Shadow format (``LineSpacing``) struct.

.. versionadded:: 0.9.0
"""

# region Import
from __future__ import annotations

from typing import Any, Dict, Tuple, Type, TypeVar, cast, overload, TYPE_CHECKING

from ooo.dyn.style.line_spacing import LineSpacing as UnoLineSpacing

from ooodev.events.args.cancel_event_args import CancelEventArgs
from ooodev.events.args.event_args import EventArgs
from ooodev.events.format_named_event import FormatNamedEvent
from ooodev.format.inner.direct.structs.struct_base import StructBase
from ooodev.format.inner.kind.format_kind import FormatKind
from ooodev.units.unit_convert import UnitConvert, UnitLength
from ooodev.utils import props as mProps
from ooodev.utils.kind.line_spacing_mode_kind import ModeKind

if TYPE_CHECKING:
    from ooodev.units.unit_obj import UnitT
# endregion Import

_TLineSpacingStruct = TypeVar(name="_TLineSpacingStruct", bound="LineSpacingStruct")


[docs]class LineSpacingStruct(StructBase): """ Line Spacing struct """ # region init
[docs] def __init__(self, mode: ModeKind = ModeKind.SINGLE, value: int | float | UnitT = 0) -> None: """ Constructor Args: mode (LineMode, optional): This value specifies the way the spacing is specified. value (Real, UnitT, optional): This value specifies the spacing in regard to Mode. Raises: ValueError: If ``value`` are less than zero. Note: If ``LineMode`` is ``SINGLE``, ``LINE_1_15``, ``LINE_1_5``, or ``DOUBLE`` then ``value`` is ignored. If ``LineMode`` is ``AT_LEAST``, ``LEADING``, or ``FIXED`` then ``value`` is a float (``in mm units``) or :ref:`proto_unit_obj` If ``LineMode`` is ``PROPORTIONAL`` then value is an int representing percentage. For example ``95`` equals ``95%``, ``130`` equals ``130%`` """ self._line_mode = mode self._mode = mode.get_mode() self._value = int(mode) enum_val = mode.get_enum_val() if mode == ModeKind.PROPORTIONAL: # no conversion try: # just in case passed in as a UnitT self._value = round(value.value) # type: ignore except AttributeError: self._value = int(value) # type: ignore elif enum_val >= 5: try: self._value = cast(int, value.get_value_mm100()) # type: ignore except AttributeError: self._value = round(UnitConvert.convert(num=value, frm=UnitLength.MM, to=UnitLength.MM100)) # type: ignore if self._value < 0: raise ValueError("mode must be a positive number") super().__init__()
# endregion init # region methods def __eq__(self, other: object) -> bool: ls2 = None if isinstance(other, LineSpacingStruct): ls2 = other.get_uno_struct() elif getattr(other, "typeName", None) == "com.sun.star.style.LineSpacing": ls2 = other if ls2: ls1 = self.get_uno_struct() return ls1.Height == ls2.Height and ls1.Mode == ls2.Mode # type: ignore return False def _supported_services(self) -> Tuple[str, ...]: try: return self._supported_services_values except AttributeError: self._supported_services_values = () return self._supported_services_values def _on_modifying(self, source: Any, event: CancelEventArgs) -> None: if self._is_default_inst: raise ValueError("Modifying a default instance is not allowed") return super()._on_modifying(source, event) def _get_property_name(self) -> str: try: return self._property_name except AttributeError: self._property_name = "ParaLineSpacing" return self._property_name
[docs] def get_attrs(self) -> Tuple[str, ...]: """ Gets the attributes that are slated for change in the current instance Returns: Tuple(str, ...): Tuple of attributes """ return (self._get_property_name(),)
# region copy() @overload def copy(self: _TLineSpacingStruct) -> _TLineSpacingStruct: ... @overload def copy(self: _TLineSpacingStruct, **kwargs) -> _TLineSpacingStruct: ...
[docs] def copy(self: _TLineSpacingStruct, **kwargs) -> _TLineSpacingStruct: # pylint: disable=unexpected-keyword-arg nu = self.__class__(mode=self._mode, height=self._value, **kwargs) # type: ignore if dv := self._get_properties(): nu._update(dv) return nu
# endregion copy() # region apply() @overload def apply(self, obj: Any, *, keys: Dict[str, str]) -> None: ... @overload def apply(self, obj: Any) -> None: ...
[docs] def apply(self, obj: Any, **kwargs) -> None: """ Applies style to object Args: obj (object): Object that contains a ``LineSpacing`` property. keys: (Dict[str, str], optional): key map for properties. Can be ``spacing`` which maps to ``ParaLineSpacing`` by default. :events: .. cssclass:: lo_event - :py:attr:`~.events.format_named_event.FormatNamedEvent.STYLE_APPLYING` :eventref:`src-docs-event-cancel` - :py:attr:`~.events.format_named_event.FormatNamedEvent.STYLE_APPLIED` :eventref:`src-docs-event` Returns: None: """ # sourcery skip: dict-assign-update-to-union if not self._is_valid_obj(obj): # will not apply on this class but may apply on child classes self._print_not_valid_srv("apply()") return cargs = CancelEventArgs(source=f"{self.apply.__qualname__}") cargs.event_data = self if cargs.cancel: return self._events.trigger(FormatNamedEvent.STYLE_APPLYING, cargs) if cargs.cancel: return keys = {"spacing": self._get_property_name()} if "keys" in kwargs: keys.update(kwargs["keys"]) key = keys["spacing"] mProps.Props.set(obj, **{key: self.get_uno_struct()}) eargs = EventArgs.from_args(cargs) self._events.trigger(FormatNamedEvent.STYLE_APPLIED, eargs)
# endregion apply()
[docs] def get_uno_struct(self) -> UnoLineSpacing: """ Gets UNO ``Gradient`` from instance. Returns: Gradient: ``Gradient`` instance """ return UnoLineSpacing(Mode=self._mode, Height=self._value)
# region from_line_spacing() @overload @classmethod def from_uno_struct(cls: Type[_TLineSpacingStruct], ln_spacing: UnoLineSpacing) -> _TLineSpacingStruct: ... @overload @classmethod def from_uno_struct( cls: Type[_TLineSpacingStruct], ln_spacing: UnoLineSpacing, **kwargs ) -> _TLineSpacingStruct: ...
[docs] @classmethod def from_uno_struct(cls: Type[_TLineSpacingStruct], ln_spacing: UnoLineSpacing, **kwargs) -> _TLineSpacingStruct: """ Converts a UNO ``LineSpacing`` struct into a ``LineSpacingStruct`` Args: ln_spacing (UnoLineSpacing): UNO ``LineSpacing`` object. Returns: LineSpacingStruct: ``LineSpacingStruct`` set with Line spacing properties. """ inst = cls(**kwargs) inst._mode = ln_spacing.Mode inst._value = ln_spacing.Height inst._line_mode = ModeKind.from_uno(ln_spacing) return inst
# endregion from_line_spacing() # endregion methods # region Properties @property def prop_format_kind(self) -> FormatKind: """Gets the kind of style""" try: return self._format_kind_prop except AttributeError: self._format_kind_prop = FormatKind.STRUCT return self._format_kind_prop @property def prop_mode(self) -> ModeKind: """Gets mode value""" return self._line_mode @property def prop_value(self) -> int: """Gets the spacing value in regard to Mode""" return self._value @property def default(self: _TLineSpacingStruct) -> _TLineSpacingStruct: # type: ignore[misc] """Gets empty Line Spacing. Static Property.""" try: return self._default_inst except AttributeError: # pylint: disable=unexpected-keyword-arg self._default_inst = self.__class__(ModeKind.SINGLE, 0, _cattribs=self._get_internal_cattribs()) # type: ignore self._default_inst._is_default_inst = True return self._default_inst
# endregion Properties