
    'j=                        d dl m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mZ d d	lmZ d d
lmZ d dlmZ d dlmZ erd dlmZ h dZ G d d          Z G d d          Z dS )    )annotations)OptionalIterableTYPE_CHECKINGIterator)contextmanager)HandleGenerator)is_valid_handle)	DXFEntity)	DXFObject)
AuditErrorAuditor)DXFInternalEzdxfError)factory)EntityQuery)default_copy)AbstractTagWriter>   EOFCLASSTABLEENDSECENDTABSECTION
ACDSRECORD
ACDSSCHEMAc                      e Zd ZdZ G d d          Zd0dZd1d
Zd2dZd3dZd4dZ	d5dZ
d6dZd7dZd8dZd9dZd:dZd;dZd<dZd<dZd<dZd=d Zd>d#Zd?d%Zed?d&            Zd0d'Zd@d)ZdAd*ZdBdCd.Zd/S )DEntityDBzA simple key/entity database.

    Every entity/object, except tables and sections, are represented as
    DXFEntity or inherited types, these entities are stored in the
    DXF document database, database-key is the `handle` as string.

    c                  (    e Zd ZdZd
dZddZd Zd	S )EntityDB.Trashcanz8Store handles to entities which should be deleted later.dbr   c                D    |j         | _         t                      | _        d S N)	_databaseset_handles)selfr    s     H/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/entitydb.py__init__zEntityDB.Trashcan.__init__0   s    \DN&)eeDMMM    handlestrc                :    | j                             |           dS )zPut handle into trashcan to delete the entity later, this is
            required for deleting entities while iterating the database.
            N)r%   addr&   r*   s     r'   r-   zEntityDB.Trashcan.add4   s      Mf%%%%%r)   c                    | j         }| j        D ];}|                    |          }|r|j        r|                                 ||v r||= <| j                                         dS )zfRemove handles in trashcan from database and destroy entities if
            still alive.
            N)r#   r%   getis_alivedestroyclear)r&   r    r*   entitys       r'   r3   zEntityDB.Trashcan.clear:   sw     B- # # %fo %NN$$$R<<6
M!!!!!r)   N)r    r   )r*   r+   )__name__
__module____qualname____doc__r(   r-   r3    r)   r'   Trashcanr   -   sQ        FF	, 	, 	, 	,	& 	& 	& 	&	" 	" 	" 	" 	"r)   r:   returnNonec                H    i | _         t                      | _        d| _        d S )NF)r#   r	   handleslockedr&   s    r'   r(   zEntityDB.__init__I   s!    /1&((!r)   r*   r+   r   c                    | j         |         S )ziGet entity by `handle`, does not filter destroyed entities nor
        entities in the trashcan.
        )r#   r.   s     r'   __getitem__zEntityDB.__getitem__O   s     ~f%%r)   r4   c                h   t          |t                    sJ t          |                      t          |t                    sJ t          |                      |j        s
J d            | j        rt          d          |dk    st          |          st          d| d          || j	        |<   dS )zSet `entity` for `handle`.zCan not store destroyed entity.Locked entity database.0zInvalid handle .N)

isinstancer+   typer   r1   r?   r   r
   
ValueErrorr#   )r&   r*   r4   s      r'   __setitem__zEntityDB.__setitem__U   s    &#&&44V44&&),,::d6ll::,AA AAA; 	C'(ABBBS== 7 7=8v888999!'vr)   c                B    | j         rt          d          | j        |= dS )zkDelete entity by `handle`. Removes entity only from database, does
        not destroy the entity.
        rD   N)r?   r   r#   r.   s     r'   __delitem__zEntityDB.__delitem__a   s.     ; 	C'(ABBBN6"""r)   boolc                t    |dS t          |t                    sJ t          |                      || j        v S )z'``True`` if database contains `handle`.NF)rG   r+   rH   r#   r.   s     r'   __contains__zEntityDB.__contains__i   s=    >5&#&&44V44&''r)   intc                *    t          | j                  S )zCount of database items.)lenr#   r@   s    r'   __len__zEntityDB.__len__p   s    4>"""r)   Iterator[str]c                *    |                                  S )zjIterable of all handles, does filter destroyed entities but not
        entities in the trashcan.
        )keysr@   s    r'   __iter__zEntityDB.__iter__t   s     yy{{r)   Optional[DXFEntity]c                6    | j                             |          S )zoReturns entity for `handle` or ``None`` if no entry exist, does
        not filter destroyed entities.
        )r#   r0   r.   s     r'   r0   zEntityDB.getz   s     ~!!&)))r)   c                N    	 | j                                         }|| j        vr|S %)zReturns next unique handle.)r>   nextr#   r.   s     r'   next_handlezEntityDB.next_handle   s1    	\&&((FT^++	r)   Iterable[str]c                >    d |                                  D             S )z8Iterable of all handles, does filter destroyed entities.c              3      K   | ]	\  }}|V  
d S r"   r9   .0r*   r4   s      r'   	<genexpr>z EntityDB.keys.<locals>.<genexpr>   &      ::>66::::::r)   itemsr@   s    r'   rV   zEntityDB.keys       ::TZZ\\::::r)   Iterable[DXFEntity]c                >    d |                                  D             S )z9Iterable of all entities, does filter destroyed entities.c              3      K   | ]	\  }}|V  
d S r"   r9   r`   s      r'   rb   z"EntityDB.values.<locals>.<genexpr>   rc   r)   rd   r@   s    r'   valueszEntityDB.values   rf   r)   Iterable[tuple[str, DXFEntity]]c                H    d | j                                         D             S )zZIterable of all (handle, entities) pairs, does filter destroyed
        entities.
        c              3  2   K   | ]\  }}|j         ||fV  d S r"   r1   r`   s      r'   rb   z!EntityDB.items.<locals>.<genexpr>   sG       
 

V
 
 
 
 
 
r)   r#   re   r@   s    r'   re   zEntityDB.items   s1    
 
"&."6"6"8"8
 
 
 	
r)   c                <   |                                 t          v r|j        j        || |j        j        <   dS |j        j        }|)|                                 }|                    |           || |<   t          |d          r|                    |            dS dS )zAdd `entity` to database, assigns a new handle to the `entity`
        if :attr:`entity.dxf.handle` is ``None``. Adding the same entity
        multiple times is possible and creates only a single database entry.

        Nadd_sub_entities_to_entitydb)dxftypeDATABASE_EXCLUDEdxfr*   r\   update_handlehasattrrq   r&   r4   r*   s      r'   r-   zEntityDB.add   s     >>///z , +1VZ&'Fj'>%%''F  (((V 69:: 	6//55555	6 	6r)   c                Z    |j         r#| |j        j        = |                                 dS dS )z7Remove `entity` from database and destroy the `entity`.N)r1   rt   r*   r2   r&   r4   s     r'   delete_entityzEntityDB.delete_entity   s9    ? 	VZ&'NN	 	r)   c                     |j         r\t          |d          r|                     fd           |j        j        }	  j        |= d|j        _        dS # t          $ r Y dS w xY wdS )z?Discard `entity` from database without destroying the `entity`.process_sub_entitiesc                .                         |           S r"   )discard)er&   s    r'   <lambda>z"EntityDB.discard.<locals>.<lambda>   s    dll1oo r)   N)r1   rv   r|   rt   r*   r#   KeyErrorrw   s   `  r'   r~   zEntityDB.discard   s    ? 		v566 G++,E,E,E,EFFFZ&FN6*$(
!!!   		 		s   A 
A"!A"c                *   |j         }|
J d            |                                 }|                    t                    }||j        _        t          j        ||           t          |t                    r|j
                            |           |S )a  Duplicates `entity` and its sub entities (VERTEX, ATTRIB, SEQEND)
        and store them with new handles in the entity database.
        Graphical entities have to be added to a layout by
        :meth:`~ezdxf.layouts.BaseLayout.add_entity`. DXF objects will
        automatically added to the OBJECTS section.

        A new owner handle will be set by adding the duplicated entity to a
        layout.

        Raises:
            CopyNotSupported: copying of `entity` is not supported

        Nzvalid DXF document required)copy_strategy)docr\   copyr   rt   r*   r   bindrG   r   objects
add_object)r&   r4   r   
new_handle
new_entitys        r'   duplicate_entityzEntityDB.duplicate_entity   s     j =%%''
 &, G G
 *
Z%%%j),, 	/K"":...r)   auditorr   c           
        | j         du s
J d            g }|                                 5 }|                                 D ]\  }}t          |          sO|                    t
          j        d|                                 d| d           |                    |           ||j	        
                    d          k    r4d| j        |<   |                    |           |                    |           	 ddd           n# 1 swxY w Y   |                                  |D ]}|j	        
                    d          }|8|                    t
          j        d|                                 d	           Vt          |          r|d
k    r;|                    t
          j        d|                                 d| d           || |<   dS )a  Restore database integrity:

        - restore database entries with modified handles (key != entity.dxf.handle)
        - remove entities with invalid handles
        - empty trashcan - destroy all entities in the trashcan
        - removes destroyed database entries (purge)

        FzDatabase is locked!Removed entity z with invalid handle "z" from entity database.)codemessager*   Nz% without handle from entity database.rE   )r?   trashcanre   r
   fixed_errorr   INVALID_ENTITY_HANDLErr   r-   rt   r0   r#   appendpurge)r&   r   add_entitiestrashr*   r4   s         r'   auditzEntityDB.audit   sm    {e###%:###]]__ 	0"&**,, 0 0&v.. &'''=!C&..2B2B !C !C#)!C !C !C (   
 IIf%%%VZ^^H5555 .2DN6*IIf%%% ''///0	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0$ 	

" 	" 	"FZ^^H--F~###9-fnn.>.> - - - $   
 "6** fmm###9?fnn.>.> ? ?%? ? ? $   
 !DLL!	" 	"s   CDD	Dr   c                6    t                               |           S )z_Returns a new trashcan, empty trashcan manually by: :
        func:`Trashcan.clear()`.
        )r   r:   r@   s    r'   new_trashcanzEntityDB.new_trashcan  s       &&&r)   c              #  b   K   |                                  }|V  |                                 dS )zoReturns a new trashcan in context manager mode, trashcan will be
        emptied when leaving context.
        N)r   r3   )r&   	trashcan_s     r'   r   zEntityDB.trashcan  s:      
 %%''	 	r)   c                `    | j         }d |                                D             }|D ]}||= dS )z^Remove all destroyed entities from database, but does not empty the
        trashcan.
        c                &    g | ]\  }}|j         |S r9   rn   r`   s      r'   
<listcomp>z"EntityDB.purge.<locals>.<listcomp>%  s#    WWW>66vWWWWr)   Nro   )r&   r    dead_handlesr*   s       r'   r   zEntityDB.purge  sH    
 ^WWRXXZZWWW" 	 	F6

	 	r)   set[str]c                X    t          d |                                 D                       S )Nc              3  >   K   | ]}|                                 V  d S r"   )rr   )ra   r4   s     r'   rb   z,EntityDB.dxf_types_in_use.<locals>.<genexpr>*  s,      @@6>>##@@@@@@r)   )r$   rj   r@   s    r'   dxf_types_in_usezEntityDB.dxf_types_in_use)  s'    @@$++--@@@@@@r)   c                    || j         v rdS |                     |           ||j        _        |                     |           dS )z|Try to reset the entity handle to a certain value.
        Returns ``True`` if successful and ``False`` otherwise.

        FT)r#   r~   rt   r*   r-   rw   s      r'   reset_handlezEntityDB.reset_handle,  sI    
 T^##5V"
tr)   *queryr   c                d    t          d | j                                        D             |          S )zEntity query over all entities in the DXF document.

        Args:
            query: query string

        .. seealso::

            :ref:`entity query string` and :ref:`entity queries`

        c              3  (   K   | ]}|j         	|V  d S r"   rn   ra   r   s     r'   rb   z!EntityDB.query.<locals>.<genexpr>C  s)      MM!!*MAMMMMMMr)   )r   r#   rj   )r&   r   s     r'   r   zEntityDB.query8  s1     MMt~'<'<'>'>MMMuUUUr)   Nr;   r<   )r*   r+   r;   r   )r*   r+   r4   r   r;   r<   )r*   r+   r;   r<   r*   r+   r;   rM   r;   rP   )r;   rT   )r*   r+   r;   rX   )r;   r+   )r;   r]   )r;   rg   )r;   rk   r4   r   r;   r<   )r4   r   r;   r   )r   r   )r;   r   )r;   r   )r4   r   r*   r+   r;   rM   )r   )r   r+   r;   r   )r5   r6   r7   r8   r:   r(   rB   rJ   rL   rO   rS   rW   r0   r\   rV   rj   re   r-   rz   r~   r   r   r   r   r   r   r   r   r   r9   r)   r'   r   r   $   s/        " " " " " " " "8" " " "& & & &
( 
( 
( 
(# # # #( ( ( (# # # #   * * * *   ; ; ; ;; ; ; ;
 
 
 
6 6 6 6.         20" 0" 0" 0"d' ' ' '    ^   A A A A
 
 
 
V V V V V V Vr)   r   c                      e Zd ZdZd#d$dZd%dZd&d
Zd'dZd(dZd Z	d)dZ
d*dZd+dZd)dZd,dZd-d.dZd/dZd0d"ZdS )1EntitySpaceat  
    An :class:`EntitySpace` is a collection of :class:`~ezdxf.entities.DXFEntity`
    objects, that stores only  references to :class:`DXFEntity` objects.

    The :class:`~ezdxf.layouts.Modelspace`, any :class:`~ezdxf.layouts.Paperspace`
    layout and :class:`~ezdxf.layouts.BlockLayout` objects have an
    :class:`EntitySpace` container to store their entities.

    NentitiesOptional[Iterable[DXFEntity]]c                J    |rt          d |D                       ng | _        d S )Nc              3  (   K   | ]}|j         	|V  d S r"   rn   r   s     r'   rb   z'EntitySpace.__init__.<locals>.<genexpr>S  s)      33q
3333333r)   listr   )r&   r   s     r'   r(   zEntitySpace.__init__Q  s1    7?GD33H333333R 	r)   r;   Iterator[DXFEntity]c                $    d | j         D             S )z5Iterable of all entities, filters destroyed entities.c              3  (   K   | ]}|j         	|V  d S r"   rn   r   s     r'   rb   z'EntitySpace.__iter__.<locals>.<genexpr>X  s)      77aAJ7777777r)   r   r@   s    r'   rW   zEntitySpace.__iter__V  s    774=7777r)   r   c                    | j         |         S )a  Get entity at index `item`

        :class:`EntitySpace` has a standard Python list like interface,
        therefore `index` can be any valid list indexing or slicing term, like
        a single index ``layout[-1]`` to get the last entity, or an index slice
        ``layout[:10]`` to get the first 10 or fewer entities as
        ``list[DXFEntity]``. Does not filter destroyed entities.

        r   r&   indexs     r'   rB   zEntitySpace.__getitem__Z  s     }U##r)   rP   c                *    t          | j                  S )z/Count of entities including destroyed entities.)rR   r   r@   s    r'   rS   zEntitySpace.__len__f  s    4=!!!r)   r*   r+   rM   c                    t          t                    sJ t                                t          fd| D                       S )z@``True`` if `handle` is present, does filter destroyed entities.c              3  8   K   | ]}|j         j        k    V  d S r"   )rt   r*   )ra   r   r*   s     r'   rb   z)EntitySpace.has_handle.<locals>.<genexpr>m  s,      88a15<6)888888r)   )rG   r+   rH   anyr.   s    `r'   
has_handlezEntitySpace.has_handlej  sJ    &#&&44V44&88884888888r)   c                .    t          |           | _        dS )z0Remove all destroyed entities from entity space.Nr   r@   s    r'   r   zEntitySpace.purgeo  s    T

r)   r4   r<   c                    t          |t                    sJ t          |                      |j        s
J d            | j                            |           dS )zAdd `entity`.z Can not store destroyed entitiesN)rG   r   rH   r1   r   r   ry   s     r'   r-   zEntitySpace.adds  sX    &),,::d6ll::,BB BBBV$$$$$r)   rg   c                :    |D ]}|                      |           dS )zAdd multiple `entities`.N)r-   )r&   r   r4   s      r'   extendzEntitySpace.extendy  s0     	 	FHHV	 	r)   	tagwriterr   c                T    t          |           D ]}|                    |           dS )zRExport all entities into DXF file by `tagwriter`.

        (internal API)
        N)iter
export_dxf)r&   r   r4   s      r'   r   zEntitySpace.export_dxf~  s:    
 4jj 	) 	)Fi((((	) 	)r)   c                :    | j                             |           dS )zRemove `entity`.N)r   removery   s     r'   r   zEntitySpace.remove  s    V$$$$$r)   c                ,    t                      | _        dS )zRemove all entities.Nr   r@   s    r'   r3   zEntitySpace.clear  s     r)   r   c                6    | j                             |          S r"   )r   popr   s     r'   r   zEntitySpace.pop  s    }  '''r)   c                <    | j                             ||           d S r"   )r   insert)r&   r   r4   s      r'   r   zEntitySpace.insert  s     UF+++++r)   r   r   c                >   |j         j        }g }| D ]T}|j        j        }| ||          ur9|                    t
          j        d| d           |                    |           U|sd S |D ]0}| j        	                    |           |
                                 1d S )Nr   z8 with a conflicting handle and without a database entry.)entitydbr0   rt   r*   r   r   REMOVED_INVALID_DXF_OBJECTr   r   r   _silent_kill)r&   r   db_getr   r4   r*   s         r'   r   zEntitySpace.audit  s    !%!#  	% 	%FZ&FVVF^^++ ##9'f ' ' '  
 V$$$ 	F 	" 	"FM  ((( !!!!		" 	"r)   r"   )r   r   )r;   r   )r;   r   r   r   r   )r   rg   r;   r<   )r   r   r;   r<   r   )r   )r   rP   r;   r   )r   rP   r4   r   r;   r<   )r   r   r;   r<   )r5   r6   r7   r8   r(   rW   rB   rS   r   r   r-   r   r   r   r3   r   r   r   r9   r)   r'   r   r   F  s;        
 
 
 
 

8 8 8 8
$ 
$ 
$ 
$" " " "9 9 9 9
# # #% % % %   
) ) ) )% % % %   
( ( ( ( (, , , ," " " " " "r)   r   N)!
__future__r   typingr   r   r   r   
contextlibr   ezdxf.tools.handler	   ezdxf.lldxf.typesr
   ezdxf.entities.dxfentityr   ezdxf.entities.dxfobjr   ezdxf.auditr   r   ezdxf.lldxf.constr   ezdxf.entitiesr   ezdxf.queryr   ezdxf.entities.copyr   ezdxf.lldxf.tagwriterr   rs   r   r   r9   r)   r'   <module>r      s   # " " " " "            & % % % % % . . . . . . - - - - - - . . . . . . + + + + + + + + + + + + + + 3 3 3 3 3 3 " " " " " " # # # # # # , , , , , , 8777777	 	 	 _V _V _V _V _V _V _V _VD	j" j" j" j" j" j" j" j" j" j"r)   