U
    cqeu                     @  sV   d Z ddlmZ ddlmZmZ ddlmZ G dd deedf Z	G dd dZ
d	S )
zRelationship-related objects.    )annotations)AnyDict)CT_Relationshipsc                      s   e Zd ZdZdd fddZdddddd	d
ddZdd Zdd Zdd Ze	dd Z
e	dd ZdddZdd Ze	dd Z  ZS )RelationshipszGCollection object for |_Relationship| instances, having list semantics.str)baseURIc                   s   t t|   || _i | _d S N)superr   __init___baseURI_target_parts_by_rId)selfr   	__class__ 0/tmp/pip-unpacked-wheel-gx5hpqp3/docx/opc/rel.pyr      s    zRelationships.__init__Fz	str | Anyboolz'_Relationship')reltypetargetrIdis_externalreturnc                 C  s,   t |||| j|}|| |< |s(|| j|< |S )z.Return a newly added |_Relationship| instance.)_Relationshipr   r   )r   r   r   r   r   relr   r   r   add_relationship   s
    
zRelationships.add_relationshipc                 C  s,   |  ||}|dkr(| j}| |||}|S )zlReturn relationship of `reltype` to `target_part`, newly added if not already
        present in collection.N)_get_matching	_next_rIdr   )r   r   target_partr   r   r   r   r   
get_or_add   s
    zRelationships.get_or_addc                 C  s6   | j ||dd}|dkr0| j}| j|||dd}|jS )z{Return rId of external relationship of `reltype` to `target_ref`, newly added
        if not already present in collection.T)r   N)r   r   r   r   )r   r   
target_refr   r   r   r   r   get_or_add_ext_rel%   s
    z Relationships.get_or_add_ext_relc                 C  s   |  |}|jS )zReturn target part of rel with matching `reltype`, raising |KeyError| if not
        found and |ValueError| if more than one matching relationship is found.)_get_rel_of_typer   )r   r   r   r   r   r   part_with_reltype.   s    
zRelationships.part_with_reltypec                 C  s   | j S )z_Dict mapping rIds to target parts for all the internal relationships in the
        collection.)r   r   r   r   r   related_parts4   s    zRelationships.related_partsc                 C  s4   t  }|  D ]}||j|j|j|j q|jS )zoSerialize this relationship collection into XML suitable for storage as a
        .rels file in an OPC package.)	r   newvaluesZadd_relr   r   r    r   xml)r   Zrels_elmr   r   r   r   r(   :   s    zRelationships.xmlc                 C  s0   dd }|   D ]}|||||r|  S qdS )zuReturn relationship of matching `reltype`, `target`, and `is_external` from
        collection, or None if not found.c                 S  s>   | j |krdS | j|krdS | jr(| jn| j}||kr:dS dS )NFT)r   r   r    r   )r   r   r   r   Z
rel_targetr   r   r   matchesG   s    

z,Relationships._get_matching.<locals>.matchesN)r'   )r   r   r   r   r)   r   r   r   r   r   C   s
    

zRelationships._get_matchingc                   sV    fdd|   D }t|dkr2d}t|  t|dkrNd}t|  |d S )zReturn single relationship of type `reltype` from the collection.

        Raises |KeyError| if no matching relationship is found. Raises |ValueError| if
        more than one matching relationship is found.
        c                   s   g | ]}|j  kr|qS r   r   ).0r   r*   r   r   
<listcomp>\   s     
 z2Relationships._get_rel_of_type.<locals>.<listcomp>r   z*no relationship of type '%s' in collection   z1multiple relationships of type '%s' in collection)r'   lenKeyError
ValueError)r   r   Zmatchingtmplr   r*   r   r"   V   s    zRelationships._get_rel_of_typec                 C  s4   t dt| d D ]}d| }|| kr|  S qdS )zNext available rId in collection, starting from 'rId1' and making use of any
        gaps in numbering, e.g. 'rId2' for rIds ['rId1', 'rId3'].r-      zrId%dN)ranger.   )r   nZrId_candidater   r   r   r   e   s    zRelationships._next_rId)F)F)__name__
__module____qualname____doc__r   r   r   r!   r#   propertyr%   r(   r   r"   r   __classcell__r   r   r   r   r   
   s    
		


r   r   c                      sj   e Zd ZdZddd fddZedd Zed	d
 Zedd Zedd Z	eddddZ
  ZS )r   z&Value object for relationship to part.Fr   )r   c                   s4   t t|   || _|| _|| _|| _t|| _d S r	   )	r
   r   r   _rId_reltype_targetr   r   _is_external)r   r   r   r   r   Zexternalr   r   r   r   r   s    z_Relationship.__init__c                 C  s   | j S r	   )r>   r$   r   r   r   r   z   s    z_Relationship.is_externalc                 C  s   | j S r	   )r<   r$   r   r   r   r   ~   s    z_Relationship.reltypec                 C  s   | j S r	   )r;   r$   r   r   r   r      s    z_Relationship.rIdc                 C  s   | j rtd| jS )NzOtarget_part property on _Relationship is undefined when target mode is External)r>   r0   r=   r$   r   r   r   r      s
    z_Relationship.target_part)r   c                 C  s    | j r| jS | jj| jS d S r	   )r>   r=   ZpartnameZrelative_refr   r$   r   r   r   r       s    z_Relationship.target_ref)F)r5   r6   r7   r8   r   r9   r   r   r   r   r    r:   r   r   r   r   r   o   s   



N)r8   
__future__r   typingr   r   Zdocx.opc.oxmlr   r   r   r   r   r   r   r   <module>   s
   e