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
parent
75c8cb9206
commit
66ef75c76d
|
@ -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)
|
||||||
|
|
|
@ -187,41 +187,48 @@ 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
|
||||||
|
print('rename:', old, '-->', new)
|
||||||
ct += 1
|
ct += 1
|
||||||
return ct
|
return ct
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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": "",
|
||||||
|
|
Loading…
Reference in New Issue