mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Task trees can now be sorted by any attribute independent of the WBS
This commit is contained in:
@@ -75,6 +75,7 @@ classes = (
|
||||
operator.BlenderBIM_RedrawDatePicker,
|
||||
operator.AddTaskColumn,
|
||||
operator.RemoveTaskColumn,
|
||||
operator.SetTaskSortColumn,
|
||||
prop.WorkPlan,
|
||||
prop.BIMWorkPlanProperties,
|
||||
prop.Task,
|
||||
|
||||
@@ -244,10 +244,14 @@ class EnableEditingTasks(bpy.types.Operator):
|
||||
|
||||
self.contracted_tasks = json.loads(self.props.contracted_tasks)
|
||||
self.sort_keys = {
|
||||
i: Data.tasks[i]["Identification"] or "" for i in Data.work_schedules[self.work_schedule]["RelatedObjects"]
|
||||
i: self.get_sort_key(Data.tasks[i]) for i in Data.work_schedules[self.work_schedule]["RelatedObjects"]
|
||||
}
|
||||
|
||||
for related_object_id in sorted(self.sort_keys, key=self.natural_sort_key):
|
||||
related_object_ids = sorted(self.sort_keys, key=self.natural_sort_key)
|
||||
if self.props.is_sort_reversed:
|
||||
related_object_ids.reverse()
|
||||
|
||||
for related_object_id in related_object_ids:
|
||||
self.create_new_task_li(related_object_id, 0)
|
||||
bpy.ops.bim.load_task_properties()
|
||||
self.props.editing_type = "TASKS"
|
||||
@@ -262,10 +266,27 @@ class EnableEditingTasks(bpy.types.Operator):
|
||||
if task["RelatedObjects"]:
|
||||
new.has_children = True
|
||||
if new.is_expanded:
|
||||
self.sort_keys = {i: Data.tasks[i]["Identification"] or "" for i in task["RelatedObjects"]}
|
||||
for related_object_id in sorted(self.sort_keys, key=self.natural_sort_key):
|
||||
self.sort_keys = {i: self.get_sort_key(Data.tasks[i]) for i in task["RelatedObjects"]}
|
||||
related_object_ids = sorted(self.sort_keys, key=self.natural_sort_key)
|
||||
if self.props.is_sort_reversed:
|
||||
related_object_ids.reverse()
|
||||
for related_object_id in related_object_ids:
|
||||
self.create_new_task_li(related_object_id, level_index + 1)
|
||||
|
||||
def get_sort_key(self, task):
|
||||
# Sorting only applies to actual tasks, not the WBS
|
||||
if task["RelatedObjects"]:
|
||||
# Sorry for the hack
|
||||
return "0000000000" + (task["Identification"] or "")
|
||||
if not self.props.sort_column:
|
||||
return task["Identification"] or ""
|
||||
column_type, name = self.props.sort_column.split(".")
|
||||
if column_type == "IfcTask":
|
||||
return task.get(name)
|
||||
elif column_type == "IfcTaskTime" and task.get("TaskTime"):
|
||||
task_time = Data.task_times[task.get("TaskTime")].get(name)
|
||||
return task["Identification"] or ""
|
||||
|
||||
def natural_sort_key(self, i, _nsre=re.compile("([0-9]+)")):
|
||||
s = self.sort_keys[i]
|
||||
return [int(text) if text.isdigit() else text.lower() for text in _nsre.split(s)]
|
||||
@@ -1710,15 +1731,15 @@ class RecalculateSchedule(bpy.types.Operator):
|
||||
class AddTaskColumn(bpy.types.Operator):
|
||||
bl_idname = "bim.add_task_column"
|
||||
bl_label = "Add Task Column"
|
||||
type: bpy.props.StringProperty()
|
||||
column_type: bpy.props.StringProperty()
|
||||
name: bpy.props.StringProperty()
|
||||
data_type: 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
|
||||
new.name = f"{self.column_type}.{self.name}"
|
||||
new.data_type = self.data_type
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -1730,3 +1751,15 @@ class RemoveTaskColumn(bpy.types.Operator):
|
||||
self.props = context.scene.BIMWorkScheduleProperties
|
||||
self.props.columns.remove(self.props.active_column_index)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class SetTaskSortColumn(bpy.types.Operator):
|
||||
bl_idname = "bim.set_task_sort_column"
|
||||
bl_label = "Set Task Sort Column"
|
||||
column: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
self.props = context.scene.BIMWorkScheduleProperties
|
||||
self.props.sort_column = self.column
|
||||
bpy.ops.bim.enable_editing_tasks(work_schedule=self.props.active_work_schedule_id)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -256,6 +256,16 @@ class BIMWorkScheduleProperties(PropertyGroup):
|
||||
should_show_column_ui: BoolProperty(name="Should Show Column UI", default=False)
|
||||
columns: CollectionProperty(name="Columns", type=Attribute)
|
||||
active_column_index: IntProperty(name="Active Column Index")
|
||||
sort_column: StringProperty(name="Sort Column")
|
||||
is_sort_reversed: BoolProperty(name="Is Sort Reversed")
|
||||
column_types: EnumProperty(
|
||||
items=[
|
||||
("IfcTask", "IfcTask", ""),
|
||||
("IfcTaskTime", "IfcTaskTime", ""),
|
||||
("Special", "Special", ""),
|
||||
],
|
||||
name="Column Types",
|
||||
)
|
||||
task_columns: EnumProperty(items=getTaskColumns, name="Task Columns")
|
||||
task_time_columns: EnumProperty(items=getTaskTimeColumns, name="Task Time Columns")
|
||||
other_columns: EnumProperty(
|
||||
|
||||
@@ -138,23 +138,26 @@ class BIM_PT_work_schedules(Panel):
|
||||
|
||||
def draw_column_ui(self):
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props, "task_columns", text="")
|
||||
row.prop(self.props, "column_types", text="")
|
||||
column_type = self.props.column_types
|
||||
if self.props.column_types == "IfcTask":
|
||||
row.prop(self.props, "task_columns", text="")
|
||||
name, data_type = self.props.task_columns.split("/")
|
||||
elif self.props.column_types == "IfcTaskTime":
|
||||
row.prop(self.props, "task_time_columns", text="")
|
||||
name, data_type = self.props.task_time_columns.split("/")
|
||||
elif self.props.column_types == "Special":
|
||||
row.prop(self.props, "other_columns", text="")
|
||||
column_type, name = self.props.other_columns.split(".")
|
||||
data_type = "string"
|
||||
row.operator("bim.set_task_sort_column", text="", icon="SORTALPHA").column = f"{column_type}.{name}"
|
||||
row.prop(
|
||||
self.props, "is_sort_reversed", text="", icon="SORT_DESC" if self.props.is_sort_reversed else "SORT_ASC"
|
||||
)
|
||||
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"
|
||||
op.column_type = column_type
|
||||
op.name = name
|
||||
op.data_type = data_type
|
||||
|
||||
self.layout.template_list("BIM_UL_task_columns", "", self.props, "columns", self.props, "active_column_index")
|
||||
|
||||
@@ -285,9 +288,12 @@ class BIM_PT_work_schedules(Panel):
|
||||
|
||||
class BIM_UL_task_columns(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
props = context.scene.BIMWorkScheduleProperties
|
||||
if item:
|
||||
row = layout.row(align=True)
|
||||
row.prop(item, "name", emboss=False, text="")
|
||||
if props.sort_column == item.name:
|
||||
row.label(text="", icon="SORTALPHA")
|
||||
row.operator("bim.remove_task_column", text="", icon="X")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user