Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-09-01 17:51:26 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-09-01 17:58:39 +0300
commit460e4024e8935e219773b053366be7ea4740962f (patch)
treebf27c7f04786ca44f64c1260b5ef2167e41a608b
parent18d4ad5a59d32922f9d70b0412da0c830baceb17 (diff)
WM: batch rename, material & object-data support
-rw-r--r--release/scripts/startup/bl_operators/wm.py176
1 files changed, 136 insertions, 40 deletions
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index f4724ee9709..79a52ccd6e7 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -1838,6 +1838,30 @@ class WM_OT_batch_rename(Operator):
bl_options = {'UNDO', 'INTERNAL'}
+ data_type: EnumProperty(
+ name="Type",
+ items=(
+ ('OBJECT', "Objects", ""),
+ ('MATERIAL', "Materials", ""),
+ None,
+ # Match object types.
+ ('MESH', "Meshs", ""),
+ ('CURVE', "Curves", ""),
+ ('META', "MetaBalls", ""),
+ ('ARMATURE', "Armatures", ""),
+ ('LATTICE', "Lattices", ""),
+ ('GPENCIL', "Grease Pencils", ""),
+ ('CAMERA', "Cameras", ""),
+ ('SPEAKER', "Speakers", ""),
+ ('LIGHT_PROBE', "LightProbes", ""),
+ None,
+ ('BONE', "Bones", ""),
+ ('NODE', "Nodes", ""),
+ ('SEQUENCE_STRIP', "Sequence Strips", ""),
+ ),
+ description="Type of data to rename",
+ )
+
data_source: EnumProperty(
name="Source",
items=(
@@ -1849,7 +1873,7 @@ class WM_OT_batch_rename(Operator):
actions: CollectionProperty(type=BatchRenameAction)
@staticmethod
- def _data_from_context(context, only_selected):
+ def _data_from_context(context, data_type, only_selected, check_context=False):
mode = context.mode
scene = context.scene
@@ -1858,47 +1882,112 @@ class WM_OT_batch_rename(Operator):
data = None
if space_type == 'SEQUENCE_EDITOR':
- data = (
- # TODO, we don't have access to seqbasep, this won't work when inside metas.
- [seq for seq in context.scene.sequence_editor.sequences_all if seq.select]
- if only_selected else
- context.scene.sequence_editor.sequences_all,
- "name",
- "Strip(s)",
- )
+ data_type_test = 'SEQUENCE_STRIP'
+ if check_context:
+ return data_type_test
+ if data_type == data_type_test:
+ data = (
+ # TODO, we don't have access to seqbasep, this won't work when inside metas.
+ [seq for seq in context.scene.sequence_editor.sequences_all if seq.select]
+ if only_selected else
+ context.scene.sequence_editor.sequences_all,
+ "name",
+ "Strip(s)",
+ )
elif space_type == 'NODE_EDITOR':
- data = (
- context.selected_nodes
- if only_selected else
- list(space.node_tree.nodes),
- "name",
- "Node(s)",
- )
+ data_type_test = 'NODE'
+ if check_context:
+ return data_type_test
+ if data_type == data_type_test:
+ data = (
+ context.selected_nodes
+ if only_selected else
+ list(space.node_tree.nodes),
+ "name",
+ "Node(s)",
+ )
else:
if mode == 'POSE' or (mode == 'WEIGHT_PAINT' and context.pose_object):
+ data_type_test = 'BONE'
+ if check_context:
+ return data_type_test
+ if data_type == data_type_test:
+ data = (
+ [pchan.bone for pchan in context.selected_pose_bones]
+ if only_selected else
+ [pchan.bone for ob in context.objects_in_mode_unique_data for pbone in ob.pose.bones],
+ "name",
+ "Bone(s)",
+ )
+ elif mode == 'EDIT_ARMATURE':
+ data_type_test = 'BONE'
+ if check_context:
+ return data_type_test
+ if data_type == data_type_test:
+ data = (
+ context.selected_editable_bones
+ if only_selected else
+ [ebone for ob in context.objects_in_mode_unique_data for ebone in ob.data.edit_bones],
+ "name",
+ "Edit Bone(s)",
+ )
+
+ if check_context:
+ return 'OBJECT'
+
+ object_data_type_attrs_map = {
+ 'MESH': ("meshes", "Mesh(es)"),
+ 'CURVE': ("curves", "Curve(s)"),
+ 'META': ("metaballs", "MetaBall(s)"),
+ 'ARMATURE': ("armatures", "Armature(s)"),
+ 'LATTICE': ("lattices", "Lattice(s)"),
+ 'GPENCIL': ("grease_pencils", "Grease Pencil(s)"),
+ 'CAMERA': ("cameras", "Camera(s)"),
+ 'SPEAKER': ("speakers", "Speaker(s)"),
+ 'LIGHT_PROBE': ("light_probes", "LightProbe(s)"),
+ }
+
+ # Finish with space types.
+ if data is None:
+
+ if data_type == 'OBJECT':
data = (
- [pchan.bone for pchan in context.selected_pose_bones]
+ context.selected_editable_objects
if only_selected else
- [pchan.bone for ob in context.objects_in_mode_unique_data for pbone in ob.pose.bones],
+ [id for id in bpy.data.objects if id.library is None],
"name",
- "Bone(s)",
+ "Object(s)",
)
- elif mode == 'EDIT_ARMATURE':
+ elif data_type == 'MATERIAL':
data = (
- context.selected_editable_bones
+ tuple(set(
+ slot.material
+ for ob in context.selected_objects
+ for slot in ob.material_slots
+ if slot.material is not None
+ ))
if only_selected else
- [ebone for ob in context.objects_in_mode_unique_data for ebone in ob.data.edit_bones],
+ [id for id in bpy.data.materials if id.library is None],
"name",
- "Edit Bone(s)",
+ "Material(s)",
)
- else:
+ elif data_type in object_data_type_attrs_map.keys():
+ attr, descr = object_data_type_attrs_map[data_type]
data = (
- context.selected_editable_objects
+ tuple(set(
+ id
+ for ob in context.selected_objects
+ if ob.type == data_type
+ for id in (ob.data,)
+ if id is not None and id.library is None
+ ))
if only_selected else
- [ob for ob in bpy.data.objects if ob.library is None],
+ [id for id in getattr(bpy.data, attr) if id.library is None],
"name",
- "Object(s)",
+ descr,
)
+
+
return data
@staticmethod
@@ -1962,10 +2051,24 @@ class WM_OT_batch_rename(Operator):
assert(0)
return name
+ def _data_update(self, context):
+ only_selected = self.data_source == 'SELECT'
+
+ self._data = self._data_from_context(context, self.data_type, only_selected)
+ if self._data is None:
+ self.data_type = self._data_from_context(context, None, False, check_context=True)
+ self._data = self._data_from_context(context, self.data_type, only_selected)
+
+ self._data_source_prev = self.data_source
+ self._data_type_prev = self.data_type
+
def draw(self, context):
layout = self.layout
row = layout.row()
+ row.prop(self, "data_type")
+
+ row = layout.row()
row.label(text="Rename {:d} {:s}".format(len(self._data[0]), self._data[2]))
row.prop(self, "data_source", expand=True)
@@ -2008,10 +2111,11 @@ class WM_OT_batch_rename(Operator):
changed = True
break
- if self._data_source_prev != self.data_source:
- only_selected = self.data_source == 'SELECT'
- self._data = self._data_from_context(context, only_selected)
- self._data_source_prev = self.data_source
+ if (
+ (self._data_source_prev != self.data_source) or
+ (self._data_type_prev != self.data_type)
+ ):
+ self._data_update(context)
changed = True
return changed
@@ -2037,15 +2141,7 @@ class WM_OT_batch_rename(Operator):
def invoke(self, context, event):
- only_selected = self.data_source == 'SELECT'
- data = self._data_from_context(context, only_selected)
- self._data_source_prev = self.data_source
-
- if data is None:
- self.report({'ERROR'}, "No usable items in this context")
- return {'CANCELLED'}
-
- self._data = data
+ self._data_update(context)
if not self.actions:
self.actions.add()