Source code for ooodev.format.inner.direct.write.para.border.borders

"""
Module for managing character borders.

.. versionadded:: 0.9.0
"""

# region imports
from __future__ import annotations
from typing import Any, Tuple, overload, cast, Type, TypeVar

from ooodev.events.args.cancel_event_args import CancelEventArgs
from ooodev.exceptions import ex as mEx
from ooodev.format.inner.direct.structs.side import Side
from ooodev.format.inner.direct.write.para.border.padding import Padding as InnerPadding
from ooodev.format.inner.direct.write.para.border.shadow import Shadow as InnerShadow
from ooodev.format.inner.direct.write.para.border.sides import Sides
from ooodev.format.inner.kind.format_kind import FormatKind
from ooodev.format.inner.style_base import StyleMulti
from ooodev.loader import lo as mLo
from ooodev.utils import props as mProps

# endregion imports

_TBorders = TypeVar(name="_TBorders", bound="Borders")


[docs]class Borders(StyleMulti): """ Border used in styles for characters. All methods starting with ``fmt_`` can be used to chain together Borders properties. .. seealso:: - :ref:`help_writer_format_direct_para_borders` .. versionadded:: 0.9.0 """ # region init
[docs] def __init__( self, *, right: Side | None = None, left: Side | None = None, top: Side | None = None, bottom: Side | None = None, all: Side | None = None, shadow: InnerShadow | None = None, padding: InnerPadding | None = None, merge: bool | None = None, ) -> None: """ Constructor Args: left (Side, None, optional): Determines the line style at the left edge. right (Side, None, optional): Determines the line style at the right edge. top (Side, None, optional): Determines the line style at the top edge. bottom (Side, None, optional): Determines the line style at the bottom edge. all (Side, None, optional): Determines the line style at the top, bottom, left, right edges. If this argument has a value then arguments ``top``, ``bottom``, ``left``, ``right`` are ignored shadow (BorderShadow, None, optional): Character Shadow padding (BorderPadding, None, optional): Character padding merge (bool, None, optional): Merge with next paragraph Returns: None: See Also: - :ref:`help_writer_format_direct_para_borders` """ init_vals = {} sides = self._get_sides_type()( left=left, right=right, top=top, bottom=bottom, all=all, ) if merge is not None: init_vals["ParaIsConnectBorder"] = merge if padding is not None: # BorderDistance is set to padding bottom for some reason. init_vals["BorderDistance"] = padding._get(padding._props.bottom) super().__init__(**init_vals) if sides.prop_has_attribs: sides._prop_parent = self self._set_style("sides", sides, *sides.get_attrs()) # type: ignore if padding is not None: self._set_style("padding", padding, *padding.get_attrs()) if shadow is not None: self._set_style("shadow", shadow, *shadow.get_attrs())
# endregion init # region format Methods
[docs] def fmt_border_side(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with left, right, top, bottom sides set or removed Args: value (Side | None): Side value Returns: Borders: Borders instance """ cp = self.copy() if self.prop_inner_sides is not None: sides = self.prop_inner_sides.fmt_border_side(value) else: sides = self._get_sides_type()(all=value) cp._set_style("sides", sides, *sides.get_attrs()) # type: ignore return cp
[docs] def fmt_left(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with left set or removed Args: value (Side | None): Side value Returns: Borders: Borders instance """ cp = self.copy() if self.prop_inner_sides is not None: sides = self.prop_inner_sides.fmt_left(value) else: sides = self._get_sides_type()(left=value) cp._set_style("sides", sides, *sides.get_attrs()) # type: ignore return cp
[docs] def fmt_right(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with right set or removed Args: value (Side | None): Side value Returns: Borders: Borders instance """ cp = self.copy() if self.prop_inner_sides is not None: sides = self.prop_inner_sides.fmt_right(value) else: sides = self._get_sides_type()(right=value) cp._set_style("sides", sides, *sides.get_attrs()) # type: ignore return cp
[docs] def fmt_top(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with top set or removed Args: value (Side | None): Side value Returns: Borders: Borders instance """ cp = self.copy() if self.prop_inner_sides is not None: sides = self.prop_inner_sides.fmt_top(value) else: sides = self._get_sides_type()(top=value) cp._set_style("sides", sides, *sides.get_attrs()) # type: ignore return cp
[docs] def fmt_bottom(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with bottom set or removed Args: value (Side | None): Side value Returns: Borders: Borders instance """ cp = self.copy() if self.prop_inner_sides is not None: sides = self.prop_inner_sides.fmt_bottom(value) else: sides = self._get_sides_type()(bottom=value) cp._set_style("sides", sides, *sides.get_attrs()) # type: ignore return cp
[docs] def fmt_shadow(self: _TBorders, value: InnerShadow | None) -> _TBorders: """ Gets copy of instance with shadow set or removed Args: value (Shadow | None): Shadow value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp = self.copy() if value is None: cp._remove_style("shadow") else: cp._set_style("shadow", value, *value.get_attrs()) return cp
[docs] def fmt_padding(self: _TBorders, value: InnerPadding | None) -> _TBorders: """ Gets copy of instance with padding set or removed Args: value (BorderPadding | None): Padding value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp = self.copy() if value is None: cp._remove_style("padding") else: cp._set_style("padding", value, *value.get_attrs()) return cp
# endregion format Methods # region methods def _get_sides_type(self) -> Type[Sides]: return Sides def _supported_services(self) -> Tuple[str, ...]: try: return self._supported_services_values except AttributeError: self._supported_services_values = ( "com.sun.star.style.CharacterProperties", "com.sun.star.style.ParagraphStyle", "com.sun.star.text.TextFrame", ) 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) # region apply() @overload def apply(self, obj: Any) -> None: ... @overload def apply(self, obj: Any, **kwargs) -> None: ...
[docs] def apply(self, obj: Any, **kwargs) -> None: """ Applies padding to ``obj`` Args: obj (object): Object that supports ``com.sun.star.style.CharacterProperties`` service. Returns: None: """ try: super().apply(obj, **kwargs) except mEx.MultiError as e: mLo.Lo.print(f"{self.__class__.__name__}.apply(): Unable to set Property") for err in e.errors: mLo.Lo.print(f" {err}")
# endregion apply() # region from_obj() @overload @classmethod def from_obj(cls: Type[_TBorders], obj: Any) -> _TBorders: ... @overload @classmethod def from_obj(cls: Type[_TBorders], obj: Any, **kwargs) -> _TBorders: ...
[docs] @classmethod def from_obj(cls: Type[_TBorders], obj: Any, **kwargs) -> _TBorders: """ Gets instance from object Args: obj (object): UNO object that supports ``com.sun.star.style.ParagraphProperties`` service. Raises: ServiceNotSupported: If ``obj`` does not support ``com.sun.star.style.ParagraphProperties`` service. Returns: Borders: ``Borders`` instance that represents the ``obj`` borders. """ # pylint: disable=protected-access inst = cls(**kwargs) if not inst._is_valid_obj(obj): raise mEx.ServiceNotSupported(inst._supported_services()[0]) inst_sides = Sides.from_obj(obj) inst_padding = InnerPadding.from_obj(obj) inst_shadow = InnerShadow.from_obj(obj) inst._set("ParaIsConnectBorder", mProps.Props.get(obj, "ParaIsConnectBorder")) inst._set("BorderDistance", mProps.Props.get(obj, "BorderDistance")) inst._set_style("sides", inst_sides, *inst_sides.get_attrs()) inst._set_style("padding", inst_padding, *inst_padding.get_attrs()) inst._set_style("shadow", inst_shadow, *inst_shadow.get_attrs()) inst.set_update_obj(obj) return inst
# endregion from_obj() # 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.PARA | FormatKind.STATIC return self._format_kind_prop @property def prop_inner_sides(self) -> Sides | None: """Gets Sides instance""" try: return self._direct_inner_sides except AttributeError: self._direct_inner_sides = cast(Sides, self._get_style_inst("sides")) return self._direct_inner_sides @property def prop_inner_padding(self) -> InnerPadding | None: """Gets Padding instance""" try: return self._direct_inner_padding except AttributeError: self._direct_inner_padding = cast(InnerPadding, self._get_style_inst("padding")) return self._direct_inner_padding @property def prop_inner_shadow(self) -> InnerShadow | None: """Gets Shadow instance""" try: return self._direct_inner_shadow except AttributeError: self._direct_inner_shadow = cast(InnerShadow, self._get_style_inst("shadow")) return self._direct_inner_shadow @property def default(self: _TBorders) -> _TBorders: # type: ignore[misc] """Gets Default Border.""" # pylint: disable=protected-access try: return self._default_inst except AttributeError: if self.prop_inner_padding is None: padding = InnerPadding().default else: padding = self.prop_inner_padding.default if self.prop_inner_shadow is None: shadow = InnerShadow().empty else: shadow = self.prop_inner_shadow.empty self._default_inst = self.__class__(all=Side().empty, padding=padding, shadow=shadow, merge=True) self._default_inst._is_default_inst = True return self._default_inst
# endregion Properties