diff --git a/CHANGELOG.md b/CHANGELOG.md index 69bb510..8696b71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # 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 - feat: check file: add check for filepath mapping (if all relative or all absolute) diff --git a/OP_layer_manager.py b/OP_layer_manager.py index 69b8cc1..d36faa2 100644 --- a/OP_layer_manager.py +++ b/OP_layer_manager.py @@ -187,42 +187,49 @@ class GPTB_OT_select_set_same_color(Operator): 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() sep = prefs.separator if not target: return - scene = bpy.context.scene + gpl = bpy.context.object.data.layers - if scene.gp_rename_selected: - lays = [l for l in gpl if l.info != 'background' and l.select] + if selected_only: + lays = [l for l in gpl if l.select] # exclude : l.info != 'background' else: - lays = [l for l in gpl if l.info != 'background'] + lays = [l for l in gpl] # exclude : if l.info != 'background' ct = 0 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) prefix = splited[0] - #print(1, splited) new_prefix = prefix.replace(target, replacement) - #print(2, splited) if prefix != new_prefix: splited[0] = new_prefix - #print(3, splited) l.info = sep.join(splited) print('rename:', old, '-->', l.info) - ct+= 1 + ct += 1 else: - old = l.info new = l.info.replace(target, replacement) if old != new: - print('rename:', old, '-->', l.info) l.info = new - ct+= 1 + print('rename:', old, '-->', new) + ct += 1 return ct 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') 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) - prefix: BoolProperty(name="Prefix only", description="Affect only prefix of name (full name if not '_' in it)", 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 (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): - 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: mess = str(count) + ' layers renamed' self.report({'INFO'}, mess) @@ -255,12 +263,19 @@ class GPTB_OT_rename_gp_layer(Operator): def draw(self, context): layout = self.layout - #layout.separator() - #layout.label('search/replace GPlayers') - layout.prop(self, "selected") - layout.prop(self, "prefix") - layout.prop(self, "find")#, text = 'find') - layout.prop(self, "replace")#, text = 'replace') + row = layout.row() + row_a= row.row() + row_a.prop(self, "selected") + + row_b= row.row() + 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--- @@ -313,6 +328,12 @@ def gpencil_dopesheet_header(self, context): 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=( GPTB_OT_rename_gp_layer, GPTB_OT_layer_name_build, @@ -326,8 +347,10 @@ def register(): bpy.types.DATA_PT_gpencil_layers.prepend(layer_name_builder) bpy.types.DOPESHEET_HT_header.append(gpencil_dopesheet_header) + bpy.types.GPENCIL_MT_layer_context_menu.append(gpencil_layer_dropdown_menu) 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.DATA_PT_gpencil_layers.remove(layer_name_builder) diff --git a/__init__.py b/__init__.py index 532d6b7..1394bc1 100755 --- a/__init__.py +++ b/__init__.py @@ -15,7 +15,7 @@ bl_info = { "name": "GP toolbox", "description": "Set of tools for Grease Pencil in animation production", "author": "Samuel Bernou, Christophe Seux", -"version": (1, 5, 5), +"version": (1, 5, 6), "blender": (2, 91, 0), "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", "warning": "",