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
This commit is contained in:
Andrej730
2023-04-11 15:27:03 +05:00
parent 75c17b820f
commit d2da01041c
6 changed files with 72 additions and 11 deletions
@@ -53,6 +53,7 @@ classes = (
operator.LoadDrawings, operator.LoadDrawings,
operator.LoadSchedules, operator.LoadSchedules,
operator.LoadSheets, operator.LoadSheets,
operator.SelectAllDrawings,
operator.OpenDrawing, operator.OpenDrawing,
operator.OpenSchedule, operator.OpenSchedule,
operator.OpenSheet, operator.OpenSheet,
@@ -146,7 +146,7 @@ class CreateDrawing(bpy.types.Operator):
bl_label = "Create Drawing" bl_label = "Create Drawing"
bl_description = ( bl_description = (
"Creates/refreshes a .svg drawing based on currently active camera.\n\n" "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) 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()) return bool(tool.Ifc.get() and tool.Drawing.is_camera_orthographic() and tool.Drawing.is_drawing_active())
def invoke(self, context, event): def invoke(self, context, event):
# printing all annotations on shift+click # printing all drawings on shift+click
if event.type == "LEFTMOUSE" and event.shift: if event.type == "LEFTMOUSE" and event.shift:
self.print_all = True self.print_all = True
else: else:
# can't rely on default value since `self.print_all = True` # can't rely on default value since the line above
# will set the value to `True` for all future calls # will set the value to `True` for all future operator calls
self.print_all = False self.print_all = False
return self.execute(context) return self.execute(context)
@@ -169,7 +169,7 @@ class CreateDrawing(bpy.types.Operator):
if self.print_all: if self.print_all:
original_drawing_id = self.props.active_drawing_id 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: else:
drawings_to_print = [self.props.active_drawing_id] drawings_to_print = [self.props.active_drawing_id]
@@ -903,6 +903,30 @@ class ChangeSheetTitleBlock(bpy.types.Operator, Operator):
sheet_builder.change_titleblock(sheet, titleblock) 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): class OpenDrawing(bpy.types.Operator):
bl_idname = "bim.open_drawing" bl_idname = "bim.open_drawing"
bl_label = "Open Drawing" bl_label = "Open Drawing"
@@ -910,23 +934,25 @@ class OpenDrawing(bpy.types.Operator):
bl_description = ( bl_description = (
"Opens a .svg drawing based on currently active camera with default system viewer\n" "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' + '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) open_all: bpy.props.BoolProperty(name="Open All", default=False)
def invoke(self, context, event): def invoke(self, context, event):
# opening all annotations on shift+click # opening all drawings on shift+click
if event.type == "LEFTMOUSE" and event.shift: if event.type == "LEFTMOUSE" and event.shift:
self.open_all = True self.open_all = True
else: else:
# can't rely on default value since `self.open_all = True` # can't rely on default value since the line above
# will set the value to `True` for all future calls # will set the value to `True` for all future operator calls
self.open_all = False self.open_all = False
return self.execute(context) return self.execute(context)
def execute(self, context): def execute(self, context):
if self.open_all: 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: else:
drawings = [tool.Ifc.get().by_id(context.scene.DocProperties.drawings.get(self.view).ifc_definition_id)] 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_idname = "bim.remove_drawing"
bl_label = "Remove Drawing" bl_label = "Remove Drawing"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
bl_description = "Remove currently selected drawing.\n\n" + "SHIFT+CLICK to remove all selected drawings"
drawing: bpy.props.IntProperty() 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): 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): class AddDrawingStyle(bpy.types.Operator):
@@ -230,6 +230,7 @@ class Drawing(PropertyGroup):
ifc_definition_id: IntProperty(name="IFC Definition ID") ifc_definition_id: IntProperty(name="IFC Definition ID")
name: StringProperty(name="Name", update=update_drawing_name) name: StringProperty(name="Name", update=update_drawing_name)
target_view: StringProperty(name="Target View") target_view: StringProperty(name="Target View")
is_selected: BoolProperty(name="Is Selected", default=True)
class Schedule(PropertyGroup): class Schedule(PropertyGroup):
@@ -185,6 +185,7 @@ class BIM_PT_drawings(Panel):
).drawing = active_drawing.ifc_definition_id ).drawing = active_drawing.ifc_definition_id
col = row.column() col = row.column()
col.alignment = "RIGHT" col.alignment = "RIGHT"
op = row.operator("bim.select_all_drawings", icon="SELECT_SUBTRACT", text="")
op = row.operator("bim.open_drawing", icon="URL", text="") op = row.operator("bim.open_drawing", icon="URL", text="")
op.view = active_drawing.name op.view = active_drawing.name
op = row.operator("bim.activate_view", icon="OUTLINER_OB_CAMERA", text="") 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): def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
if item: if item:
row = layout.row(align=True) 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" icon = "UV_FACESEL"
if item.target_view == "ELEVATION_VIEW": if item.target_view == "ELEVATION_VIEW":
icon = "UV_VERTEXSEL" icon = "UV_VERTEXSEL"
@@ -260,15 +260,18 @@ def remove_drawing(ifc, drawing_tool, drawing=None):
collection = drawing_tool.get_drawing_collection(drawing) collection = drawing_tool.get_drawing_collection(drawing)
if collection: if collection:
drawing_tool.delete_collection(collection) drawing_tool.delete_collection(collection)
group = drawing_tool.get_drawing_group(drawing) group = drawing_tool.get_drawing_group(drawing)
if group: if group:
drawing_tool.delete_drawing_elements(drawing_tool.get_group_elements(group)) drawing_tool.delete_drawing_elements(drawing_tool.get_group_elements(group))
ifc.run("group.remove_group", group=group) ifc.run("group.remove_group", group=group)
for reference in drawing_tool.get_drawing_references(drawing): for reference in drawing_tool.get_drawing_references(drawing):
reference_obj = ifc.get_object(reference) reference_obj = ifc.get_object(reference)
if reference_obj: if reference_obj:
drawing_tool.delete_object(reference_obj) drawing_tool.delete_object(reference_obj)
ifc.run("root.remove_product", product=reference) ifc.run("root.remove_product", product=reference)
information = drawing_tool.get_reference_document(drawing_tool.get_drawing_document(drawing)) information = drawing_tool.get_reference_document(drawing_tool.get_drawing_document(drawing))
uri = ifc.resolve_uri(drawing_tool.get_document_uri(information)) uri = ifc.resolve_uri(drawing_tool.get_document_uri(information))
if drawing_tool.does_file_exist(uri): if drawing_tool.does_file_exist(uri):
@@ -542,6 +542,9 @@ class Drawing(blenderbim.core.tool.Drawing):
@classmethod @classmethod
def import_drawings(cls): 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() bpy.context.scene.DocProperties.drawings.clear()
drawings = [e for e in tool.Ifc.get().by_type("IfcAnnotation") if e.ObjectType == "DRAWING"] drawings = [e for e in tool.Ifc.get().by_type("IfcAnnotation") if e.ObjectType == "DRAWING"]
for drawing in drawings: for drawing in drawings:
@@ -549,6 +552,7 @@ class Drawing(blenderbim.core.tool.Drawing):
new.ifc_definition_id = drawing.id() new.ifc_definition_id = drawing.id()
new.name = drawing.Name or "Unnamed" new.name = drawing.Name or "Unnamed"
new.target_view = cls.get_drawing_target_view(drawing) new.target_view = cls.get_drawing_target_view(drawing)
new.is_selected = current_drawings_selection.get(drawing.id(), True)
@classmethod @classmethod
def import_schedules(cls): def import_schedules(cls):