Source code for ooodev.draw.shapes.shape_class_factory

from __future__ import annotations
from typing import Any, TYPE_CHECKING, Dict, Type
import uno
from import XGluePointsSupplier

from ooodev.draw.shapes.draw_shape import DrawShape
from ooodev.adapter.drawing.fill_properties_partial import FillPropertiesPartial
from ooodev.adapter.drawing.line_properties_partial import LinePropertiesPartial
from ooodev.adapter.drawing.shadow_properties_partial import ShadowPropertiesPartial
from ooodev.adapter.drawing.text_properties_partial import TextPropertiesPartial
from ooodev.adapter.document.link_target_properties_partial import LinkTargetPropertiesPartial
from ooodev.adapter.drawing.glue_points_supplier_partial import GluePointsSupplierPartial
from ooodev.adapter.presentation.shape_properties_partial import ShapePropertiesPartial
from ooodev.adapter.drawing.shape_group_partial import ShapeGroupPartial
from ooodev.adapter.drawing.shapes_partial import ShapesPartial
from import OfficeDocumentPropPartial
from ooodev.loader.inst.doc_type import DocType

from ooodev.adapter.drawing.rotation_descriptor_properties_partial import RotationDescriptorPropertiesPartial
from ooodev.utils import info as mInfo
from ooodev.loader import lo as mLo

    from ooodev.loader.inst.lo_inst import LoInst

[docs]class ShapeClassFactory(OfficeDocumentPropPartial): """ " Generates a class instance of a shape. If a shape supports a service, a partial class is created for that service. The partial class is a subclass of the DrawShape class. The Service to partial class mapping is as follows: - ```` -> ``ooodev.adapter.drawing.line_properties_partial.LinePropertiesPartial`` - ```` -> ``ooodev.adapter.drawing.fill_properties_partial.FillPropertiesPartial`` - ```` -> ``ooodev.adapter.drawing.shadow_properties_partial.ShadowPropertiesPartial`` - ```` -> ``ooodev.adapter.drawing.rotation_descriptor_properties_partial.RotationDescriptorPropertiesPartial`` - ```` -> ``ooodev.adapter.drawing.text_properties_partial.TextPropertiesPartial`` - ````-> ``ooodev.adapter.document.link_target_properties_partial.LinkTargetPropertiesPartial`` If the shape supports the ```` service, the following partial classes are implemented: - ``ooodev.adapter.drawing.shape_group_partial.ShapeGroupPartial`` - ``ooodev.adapter.drawing.shapes_partial.ShapesPartial`` - ``ooodev.adapter.drawing.rotation_descriptor_properties_partial.RotationDescriptorPropertiesPartial`` - ``ooodev.adapter.document.link_target_properties_partial.LinkTargetPropertiesPartial`` If the shape supports the ``XGluePointsSupplier`` interface, the following partial class is also implemented: - ``ooodev.adapter.drawing.glue_points_supplier_partial.GluePointsSupplierPartial`` If the shape document is of type ``DocType.IMPRESS`` (Impress document) and the shape supports the ```` service, the following partial class is also implemented: - ``ooodev.adapter.presentation.shape_properties_partial.ShapePropertiesPartial`` """
[docs] def __init__( self, *, owner: Any, component: Any, class_name: str = "", lo_inst: LoInst | None = None, base_class: Type[Any] = DrawShape, ) -> None: """ Constructor Args: owner (Any): Owner of the shape component (Any): UNO component that represents the shape class_name (str, optional): Class Name. Default to the name of the ``base_class``. lo_inst (LoInst | None, optional): Load Office instance. Defaults to None. base_class (Type[Any], optional): Base Class Parent that the shape inherits from. Defaults to DrawShape. Raises: ValueError: _description_ """ # in Python 3.7 and later, dict keys are ordered. This is important because the order of the bases if not isinstance(owner, OfficeDocumentPropPartial): raise ValueError("owner must be an instance of OfficeDocumentPropPartial") OfficeDocumentPropPartial.__init__(self, owner.office_doc) if lo_inst is None: lo_inst = mLo.Lo.current_lo self._owner = owner self._lo_inst = lo_inst self._name = class_name or base_class.__name__ self._component = component self._base_class = base_class self._existing = set(type.mro(base_class)) self._bases_partial: Dict[Type, Any] = {} self._bases_interfaces: Dict[Type, Any] = {} self._supported = set(mInfo.Info.get_available_services(self._component)) if "" in self._supported and LinePropertiesPartial not in self._existing: self._bases_partial[LinePropertiesPartial] = None if "" in self._supported and FillPropertiesPartial not in self._existing: self._bases_partial[FillPropertiesPartial] = None if ( "" in self._supported and ShadowPropertiesPartial not in self._existing ): self._bases_partial[ShadowPropertiesPartial] = None if ( "" in self._supported and RotationDescriptorPropertiesPartial not in self._existing ): self._bases_partial[RotationDescriptorPropertiesPartial] = None if "" in self._supported and TextPropertiesPartial not in self._existing: self._bases_partial[TextPropertiesPartial] = None if "" in self._supported and LinkTargetPropertiesPartial not in self._existing: self._bases_partial[LinkTargetPropertiesPartial] = None if "" in self._supported: if ShapeGroupPartial not in self._existing: self._bases_interfaces[ShapeGroupPartial] = None if ShapesPartial not in self._existing: self._bases_interfaces[ShapesPartial] = None if RotationDescriptorPropertiesPartial not in self._existing: self._bases_partial[RotationDescriptorPropertiesPartial] = None if RotationDescriptorPropertiesPartial not in self._existing: self._bases_partial[RotationDescriptorPropertiesPartial] = None # sourcery skip: swap-nested-ifs # sourcery skip: merge-nested-ifs if self.office_doc.DOC_TYPE == DocType.IMPRESS: # Even though shapes in Draw and Impress are the same, the supported services are different. # A shape in Draw may say it supports a presentation service but it may not. # When a shape is drawn on a Drawpage in the Draw program. and the the draw.get_selected_shapes() is used to get # the selected shapes, the shape will not have the presentation service even thought is is reported in the getAvailableServices() if "" in self._supported: self._bases_partial[ShapePropertiesPartial] = None if mLo.Lo.qi(XGluePointsSupplier, component) is not None: if GluePointsSupplierPartial not in self._existing: self._bases_interfaces[GluePointsSupplierPartial] = None
def _generate_class(self, **kwargs) -> type: """ Combines all the partial classes and the base class to create a new class. If there are no new partial classes, the base class is returned """ bases = [self._base_class] + list(self._bases_interfaces.keys()) + list(self._bases_partial.keys()) if len(bases) == 1 and not kwargs and self._base_class.__name__ == self._name: return self._base_class else: return type(self._name, tuple(bases), kwargs)
[docs] def get_class(self, **kwargs) -> Any: """ Gets the class instance of the shape. The returned class instance is a subclass of DrawShape and the other partial classes that are supported by the shape. Returns: Any: Shape class instance """ # pylint: disable=consider-iterating-dictionary # pylint: disable=consider-using-dict-items # pylint: disable=unnecessary-dunder-call clazz = self._generate_class(**kwargs) instance = clazz(self._owner, self._component, self._lo_inst) for t in self._bases_interfaces.keys(): t.__init__(instance, self._component, None) # type: ignore for t in self._bases_partial.keys(): t.__init__(instance, self._component) # type: ignore return instance