diff --git a/src/blenderbim/blenderbim/bim/__init__.py b/src/blenderbim/blenderbim/bim/__init__.py index f6532798c6..8d0c3d33da 100644 --- a/src/blenderbim/blenderbim/bim/__init__.py +++ b/src/blenderbim/blenderbim/bim/__init__.py @@ -95,6 +95,7 @@ classes = [ operator.SelectURIAttribute, operator.EditBlenderCollection, operator.BIM_OT_open_webbrowser, + operator.BIM_OT_show_description, prop.StrProperty, operator.BIM_OT_enum_property_search, # /!\ Register AFTER prop.StrProperty prop.ObjProperty, diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py index dcf1ea36d6..7f0440f7d4 100644 --- a/src/blenderbim/blenderbim/bim/helper.py +++ b/src/blenderbim/blenderbim/bim/helper.py @@ -26,6 +26,7 @@ import ifcopenshell.util.attribute from mathutils import geometry from mathutils import Vector from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.prop import get_attribute_description, get_predefined_type_description def draw_attributes(props, layout, copy_operator=None): @@ -100,9 +101,20 @@ def import_attribute(attribute, props, data, callback=None): elif data_type == "float": new.float_value = 0.0 if new.is_null else data[attribute.name()] elif data_type == "enum": - new.enum_items = json.dumps(ifcopenshell.util.attribute.get_enum_items(attribute)) + enum_items = ifcopenshell.util.attribute.get_enum_items(attribute) + new.enum_items = json.dumps(enum_items) + new.enum_descriptions.clear() + if isinstance(enum_items, dict): + enum_items = enum_items.keys() + for enum_item in enum_items: + new_enum_description = new.enum_descriptions.add() + # TODO this only supports predefined type enums. Add support for other types of enums ? + new_enum_description.name = get_predefined_type_description(data["type"], enum_item) or "" if data[attribute.name()]: new.enum_value = data[attribute.name()] + description = get_attribute_description(data["type"], attribute.name()) + if description: + new.description = description def export_attributes(props, callback=None): diff --git a/src/blenderbim/blenderbim/bim/operator.py b/src/blenderbim/blenderbim/bim/operator.py index 5097257704..e1ac1f7308 100644 --- a/src/blenderbim/blenderbim/bim/operator.py +++ b/src/blenderbim/blenderbim/bim/operator.py @@ -683,3 +683,16 @@ class EditBlenderCollection(bpy.types.Operator): else: getattr(context.bim_prop_group, self.collection).remove(self.index) return {"FINISHED"} + + +class BIM_OT_show_description(bpy.types.Operator): + bl_idname = "bim.show_description" + bl_label = "Description" + description: bpy.props.StringProperty() + + def execute(self, context): + return {"FINISHED"} + + @classmethod + def description(cls, context, properties): + return properties.description diff --git a/src/blenderbim/blenderbim/bim/prop.py b/src/blenderbim/blenderbim/bim/prop.py index 69b442ccc4..c7c27c1dbd 100644 --- a/src/blenderbim/blenderbim/bim/prop.py +++ b/src/blenderbim/blenderbim/bim/prop.py @@ -128,10 +128,26 @@ def get_predefined_type_description(entity, predefined_type): return get_predefined_type_doc(schema, entity, predefined_type) +HARDCODED_ATTRIBUTE_DESCRIPTIONS = { + "GlobalId": "Unique Entity Identifier", + "Name": "TODO", + "Description": "TODO", + "PredefinedType": "TODO", + "ObjectType": "TODO", + "Tag": "TODO", +} + + def get_attribute_description(entity, attribute): - schema = tool.Ifc.get_schema() - if schema is not None: - return get_attribute_doc(schema, entity, attribute) + doc = HARDCODED_ATTRIBUTE_DESCRIPTIONS.get(attribute, None) + if doc is None: + schema = tool.Ifc.get_schema() + if schema is not None: + try: + doc = get_attribute_doc(schema, entity, attribute) + except KeyError: # This entity doesn't have any attribute or doesn't implement this attribute + pass + return doc def get_property_set_docs(pset): @@ -174,6 +190,10 @@ def get_attribute_enum_values(prop, context): ) ) + items = [ + (identifier, name, prop.enum_descriptions[i].name) for i, (identifier, name, _) in enumerate(items) + ] + return items @@ -238,12 +258,14 @@ def update_attribute_value(self, context): class Attribute(PropertyGroup): name: StringProperty(name="Name") + description: StringProperty(name="Description") data_type: StringProperty(name="Data Type") string_value: StringProperty(name="Value", update=update_attribute_value) bool_value: BoolProperty(name="Value", update=update_attribute_value) int_value: IntProperty(name="Value", update=update_attribute_value) float_value: FloatProperty(name="Value", update=update_attribute_value) enum_items: StringProperty(name="Value") + enum_descriptions: CollectionProperty(type=StrProperty) enum_value: EnumProperty(items=get_attribute_enum_values, name="Value", update=update_attribute_value) is_null: BoolProperty(name="Is Null") is_optional: BoolProperty(name="Is Optional") diff --git a/src/blenderbim/blenderbim/bim/ui.py b/src/blenderbim/blenderbim/bim/ui.py index 6b07d9a131..6574eb6469 100644 --- a/src/blenderbim/blenderbim/bim/ui.py +++ b/src/blenderbim/blenderbim/bim/ui.py @@ -394,8 +394,17 @@ def draw_custom_context_menu(self, context): url = get_ifc_entity_doc_url(prop_value) if not bool(url): url = get_property_set_doc_url(prop_value) + + description = getattr(context.button_pointer, "description", None) + if not url and not description: + return + layout = self.layout + layout.separator() if url: - layout = self.layout - layout.separator() url_op = layout.operator("bim.open_webbrowser", icon="URL", text="Online IFC Documentation") url_op.url = url + if description: + op_description = layout.operator( + "bim.show_description", text="Hover for Description", icon="INFO", emboss=False + ) + op_description.description = description