Implement cost identification numbers and big cleanup to cost schedule UI

This commit is contained in:
Dion Moult
2021-08-13 18:01:23 +10:00
parent 26f800331e
commit 2f3c79a0e6
5 changed files with 87 additions and 47 deletions
@@ -103,6 +103,7 @@ class EnableEditingCostItems(bpy.types.Operator):
if context.preferences.addons["blenderbim"].preferences.should_play_chaching_sound:
self.play_chaching_sound() # lol
self.props = context.scene.BIMCostProperties
self.props.is_cost_update_enabled = False
self.props.active_cost_schedule_id = self.cost_schedule
while len(self.props.cost_items) > 0:
self.props.cost_items.remove(0)
@@ -111,6 +112,7 @@ class EnableEditingCostItems(bpy.types.Operator):
for related_object_id in Data.cost_schedules[self.cost_schedule]["Controls"]:
self.create_new_cost_item_li(related_object_id, 0)
self.props.is_editing = "COST_ITEMS"
self.props.is_cost_update_enabled = True
return {"FINISHED"}
def play_chaching_sound(self):
@@ -134,6 +136,7 @@ class EnableEditingCostItems(bpy.types.Operator):
new = self.props.cost_items.add()
new.ifc_definition_id = related_object_id
new.name = cost_item["Name"] or "Unnamed"
new.identification = cost_item["Identification"] or "XXX"
new.is_expanded = related_object_id not in self.contracted_cost_items
new.level_index = level_index
if cost_item["IsNestedBy"]:
@@ -128,11 +128,27 @@ def update_cost_item_index(self, context):
bpy.ops.bim.load_cost_item_quantities()
def updateCostItemName(self, context):
if self.name == "Unnamed":
def updateCostItemIdentification(self, context):
props = context.scene.BIMCostProperties
if not props.is_cost_update_enabled or self.identification == "XXX":
return
self.file = IfcStore.get_file()
ifcopenshell.api.run(
"cost.edit_cost_item",
self.file,
**{"cost_item": self.file.by_id(self.ifc_definition_id), "attributes": {"Identification": self.identification}},
)
Data.load(self.file)
if props.active_cost_item_id == self.ifc_definition_id:
attribute = props.cost_item_attributes.get("Identification")
attribute.string_value = self.identification
def updateCostItemName(self, context):
props = context.scene.BIMCostProperties
if not props.is_cost_update_enabled or self.name == "Unnamed":
return
self.file = IfcStore.get_file()
ifcopenshell.api.run(
"cost.edit_cost_item",
self.file,
@@ -146,6 +162,7 @@ def updateCostItemName(self, context):
class CostItem(PropertyGroup):
name: StringProperty(name="Name", update=updateCostItemName)
identification: StringProperty(name="Identification", update=updateCostItemIdentification)
ifc_definition_id: IntProperty(name="IFC Definition ID")
has_children: BoolProperty(name="Has Children")
is_expanded: BoolProperty(name="Is Expanded")
@@ -159,6 +176,7 @@ class CostItemQuantity(PropertyGroup):
class BIMCostProperties(PropertyGroup):
is_cost_update_enabled: BoolProperty(name="Is Cost Update Enabled", default=True)
cost_schedule_attributes: CollectionProperty(name="Cost Schedule Attributes", type=Attribute)
is_editing: StringProperty(name="Is Editing")
active_cost_schedule_id: IntProperty(name="Active Cost Schedule Id")
+46 -30
View File
@@ -76,6 +76,32 @@ class BIM_PT_cost_schedules(Panel):
row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
def draw_editable_cost_item_ui(self, cost_schedule_id):
row = self.layout.row(align=True)
row.alignment = "RIGHT"
ifc_definition_id = None
if self.props.cost_items and self.props.active_cost_item_index < len(self.props.cost_items):
ifc_definition_id = self.props.cost_items[self.props.active_cost_item_index].ifc_definition_id
if ifc_definition_id:
if Data.cost_schedules[self.props.active_cost_schedule_id]["PredefinedType"] != "SCHEDULEOFRATES":
op = row.operator("bim.enable_editing_cost_item_quantities", text="", icon="PROPERTIES")
op.cost_item = ifc_definition_id
op = row.operator("bim.enable_editing_cost_item_values", text="", icon="DISC")
op.cost_item = ifc_definition_id
row.operator("bim.add_cost_item", text="", icon="ADD").cost_item = ifc_definition_id
if self.props.active_cost_item_id == ifc_definition_id:
if self.props.cost_item_editing_type == "ATTRIBUTES":
row.operator("bim.edit_cost_item", text="", icon="CHECKMARK")
row.operator("bim.disable_editing_cost_item", text="", icon="CANCEL")
else:
op = row.operator("bim.enable_editing_cost_item", text="", icon="GREASEPENCIL")
op.cost_item = ifc_definition_id
row.operator("bim.remove_cost_item", text="", icon="X").cost_item = ifc_definition_id
self.layout.template_list(
"BIM_UL_cost_items",
"",
@@ -348,7 +374,7 @@ class BIM_PT_cost_item_quantities(Panel):
class BIM_UL_cost_items(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
if item:
props = context.scene.BIMCostProperties
self.props = context.scene.BIMCostProperties
cost_item = Data.cost_items[item.ifc_definition_id]
row = layout.row(align=True)
@@ -366,40 +392,30 @@ class BIM_UL_cost_items(UIList):
else:
row.label(text="", icon="DOT")
split1 = row.split(factor=0.7)
split1.prop(item, "name", emboss=False, text="")
split1 = row.split(factor=0.1)
split1.prop(item, "identification", emboss=False, text="")
split2 = split1.split(factor=0.5)
split2.alignment = "RIGHT"
split2.prop(item, "name", emboss=False, text="")
if Data.cost_schedules[props.active_cost_schedule_id]["PredefinedType"] != "SCHEDULEOFRATES":
op = row.operator("bim.enable_editing_cost_item_quantities", text="", icon="PROPERTIES")
op.cost_item = item.ifc_definition_id
row.label(text="{0:.2f}".format(cost_item["TotalCostQuantity"]) + f" ({cost_item['UnitSymbol']})")
if Data.cost_schedules[self.props.active_cost_schedule_id]["PredefinedType"] != "SCHEDULEOFRATES":
split2.label(text="{0:.2f}".format(cost_item["TotalCostQuantity"]) + f" ({cost_item['UnitSymbol'] or '?'})")
op = row.operator("bim.enable_editing_cost_item_values", text="", icon="DISC")
op.cost_item = item.ifc_definition_id
row.label(text="{0:.2f}".format(cost_item["TotalAppliedValue"]))
split2.label(text="{0:.2f}".format(cost_item["TotalAppliedValue"]))
for column in props.columns:
row.label(text=str(cost_item["CategoryValues"].get(column.name, "-")))
for column in self.props.columns:
split2.label(text=str(cost_item["CategoryValues"].get(column.name, "-")))
row.label(text="{0:.2f}".format(cost_item["TotalCostValue"]), icon="CON_TRANSLIKE")
split2.label(text="{0:.2f}".format(cost_item["TotalCostValue"]))
self.draw_buttons(split2, item, cost_item)
if props.active_cost_item_id == item.ifc_definition_id:
if props.cost_item_editing_type == "ATTRIBUTES":
row.operator("bim.edit_cost_item", text="", icon="CHECKMARK")
row.operator("bim.disable_editing_cost_item", text="", icon="CANCEL")
elif props.active_cost_item_id:
if props.cost_item_editing_type == "VALUES":
op = row.operator("bim.copy_cost_item_values", text="", icon="COPYDOWN")
op.source = props.active_cost_item_id
op.destination = item.ifc_definition_id
row.operator("bim.add_cost_item", text="", icon="ADD").cost_item = item.ifc_definition_id
row.operator("bim.remove_cost_item", text="", icon="X").cost_item = item.ifc_definition_id
else:
row.operator(
"bim.enable_editing_cost_item", text="", icon="GREASEPENCIL"
).cost_item = item.ifc_definition_id
row.operator("bim.add_cost_item", text="", icon="ADD").cost_item = item.ifc_definition_id
row.operator("bim.remove_cost_item", text="", icon="X").cost_item = item.ifc_definition_id
def draw_buttons(self, row, item, cost_item):
pass # TODO: reimplement somewhere with better UX
# elif self.props.active_cost_item_id:
# if self.props.cost_item_editing_type == "VALUES":
# op = row.operator("bim.copy_cost_item_values", text="", icon="COPYDOWN")
# op.source = self.props.active_cost_item_id
# op.destination = item.ifc_definition_id
class BIM_UL_cost_columns(UIList):