Source code for

Module for managing paragraph Drop Caps.

.. versionadded:: 0.9.0

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

from import CancelEventArgs
from import KeyValCancelArgs
from ooodev.exceptions import ex as mEx
from import DropCapStruct
from ooodev.format.inner.kind.format_kind import FormatKind
from ooodev.format.inner.style_base import StyleMulti
from import StyleCharKind
from ooodev.loader import lo as mLo
from ooodev.units.unit_convert import UnitConvert
from ooodev.units.unit_obj import UnitT
from ooodev.utils import props as mProps

# endregion Imports

_TDropCaps = TypeVar(name="_TDropCaps", bound="DropCaps")

[docs]class DropCaps(StyleMulti): """ Paragraph Drop Caps .. seealso:: - :ref:`help_writer_format_direct_para_drop_caps` .. versionadded:: 0.9.0 """ # region init
[docs] def __init__( self, *, count: int = 0, spaces: float | UnitT = 0.0, lines: int = 3, style: StyleCharKind | str | None = None, whole_word: bool | None = None, ) -> None: """ Constructor Args: count (int): Specifies the number of characters in the drop cap. Must be from ``0`` to ``255``. spaces (float, UnitT): Specifies the distance between the drop cap in the following text (in ``mm`` units) or :ref:`proto_unit_obj`. lines (int): Specifies the number of lines used for a drop cap. Must be from ``0`` to ``255``. style (StyleCharKind, str, optional): Specifies the character style name for drop caps. whole_word (bool, optional): specifies if Drop Cap is applied to the whole first word. Returns: None: Note: If ``count==-1`` then only ``style`` can be updated. If ``count==0`` then all other arguments are ignored and instance set to remove drop caps when ``apply()`` is called. See Also: - :ref:`help_writer_format_direct_para_drop_caps` """ # pylint: disable=unexpected-keyword-arg # # if count == -1 then do not include DropCapStruct. only update style # if count = 0 then default to no drop cap values dc = None init_vars = {} if count == -1: if style is not None: init_vars["DropCapCharStyleName"] = str(style) elif count == 0: # set defaults to apply no drop caps whole_word = False style = "" init_vars["DropCapWholeWord"] = False init_vars["DropCapCharStyleName"] = "" dc = DropCapStruct(count=0, distance=0, lines=0, _cattribs=self._get_cattribs()) # type: ignore elif count > 0: try: dist = spaces.get_value_mm100() # type: ignore except AttributeError: dist = UnitConvert.convert_mm_mm100(spaces) # type: ignore dc = DropCapStruct(count=count, distance=dist, lines=lines, _cattribs=self._get_cattribs()) # type: ignore if whole_word is not None: init_vars["DropCapWholeWord"] = whole_word if whole_word: # when whole word is set the count must be 1 (for one word) dc.prop_count = 1 if style is not None: init_vars["DropCapCharStyleName"] = str(style) else: raise ValueError("Count must not be less then -1") super().__init__(**init_vars) if dc: self._set_style_dc(dc)
# endregion init # region methods
[docs] def dispatch_reset(self) -> None: """ Resets the cursor at is current position/selection to remove any Drop Caps Formatting using a dispatch command. Returns: None: Example: .. code-block:: python dc = DropCaps(count=1, style=StyleCharKind.DROP_CAPS) Write.append_para(cursor=cursor, text="Hello World!", styles=(dc,)) dc.dispatch_reset() """ drop_cap_args = { "FormatDropcap.Lines": 1, "FormatDropcap.Count": 1, "FormatDropcap.Distance": 0, "FormatDropcap.WholeWord": False, } drop_cap_props = mProps.Props.make_props(**drop_cap_args) mLo.Lo.dispatch_cmd("FormatDropcap", drop_cap_props) # mLo.Lo.delay(300) mLo.Lo.dispatch_cmd("SetDropCapCharStyleName", mProps.Props.make_props(CharStyleName=""))
# mLo.Lo.delay(300) # endregion methods # region Overrides
[docs] def on_property_setting(self, source: Any, event_args: KeyValCancelArgs) -> None: """ Triggers for each property that is set Args: source (Any): Event Source. event_args (KeyValueCancelArgs): Event Args """ # sourcery skip: merge-nested-ifs if event_args.key == "DropCapCharStyleName": # DropCapCharStyleName will not allow itself to be set if it has empty string # as a value, even though it ia a string and will take a string value of any valid # character style. if event_args.value is None or event_args.value == "": # instruct Props.set to call set_default() event_args.default = True super().on_property_setting(source, event_args)
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 _supported_services(self) -> Tuple[str, ...]: try: return self._supported_services_values except AttributeError: self._supported_services_values = ( "", "", "", ) return self._supported_services_values # endregion Overrides # region internal methods def _set_style_dc(self, dc: DropCapStruct | None) -> None: if dc is None: self._remove_style("drop_cap") return dc._prop_parent = self self._set_style("drop_cap", dc, *dc.get_attrs()) def _get_cattribs(self) -> dict: return { "_supported_services_values": self._supported_services(), "_property_name": "DropCapFormat", "_format_kind_prop": self.prop_format_kind, } # endregion internal methods # region Static Methods # region from_obj() @overload @classmethod def from_obj(cls: Type[_TDropCaps], obj: Any) -> _TDropCaps: ... @overload @classmethod def from_obj(cls: Type[_TDropCaps], obj: Any, **kwargs) -> _TDropCaps: ...
[docs] @classmethod def from_obj(cls: Type[_TDropCaps], obj: Any, **kwargs) -> _TDropCaps: """ Gets instance from object Args: obj (object): UNO object. Raises: NotSupportedError: If ``obj`` is not supported. Returns: DropCaps: ``DropCaps`` instance that represents ``obj`` Drop Caps. """ # 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__}"') dc = DropCapStruct.from_obj(obj, _cattribs=inst._get_cattribs()) inst._set_style_dc(dc) whole_word = cast(bool, mProps.Props.get(obj, "DropCapWholeWord")) style = cast(str, mProps.Props.get(obj, "DropCapCharStyleName")) if whole_word is not None: inst._set("DropCapWholeWord", whole_word) if style is not None: inst._set("DropCapCharStyleName", style) inst.set_update_obj(obj) return inst
# endregion from_obj() # endregion Static 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.TXT_CONTENT return self._format_kind_prop @property def prop_inner(self) -> DropCapStruct | None: """Gets Drop Caps Format instance""" try: return self._direct_inner except AttributeError: self._direct_inner = cast(DropCapStruct, self._get_style_inst("drop_cap")) return self._direct_inner @property def default(self: _TDropCaps) -> _TDropCaps: """Gets ``DropCaps`` default.""" try: return self._default_inst except AttributeError: inst = self.__class__(count=0, _cattribs=self._get_cattribs()) # type: ignore inst._is_default_inst = True self._default_inst = inst return self._default_inst
# endregion properties