diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-09-06 16:21:26 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-09-06 16:24:13 +0300 |
commit | d83f62e185b8e132203654111538229aff1504ac (patch) | |
tree | 6550b8f6b670b37e81cf1c3d4885bb475b53fd5b | |
parent | a94bf0e1349b4ee39e308a565fe26a4bd7cb7543 (diff) |
WM: batch rename support for regex groups
Optionally use regular expressions for the destination name,
allows re-ordering words while renaming.
Initial patch by @jmztn with error handling and UI changes.
-rw-r--r-- | release/scripts/startup/bl_operators/wm.py | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index f7b4a4e80e6..f672276c4f2 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1816,10 +1816,14 @@ class BatchRenameAction(bpy.types.PropertyGroup): replace_src: StringProperty(name="Find") replace_dst: StringProperty(name="Replace") replace_match_case: BoolProperty(name="Case Sensitive") - replace_regex: BoolProperty( - name="Regular Expression", + use_replace_regex_src: BoolProperty( + name="Regular Expression Find", description="Use regular expressions to match text in the 'Find' field" ) + use_replace_regex_dst: BoolProperty( + name="Regular Expression Replace", + description="Use regular expression for the replacement text (supporting groups)" + ) # type: 'CASE'. case_method: EnumProperty( @@ -2029,13 +2033,18 @@ class WM_OT_batch_rename(Operator): name = name.rstrip(chars_strip) elif ty == 'REPLACE': - if action.replace_regex: + if action.use_replace_regex_src: replace_src = action.replace_src + if action.use_replace_regex_dst: + replace_dst = action.replace_dst + else: + replace_dst = re.escape(action.replace_dst) else: replace_src = re.escape(action.replace_src) + replace_dst = re.escape(action.replace_dst) name = re.sub( replace_src, - re.escape(action.replace_dst), + replace_dst, name, flags=( 0 if action.replace_match_case else @@ -2097,22 +2106,39 @@ class WM_OT_batch_rename(Operator): box.row().prop(action, "strip_part") elif ty == 'REPLACE': - row = box.row() - re_error = None - if action.replace_regex: + row = box.row(align=True) + re_error_src = None + if action.use_replace_regex_src: try: re.compile(action.replace_src) except Exception as ex: + re_error_src = str(ex) row.alert = True - re_error = str(ex) row.prop(action, "replace_src") - if re_error is not None: - box.label(text=re_error) + row.prop(action, "use_replace_regex_src", text="", icon='SORTBYEXT') + if re_error_src is not None: + box.label(text=re_error_src) + + re_error_dst = None + row = box.row(align=True) + if action.use_replace_regex_src: + if action.use_replace_regex_dst: + if re_error_src is None: + try: + re.sub(action.replace_src, action.replace_dst, "") + except Exception as ex: + re_error_dst = str(ex) + row.alert = True + + row.prop(action, "replace_dst") + rowsub = row.row(align=True) + rowsub.active = action.use_replace_regex_src + rowsub.prop(action, "use_replace_regex_dst", text="", icon='SORTBYEXT') + if re_error_dst is not None: + box.label(text=re_error_dst) - box.row().prop(action, "replace_dst") row = box.row() row.prop(action, "replace_match_case") - row.prop(action, "replace_regex") elif ty == 'CASE': box.row().prop(action, "case_method", expand=True) @@ -2151,13 +2177,20 @@ class WM_OT_batch_rename(Operator): # Sanitize actions. for action in actions: - if action.replace_regex: + if action.use_replace_regex_src: try: re.compile(action.replace_src) except Exception as ex: - self.report({'ERROR'}, "Invalid regular expression: " + str(ex)) + self.report({'ERROR'}, "Invalid regular expression (find): " + str(ex)) return {'CANCELLED'} + if action.use_replace_regex_dst: + try: + re.sub(action.replace_src, action.replace_dst, "") + except Exception as ex: + self.report({'ERROR'}, "Invalid regular expression (replace): " + str(ex)) + return {'CANCELLED'} + total_len = 0 change_len = 0 for item in seq: |