# Purpose: entity section # Created: 13.03.2011 # Copyright (c) 2011-2018, Manfred Moitzi # License: MIT License from typing import TYPE_CHECKING, Iterable, Iterator import abc from ezdxf.lldxf.tags import DXFStructureError, DXFValueError from ezdxf.lldxf.extendedtags import get_xtags_linker from ezdxf.query import EntityQuery if TYPE_CHECKING: # import forward declarations from ezdxf.eztypes import ExtendedTags, TagWriter, DXFEntity, EntitySpace, Drawing, DXFFactoryType, EntityDB class AbstractSection: name = 'abstract' # type: str def __init__(self, entity_space: 'EntitySpace', entities: Iterable['ExtendedTags'], drawing: 'Drawing'): self._entity_space = entity_space self.drawing = drawing if entities is not None: self._build(iter(entities)) @property def dxffactory(self) -> 'DXFFactoryType': return self.drawing.dxffactory @property def entitydb(self) -> 'EntityDB': return self.drawing.entitydb def get_entity_space(self) -> 'EntitySpace': return self._entity_space def _build(self, entities: Iterator['ExtendedTags']) -> None: section_head = next(entities) if section_head[0] != (0, 'SECTION') or section_head[1] != (2, self.name.upper()): raise DXFStructureError("Critical structure error in {} section.".format(self.name.upper())) linked_tags = get_xtags_linker() for entity in entities: if not linked_tags(entity): # don't store linked entities (VERTEX, ATTRIB, SEQEND) in entity space self._entity_space.store_tags(entity) def write(self, tagwriter: 'TagWriter') -> None: tagwriter.write_str(" 0\nSECTION\n 2\n%s\n" % self.name.upper()) self._entity_space.write(tagwriter) tagwriter.write_tag2(0, "ENDSEC") def create_new_dxf_entity(self, _type: str, dxfattribs: dict) -> 'DXFEntity': """ Create new DXF entity add it to th entity database and add it to the entity space. """ dxf_entity = self.dxffactory.create_db_entry(_type, dxfattribs) self._entity_space.add_handle(dxf_entity.dxf.handle) return dxf_entity def add_handle(self, handle: str) -> None: self._entity_space.add_handle(handle) def remove_handle(self, handle: str) -> None: try: self._entity_space.remove(handle) except ValueError: raise DXFValueError('Handle #{} not in entity space.'.format(handle)) def delete_entity(self, entity: 'DXFEntity') -> None: self.remove_handle(entity.dxf.handle) self.entitydb.delete_entity(entity) # start of public interface @abc.abstractmethod def __iter__(self) -> Iterable['DXFEntity']: pass def __len__(self) -> int: return len(self._entity_space) def __contains__(self, handle: str) -> bool: return handle in self._entity_space def query(self, query: str = '*') -> EntityQuery: return EntityQuery(iter(self), query) def delete_all_entities(self) -> None: """ Delete all entities. """ self._entity_space.delete_all_entities() # end of public interface