gp layer batch rename find-replace

1.5.6

- feat: layer drop-down menu include an operator for batch find/replace GP layers (idname: `gp.rename_gp_layers`)
gpv2
Pullusb 2021-07-13 16:23:39 +02:00
parent 75c8cb9206
commit 66ef75c76d
3 changed files with 52 additions and 24 deletions

View File

@ -1,5 +1,10 @@
# Changelog # Changelog
1.5.6
- feat: layer drop-down menu include an operator for batch find/replace GP layers (idname: `gp.rename_gp_layers`)
1.5.5 1.5.5
- feat: check file: add check for filepath mapping (if all relative or all absolute) - feat: check file: add check for filepath mapping (if all relative or all absolute)

View File

@ -187,42 +187,49 @@ class GPTB_OT_select_set_same_color(Operator):
return {"FINISHED"} return {"FINISHED"}
def replace_layer_name(target, replacement, selected_only=True, prefix_only=True): def replace_layer_name(target, replacement, selected_only=True, prefix_only=True, regex=False):
prefs = get_addon_prefs() prefs = get_addon_prefs()
sep = prefs.separator sep = prefs.separator
if not target: if not target:
return return
scene = bpy.context.scene
gpl = bpy.context.object.data.layers gpl = bpy.context.object.data.layers
if scene.gp_rename_selected: if selected_only:
lays = [l for l in gpl if l.info != 'background' and l.select] lays = [l for l in gpl if l.select] # exclude : l.info != 'background'
else: else:
lays = [l for l in gpl if l.info != 'background'] lays = [l for l in gpl] # exclude : if l.info != 'background'
ct = 0 ct = 0
for l in lays: for l in lays:
if scene.gp_rename_prefix:
old = l.info old = l.info
if regex:
new = re.sub(target, replacement, l.info)
if old != new:
l.info = new
print('rename:', old, '-->', new)
ct += 1
continue
if prefix_only:
if not sep in l.info:
# only if separator exists
continue
splited = l.info.split(sep) splited = l.info.split(sep)
prefix = splited[0] prefix = splited[0]
#print(1, splited)
new_prefix = prefix.replace(target, replacement) new_prefix = prefix.replace(target, replacement)
#print(2, splited)
if prefix != new_prefix: if prefix != new_prefix:
splited[0] = new_prefix splited[0] = new_prefix
#print(3, splited)
l.info = sep.join(splited) l.info = sep.join(splited)
print('rename:', old, '-->', l.info) print('rename:', old, '-->', l.info)
ct+= 1 ct += 1
else: else:
old = l.info
new = l.info.replace(target, replacement) new = l.info.replace(target, replacement)
if old != new: if old != new:
print('rename:', old, '-->', l.info)
l.info = new l.info = new
ct+= 1 print('rename:', old, '-->', new)
ct += 1
return ct return ct
class GPTB_OT_rename_gp_layer(Operator): class GPTB_OT_rename_gp_layer(Operator):
@ -237,11 +244,12 @@ class GPTB_OT_rename_gp_layer(Operator):
find: StringProperty(name="Find", description="Name to replace", default="", maxlen=0, options={'ANIMATABLE'}, subtype='NONE') find: StringProperty(name="Find", description="Name to replace", default="", maxlen=0, options={'ANIMATABLE'}, subtype='NONE')
replace: StringProperty(name="Repl", description="New name placed", default="", maxlen=0, options={'ANIMATABLE'}, subtype='NONE') replace: StringProperty(name="Repl", description="New name placed", default="", maxlen=0, options={'ANIMATABLE'}, subtype='NONE')
selected: BoolProperty(name="Selected layer only", description="Affect only selected layers", default=True) selected: BoolProperty(name="Selected Only", description="Affect only selected layers", default=False)
prefix: BoolProperty(name="Prefix only", description="Affect only prefix of name (full name if not '_' in it)", default=True) prefix: BoolProperty(name="Prefix Only", description="Affect only prefix of name (skip layer without separator in name)", default=False)
use_regex: BoolProperty(name="Regex", description="use regular expression (advanced), equivalent to python re.sub()", default=False)
def execute(self, context): def execute(self, context):
count = replace_layer_name(self.find, self.replace, selected_only=self.select, prefix_only=self.prefix) count = replace_layer_name(self.find, self.replace, selected_only=self.selected, prefix_only=self.prefix, regex=self.use_regex)
if count: if count:
mess = str(count) + ' layers renamed' mess = str(count) + ' layers renamed'
self.report({'INFO'}, mess) self.report({'INFO'}, mess)
@ -255,12 +263,19 @@ class GPTB_OT_rename_gp_layer(Operator):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
#layout.separator() row = layout.row()
#layout.label('search/replace GPlayers') row_a= row.row()
layout.prop(self, "selected") row_a.prop(self, "selected")
layout.prop(self, "prefix")
layout.prop(self, "find")#, text = 'find') row_b= row.row()
layout.prop(self, "replace")#, text = 'replace') row_b.prop(self, "prefix")
row_c= row.row()
row_c.prop(self, "use_regex")
row_b.active = not self.use_regex
layout.prop(self, "find")
layout.prop(self, "replace")
## --- UI layer panel--- ## --- UI layer panel---
@ -313,6 +328,12 @@ def gpencil_dopesheet_header(self, context):
row.operator('gp.select_same_color', text='', icon='RESTRICT_COLOR_ON') row.operator('gp.select_same_color', text='', icon='RESTRICT_COLOR_ON')
## --- UI context menu ---
def gpencil_layer_dropdown_menu(self, context):
'''to append in GPENCIL_MT_layer_context_menu'''
self.layout.operator('gp.rename_gp_layers', icon='BORDERMOVE')
classes=( classes=(
GPTB_OT_rename_gp_layer, GPTB_OT_rename_gp_layer,
GPTB_OT_layer_name_build, GPTB_OT_layer_name_build,
@ -326,8 +347,10 @@ def register():
bpy.types.DATA_PT_gpencil_layers.prepend(layer_name_builder) bpy.types.DATA_PT_gpencil_layers.prepend(layer_name_builder)
bpy.types.DOPESHEET_HT_header.append(gpencil_dopesheet_header) bpy.types.DOPESHEET_HT_header.append(gpencil_dopesheet_header)
bpy.types.GPENCIL_MT_layer_context_menu.append(gpencil_layer_dropdown_menu)
def unregister(): def unregister():
bpy.types.GPENCIL_MT_layer_context_menu.remove(gpencil_layer_dropdown_menu)
bpy.types.DOPESHEET_HT_header.remove(gpencil_dopesheet_header) bpy.types.DOPESHEET_HT_header.remove(gpencil_dopesheet_header)
bpy.types.DATA_PT_gpencil_layers.remove(layer_name_builder) bpy.types.DATA_PT_gpencil_layers.remove(layer_name_builder)

View File

@ -15,7 +15,7 @@ bl_info = {
"name": "GP toolbox", "name": "GP toolbox",
"description": "Set of tools for Grease Pencil in animation production", "description": "Set of tools for Grease Pencil in animation production",
"author": "Samuel Bernou, Christophe Seux", "author": "Samuel Bernou, Christophe Seux",
"version": (1, 5, 5), "version": (1, 5, 6),
"blender": (2, 91, 0), "blender": (2, 91, 0),
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
"warning": "", "warning": "",