
    Og=                        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 y)    )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dd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d%d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ddZd,dZd-dZd.d/dZy)0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y)EntityDB.Trashcanz8Store handles to entities which should be deleted later.c                D    |j                   | _         t               | _        y N)	_databaseset_handles)selfdbs     S/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/entitydb.py__init__zEntityDB.Trashcan.__init__0   s    \\DN&)eDM    c                :    | j                   j                  |       y)zPut handle into trashcan to delete the entity later, this is
            required for deleting entities while iterating the database.
            N)r$   addr%   handles     r'   r+   zEntityDB.Trashcan.add4   s     MMf%r)   c                    | j                   }| j                  D ]9  }|j                  |      }|r|j                  r|j	                          ||v s7||= ; | j                  j                          y)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'   r2   zEntityDB.Trashcan.clear:   s`     B-- #fooNN$R<6
# MM!r)   N)r&   r   )r-   str)__name__
__module____qualname____doc__r(   r+   r2    r)   r'   Trashcanr   -   s    F	,	&	"r)   r:   c                >    i | _         t               | _        d| _        y )NF)r"   r	   handleslockedr%   s    r'   r(   zEntityDB.__init__I   s    /1&(!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)   c                4   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                  |<   y)zSet `entity` for `handle`.zCan not store destroyed entity.Locked entity database.0zInvalid handle .N)

isinstancer4   typer   r0   r=   r   r
   
ValueErrorr"   )r%   r-   r3   s      r'   __setitem__zEntityDB.__setitem__U   s    &#&4V4&&),:d6l:,A AA;;'(ABBS= 7vha899!'vr)   c                L    | j                   rt        d      | j                  |= y)zkDelete entity by `handle`. Removes entity only from database, does
        not destroy the entity.
        rB   N)r=   r   r"   r,   s     r'   __delitem__zEntityDB.__delitem__a   s#     ;;'(ABBNN6"r)   c                d    |yt        |t              sJ t        |             || j                  v S )z'``True`` if database contains `handle`.F)rE   r4   rF   r"   r,   s     r'   __contains__zEntityDB.__contains__i   s2    >&#&4V4&''r)   c                ,    t        | j                        S )zCount of database items.)lenr"   r>   s    r'   __len__zEntityDB.__len__p   s    4>>""r)   c                "    | j                         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)   c                8    | j                   j                  |      S )zoReturns entity for `handle` or ``None`` if no entry exist, does
        not filter destroyed entities.
        )r"   r/   r,   s     r'   r/   zEntityDB.getz   s     ~~!!&))r)   c                Z    	 | j                   j                         }|| j                  vr|S +)zReturns next unique handle.)r<   nextr"   r,   s     r'   next_handlezEntityDB.next_handle   s-    \\&&(FT^^+ r)   c                0    d | j                         D        S )z8Iterable of all handles, does filter destroyed entities.c              3  &   K   | ]	  \  }}|  y wr!   r9   .0r-   r3   s      r'   	<genexpr>z EntityDB.keys.<locals>.<genexpr>        :>66:   itemsr>   s    r'   rQ   zEntityDB.keys       :TZZ\::r)   c                0    d | j                         D        S )z9Iterable of all entities, does filter destroyed entities.c              3  &   K   | ]	  \  }}|  y wr!   r9   rY   s      r'   r[   z"EntityDB.values.<locals>.<genexpr>   r\   r]   r^   r>   s    r'   valueszEntityDB.values   r`   r)   c                D    d | j                   j                         D        S )zZIterable of all (handle, entities) pairs, does filter destroyed
        entities.
        c              3  B   K   | ]  \  }}|j                   r||f  y wr!   r0   rY   s      r'   r[   z!EntityDB.items.<locals>.<genexpr>   s(      
 V
s   )r"   r_   r>   s    r'   r_   zEntityDB.items   s!    
"&.."6"6"8
 	
r)   c                H   |j                         t        v r0|j                  j                  || |j                  j                  <   y|j                  j                  }|!| j	                         }|j                  |       || |<   t        |d      r|j                  |        yy)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-   rV   update_handlehasattrrh   r%   r3   r-   s      r'   r+   zEntityDB.add   s     >>//zz  , +1VZZ&&'jj''>%%'F  (V 69://5 ;r)   c                l    |j                   r(| |j                  j                  = |j                          yy)z7Remove `entity` from database and destroy the `entity`.N)r0   rk   r-   r1   r%   r3   s     r'   delete_entityzEntityDB.delete_entity   s*    ??VZZ&&'NN r)   c                     |j                   rVt        |d      r|j                   fd       |j                  j                  }	  j
                  |= d|j                  _        yy# t        $ r Y yw xY w)z?Discard `entity` from database without destroying the `entity`.process_sub_entitiesc                &    j                  |       S r!   )discard)er%   s    r'   <lambda>z"EntityDB.discard.<locals>.<lambda>   s    dll1o r)   N)r0   rm   rs   rk   r-   r"   KeyErrorrn   s   `  r'   ru   zEntityDB.discard   si    ??v56++,EFZZ&&FNN6*$(

!   s   A% %	A10A1c                    |j                   }|J d       | j                         }|j                  t              }||j                  _        t        j                  ||       t        |t              r|j                  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

        zvalid DXF document required)copy_strategy)docrV   copyr   rk   r-   r   bindrE   r   objects
add_object)r%   r3   r{   
new_handle
new_entitys        r'   duplicate_entityzEntityDB.duplicate_entity   sw     jj= ==%%'
 &, G
 *
Z%j),KK"":.r)   c           
     Z   | j                   du sJ d       g }| j                         5 }| j                         D ]  \  }}t        |      sG|j	                  t
        j                  d|j                          d| d       |j                  |       ||j                  j                  d      k7  swd| j                  |<   |j                  |       |j                  |        	 ddd       | j                          |D ]  }|j                  j                  d      }|4|j	                  t
        j                  d|j                          d	       Tt        |      r|d
k(  r7|j	                  t
        j                  d|j                          d| d       || |<    y# 1 sw Y   xY w)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.rC   )r=   trashcanr_   r
   fixed_errorr   INVALID_ENTITY_HANDLEri   r+   rk   r/   r"   appendpurge)r%   auditoradd_entitiestrashr-   r3   s         r'   auditzEntityDB.audit   s    {{e#:%::#]]_ 	0"&**, 0&v.'''=="1&..2B1C D##)(*A!C ( 
 IIf%VZZ^^H55 .2DNN6*IIf% ''/0	0$ 	

" 	"FZZ^^H-F~###99-fnn.>-? @, - $ 
 "6*fm###99-fnn.>-? @%h&=? $ 
 !DL!	")	0 	0s   BF!03F!!F*c                ,    t         j                  |       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              #  T   K   | j                         }| |j                          yw)zoReturns a new trashcan in context manager mode, trashcan will be
        emptied when leaving context.
        N)r   r2   )r%   	trashcan_s     r'   r   zEntityDB.trashcan  s'     
 %%'	 	s   &(c                    | j                   }|j                         D cg c]  \  }}|j                  r| }}}|D ]  }||=  yc c}}w )z^Remove all destroyed entities from database, but does not empty the
        trashcan.
        N)r"   r_   r0   )r%   r&   r-   r3   dead_handless        r'   r   zEntityDB.purge  sL    
 ^^57XXZW>66vWW" 	F6
	 Xs
   AAc                B    t        d | j                         D              S )Nc              3  <   K   | ]  }|j                           y wr!   )ri   )rZ   r3   s     r'   r[   z,EntityDB.dxf_types_in_use.<locals>.<genexpr>*  s     @6>>#@s   )r#   rc   r>   s    r'   dxf_types_in_usezEntityDB.dxf_types_in_use)  s    @$++-@@@r)   c                    || j                   v ry| j                  |       ||j                  _        | j	                  |       y)z|Try to reset the entity handle to a certain value.
        Returns ``True`` if successful and ``False`` otherwise.

        FT)r"   ru   rk   r-   r+   rn   s      r'   reset_handlezEntityDB.reset_handle,  s:    
 T^^#V"

r)   c                X    t        d | j                  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                   s|  y wr!   rf   rZ   rv   s     r'   r[   z!EntityDB.query.<locals>.<genexpr>C  s     M!!**AM   )r   r"   rc   )r%   querys     r'   r   zEntityDB.query8  s$     Mt~~'<'<'>MuUUr)   NreturnNone)r-   r4   r   r   )r-   r4   r3   r   r   r   )r-   r4   r   r   r-   r4   r   boolr   int)r   zIterator[str])r-   r4   r   zOptional[DXFEntity])r   r4   )r   zIterable[str])r   Iterable[DXFEntity])r   zIterable[tuple[str, DXFEntity]]r3   r   r   r   )r3   r   r   r   )r   r   )r   r   )r   zset[str])r3   r   r-   r4   r   r   )*)r   r4   r   r   )r5   r6   r7   r8   r:   r(   r@   rH   rJ   rL   rO   rR   r/   rV   rQ   rc   r_   r+   rq   ru   r   r   r   r   r   r   r   r   r   r9   r)   r'   r   r   $   s    " "8"&
(#(#*;;
6.20"d'  A
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ddZy)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.

    Nc                F    |rt        d |D              | _        y g | _        y )Nc              3  :   K   | ]  }|j                   s|  y wr!   rf   r   s     r'   r[   z'EntitySpace.__init__.<locals>.<genexpr>S  s     3q

3r   listentities)r%   r   s     r'   r(   zEntitySpace.__init__Q  s#    7?D3H33 	EG 	r)   c                (    d | j                   D        S )z5Iterable of all entities, filters destroyed entities.c              3  :   K   | ]  }|j                   s|  y wr!   rf   r   s     r'   r[   z'EntitySpace.__iter__.<locals>.<genexpr>X  s     7aAJJ7r   r   r>   s    r'   rR   zEntitySpace.__iter__V  s    74==77r)   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'   r@   zEntitySpace.__getitem__Z  s     }}U##r)   c                ,    t        | j                        S )z/Count of entities including destroyed entities.)rN   r   r>   s    r'   rO   zEntitySpace.__len__f  s    4==!!r)   c                l    t        t              sJ t                     t        fd| D              S )z@``True`` if `handle` is present, does filter destroyed entities.c              3  P   K   | ]  }|j                   j                  k(    y wr!   )rk   r-   )rZ   rv   r-   s     r'   r[   z)EntitySpace.has_handle.<locals>.<genexpr>m  s     8a155<<6)8s   #&)rE   r4   rF   anyr,   s    `r'   
has_handlezEntitySpace.has_handlej  s-    &#&4V4&84888r)   c                $    t        |       | _        y)z0Remove all destroyed entities from entity space.Nr   r>   s    r'   r   zEntitySpace.purgeo  s    T
r)   c                    t        |t              sJ t        |             |j                  sJ d       | j                  j                  |       y)zAdd `entity`.z Can not store destroyed entitiesN)rE   r   rF   r0   r   r   rp   s     r'   r+   zEntitySpace.adds  s?    &),:d6l:,B BBV$r)   c                4    |D ]  }| j                  |        y)zAdd multiple `entities`.N)r+   )r%   r   r3   s      r'   extendzEntitySpace.extendy  s     	FHHV	r)   c                F    t        |       D ]  }|j                  |        y)zRExport all entities into DXF file by `tagwriter`.

        (internal API)
        N)iter
export_dxf)r%   	tagwriterr3   s      r'   r   zEntitySpace.export_dxf~  s%    
 4j 	)Fi(	)r)   c                :    | j                   j                  |       y)zRemove `entity`.N)r   removerp   s     r'   r   zEntitySpace.remove  s    V$r)   c                "    t               | _        y)zRemove all entities.Nr   r>   s    r'   r2   zEntitySpace.clear  s     r)   c                8    | j                   j                  |      S r!   )r   popr   s     r'   r   zEntitySpace.pop  s    }}  ''r)   c                <    | j                   j                  ||       y r!   )r   insert)r%   r   r3   s      r'   r   zEntitySpace.insert  s    UF+r)   c                X   |j                   j                  }g }| D ]X  }|j                  j                  }| ||      us$|j	                  t
        j                  d| d       |j                  |       Z |sy |D ]-  }| j                  j                  |       |j                          / y )Nr   z8 with a conflicting handle and without a database entry.)entitydbr/   rk   r-   r   r   REMOVED_INVALID_DXF_OBJECTr   r   r   _silent_kill)r%   r   db_getr   r3   r-   s         r'   r   zEntitySpace.audit  s    !!%%!#  	%FZZ&&FVF^+ ##99%fX .& '
 V$	%   	"FMM  ( !		"r)   r!   )r   zOptional[Iterable[DXFEntity]])r   zIterator[DXFEntity])r   r   r   r   r   )r   r   r   r   )r   r   r   r   r   ))r   r   r   r   )r   r   r3   r   r   r   )r   r   r   r   )r5   r6   r7   r8   r(   rR   r@   rO   r   r   r+   r   r   r   r2   r   r   r   r9   r)   r'   r   r   F  sM    

8
$"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   rj   r   r   r9   r)   r'   <module>r      s]    #  & . - . + + 3 " # ,7	 _V _VD	j" j"r)   