ADD: Multi-rename - replace also in file extensions option

This commit is contained in:
Alexander Koblov 2025-10-04 14:08:06 +03:00
commit 44f38d82ac
3 changed files with 73 additions and 33 deletions

View file

@ -397,9 +397,9 @@ object frmMultiRename: TfrmMultiRename
AnchorSideRight.Control = edReplace
AnchorSideRight.Side = asrBottom
Left = 4
Height = 46
Top = 86
Width = 318
Height = 56
Top = 98
Width = 351
Anchors = [akTop, akLeft, akRight]
AutoSize = True
BevelOuter = bvNone
@ -407,53 +407,63 @@ object frmMultiRename: TfrmMultiRename
ChildSizing.HorizontalSpacing = 12
ChildSizing.VerticalSpacing = 2
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 2
ClientHeight = 46
ClientWidth = 318
ChildSizing.ControlsPerLine = 3
ClientHeight = 56
ClientWidth = 351
TabOrder = 2
object cbRegExp: TCheckBox
Left = 0
Height = 19
Height = 24
Top = 4
Width = 124
Width = 150
BorderSpacing.Top = 4
Caption = 'Regular e&xpressions'
OnChange = cbRegExpChange
ParentFont = False
TabOrder = 0
OnChange = cbRegExpChange
end
object cbCaseSens: TCheckBox
Left = 136
Height = 19
Left = 162
Height = 24
Hint = 'Case sensitive'
Top = 4
Width = 42
Width = 53
Caption = 'A≠a'
OnChange = cbNameStyleChange
TabOrder = 2
OnChange = cbNameStyleChange
end
object cbRepExt: TCheckBox
Left = 227
Height = 24
Hint = 'Replace also in file extensions'
Top = 4
Width = 34
Caption = 'E'
TabOrder = 4
OnChange = cbNameStyleChange
end
object cbUseSubs: TCheckBox
AnchorSideBottom.Side = asrBottom
Left = 0
Height = 19
Top = 25
Width = 124
Height = 24
Top = 30
Width = 150
BorderSpacing.Top = 2
Caption = '&Use substitution'
Enabled = False
OnChange = cbNameStyleChange
ParentFont = False
TabOrder = 1
OnChange = cbNameStyleChange
end
object cbOnlyFirst: TCheckBox
Left = 136
Height = 19
Left = 162
Height = 24
Hint = 'Replace only once per file'
Top = 25
Width = 42
Top = 30
Width = 53
Caption = '1x'
OnChange = cbNameStyleChange
TabOrder = 3
OnChange = cbNameStyleChange
end
end
end

View file

@ -13,6 +13,8 @@
{"hash":20463635,"name":"tfrmmultirename.cbregexp.caption","sourcebytes":[82,101,103,117,108,97,114,32,101,38,120,112,114,101,115,115,105,111,110,115],"value":"Regular e&xpressions"},
{"hash":219672053,"name":"tfrmmultirename.cbcasesens.hint","sourcebytes":[67,97,115,101,32,115,101,110,115,105,116,105,118,101],"value":"Case sensitive"},
{"hash":5223265,"name":"tfrmmultirename.cbcasesens.caption","sourcebytes":[65,226,137,160,97],"value":"A\u2260a"},
{"hash":21912259,"name":"tfrmmultirename.cbrepext.hint","sourcebytes":[82,101,112,108,97,99,101,32,97,108,115,111,32,105,110,32,102,105,108,101,32,101,120,116,101,110,115,105,111,110,115],"value":"Replace also in file extensions"},
{"hash":69,"name":"tfrmmultirename.cbrepext.caption","sourcebytes":[69],"value":"E"},
{"hash":121437630,"name":"tfrmmultirename.cbusesubs.caption","sourcebytes":[38,85,115,101,32,115,117,98,115,116,105,116,117,116,105,111,110],"value":"&Use substitution"},
{"hash":54067429,"name":"tfrmmultirename.cbonlyfirst.hint","sourcebytes":[82,101,112,108,97,99,101,32,111,110,108,121,32,111,110,99,101,32,112,101,114,32,102,105,108,101],"value":"Replace only once per file"},
{"hash":904,"name":"tfrmmultirename.cbonlyfirst.caption","sourcebytes":[49,120],"value":"1x"},
@ -48,6 +50,7 @@
{"hash":241100437,"name":"tfrmmultirename.actviewrenamelogfile.caption","sourcebytes":[86,105,101,119,32,82,101,110,97,109,101,32,76,111,103,32,70,105,108,101],"value":"View Rename Log File"},
{"hash":263529797,"name":"tfrmmultirename.actinvokerelativepath.caption","sourcebytes":[73,110,118,111,107,101,32,82,101,108,97,116,105,118,101,32,80,97,116,104,32,77,101,110,117],"value":"Invoke Relative Path Menu"},
{"hash":256660862,"name":"tfrmmultirename.actloadnamesfromfile.caption","sourcebytes":[76,111,97,100,32,78,97,109,101,115,32,102,114,111,109,32,70,105,108,101,46,46,46],"value":"Load Names from File..."},
{"hash":240984948,"name":"tfrmmultirename.actloadnamesfromclipboard.caption","sourcebytes":[76,111,97,100,32,78,97,109,101,115,32,102,114,111,109,32,67,108,105,112,98,111,97,114,100],"value":"Load Names from Clipboard"},
{"hash":227296782,"name":"tfrmmultirename.acteditnames.caption","sourcebytes":[69,100,105,116,32,78,97,109,101,115,46,46,46],"value":"Edit Names..."},
{"hash":72890318,"name":"tfrmmultirename.acteditnewnames.caption","sourcebytes":[69,100,105,116,32,67,117,114,114,101,110,116,32,78,101,119,32,78,97,109,101,115,46,46,46],"value":"Edit Current New Names..."},
{"hash":87501221,"name":"tfrmmultirename.actshowpresetsmenu.caption","sourcebytes":[83,104,111,119,32,80,114,101,115,101,116,32,77,101,110,117],"value":"Show Preset Menu"},

View file

@ -3,7 +3,7 @@
-------------------------------------------------------------------------
Multi-Rename Tool dialog window
Copyright (C) 2007-2023 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2007-2025 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -64,6 +64,7 @@ type
FExtensionStyle: integer;
FFind: string;
FReplace: string;
FRepExt: Boolean;
FRegExp: boolean;
FUseSubs: boolean;
FCaseSens: Boolean;
@ -82,6 +83,7 @@ type
property ExtensionStyle: integer read FExtensionStyle write FExtensionStyle;
property Find: string read FFind write FFind;
property Replace: string read FReplace write FReplace;
property RepExt: boolean read FRepExt write FRepExt;
property RegExp: boolean read FRegExp write FRegExp;
property UseSubs: boolean read FUseSubs write FUseSubs;
property CaseSens: Boolean read FCaseSens write FCaseSens;
@ -128,6 +130,7 @@ type
cbRegExp: TCheckBox;
cbUseSubs: TCheckBox;
cbOnlyFirst: TCheckBox;
cbRepExt: TCheckBox;
pnlFindReplace: TPanel;
pnlButtons: TPanel;
StringGrid: TStringGrid;
@ -469,6 +472,7 @@ begin
FExtensionStyle := 0;
FFind := '';
FReplace := '';
FRepExt := True;
FRegExp := False;
FUseSubs := False;
FCaseSens := False;
@ -1001,6 +1005,7 @@ begin
AMultiRenamePreset.ExtensionStyle := AConfig.GetValue(ANode, 'ExtensionStyle', 0);
AMultiRenamePreset.Find := AConfig.GetValue(ANode, 'Find', '');
AMultiRenamePreset.Replace := AConfig.GetValue(ANode, 'Replace', '');
AMultiRenamePreset.RepExt := AConfig.GetValue(ANode, 'RepExt', True);
AMultiRenamePreset.RegExp := AConfig.GetValue(ANode, 'RegExp', False);
AMultiRenamePreset.UseSubs := AConfig.GetValue(ANode, 'UseSubs', False);
AMultiRenamePreset.CaseSens := AConfig.GetValue(ANode, 'CaseSensitive', False);
@ -1101,6 +1106,7 @@ begin
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].ExtensionStyle := cmbExtensionStyle.ItemIndex;
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Find := edFind.Text;
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Replace := edReplace.Text;
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].RepExt := cbRepExt.Checked;
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].RegExp := cbRegExp.Checked;
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].UseSubs := cbUseSubs.Checked;
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].CaseSens := cbCaseSens.Checked;
@ -1155,6 +1161,7 @@ begin
AConfig.AddValue(SubNode, 'ExtensionStyle', FMultiRenamePresetList.MultiRenamePreset[i].ExtensionStyle);
AConfig.AddValue(SubNode, 'Find', FMultiRenamePresetList.MultiRenamePreset[i].Find);
AConfig.AddValue(SubNode, 'Replace', FMultiRenamePresetList.MultiRenamePreset[i].Replace);
AConfig.AddValue(SubNode, 'RepExt', FMultiRenamePresetList.MultiRenamePreset[i].RepExt);
AConfig.AddValue(SubNode, 'RegExp', FMultiRenamePresetList.MultiRenamePreset[i].RegExp);
AConfig.AddValue(SubNode, 'UseSubs', FMultiRenamePresetList.MultiRenamePreset[i].UseSubs);
AConfig.AddValue(SubNode, 'CaseSensitive', FMultiRenamePresetList.MultiRenamePreset[i].CaseSens);
@ -2092,15 +2099,21 @@ begin
// Find and replace
if (edFind.Text <> '') then
begin
if cbRepExt.Checked then
sTmpName := Result
else begin
sTmpExt := ExtractFileExt(Result);
sTmpName := Copy(Result, 1, Length(Result) - Length(sTmpExt));
end;
if cbRegExp.Checked then
try
wsText:= CeUtf8ToUtf16(Result);
wsText:= CeUtf8ToUtf16(sTmpName);
wsReplace:= CeUtf8ToUtf16(edReplace.Text);
FRegExp.ModifierI := not cbCaseSens.Checked;
if not cbOnlyFirst.Checked then
begin
Result := CeUtf16ToUtf8(FRegExp.Replace(wsText, wsReplace, cbUseSubs.Checked));
sTmpName := CeUtf16ToUtf8(FRegExp.Replace(wsText, wsReplace, cbUseSubs.Checked));
end
else if FRegExp.Exec(wsText) then
begin
@ -2110,7 +2123,7 @@ begin
else begin
Insert(wsReplace, wsText, FRegExp.MatchPos[0]);
end;
Result:= CeUtf16ToUtf8(wsText);
sTmpName:= CeUtf16ToUtf8(wsText);
end;
except
Result := rsMsgErrRegExpSyntax;
@ -2125,20 +2138,32 @@ begin
if (FReplaceText.Count = 0) then
FReplaceText.Add('');
for I := 0 to FFindText.Count - 1 do
Result := UTF8StringReplace(Result, FFindText[I], FReplaceText[Min(I, FReplaceText.Count - 1)], Flags);
sTmpName := UTF8StringReplace(sTmpName, FFindText[I], FReplaceText[Min(I, FReplaceText.Count - 1)], Flags);
end;
if not bError then
begin
if cbRepExt.Checked then
Result := sTmpName
else begin
Result := sTmpName + sTmpExt;
end;
end;
end;
// File name style
sTmpExt := ExtractFileExt(Result);
sTmpName := Copy(Result, 1, Length(Result) - Length(sTmpExt));
if not bError then
begin
// File name style
sTmpExt := ExtractFileExt(Result);
sTmpName := Copy(Result, 1, Length(Result) - Length(sTmpExt));
sTmpName := ApplyStyle(sTmpName, cbNameMaskStyle.ItemIndex);
sTmpExt := ApplyStyle(sTmpExt, cmbExtensionStyle.ItemIndex);
sTmpName := ApplyStyle(sTmpName, cbNameMaskStyle.ItemIndex);
sTmpExt := ApplyStyle(sTmpExt, cmbExtensionStyle.ItemIndex);
Result := sTmpName + sTmpExt;
Result := sTmpName + sTmpExt;
end;
actRename.Enabled := not bError;
if bError then
begin
edFind.Color := clRed;
@ -2294,6 +2319,7 @@ begin
cbExt.SelStart := UTF8Length(cbExt.Text);
edFind.Text := '';
edReplace.Text := '';
cbRepExt.Checked := True;
cbRegExp.Checked := False;
cbUseSubs.Checked := False;
cbCaseSens.Checked := False;
@ -2646,6 +2672,7 @@ begin
cmbExtensionStyle.ItemIndex := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].ExtensionStyle;
edFind.Text := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Find;
edReplace.Text := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Replace;
cbRepExt.Checked := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].RepExt;
cbRegExp.Checked := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].RegExp;
cbUseSubs.Checked := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].UseSubs;
cbCaseSens.Checked := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].CaseSens;