You can now customise the data columns shown in the work task tree

This commit is contained in:
Dion Moult
2021-06-22 19:32:59 +10:00
parent 2c49b3bde8
commit e863015e85
4 changed files with 150 additions and 35 deletions
@@ -73,6 +73,8 @@ classes = (
operator.BlenderBIM_DatePicker, operator.BlenderBIM_DatePicker,
operator.BlenderBIM_DatePickerSetDate, operator.BlenderBIM_DatePickerSetDate,
operator.BlenderBIM_RedrawDatePicker, operator.BlenderBIM_RedrawDatePicker,
operator.AddTaskColumn,
operator.RemoveTaskColumn,
prop.WorkPlan, prop.WorkPlan,
prop.BIMWorkPlanProperties, prop.BIMWorkPlanProperties,
prop.Task, prop.Task,
@@ -85,6 +87,7 @@ classes = (
ui.BIM_PT_work_plans, ui.BIM_PT_work_plans,
ui.BIM_PT_work_schedules, ui.BIM_PT_work_schedules,
ui.BIM_PT_work_calendars, ui.BIM_PT_work_calendars,
ui.BIM_UL_task_columns,
ui.BIM_UL_tasks, ui.BIM_UL_tasks,
) )
@@ -1705,3 +1705,28 @@ class RecalculateSchedule(bpy.types.Operator):
) )
Data.load(self.file) Data.load(self.file)
return {"FINISHED"} return {"FINISHED"}
class AddTaskColumn(bpy.types.Operator):
bl_idname = "bim.add_task_column"
bl_label = "Add Task Column"
type: bpy.props.StringProperty()
name: bpy.props.StringProperty()
def execute(self, context):
self.props = context.scene.BIMWorkScheduleProperties
new = self.props.columns.add()
name, data_type = self.name.split("/")
new.name = f"{self.type}.{name}"
new.data_type = data_type
return {"FINISHED"}
class RemoveTaskColumn(bpy.types.Operator):
bl_idname = "bim.remove_task_column"
bl_label = "Remove Task Column"
def execute(self, context):
self.props = context.scene.BIMWorkScheduleProperties
self.props.columns.remove(self.props.active_column_index)
return {"FINISHED"}
@@ -1,5 +1,6 @@
import bpy import bpy
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.attribute
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.sequence.data import Data from ifcopenshell.api.sequence.data import Data
from blenderbim.bim.prop import StrProperty, Attribute from blenderbim.bim.prop import StrProperty, Attribute
@@ -17,6 +18,53 @@ from bpy.props import (
) )
taskcolumns_enum = []
tasktimecolumns_enum = []
def purge():
global taskcolumns_enum
global tasktimecolumns_enum
taskcolumns_enum = []
tasktimecolumns_enum = []
def getTaskColumns(self, context):
global taskcolumns_enum
if not len(taskcolumns_enum) and IfcStore.get_schema():
taskcolumns_enum.extend(
[
(a.name() + "/" + ifcopenshell.util.attribute.get_primitive_type(a), a.name(), "")
for a in IfcStore.get_schema().declaration_by_name("IfcTask").all_attributes()
if ifcopenshell.util.attribute.get_primitive_type(a)
in ["string", "float", "integer", "boolean", "enum"]
]
)
return taskcolumns_enum
def getTaskTimeColumns(self, context):
global tasktimecolumns_enum
if not len(tasktimecolumns_enum) and IfcStore.get_schema():
tasktimecolumns_enum.extend(
[
(a.name() + "/" + ifcopenshell.util.attribute.get_primitive_type(a), a.name(), "")
for a in IfcStore.get_schema().declaration_by_name("IfcTaskTime").all_attributes()
if ifcopenshell.util.attribute.get_primitive_type(a)
in ["string", "float", "integer", "boolean", "enum"]
]
)
return tasktimecolumns_enum
def getWorkSchedules(self, context):
return [(str(k), v["Name"], "") for k, v in Data.work_schedules.items()]
def getWorkCalendars(self, context):
return [(str(k), v["Name"], "") for k, v in Data.work_calendars.items()]
def updateTaskName(self, context): def updateTaskName(self, context):
props = context.scene.BIMWorkScheduleProperties props = context.scene.BIMWorkScheduleProperties
if not props.is_task_update_enabled or self.name == "Unnamed": if not props.is_task_update_enabled or self.name == "Unnamed":
@@ -160,17 +208,6 @@ def updateVisualisationStartFinish(self, context, startfinish):
setattr(self, startfinish, canonical_value) setattr(self, startfinish, canonical_value)
workschedule_enum = []
def getWorkSchedules(self, context):
return [(str(k), v["Name"], "") for k, v in Data.work_schedules.items()]
def getWorkCalendars(self, context):
return [(str(k), v["Name"], "") for k, v in Data.work_calendars.items()]
class Task(PropertyGroup): class Task(PropertyGroup):
name: StringProperty(name="Name", update=updateTaskName) name: StringProperty(name="Name", update=updateTaskName)
identification: StringProperty(name="Identification", update=updateTaskIdentification) identification: StringProperty(name="Identification", update=updateTaskIdentification)
@@ -216,8 +253,17 @@ class BIMWorkScheduleProperties(PropertyGroup):
active_task_id: IntProperty(name="Active Task Id") active_task_id: IntProperty(name="Active Task Id")
task_attributes: CollectionProperty(name="Task Attributes", type=Attribute) task_attributes: CollectionProperty(name="Task Attributes", type=Attribute)
should_show_visualisation_ui: BoolProperty(name="Should Show Visualisation UI", default=False) should_show_visualisation_ui: BoolProperty(name="Should Show Visualisation UI", default=False)
should_show_times: BoolProperty(name="Should Show Times", default=False) should_show_column_ui: BoolProperty(name="Should Show Column UI", default=False)
should_show_calendars: BoolProperty(name="Should Show Calendars", default=False) columns: CollectionProperty(name="Columns", type=Attribute)
active_column_index: IntProperty(name="Active Column Index")
task_columns: EnumProperty(items=getTaskColumns, name="Task Columns")
task_time_columns: EnumProperty(items=getTaskTimeColumns, name="Task Time Columns")
other_columns: EnumProperty(
items=[
("Controls.Calendar", "Calendar", ""),
],
name="Special Columns",
)
active_task_time_id: IntProperty(name="Active Task Id") active_task_time_id: IntProperty(name="Active Task Id")
task_time_attributes: CollectionProperty(name="Task Time Attributes", type=Attribute) task_time_attributes: CollectionProperty(name="Task Time Attributes", type=Attribute)
contracted_tasks: StringProperty(name="Contracted Task Items", default="[]") contracted_tasks: StringProperty(name="Contracted Task Items", default="[]")
@@ -111,8 +111,7 @@ class BIM_PT_work_schedules(Panel):
if self.props.editing_type == "WORK_SCHEDULE": if self.props.editing_type == "WORK_SCHEDULE":
row.operator("bim.edit_work_schedule", text="", icon="CHECKMARK") row.operator("bim.edit_work_schedule", text="", icon="CHECKMARK")
elif self.props.editing_type == "TASKS": elif self.props.editing_type == "TASKS":
row.prop(self.props, "should_show_times", text="", icon="TIME") row.prop(self.props, "should_show_column_ui", text="", icon="SHORTDISPLAY")
row.prop(self.props, "should_show_calendars", text="", icon="VIEW_ORTHO")
row.prop(self.props, "should_show_visualisation_ui", text="", icon="CAMERA_STEREO") row.prop(self.props, "should_show_visualisation_ui", text="", icon="CAMERA_STEREO")
row.operator("bim.generate_gantt_chart", text="", icon="NLA").work_schedule = work_schedule_id row.operator("bim.generate_gantt_chart", text="", icon="NLA").work_schedule = work_schedule_id
row.operator("bim.recalculate_schedule", text="", icon="FILE_REFRESH").work_schedule = work_schedule_id row.operator("bim.recalculate_schedule", text="", icon="FILE_REFRESH").work_schedule = work_schedule_id
@@ -128,6 +127,8 @@ class BIM_PT_work_schedules(Panel):
row.operator("bim.remove_work_schedule", text="", icon="X").work_schedule = work_schedule_id row.operator("bim.remove_work_schedule", text="", icon="X").work_schedule = work_schedule_id
if self.props.active_work_schedule_id == work_schedule_id: if self.props.active_work_schedule_id == work_schedule_id:
if self.props.should_show_column_ui:
self.draw_column_ui()
if self.props.should_show_visualisation_ui: if self.props.should_show_visualisation_ui:
self.draw_visualisation_ui() self.draw_visualisation_ui()
if self.props.editing_type == "WORK_SCHEDULE": if self.props.editing_type == "WORK_SCHEDULE":
@@ -135,6 +136,28 @@ class BIM_PT_work_schedules(Panel):
elif self.props.editing_type == "TASKS": elif self.props.editing_type == "TASKS":
self.draw_editable_task_ui(work_schedule_id) self.draw_editable_task_ui(work_schedule_id)
def draw_column_ui(self):
row = self.layout.row(align=True)
row.prop(self.props, "task_columns", text="")
op = row.operator("bim.add_task_column", text="", icon="ADD")
op.type = "IfcTask"
op.name = self.props.task_columns
row = self.layout.row(align=True)
row.prop(self.props, "task_time_columns", text="")
op = row.operator("bim.add_task_column", text="", icon="ADD")
op.type = "IfcTaskTime"
op.name = self.props.task_time_columns
row = self.layout.row(align=True)
row.prop(self.props, "other_columns", text="")
op = row.operator("bim.add_task_column", text="", icon="ADD")
type, name = self.props.other_columns.split(".")
op.type = type
op.name = f"{name}/string"
self.layout.template_list("BIM_UL_task_columns", "", self.props, "columns", self.props, "active_column_index")
def draw_visualisation_ui(self): def draw_visualisation_ui(self):
row = self.layout.row(align=True) row = self.layout.row(align=True)
target_prop = "BIMWorkScheduleProperties.visualisation_start" target_prop = "BIMWorkScheduleProperties.visualisation_start"
@@ -260,10 +283,19 @@ class BIM_PT_work_schedules(Panel):
blenderbim.bim.helper.draw_attributes(self.props.task_time_attributes, self.layout) blenderbim.bim.helper.draw_attributes(self.props.task_time_attributes, self.layout)
class BIM_UL_task_columns(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
if item:
row = layout.row(align=True)
row.prop(item, "name", emboss=False, text="")
row.operator("bim.remove_task_column", text="", icon="X")
class BIM_UL_tasks(UIList): class BIM_UL_tasks(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
if item: if item:
props = context.scene.BIMWorkScheduleProperties props = context.scene.BIMWorkScheduleProperties
task = IfcStore.get_file().by_id(item.ifc_definition_id)
row = layout.row(align=True) row = layout.row(align=True)
for i in range(0, item.level_index): for i in range(0, item.level_index):
row.label(text="", icon="BLANK1") row.label(text="", icon="BLANK1")
@@ -281,27 +313,36 @@ class BIM_UL_tasks(UIList):
row.prop(item, "identification", emboss=False, text="") row.prop(item, "identification", emboss=False, text="")
row.prop(item, "name", emboss=False, text="") row.prop(item, "name", emboss=False, text="")
if props.should_show_times: for column in props.columns:
if item.derived_start: if column.name == "IfcTaskTime.ScheduleStart":
row.label(text=item.derived_start + "*") if item.derived_start:
row.label(text=item.derived_start + "*")
else:
row.prop(item, "start", emboss=False, text="")
elif column.name == "IfcTaskTime.ScheduleFinish":
if item.derived_finish:
row.label(text=item.derived_finish + "*")
else:
row.prop(item, "finish", emboss=False, text="")
elif column.name == "IfcTaskTime.ScheduleDuration":
if item.derived_duration:
row.label(text=item.derived_duration + "*")
else:
row.prop(item, "duration", emboss=False, text="")
elif column.name == "Controls.Calendar":
if item.derived_calendar:
row.label(text=item.derived_calendar + "*")
else:
row.label(text=item.calendar or "-")
else: else:
row.prop(item, "start", emboss=False, text="") ifc_class, name = column.name.split(".")
if ifc_class == "IfcTask":
if item.derived_finish: value = getattr(task, name)
row.label(text=item.derived_finish + "*") elif ifc_class == "IfcTaskTime":
else: value = getattr(task.TaskTime, name) if task.TaskTime else None
row.prop(item, "finish", emboss=False, text="") if value is None:
value = "-"
if item.derived_duration: row.label(text=str(value))
row.label(text=item.derived_duration + "*")
else:
row.prop(item, "duration", emboss=False, text="")
if props.should_show_calendars:
if item.derived_calendar:
row.label(text=item.derived_calendar + "*")
else:
row.label(text=item.calendar or "-")
if context.active_object: if context.active_object:
oprops = context.active_object.BIMObjectProperties oprops = context.active_object.BIMObjectProperties