From d2da01041cd6b2331e538746417e0452a7c8b996 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Tue, 11 Apr 2023 15:27:03 +0500 Subject: [PATCH] Added checkboxes to drawing list to mark multiple selected drawings Checkboxes affect the drawings that will be used when you shift click "Create drawing", "Open Drawing", "Remove Drawing". Previously those opeartors were always applying the action to all drawings. Also added option to remove selected drawings with shift+click to "Remove Drawing" and added new operator "Select all drawings" to select drawings in one click (you can shift click it to delsect all drawings). Example - https://i.imgur.com/GAGghu5.png --- .../blenderbim/bim/module/drawing/__init__.py | 1 + .../blenderbim/bim/module/drawing/operator.py | 71 ++++++++++++++++--- .../blenderbim/bim/module/drawing/prop.py | 1 + .../blenderbim/bim/module/drawing/ui.py | 3 + src/blenderbim/blenderbim/core/drawing.py | 3 + src/blenderbim/blenderbim/tool/drawing.py | 4 ++ 6 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/__init__.py b/src/blenderbim/blenderbim/bim/module/drawing/__init__.py index 099c09826d..59e192936e 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/__init__.py @@ -53,6 +53,7 @@ classes = ( operator.LoadDrawings, operator.LoadSchedules, operator.LoadSheets, + operator.SelectAllDrawings, operator.OpenDrawing, operator.OpenSchedule, operator.OpenSheet, diff --git a/src/blenderbim/blenderbim/bim/module/drawing/operator.py b/src/blenderbim/blenderbim/bim/module/drawing/operator.py index 80026ec1a2..bbc1678efe 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/operator.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/operator.py @@ -146,7 +146,7 @@ class CreateDrawing(bpy.types.Operator): bl_label = "Create Drawing" bl_description = ( "Creates/refreshes a .svg drawing based on currently active camera.\n\n" - + "SHIFT+CLICK to print all annotations" + + "SHIFT+CLICK to print all selected drawings" ) print_all: bpy.props.BoolProperty(name="Print All", default=False) @@ -155,12 +155,12 @@ class CreateDrawing(bpy.types.Operator): return bool(tool.Ifc.get() and tool.Drawing.is_camera_orthographic() and tool.Drawing.is_drawing_active()) def invoke(self, context, event): - # printing all annotations on shift+click + # printing all drawings on shift+click if event.type == "LEFTMOUSE" and event.shift: self.print_all = True else: - # can't rely on default value since `self.print_all = True` - # will set the value to `True` for all future calls + # can't rely on default value since the line above + # will set the value to `True` for all future operator calls self.print_all = False return self.execute(context) @@ -169,7 +169,7 @@ class CreateDrawing(bpy.types.Operator): if self.print_all: original_drawing_id = self.props.active_drawing_id - drawings_to_print = [drawing.ifc_definition_id for drawing in self.props.drawings] + drawings_to_print = [d.ifc_definition_id for d in self.props.drawings if d.is_selected] else: drawings_to_print = [self.props.active_drawing_id] @@ -903,6 +903,30 @@ class ChangeSheetTitleBlock(bpy.types.Operator, Operator): sheet_builder.change_titleblock(sheet, titleblock) +class SelectAllDrawings(bpy.types.Operator): + bl_idname = "bim.select_all_drawings" + bl_label = "Select All Drawings" + view: bpy.props.StringProperty() + bl_description = "Select all drawings in the drawing list.\n\n" + "SHIFT+CLICK to deselect all drawings" + select_all: bpy.props.BoolProperty(name="Open All", default=False) + + def invoke(self, context, event): + # deselect all drawings on shift+click + if event.type == "LEFTMOUSE" and event.shift: + self.select_all = False + else: + # can't rely on default value since the line above + # will set the value to `True` for all future operator calls + self.select_all = True + return self.execute(context) + + def execute(self, context): + for drawing in context.scene.DocProperties.drawings: + if drawing.is_selected != self.select_all: + drawing.is_selected = self.select_all + return {"FINISHED"} + + class OpenDrawing(bpy.types.Operator): bl_idname = "bim.open_drawing" bl_label = "Open Drawing" @@ -910,23 +934,25 @@ class OpenDrawing(bpy.types.Operator): bl_description = ( "Opens a .svg drawing based on currently active camera with default system viewer\n" + 'or using "svg_command" from the BlenderBIM preferences (if provided).\n\n' - + "SHIFT+CLICK to open all drawings" + + "SHIFT+CLICK to open all selected drawings" ) open_all: bpy.props.BoolProperty(name="Open All", default=False) def invoke(self, context, event): - # opening all annotations on shift+click + # opening all drawings on shift+click if event.type == "LEFTMOUSE" and event.shift: self.open_all = True else: - # can't rely on default value since `self.open_all = True` - # will set the value to `True` for all future calls + # can't rely on default value since the line above + # will set the value to `True` for all future operator calls self.open_all = False return self.execute(context) def execute(self, context): if self.open_all: - drawings = [tool.Ifc.get().by_id(d.ifc_definition_id) for d in context.scene.DocProperties.drawings] + drawings = [ + tool.Ifc.get().by_id(d.ifc_definition_id) for d in context.scene.DocProperties.drawings if d.is_selected + ] else: drawings = [tool.Ifc.get().by_id(context.scene.DocProperties.drawings.get(self.view).ifc_definition_id)] @@ -1004,10 +1030,33 @@ class RemoveDrawing(bpy.types.Operator, Operator): bl_idname = "bim.remove_drawing" bl_label = "Remove Drawing" bl_options = {"REGISTER", "UNDO"} + bl_description = "Remove currently selected drawing.\n\n" + "SHIFT+CLICK to remove all selected drawings" + drawing: bpy.props.IntProperty() + remove_all: bpy.props.BoolProperty(name="Remove All", default=False) + + def invoke(self, context, event): + # removing all selected drawings on shift+click + if event.type == "LEFTMOUSE" and event.shift: + self.remove_all = True + else: + # can't rely on default value since the line above + # will set the value to `True` for all future operator calls + self.remove_all = False + return self.execute(context) def _execute(self, context): - core.remove_drawing(tool.Ifc, tool.Drawing, drawing=tool.Ifc.get().by_id(self.drawing)) + if self.remove_all: + drawings = [ + tool.Ifc.get().by_id(d.ifc_definition_id) for d in context.scene.DocProperties.drawings if d.is_selected + ] + else: + drawings = [tool.Ifc.get().by_id(self.drawing)] + + print("Removing drawings: {}".format([d for d in drawings])) + + for drawing in drawings: + core.remove_drawing(tool.Ifc, tool.Drawing, drawing=drawing) class AddDrawingStyle(bpy.types.Operator): diff --git a/src/blenderbim/blenderbim/bim/module/drawing/prop.py b/src/blenderbim/blenderbim/bim/module/drawing/prop.py index 633ebbefaf..2a04df4342 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/prop.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/prop.py @@ -230,6 +230,7 @@ class Drawing(PropertyGroup): ifc_definition_id: IntProperty(name="IFC Definition ID") name: StringProperty(name="Name", update=update_drawing_name) target_view: StringProperty(name="Target View") + is_selected: BoolProperty(name="Is Selected", default=True) class Schedule(PropertyGroup): diff --git a/src/blenderbim/blenderbim/bim/module/drawing/ui.py b/src/blenderbim/blenderbim/bim/module/drawing/ui.py index cb99a3574c..247b912d9f 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/ui.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/ui.py @@ -185,6 +185,7 @@ class BIM_PT_drawings(Panel): ).drawing = active_drawing.ifc_definition_id col = row.column() col.alignment = "RIGHT" + op = row.operator("bim.select_all_drawings", icon="SELECT_SUBTRACT", text="") op = row.operator("bim.open_drawing", icon="URL", text="") op.view = active_drawing.name op = row.operator("bim.activate_view", icon="OUTLINER_OB_CAMERA", text="") @@ -491,6 +492,8 @@ class BIM_UL_drawinglist(bpy.types.UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname): if item: row = layout.row(align=True) + selected_icon = "CHECKBOX_HLT" if item.is_selected else "CHECKBOX_DEHLT" + row.prop(item, "is_selected", text="", icon=selected_icon) icon = "UV_FACESEL" if item.target_view == "ELEVATION_VIEW": icon = "UV_VERTEXSEL" diff --git a/src/blenderbim/blenderbim/core/drawing.py b/src/blenderbim/blenderbim/core/drawing.py index 568a6e6eab..24d83da833 100644 --- a/src/blenderbim/blenderbim/core/drawing.py +++ b/src/blenderbim/blenderbim/core/drawing.py @@ -260,15 +260,18 @@ def remove_drawing(ifc, drawing_tool, drawing=None): collection = drawing_tool.get_drawing_collection(drawing) if collection: drawing_tool.delete_collection(collection) + group = drawing_tool.get_drawing_group(drawing) if group: drawing_tool.delete_drawing_elements(drawing_tool.get_group_elements(group)) ifc.run("group.remove_group", group=group) + for reference in drawing_tool.get_drawing_references(drawing): reference_obj = ifc.get_object(reference) if reference_obj: drawing_tool.delete_object(reference_obj) ifc.run("root.remove_product", product=reference) + information = drawing_tool.get_reference_document(drawing_tool.get_drawing_document(drawing)) uri = ifc.resolve_uri(drawing_tool.get_document_uri(information)) if drawing_tool.does_file_exist(uri): diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index d9405e730d..29b9584870 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -542,6 +542,9 @@ class Drawing(blenderbim.core.tool.Drawing): @classmethod def import_drawings(cls): + current_drawings_selection = { + d.ifc_definition_id: d.is_selected for d in bpy.context.scene.DocProperties.drawings + } bpy.context.scene.DocProperties.drawings.clear() drawings = [e for e in tool.Ifc.get().by_type("IfcAnnotation") if e.ObjectType == "DRAWING"] for drawing in drawings: @@ -549,6 +552,7 @@ class Drawing(blenderbim.core.tool.Drawing): new.ifc_definition_id = drawing.id() new.name = drawing.Name or "Unnamed" new.target_view = cls.get_drawing_target_view(drawing) + new.is_selected = current_drawings_selection.get(drawing.id(), True) @classmethod def import_schedules(cls):