1# Copyright (c) 2019-2020 Manfred Moitzi 2# License: MIT License 3from typing import TYPE_CHECKING, Tuple 4from .dxfentity import DXFEntity, SubclassProcessor, DXFNamespace 5from ezdxf.lldxf.attributes import ( 6 DXFAttr, DXFAttributes, DefSubclass, group_code_mapping, 7) 8from ezdxf.lldxf.const import DXF2004, DXF2000 9from .factory import register_entity 10 11if TYPE_CHECKING: 12 from ezdxf.eztypes import Drawing, ExtendedTags, TagWriter 13 14__all__ = ['DXFClass'] 15 16class_def = DefSubclass(None, { 17 # Class DXF record name; always unique 18 'name': DXFAttr(1), 19 # C++ class name. Used to bind with software that defines object class 20 # behavior; always unique 21 'cpp_class_name': DXFAttr(2), 22 # Application name. Posted in Alert box when a class definition listed in 23 # this section is not currently loaded 24 'app_name': DXFAttr(3), 25 # Proxy capabilities flag. Bit-coded value that indicates the capabilities 26 # of this object as a proxy: 27 # 0 = No operations allowed (0) 28 # 1 = Erase allowed (0x1) 29 # 2 = Transform allowed (0x2) 30 # 4 = Color change allowed (0x4) 31 # 8 = Layer change allowed (0x8) 32 # 16 = Linetype change allowed (0x10) 33 # 32 = Linetype scale change allowed (0x20) 34 # 64 = Visibility change allowed (0x40) 35 # 128 = Cloning allowed (0x80) 36 # 256 = Lineweight change allowed (0x100) 37 # 512 = Plot Style Name change allowed (0x200) 38 # 895 = All operations except cloning allowed (0x37F) 39 # 1023 = All operations allowed (0x3FF) 40 # 1024 = Disables proxy warning dialog (0x400) 41 # 32768 = R13 format proxy (0x8000) 42 'flags': DXFAttr(90, default=0), 43 # Instance count for a custom class 44 'instance_count': DXFAttr(91, dxfversion=DXF2004, default=0), 45 # Was-a-proxy flag. Set to 1 if class was not loaded when this DXF file was 46 # created, and 0 otherwise 47 'was_a_proxy': DXFAttr(280, default=0), 48 # Is-an-entity flag. Set to 1 if class was derived from the AcDbEntity class 49 # and can reside in the BLOCKS or ENTITIES section. If 0, instances may 50 # appear only in the OBJECTS section 51 'is_an_entity': DXFAttr(281, default=0), 52}) 53class_def_group_codes = group_code_mapping(class_def) 54 55 56@register_entity 57class DXFClass(DXFEntity): 58 DXFTYPE = 'CLASS' 59 DXFATTRIBS = DXFAttributes(class_def) 60 MIN_DXF_VERSION_FOR_EXPORT = DXF2000 61 62 @classmethod 63 def new(cls, handle: str = None, owner: str = None, dxfattribs: dict = None, 64 doc: 'Drawing' = None) -> 'DXFClass': 65 """ New CLASS constructor - has no handle, no owner and do not need 66 document reference . 67 """ 68 dxf_class = cls() 69 dxf_class.doc = doc 70 dxfattribs = dxfattribs or {} 71 dxf_class.update_dxf_attribs(dxfattribs) 72 return dxf_class 73 74 def load_tags(self, tags: 'ExtendedTags', dxfversion=None) -> None: 75 """ Called by load constructor. CLASS is special. """ 76 if tags: 77 # do not process base class!!! 78 self.dxf = DXFNamespace(entity=self) 79 processor = SubclassProcessor(tags) 80 processor.fast_load_dxfattribs( 81 self.dxf, class_def_group_codes, 0, log=False) 82 83 def export_dxf(self, tagwriter: 'TagWriter'): 84 """ Do complete export here, because CLASS is special. """ 85 dxfversion = tagwriter.dxfversion 86 if dxfversion < DXF2000: 87 return 88 attribs = self.dxf 89 tagwriter.write_tag2(0, self.DXFTYPE) 90 attribs.export_dxf_attribs(tagwriter, [ 91 'name', 'cpp_class_name', 'app_name', 'flags', 'instance_count', 92 'was_a_proxy', 'is_an_entity', 93 ]) 94 95 @property 96 def key(self) -> Tuple[str, str]: 97 return self.dxf.name, self.dxf.cpp_class_name 98