Source code for ooodev.format.inner.direct.write.table.borders.borders

"""
Module for managing table borders (cells and ranges).

.. versionadded:: 0.9.0
"""

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

from ooodev.events.args.cancel_event_args import CancelEventArgs
from ooodev.exceptions import ex as mEx
from ooodev.units.unit_obj import UnitT
from ooodev.loader import lo as mLo
from ooodev.utils import props as mProps
from ooodev.format.inner.kind.format_kind import FormatKind
from ooodev.format.inner.style_base import StyleMulti
from ooodev.format.inner.direct.calc.border.padding import Padding
from ooodev.format.inner.direct.calc.border.shadow import Shadow
from ooodev.format.inner.common.props.prop_pair import PropPair
from ooodev.format.inner.common.props.struct_border_table_props import StructBorderTableProps
from ooodev.format.inner.common.props.table_borders_props import TableBordersProps
from ooodev.format.inner.direct.structs.side import Side
from ooodev.format.inner.direct.structs.table_border_distances_struct import TableBorderDistancesStruct
from ooodev.format.inner.direct.structs.table_border_struct import TableBorderStruct


# endregion imports

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


[docs]class Borders(StyleMulti): """ Table Borders used in styles for table cells and ranges. Any properties starting with ``prop_`` set or get current instance values. All methods starting with ``fmt_`` can be used to chain together properties. .. seealso:: - :ref:`help_writer_format_direct_table_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, border_side: Side | None = None, vertical: Side | None = None, horizontal: Side | None = None, distance: float | UnitT | None = None, shadow: Shadow | None = None, padding: Padding | None = None, merge_adjacent: bool | None = None, ) -> None: """ Constructor Args: left (Side,, optional): Specifies the line style at the left edge. right (Side, optional): Specifies the line style at the right edge. top (Side, optional): Specifies the line style at the top edge. bottom (Side, optional): Specifies the line style at the bottom edge. border_side (Side, optional): Specifies the line style at the top, bottom, left, right edges. If this argument has a value then arguments ``top``, ``bottom``, ``left``, ``right`` are ignored horizontal (Side, optional): Specifies the line style of horizontal lines for the inner part of a cell range. vertical (Side, optional): Specifies the line style of vertical lines for the inner part of a cell range. distance (float, UnitT, optional): Contains the distance between the lines and other contents in ``mm`` units or :ref:`proto_unit_obj`. shadow (Shadow, optional): Cell Shadow. padding (BorderPadding, optional): Cell padding. merge_adjacent (bool, optional): Specifies if adjacent line style are to be merged. Returns: None: Hint: - ``LineSize`` can be imported from ``ooodev.format.writer.direct.char.borders`` - ``Padding`` can be imported from ``ooodev.format.inner.direct.calc.border.padding`` - ``ShadowFormat`` can be imported from ``ooodev.format.writer.direct.char.borders`` - ``Side`` can be imported from ``ooodev.format.writer.direct.char.borders`` - ``side`` can be imported from ``ooodev.format.inner.direct.structs.side`` - ``ShadowLocation`` can be imported ``from ooo.dyn.table.shadow_location`` - ``Shadow`` can be imported from ``ooodev.format.inner.direct.calc.border.shadow`` See Also: - :ref:`help_writer_format_direct_table_borders` """ # pylint: disable=unexpected-keyword-arg super().__init__() if shadow is None: shadow_fmt = None else: shadow_fmt = shadow.copy(_cattribs=self._get_shadow_cattribs()) border_table = TableBorderStruct( left=left, right=right, top=top, bottom=bottom, border_side=border_side, horizontal=horizontal, vertical=vertical, distance=distance, _cattribs=self._get_tb_cattribs(), # type: ignore ) if padding is not None: # using paddint and converting to TableBorderDistancesStruct. # TableBorderDistancesStruct could be used but padding is used on other places so keep it that same. tb_padding_struct = TableBorderDistancesStruct( left=padding.prop_left or 0, right=padding.prop_right or 0, top=padding.prop_top or 0, bottom=padding.prop_bottom or 0, _cattribs=self._get_tbd_cattribs(), # type: ignore ) else: tb_padding_struct = None if merge_adjacent is not None: self.prop_merge_adjacent = merge_adjacent if border_table.prop_has_attribs: self._set_style("border_table", border_table) # type: ignore if tb_padding_struct is not None: self._set_style("padding", tb_padding_struct) # type: ignore if shadow_fmt is not None: self._set_style("shadow", shadow_fmt)
# endregion init # region Internal Methods def _get_tb_cattribs(self) -> dict: return { "_property_name": self._props.tbl_border, "_supported_services_values": self._supported_services(), "_format_kind_prop": self.prop_format_kind, "_props_internal_attributes": StructBorderTableProps( left=self._props.tbl_bdr_left, top=self._props.tbl_bdr_top, right=self._props.tbl_bdr_right, bottom=self._props.tbl_bdr_bottom, horz=self._props.tbl_bdr_horz, vert=self._props.tbl_bdr_vert, dist=self._props.tbl_bdr_dist, ), } def _get_shadow_cattribs(self) -> dict: return { "_property_name": self._props.shadow, "_supported_services_values": self._supported_services(), "_format_kind_prop": self.prop_format_kind, } def _get_tbd_cattribs(self) -> dict: return { "_property_name": self._props.tbl_distance, "_supported_services_values": self._supported_services(), "_format_kind_prop": self.prop_format_kind, } # endregion Internal Methods # region Overrides def _on_modifying(self, source: Any, event_args: CancelEventArgs) -> None: if self._is_default_inst: raise ValueError("Modifying a default instance is not allowed") return super()._on_modifying(source, event_args) def _supported_services(self) -> Tuple[str, ...]: try: return self._supported_services_values except AttributeError: self._supported_services_values = ("com.sun.star.text.TextTable",) return self._supported_services_values # 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.ParagraphProperties`` service. Returns: None: """ super().apply(obj, **kwargs)
# endregion apply() def _props_set(self, obj: Any, **kwargs: Any) -> None: try: super()._props_set(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 Overrides # region Static Methods # 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. Raises: NotSupportedError: If ``obj`` is not supported. Returns: Borders: ``Borders`` instance that represents ``obj`` border properties. """ # pylint: disable=protected-access inst = cls(**kwargs) if not inst._is_valid_obj(obj): raise mEx.NotSupportedError(f'Object is not supported for conversion to "{cls.__name__}"') inst.prop_merge_adjacent = bool(mProps.Props.get(obj, inst._props.merge, True)) tbl_border = TableBorderStruct.from_obj(obj, _cattribs=inst._get_tb_cattribs()) tbl_border_distance = TableBorderDistancesStruct.from_obj(obj, _cattribs=inst._get_tbd_cattribs()) shadow_fmt = Shadow.from_obj(obj, _cattribs=inst._get_shadow_cattribs()) inst._set_style("border_table", tbl_border) inst._set_style("padding", tbl_border_distance) inst._set_style("shadow", shadow_fmt) inst.set_update_obj(obj) return inst
# endregion from_obj() # endregion Static Methods # region Style Methods def _fmt_get_border_table(self: _TBorders, value: Side | None, side: str) -> Tuple[_TBorders, bool]: # pylint: disable=protected-access cp = self.copy() has_style = cp._has_style("border_table") if value is None: if has_style: cp._remove_style("border_table") return (cp, True) if not has_style: args = {side: value, "_cattribs": self._get_tb_cattribs()} border_table = TableBorderStruct(**args) cp._set_style("border_table", border_table) # type: ignore return (cp, True) return (cp, False)
[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, optional): Side value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp, ret = self._fmt_get_border_table(value, "border_side") if ret: return cp bt = cast(TableBorderStruct, cp._get_style_inst("border_table")) bt.prop_left = value bt.prop_right = value bt.prop_top = value bt.prop_bottom = value return cp
[docs] def fmt_left(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with left set or removed Args: value (Side, optional): Side value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp, ret = self._fmt_get_border_table(value, "left") if ret: return cp bt = cast(TableBorderStruct, cp._get_style_inst("border_table")) bt.prop_left = value return cp
[docs] def fmt_right(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with right set or removed Args: value (Side, optional): Side value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp, ret = self._fmt_get_border_table(value, "right") if ret: return cp bt = cast(TableBorderStruct, cp._get_style_inst("border_table")) bt.prop_right = value return cp
[docs] def fmt_top(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with top set or removed Args: value (Side, optional): Side value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp, ret = self._fmt_get_border_table(value, "top") if ret: return cp bt = cast(TableBorderStruct, cp._get_style_inst("border_table")) bt.prop_top = value return cp
[docs] def fmt_bottom(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with bottom set or removed Args: value (Side, optional): Side value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp, ret = self._fmt_get_border_table(value, "bottom") if ret: return cp bt = cast(TableBorderStruct, cp._get_style_inst("border_table")) bt.prop_bottom = value return cp
[docs] def fmt_horizontal(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with horizontal set or removed Args: value (Side, optional): Side value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp, ret = self._fmt_get_border_table(value, "horizontal") if ret: return cp bt = cast(TableBorderStruct, cp._get_style_inst("border_table")) bt.prop_horizontal = value return cp
[docs] def fmt_vertical(self: _TBorders, value: Side | None) -> _TBorders: """ Gets copy of instance with vertical set or removed Args: value (Side, optional): Side value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp, ret = self._fmt_get_border_table(value, "vertical") if ret: return cp bt = cast(TableBorderStruct, cp._get_style_inst("border_table")) bt.prop_vertical = value return cp
[docs] def fmt_distance(self: _TBorders, value: float | UnitT | None) -> _TBorders: """ Gets copy of instance with distance set or removed Args: value (float, UnitT, optional): Distance value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp = self.copy() bt = cast(TableBorderStruct, cp._get_style_inst("distance")) bt.prop_distance = value return cp
[docs] def fmt_shadow(self: _TBorders, value: Shadow | None) -> _TBorders: """ Gets copy of instance with shadow set or removed Args: value (Shadow, optional): Shadow value Returns: Borders: Borders instance """ # pylint: disable=protected-access cp = self.copy() if value is None: cp._remove_style("shadow") else: shadow_fmt = value.copy(_cattribs=self._get_shadow_cattribs()) cp._set_style("shadow", shadow_fmt) return cp
[docs] def fmt_padding(self: _TBorders, value: Padding | None) -> _TBorders: """ Gets copy of instance with padding set or removed Args: value (Padding, optional): Padding value Returns: Borders: Borders instance """ # pylint: disable=protected-access # pylint: disable=unexpected-keyword-arg cp = self.copy() if value is None: cp._remove_style("padding") else: tb_padding_struct = TableBorderDistancesStruct( left=value.prop_left or 0, right=value.prop_right or 0, top=value.prop_top or 0, bottom=value.prop_bottom or 0, _cattribs=self._get_tbd_cattribs(), # type: ignore ) cp._set_style("padding", tb_padding_struct) # type: ignore return cp
# endregion Style 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.CELL return self._format_kind_prop @property def prop_merge_adjacent(self) -> bool | None: """ Gets/Sets merge_adjacent. """ return self._get(self._props.merge) @prop_merge_adjacent.setter def prop_merge_adjacent(self, value: bool | None): if value is None: self._remove(self._props.merge) return self._set(self._props.merge, value) @property def prop_inner_padding(self) -> TableBorderDistancesStruct: """Gets inner Padding as ``TableBorderDistancesStruct`` instance""" try: return self._direct_inner_padding except AttributeError: self._direct_inner_padding = cast(TableBorderDistancesStruct, self._get_style_inst("padding")) return self._direct_inner_padding @property def prop_inner_border_table(self) -> TableBorderStruct: """Gets inner border table instance""" try: return self._direct_inner_table except AttributeError: self._direct_inner_table = cast(TableBorderStruct, self._get_style_inst("border_table")) return self._direct_inner_table @property def prop_inner_shadow(self) -> Shadow | None: """Gets inner shadow instance""" try: return self._direct_inner_shadow except AttributeError: self._direct_inner_shadow = cast(Shadow, self._get_style_inst("shadow")) return self._direct_inner_shadow @property def _props(self) -> TableBordersProps: """Gets _props.""" try: return self._props_internal_attributes except AttributeError: self._props_internal_attributes = TableBordersProps( tbl_border="TableBorder2", shadow="ShadowFormat", tbl_distance="TableBorderDistances", merge="CollapsingBorders", tbl_bdr_left=PropPair("LeftLine", "IsLeftLineValid"), tbl_bdr_top=PropPair("TopLine", "IsTopLineValid"), tbl_bdr_right=PropPair("RightLine", "IsRightLineValid"), tbl_bdr_bottom=PropPair("BottomLine", "IsBottomLineValid"), tbl_bdr_horz=PropPair("HorizontalLine", "IsHorizontalLineValid"), tbl_bdr_vert=PropPair("VerticalLine", "IsVerticalLineValid"), tbl_bdr_dist=PropPair("Distance", "IsDistanceValid"), ) return self._props_internal_attributes @property def default(self: _TBorders) -> _TBorders: # type: ignore[misc] """Gets Default Border.""" # pylint: disable=protected-access # pylint: disable=unexpected-keyword-arg try: return self._default_inst except AttributeError: self._default_inst = self.__class__( border_side=Side(), padding=Padding(_cattribs=self._get_tbd_cattribs()).default # type: ignore ) self._default_inst._is_default_inst = True return self._default_inst @property def empty(self: _TBorders) -> _TBorders: # type: ignore[misc] """Gets Empty Border. When style is applied formatting is removed.""" # pylint: disable=protected-access # pylint: disable=unexpected-keyword-arg try: return self._empty_inst except AttributeError: side = Side() self._empty_inst = self.__class__( border_side=side.empty, vertical=side.empty, horizontal=side.empty, diagonal_down=side.empty, # type: ignore diagonal_up=side.empty, # type: ignore distance=0.0, shadow=Shadow(_cattribs=self._get_shadow_cattribs()).empty, # type: ignore padding=Padding(_cattribs=self._get_tbd_cattribs()).default, # type: ignore ) self._empty_inst._is_default_inst = True return self._empty_inst
# endregion Properties