o
    W_                     @   s   d Z ddlmZmZmZmZ ddlmZ ddlm	Z	 ddlm
Z
 ddlmZ dd	lmZ dd
lmZ G dd deZG dd deZG dd deZdS )zC
Open Packaging Convention (OPC) objects related to package parts.
    )absolute_importdivisionprint_functionunicode_literals   )cls_method_fn)serialize_part_xml   	parse_xml)PackURI)Relationships)lazypropertyc                       s   e Zd ZdZd% fdd	Zdd Zdd Zed	d
 Zedd Z	dd Z
edd Zd&ddZedd Zedd Zejdd Zdd Zd&ddZedd Zedd  Zd!d" Zd#d$ Z  ZS )'Partz
    Base class for package parts. Provides common properties and methods, but
    intended to be subclassed in client code to implement specific part
    behaviors.
    Nc                    s*   t t|   || _|| _|| _|| _d S N)superr   __init__	_partname_content_type_blob_package)selfpartnamecontent_typeblobpackage	__class__ =D:\Projects\ConvertPro\env\Lib\site-packages\docx\opc\part.pyr      s
   
zPart.__init__c                 C      dS )z
        Entry point for post-unmarshaling processing, for example to parse
        the part XML. May be overridden by subclasses without forwarding call
        to super.
        Nr   r   r   r   r   after_unmarshal       zPart.after_unmarshalc                 C   r    )z
        Entry point for pre-serialization processing, for example to finalize
        part naming if necessary. May be overridden by subclasses without
        forwarding call to super.
        Nr   r!   r   r   r   before_marshal*   r#   zPart.before_marshalc                 C      | j S )z
        Contents of this package part as a sequence of bytes. May be text or
        binary. Intended to be overridden by subclasses. Default behavior is
        to return load blob.
        )r   r!   r   r   r   r   4   s   z	Part.blobc                 C   r%   )z,
        Content type of this part.
        )r   r!   r   r   r   r   =      zPart.content_typec                 C   s   |  |dk r| j|= dS dS )z
        Remove the relationship identified by *rId* if its reference count
        is less than 2. Relationships with a reference count of 0 are
        implicit relationships.
        r	   N)_rel_ref_countrels)r   rIdr   r   r   drop_relD   s   zPart.drop_relc                 C   s   | ||||S r   r   )clsr   r   r   r   r   r   r   loadM   s   z	Part.loadFc                 C   s   | j ||||S )a  
        Return newly added |_Relationship| instance of *reltype* between this
        part and *target* with key *rId*. Target mode is set to
        ``RTM.EXTERNAL`` if *is_external* is |True|. Intended for use during
        load from a serialized package, where the rId is well-known. Other
        methods exist for adding a new relationship to a part when
        manipulating a part.
        )r(   Zadd_relationship)r   reltypetargetr)   is_externalr   r   r   load_relQ   s   	zPart.load_relc                 C   r%   )z=
        |OpcPackage| instance this part belongs to.
        )r   r!   r   r   r   r   \   r&   zPart.packagec                 C   r%   )zi
        |PackURI| instance holding partname of this part, e.g.
        '/ppt/slides/slide1.xml'
        )r   r!   r   r   r   r   c   s   zPart.partnamec                 C   s*   t |tsd}t|t|j || _d S )Nz.partname must be instance of PackURI, got '%s')
isinstancer   	TypeErrortype__name__r   )r   r   tmplr   r   r   r   k   s   

c                 C   s   | j |S )a-  
        Return part to which this part has a relationship of *reltype*.
        Raises |KeyError| if no such relationship is found and |ValueError|
        if more than one such relationship is found. Provides ability to
        resolve implicitly related part, such as Slide -> SlideLayout.
        )r(   Zpart_with_reltype)r   r-   r   r   r   part_related_byr   s   zPart.part_related_byc                 C   s&   |r	| j ||S | j ||}|jS )z
        Return rId key of relationship of *reltype* to *target*, from an
        existing relationship if there is one, otherwise a newly created one.
        )r(   Zget_or_add_ext_relZ
get_or_addr)   )r   r.   r-   r/   relr   r   r   	relate_to{   s   zPart.relate_toc                 C   s   | j jS )z
        Dictionary mapping related parts by rId, so child objects can resolve
        explicit relationships present in the part XML, e.g. sldIdLst to a
        specific |Slide| instance.
        )r(   related_partsr!   r   r   r   r9      s   zPart.related_partsc                 C   s   t | jjS )zS
        |Relationships| instance holding the relationships for this part.
        )r   r   ZbaseURIr!   r   r   r   r(      s   z	Part.relsc                 C   s   | j | }|jS )za
        Return URL contained in target ref of relationship identified by
        *rId*.
        )r(   
target_ref)r   r)   r7   r   r   r   r:      s   
zPart.target_refc                    s"   | j d}t fdd|D S )zt
        Return the count of references in this part's XML to the relationship
        identified by *rId*.
        z//@r:idc                    s   g | ]}| kr|qS r   r   ).0Z_rIdr)   r   r   
<listcomp>   s    z'Part._rel_ref_count.<locals>.<listcomp>)_elementZxpathlen)r   r)   ZrIdsr   r<   r   r'      s   zPart._rel_ref_count)NN)F)r4   
__module____qualname____doc__r   r"   r$   propertyr   r   r*   classmethodr,   r0   r   r   setterr6   r8   r9   r   r(   r:   r'   __classcell__r   r   r   r   r      s6    



	





	

r   c                   @   s0   e Zd ZdZdZi ZeZdd Ze	dd Z
dS )PartFactorya  
    Provides a way for client code to specify a subclass of |Part| to be
    constructed by |Unmarshaller| based on its content type and/or a custom
    callable. Setting ``PartFactory.part_class_selector`` to a callable
    object will cause that object to be called with the parameters
    ``content_type, reltype``, once for each part in the package. If the
    callable returns an object, it is used as the class for that part. If it
    returns |None|, part class selection falls back to the content type map
    defined in ``PartFactory.part_type_for``. If no class is returned from
    either of these, the class contained in ``PartFactory.default_part_type``
    is used to construct the part, which is by default ``opc.package.Part``.
    Nc                 C   sD   d }| j d urt| d}|||}|d u r| |}|||||S )Npart_class_selector)rH   r   _part_cls_forr,   )r+   r   r   r-   r   r   Z	PartClassrH   r   r   r   __new__   s   



zPartFactory.__new__c                 C   s   || j v r
| j | S | jS )z
        Return the custom part class registered for *content_type*, or the
        default part class if no custom class is registered for
        *content_type*.
        )part_type_fordefault_part_type)r+   r   r   r   r   rI      s   

zPartFactory._part_cls_for)r4   r@   rA   rB   rH   rK   r   rL   rJ   rD   rI   r   r   r   r   rG      s    	rG   c                       sP   e Zd ZdZ fddZedd Zedd Zedd	 Z	ed
d Z
  ZS )XmlParta   
    Base class for package parts containing an XML payload, which is most of
    them. Provides additional methods to the |Part| base class that take care
    of parsing and reserializing the XML payload and managing relationships
    to other parts.
    c                    s    t t| j|||d || _d S )N)r   )r   rM   r   r>   )r   r   r   elementr   r   r   r   r      s   

zXmlPart.__init__c                 C   s
   t | jS r   )r   r>   r!   r   r   r   r      s   
zXmlPart.blobc                 C   r%   )z8
        The root XML element of this XML part.
        )r>   r!   r   r   r   rN      r&   zXmlPart.elementc                 C   s   t |}| ||||S r   r
   )r+   r   r   r   r   rN   r   r   r   r,      s   zXmlPart.loadc                 C   s   | S )z
        Part of the parent protocol, "children" of the document will not know
        the part that contains them so must ask their parent object. That
        chain of delegation ends here for child objects.
        r   r!   r   r   r   part   s   zXmlPart.part)r4   r@   rA   rB   r   rC   r   rN   rD   r,   rO   rF   r   r   r   r   rM      s    


rM   N)rB   Z
__future__r   r   r   r   compatr   Zoxmlr   r   Zpackurir   r7   r   sharedr   objectr   rG   rM   r   r   r   r   <module>   s    &