mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
3085 lines
106 KiB
ObjectPascal
3085 lines
106 KiB
ObjectPascal
{
|
|
Double Commander
|
|
-------------------------------------------------------------------------
|
|
Multi-Rename Tool dialog window
|
|
|
|
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
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
Original comment:
|
|
----------------------------
|
|
Seksi Commander
|
|
----------------------------
|
|
Licence : GNU GPL v 2.0
|
|
Author : Pavel Letko (letcuv@centrum.cz)
|
|
|
|
Advanced multi rename tool
|
|
|
|
contributors:
|
|
|
|
Copyright (C) 2007-2018 Alexander Koblov (alexx2000@mail.ru)
|
|
}
|
|
|
|
unit fMultiRename;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
//Lazarus, Free-Pascal, etc.
|
|
LazUtf8, SysUtils, Classes, Graphics, Forms, StdCtrls, Menus, Controls,
|
|
LCLType, StringHashList, Grids, ExtCtrls, Buttons, ActnList, EditBtn,
|
|
KASButton, KASToolPanel,
|
|
|
|
//DC
|
|
DCXmlConfig, uOSForms, uRegExprW, uFileProperty, uFormCommands,
|
|
uFileSourceSetFilePropertyOperation, DCStringHashListUtf8, uClassesEx, uFile,
|
|
uFileSource, DCClassesUtf8, uHotkeyManager;
|
|
|
|
const
|
|
HotkeysCategoryMultiRename = 'MultiRename'; // <--Not displayed to user, stored in .scf (Shortcut Configuration File)
|
|
|
|
type
|
|
{ TMultiRenamePreset }
|
|
TMultiRenamePreset = class(TObject)
|
|
private
|
|
FPresetName: string;
|
|
FFileName: string;
|
|
FExtension: string;
|
|
FFileNameStyle: integer;
|
|
FExtensionStyle: integer;
|
|
FFind: string;
|
|
FReplace: string;
|
|
FRepExt: Boolean;
|
|
FRegExp: boolean;
|
|
FUseSubs: boolean;
|
|
FCaseSens: Boolean;
|
|
FOnlyFirst: Boolean;
|
|
FCounter: string;
|
|
FInterval: string;
|
|
FWidth: integer;
|
|
FLog: boolean;
|
|
FLogFile: string;
|
|
FLogAppend: boolean;
|
|
public
|
|
property PresetName: string read FPresetName write FPresetName;
|
|
property FileName: string read FFileName write FFileName;
|
|
property Extension: string read FExtension write FExtension;
|
|
property FileNameStyle: integer read FFileNameStyle write FFileNameStyle;
|
|
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;
|
|
property OnlyFirst: Boolean read FOnlyFirst write FOnlyFirst;
|
|
property Counter: string read FCounter write FCounter;
|
|
property Interval: string read FInterval write FInterval;
|
|
property Width: integer read FWidth write FWidth;
|
|
property Log: boolean read FLog write FLog;
|
|
property LogFile: string read FLogFile write FLogFile;
|
|
property LogAppend: boolean read FLogAppend write FLogAppend;
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
{ TMultiRenamePresetList }
|
|
TMultiRenamePresetList = class(TList)
|
|
private
|
|
function GetMultiRenamePreset(Index: integer): TMultiRenamePreset;
|
|
public
|
|
property MultiRenamePreset[Index: integer]: TMultiRenamePreset read GetMultiRenamePreset;
|
|
procedure Delete(Index: integer);
|
|
procedure Clear; override;
|
|
function Find(sPresetName: string): integer;
|
|
end;
|
|
|
|
{ tTargetForMask }
|
|
//Used to indicate of a mask is used for the "Filename" or the "Extension".
|
|
tTargetForMask = (tfmFilename, tfmExtension);
|
|
|
|
{ tRenameMaskToUse }
|
|
//Used as a parameter type to indicate the kind of field the mask is related to.
|
|
tRenameMaskToUse = (rmtuFilename, rmtuExtension, rmtuCounter, rmtuDate, rmtuTime, rmtuPlugins);
|
|
|
|
{ tSourceOfInformation }
|
|
tSourceOfInformation = (soiFilename, soiExtension, soiCounter, soiGUID, soiVariable, soiDate, soiTime, soiPlugins, soiFullName, soiPath);
|
|
|
|
{ tMenuActionStyle }
|
|
//Used to help to group common or similar action done for each mask.
|
|
tMenuActionStyle = (masStraight, masXCharacters, masXYCharacters, masAskVariable, masDirectorySelector);
|
|
|
|
{ TfrmMultiRename }
|
|
TfrmMultiRename = class(TAloneForm, IFormCommands)
|
|
cbCaseSens: TCheckBox;
|
|
cbRegExp: TCheckBox;
|
|
cbUseSubs: TCheckBox;
|
|
cbOnlyFirst: TCheckBox;
|
|
cbRepExt: TCheckBox;
|
|
pnlFindReplace: TPanel;
|
|
pnlButtons: TPanel;
|
|
StringGrid: TStringGrid;
|
|
pnlOptions: TPanel;
|
|
pnlOptionsLeft: TPanel;
|
|
gbMaska: TGroupBox;
|
|
lbName: TLabel;
|
|
cbName: TComboBox;
|
|
btnAnyNameMask: TKASButton;
|
|
cbNameMaskStyle: TComboBox;
|
|
lbExt: TLabel;
|
|
cbExt: TComboBox;
|
|
btnAnyExtMask: TKASButton;
|
|
cmbExtensionStyle: TComboBox;
|
|
gbPresets: TGroupBox;
|
|
cbPresets: TComboBox;
|
|
btnPresets: TKASButton;
|
|
spltMainSplitter: TSplitter;
|
|
pnlOptionsRight: TKASToolPanel;
|
|
gbFindReplace: TGroupBox;
|
|
lbFind: TLabel;
|
|
edFind: TEdit;
|
|
lbReplace: TLabel;
|
|
edReplace: TEdit;
|
|
gbCounter: TGroupBox;
|
|
lbStNb: TLabel;
|
|
edPoc: TEdit;
|
|
lbInterval: TLabel;
|
|
edInterval: TEdit;
|
|
lbWidth: TLabel;
|
|
cmbxWidth: TComboBox;
|
|
btnRestore: TBitBtn;
|
|
btnRename: TBitBtn;
|
|
btnConfig: TBitBtn;
|
|
btnEditor: TBitBtn;
|
|
btnClose: TBitBtn;
|
|
cbLog: TCheckBox;
|
|
cbLogAppend: TCheckBox;
|
|
fneRenameLogFileFilename: TFileNameEdit;
|
|
btnRelativeRenameLogFile: TSpeedButton;
|
|
btnViewRenameLogFile: TSpeedButton;
|
|
mmMainMenu: TMainMenu;
|
|
miActions: TMenuItem;
|
|
miResetAll: TMenuItem;
|
|
miEditor: TMenuItem;
|
|
miLoadNamesFromFile: TMenuItem;
|
|
miEditNames: TMenuItem;
|
|
miEditNewNames: TMenuItem;
|
|
miSeparator1: TMenuItem;
|
|
miConfiguration: TMenuItem;
|
|
miSeparator2: TMenuItem;
|
|
miRename: TMenuItem;
|
|
miClose: TMenuItem;
|
|
pmPresets: TPopupMenu;
|
|
pmFloatingMainMaskMenu: TPopupMenu;
|
|
pmDynamicMasks: TPopupMenu;
|
|
pmEditDirect: TPopupMenu;
|
|
mnuLoadFromFile: TMenuItem;
|
|
mnuEditNames: TMenuItem;
|
|
mnuEditNewNames: TMenuItem;
|
|
pmPathToBeRelativeToHelper: TPopupMenu;
|
|
actList: TActionList;
|
|
actResetAll: TAction;
|
|
actInvokeEditor: TAction;
|
|
actLoadNamesFromFile: TAction;
|
|
actLoadNamesFromClipboard: TAction;
|
|
actEditNames: TAction;
|
|
actEditNewNames: TAction;
|
|
actConfig: TAction;
|
|
actRename: TAction;
|
|
actClose: TAction;
|
|
actShowPresetsMenu: TAction;
|
|
actDropDownPresetList: TAction;
|
|
actLoadLastPreset: TAction;
|
|
actLoadPreset: TAction;
|
|
actLoadPreset1: TAction;
|
|
actLoadPreset2: TAction;
|
|
actLoadPreset3: TAction;
|
|
actLoadPreset4: TAction;
|
|
actLoadPreset5: TAction;
|
|
actLoadPreset6: TAction;
|
|
actLoadPreset7: TAction;
|
|
actLoadPreset8: TAction;
|
|
actLoadPreset9: TAction;
|
|
actSavePreset: TAction;
|
|
actSavePresetAs: TAction;
|
|
actRenamePreset: TAction;
|
|
actDeletePreset: TAction;
|
|
actSortPresets: TAction;
|
|
actAnyNameMask: TAction;
|
|
actNameNameMask: TAction;
|
|
actExtNameMask: TAction;
|
|
actDateNameMask: TAction;
|
|
actTimeNameMask: TAction;
|
|
actCtrNameMask: TAction;
|
|
actPlgnNameMask: TAction;
|
|
actClearNameMask: TAction;
|
|
actAnyExtMask: TAction;
|
|
actNameExtMask: TAction;
|
|
actExtExtMask: TAction;
|
|
actDateExtMask: TAction;
|
|
actTimeExtMask: TAction;
|
|
actCtrExtMask: TAction;
|
|
actPlgnExtMask: TAction;
|
|
actClearExtMask: TAction;
|
|
actInvokeRelativePath: TAction;
|
|
actViewRenameLogFile: TAction;
|
|
procedure FormCreate({%H-}Sender: TObject);
|
|
procedure FormCloseQuery({%H-}Sender: TObject; var CanClose: boolean);
|
|
procedure FormClose({%H-}Sender: TObject; var CloseAction: TCloseAction);
|
|
procedure FormShow(Sender: TObject);
|
|
procedure StringGridKeyDown({%H-}Sender: TObject; var Key: word; Shift: TShiftState);
|
|
procedure StringGridMouseDown({%H-}Sender: TObject; Button: TMouseButton; {%H-}Shift: TShiftState; X, Y: integer);
|
|
procedure StringGridMouseUp({%H-}Sender: TObject; Button: TMouseButton; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: integer);
|
|
procedure StringGridSelection({%H-}Sender: TObject; {%H-}aCol, aRow: integer);
|
|
procedure StringGridTopLeftChanged({%H-}Sender: TObject);
|
|
procedure cbNameStyleChange({%H-}Sender: TObject);
|
|
procedure cbPresetsChange({%H-}Sender: TObject);
|
|
procedure cbPresetsCloseUp({%H-}Sender: TObject);
|
|
procedure edFindChange({%H-}Sender: TObject);
|
|
procedure edReplaceChange({%H-}Sender: TObject);
|
|
procedure cbRegExpChange({%H-}Sender: TObject);
|
|
procedure edPocChange({%H-}Sender: TObject);
|
|
procedure edIntervalChange({%H-}Sender: TObject);
|
|
procedure cbLogClick({%H-}Sender: TObject);
|
|
procedure actExecute(Sender: TObject);
|
|
procedure actInvokeRelativePathExecute(Sender: TObject);
|
|
private
|
|
IniPropStorage: TIniPropStorageEx;
|
|
FCommands: TFormCommands;
|
|
FActuallyRenamingFile: boolean;
|
|
FSourceRow: integer;
|
|
FMoveRow: boolean;
|
|
FFileSource: IFileSource;
|
|
FFiles: TFiles;
|
|
FNewNames: TStringHashListUtf8;
|
|
FOldNames: TStringHashListUtf8;
|
|
FNames: TStringList;
|
|
FslVariableNames, FslVariableValues, FslVariableSuggestionName, FslVariableSuggestionValue: TStringList;
|
|
FRegExp: TRegExprW;
|
|
FFindText: TStringList;
|
|
FReplaceText: TStringList;
|
|
FPluginDispatcher: tTargetForMask;
|
|
FMultiRenamePresetList: TMultiRenamePresetList;
|
|
FParamPresetToLoadOnStart: string;
|
|
FLastPreset: string;
|
|
FbRememberLog, FbRememberAppend: boolean;
|
|
FsRememberRenameLogFilename: string;
|
|
FLog: TStringListEx;
|
|
property Commands: TFormCommands read FCommands implements IFormCommands;
|
|
procedure RestoreProperties(Sender: TObject);
|
|
procedure SetConfigurationState(bConfigurationSaved: boolean);
|
|
function GetPresetNameForCommand(const Params: array of string): string;
|
|
procedure LoadPresetsXml(AConfig: TXmlConfig);
|
|
function isOkToLosePresetModification: boolean;
|
|
procedure SavePreset(PresetName: string);
|
|
procedure SavePresetsXml(AConfig: TXmlConfig);
|
|
procedure SavePresets;
|
|
procedure DeletePreset(PresetName: string);
|
|
procedure FillPresetsList(const WantedSelectedPresetName: string = '');
|
|
procedure RefreshActivePresetCommands;
|
|
procedure InitializeMaskHelper;
|
|
procedure PopulateMainMenu;
|
|
procedure PopulateFilenameMenu(AMenuSomething: TComponent);
|
|
procedure PopulateExtensionMenu(AMenuSomething: TComponent);
|
|
procedure BuildMaskMenu(AMenuSomething: TComponent; iTarget: tTargetForMask; iMenuTypeMask: tRenameMaskToUse);
|
|
procedure BuildPresetsMenu(AMenuSomething: TComponent);
|
|
procedure BuildMenuAndPopup(iTarget: tTargetForMask; iMenuTypeMask: tRenameMaskToUse);
|
|
function GetMaskCategoryName(aRenameMaskToUse: tRenameMaskToUse): string;
|
|
function GetImageIndexCategoryName(aRenameMaskToUse: tRenameMaskToUse): integer;
|
|
function GetCategoryAction(TargetForMask: tTargetForMask; aRenameMask: tRenameMaskToUse): TAction;
|
|
function AppendSubMenuToThisMenu(ATargetMenu: TMenuItem; sCaption: string; iImageIndex: integer): TMenuItem;
|
|
function AppendActionMenuToThisMenu(ATargetMenu: TMenuItem; paramAction: TAction): TMenuItem;
|
|
procedure MenuItemXCharactersMaskClick(Sender: TObject);
|
|
procedure MenuItemVariableMaskClick(Sender: TObject);
|
|
procedure MenuItemStraightMaskClick(Sender: TObject);
|
|
procedure MenuItemDirectorySelectorMaskClick(Sender: TObject);
|
|
procedure PopupDynamicMenuAtThisControl(APopUpMenu: TPopupMenu; AControl: TControl);
|
|
procedure miPluginClick(Sender: TObject);
|
|
procedure InsertMask(const Mask: string; edChoose: TComboBox);
|
|
procedure InsertMask(const Mask: string; TargetForMask: tTargetForMask);
|
|
function sReplace(sMask: string; ItemNr: integer): string;
|
|
function sReplaceXX(const sFormatStr, sOrig: string): string;
|
|
function sReplaceVariable(const sFormatStr: string): string;
|
|
function sReplaceBadChars(const sPath: string): string;
|
|
function IsLetter(AChar: AnsiChar): boolean;
|
|
function ApplyStyle(InputString: string; Style: integer): string;
|
|
function FirstCharToUppercaseUTF8(InputString: string): string;
|
|
function FirstCharOfFirstWordToUppercaseUTF8(InputString: string): string;
|
|
function FirstCharOfEveryWordToUppercaseUTF8(InputString: string): string;
|
|
procedure LoadNamesFromList(const AFileList: TStrings);
|
|
procedure LoadNamesFromFile(const AFileName: string);
|
|
function FreshText(ItemIndex: integer): string;
|
|
function sHandleFormatString(const sFormatStr: string; ItemNr: integer): string;
|
|
procedure SetFilePropertyResult(Index: integer; aFile: TFile; aTemplate: TFileProperty; Result: TSetFilePropertyResult);
|
|
procedure SetOutputGlobalRenameLogFilename;
|
|
public
|
|
{ Public declarations }
|
|
constructor Create(TheOwner: TComponent); override; //Not used for actual renaming file. Present there just for the "TfrmOptionsHotkeys.FillCommandList" function who need to create the form in memory to extract internal commands from it.
|
|
constructor Create(TheOwner: TComponent; aFileSource: IFileSource; var aFiles: TFiles; const paramPreset: string); reintroduce;
|
|
destructor Destroy; override;
|
|
published
|
|
procedure cm_ResetAll(const Params: array of string);
|
|
procedure cm_InvokeEditor(const {%H-}Params: array of string);
|
|
procedure cm_LoadNamesFromFile(const {%H-}Params: array of string);
|
|
procedure cm_LoadNamesFromClipboard(const {%H-}Params: array of string);
|
|
procedure cm_EditNames(const {%H-}Params: array of string);
|
|
procedure cm_EditNewNames(const {%H-}Params: array of string);
|
|
procedure cm_Config(const {%H-}Params: array of string);
|
|
procedure cm_Rename(const {%H-}Params: array of string);
|
|
procedure cm_Close(const {%H-}Params: array of string);
|
|
procedure cm_ShowPresetsMenu(const {%H-}Params: array of string);
|
|
procedure cm_DropDownPresetList(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset(const Params: array of string);
|
|
procedure cm_LoadLastPreset(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset1(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset2(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset3(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset4(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset5(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset6(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset7(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset8(const {%H-}Params: array of string);
|
|
procedure cm_LoadPreset9(const {%H-}Params: array of string);
|
|
procedure cm_SavePreset(const Params: array of string);
|
|
procedure cm_SavePresetAs(const Params: array of string);
|
|
procedure cm_RenamePreset(const Params: array of string);
|
|
procedure cm_DeletePreset(const Params: array of string);
|
|
procedure cm_SortPresets(const Params: array of string);
|
|
procedure cm_AnyNameMask(const {%H-}Params: array of string);
|
|
procedure cm_NameNameMask(const {%H-}Params: array of string);
|
|
procedure cm_ExtNameMask(const {%H-}Params: array of string);
|
|
procedure cm_CtrNameMask(const {%H-}Params: array of string);
|
|
procedure cm_DateNameMask(const {%H-}Params: array of string);
|
|
procedure cm_TimeNameMask(const {%H-}Params: array of string);
|
|
procedure cm_PlgnNameMask(const {%H-}Params: array of string);
|
|
procedure cm_ClearNameMask(const {%H-}Params: array of string);
|
|
procedure cm_AnyExtMask(const {%H-}Params: array of string);
|
|
procedure cm_NameExtMask(const {%H-}Params: array of string);
|
|
procedure cm_ExtExtMask(const {%H-}Params: array of string);
|
|
procedure cm_CtrExtMask(const {%H-}Params: array of string);
|
|
procedure cm_DateExtMask(const {%H-}Params: array of string);
|
|
procedure cm_TimeExtMask(const {%H-}Params: array of string);
|
|
procedure cm_PlgnExtMask(const {%H-}Params: array of string);
|
|
procedure cm_ClearExtMask(const {%H-}Params: array of string);
|
|
procedure cm_ViewRenameLogFile(const {%H-}Params: array of string);
|
|
end;
|
|
|
|
{initialization function}
|
|
function ShowMultiRenameForm(aFileSource: IFileSource; var aFiles: TFiles; const PresetToLoad: string = ''): boolean;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses
|
|
//Lazarus, Free-Pascal, etc.
|
|
Dialogs, Math, Clipbrd,
|
|
|
|
//DC
|
|
fMain, uFileSourceOperation, uOperationsManager, uOSUtils, uDCUtils, uDebug,
|
|
DCOSUtils, DCStrUtils, uLng, uGlobs, uSpecialDir, uFileProcs, uShowForm,
|
|
fSelectTextRange, fSelectPathRange, uShowMsg, uFileFunctions, dmCommonData,
|
|
fMultiRenameWait, fSortAnything, DCConvertEncoding;
|
|
|
|
type
|
|
tMaskHelper = record
|
|
sMenuItem: string;
|
|
sKeyword: string;
|
|
MenuActionStyle: tMenuActionStyle;
|
|
iMenuType: tRenameMaskToUse;
|
|
iSourceOfInformation: tSourceOfInformation;
|
|
end;
|
|
|
|
const
|
|
sPresetsSection = 'MultiRenamePresets';
|
|
sLASTPRESET = '{BC322BF1-2185-47F6-9F99-D27ED1E23E53}';
|
|
sFRESHMASKS = '{40422152-9D05-469E-9B81-791AF8C369D8}';
|
|
iTARGETMASK = $00000001;
|
|
|
|
sREFRESHCOMMANDS = 'refreshcommands';
|
|
sDEFAULTLOGFILENAME = 'default.log';
|
|
|
|
CONFIG_NOTSAVED = False;
|
|
CONFIG_SAVED = True;
|
|
|
|
NBMAXHELPERS = 30;
|
|
|
|
var
|
|
//Sequence of operation to add a new mask:
|
|
// 1. Add its entry below in the "MaskHelpers" array.
|
|
// 2. Go immediately set its translatable string for the user in the function "InitializeMaskHelper" and the text in unit "uLng".
|
|
// 3. When editing "InitializeMaskHelper", make sure to update the TWO columns of indexes.
|
|
// 4. In the procedure "BuildMaskMenu", there is good chance you need to associated to the "AMenuItem.OnClick" the correct function based on "MaskHelpers[iSeekIndex].MenuActionStyle".
|
|
// 5. If it's a NEW procedure, you'll need to write it. You may check "MenuItemXCharactersMaskClick" for inspiration.
|
|
// 6. There is good chance you need to edit "sHandleFormatString" to add your new mask and action to do with it.
|
|
|
|
MaskHelpers: array[0..pred(NBMAXHELPERS)] of tMaskHelper =
|
|
(
|
|
(sMenuItem: ''; sKeyword: '[N]'; MenuActionStyle: masStraight; iMenuType: rmtuFilename; iSourceOfInformation: soiFilename),
|
|
(sMenuItem: ''; sKeyword: '[Nx]'; MenuActionStyle: masXCharacters; iMenuType: rmtuFilename; iSourceOfInformation: soiFilename),
|
|
(sMenuItem: ''; sKeyword: '[Nx:y]'; MenuActionStyle: masXYCharacters; iMenuType: rmtuFilename; iSourceOfInformation: soiFilename),
|
|
(sMenuItem: ''; sKeyword: '[A]'; MenuActionStyle: masStraight; iMenuType: rmtuFilename; iSourceOfInformation: soiFullName),
|
|
(sMenuItem: ''; sKeyword: '[Ax:y]'; MenuActionStyle: masXYCharacters; iMenuType: rmtuFilename; iSourceOfInformation: soiFullName),
|
|
(sMenuItem: ''; sKeyword: '[P]'; MenuActionStyle: masDirectorySelector; iMenuType: rmtuFilename; iSourceOfInformation: soiPath),
|
|
(sMenuItem: ''; sKeyword: '[E]'; MenuActionStyle: masStraight; iMenuType: rmtuExtension; iSourceOfInformation: soiExtension),
|
|
(sMenuItem: ''; sKeyword: '[Ex]'; MenuActionStyle: masXCharacters; iMenuType: rmtuExtension; iSourceOfInformation: soiExtension),
|
|
(sMenuItem: ''; sKeyword: '[Ex:y]'; MenuActionStyle: masXYCharacters; iMenuType: rmtuExtension; iSourceOfInformation: soiExtension),
|
|
(sMenuItem: ''; sKeyword: '[C]'; MenuActionStyle: masStraight; iMenuType: rmtuCounter; iSourceOfInformation: soiCounter),
|
|
(sMenuItem: ''; sKeyword: '[G]'; MenuActionStyle: masStraight; iMenuType: rmtuCounter; iSourceOfInformation: soiGUID),
|
|
(sMenuItem: ''; sKeyword: '[V:x]'; MenuActionStyle: masAskVariable; iMenuType: rmtuCounter; iSourceOfInformation: soiVariable),
|
|
(sMenuItem: ''; sKeyword: '[Y]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[YYYY]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[M]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[MM]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[MMM]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[MMMM]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[D]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[DD]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[DDD]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[DDDD]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[YYYY]-[MM]-[DD]'; MenuActionStyle: masStraight; iMenuType: rmtuDate; iSourceOfInformation: soiDate),
|
|
(sMenuItem: ''; sKeyword: '[h]'; MenuActionStyle: masStraight; iMenuType: rmtuTime; iSourceOfInformation: soiTime),
|
|
(sMenuItem: ''; sKeyword: '[hh]'; MenuActionStyle: masStraight; iMenuType: rmtuTime; iSourceOfInformation: soiTime),
|
|
(sMenuItem: ''; sKeyword: '[n]'; MenuActionStyle: masStraight; iMenuType: rmtuTime; iSourceOfInformation: soiTime),
|
|
(sMenuItem: ''; sKeyword: '[nn]'; MenuActionStyle: masStraight; iMenuType: rmtuTime; iSourceOfInformation: soiTime),
|
|
(sMenuItem: ''; sKeyword: '[s]'; MenuActionStyle: masStraight; iMenuType: rmtuTime; iSourceOfInformation: soiTime),
|
|
(sMenuItem: ''; sKeyword: '[ss]'; MenuActionStyle: masStraight; iMenuType: rmtuTime; iSourceOfInformation: soiTime),
|
|
(sMenuItem: ''; sKeyword: '[hh]-[nn]-[ss]'; MenuActionStyle: masStraight; iMenuType: rmtuTime; iSourceOfInformation: soiTime)
|
|
);
|
|
|
|
{ TMultiRenamePreset.Create }
|
|
constructor TMultiRenamePreset.Create;
|
|
begin
|
|
FPresetName := '';
|
|
FFileName := '[N]';
|
|
FExtension := '[E]';
|
|
FFileNameStyle := 0;
|
|
FExtensionStyle := 0;
|
|
FFind := '';
|
|
FReplace := '';
|
|
FRepExt := True;
|
|
FRegExp := False;
|
|
FUseSubs := False;
|
|
FCaseSens := False;
|
|
FOnlyFirst := False;
|
|
FCounter := '1';
|
|
FInterval := '1';
|
|
FWidth := 0;
|
|
FLog := False;
|
|
FLogFile := '';
|
|
FLogAppend := False;
|
|
end;
|
|
|
|
{ TMultiRenamePreset.Destory }
|
|
// Not so necessary, but useful with a breakpoint to validate object is really free from memory when deleting an element from the list of clearing that list.
|
|
destructor TMultiRenamePreset.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TMultiRenamePresetList.GetMultiRenamePreset }
|
|
function TMultiRenamePresetList.GetMultiRenamePreset(Index: integer): TMultiRenamePreset;
|
|
begin
|
|
Result := TMultiRenamePreset(Items[Index]);
|
|
end;
|
|
|
|
{ TMultiRenamePresetList.Delete }
|
|
procedure TMultiRenamePresetList.Delete(Index: integer);
|
|
begin
|
|
TMultiRenamePreset(Items[Index]).Free;
|
|
inherited Delete(Index);
|
|
end;
|
|
|
|
{ TMultiRenamePresetList.Clear }
|
|
procedure TMultiRenamePresetList.Clear;
|
|
var
|
|
Index: integer;
|
|
begin
|
|
for Index := pred(Count) downto 0 do
|
|
TMultiRenamePreset(Items[Index]).Free;
|
|
inherited Clear;
|
|
end;
|
|
|
|
{ TMultiRenamePresetList.Find }
|
|
function TMultiRenamePresetList.Find(sPresetName: string): integer;
|
|
var
|
|
iSeeker: integer = 0;
|
|
begin
|
|
Result := -1;
|
|
while (Result = -1) and (iSeeker < Count) do
|
|
if SameText(sPresetName, MultiRenamePreset[iSeeker].PresetName) then
|
|
Result := iSeeker
|
|
else
|
|
Inc(iSeeker);
|
|
end;
|
|
|
|
{ TfrmMultiRename.Create }
|
|
//Not used for actual renaming file.
|
|
//Present there just for the "TfrmOptionsHotkeys.FillCommandList" function who need to create the form in memory to extract internal commands from it.
|
|
constructor TfrmMultiRename.Create(TheOwner: TComponent);
|
|
var
|
|
FDummyFiles: TFiles;
|
|
begin
|
|
FDummyFiles := TFiles.Create(''); //Will be self destroyed by the "TfrmMultiRename" object itself.
|
|
Create(TheOwner, nil, FDummyFiles, '');
|
|
end;
|
|
|
|
{ TfrmMultiRename.Create }
|
|
constructor TfrmMultiRename.Create(TheOwner: TComponent; aFileSource: IFileSource; var aFiles: TFiles; const paramPreset: string);
|
|
begin
|
|
FActuallyRenamingFile := False;
|
|
FRegExp := TRegExprW.Create;
|
|
FNames := TStringList.Create;
|
|
FFindText := TStringList.Create;
|
|
FFindText.StrictDelimiter := True;
|
|
FFindText.Delimiter := '|';
|
|
FReplaceText := TStringList.Create;
|
|
FReplaceText.StrictDelimiter := True;
|
|
FReplaceText.Delimiter := '|';
|
|
FMultiRenamePresetList := TMultiRenamePresetList.Create;
|
|
FNewNames := TStringHashListUtf8.Create(FileNameCaseSensitive);
|
|
FOldNames := TStringHashListUtf8.Create(FileNameCaseSensitive);
|
|
FslVariableNames := TStringList.Create;
|
|
FslVariableValues := TStringList.Create;
|
|
FslVariableSuggestionName := TStringList.Create;
|
|
FslVariableSuggestionValue := TStringList.Create;
|
|
FFileSource := aFileSource;
|
|
FFiles := aFiles;
|
|
aFiles := nil;
|
|
FSourceRow := -1;
|
|
FMoveRow := False;
|
|
FParamPresetToLoadOnStart := paramPreset;
|
|
inherited Create(TheOwner);
|
|
|
|
FCommands := TFormCommands.Create(Self, actList);
|
|
end;
|
|
|
|
{ TfrmMultiRename.Destroy }
|
|
destructor TfrmMultiRename.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
FMultiRenamePresetList.Clear;
|
|
FreeAndNil(FMultiRenamePresetList);
|
|
FreeAndNil(FNewNames);
|
|
FreeAndNil(FOldNames);
|
|
FreeAndNil(FslVariableNames);
|
|
FreeAndNil(FslVariableValues);
|
|
FreeAndNil(FslVariableSuggestionName);
|
|
FreeAndNil(FslVariableSuggestionValue);
|
|
FreeAndNil(FFiles);
|
|
FreeAndNil(FNames);
|
|
FreeAndNil(FRegExp);
|
|
FreeAndNil(FFindText);
|
|
FreeAndNil(FReplaceText);
|
|
end;
|
|
|
|
{ TfrmMultiRename.FormCreate }
|
|
procedure TfrmMultiRename.FormCreate({%H-}Sender: TObject);
|
|
var
|
|
HMMultiRename: THMForm;
|
|
begin
|
|
// Localize File name style ComboBox
|
|
ParseLineToList(rsMulRenFileNameStyleList, cbNameMaskStyle.Items);
|
|
ParseLineToList(rsMulRenFileNameStyleList, cmbExtensionStyle.Items);
|
|
InitializeMaskHelper;
|
|
|
|
// Set row count
|
|
StringGrid.RowCount := FFiles.Count + 1;
|
|
StringGrid.FocusRectVisible := False;
|
|
|
|
// Initialize property storage
|
|
IniPropStorage := InitPropStorage(Self);
|
|
IniPropStorage.OnRestoreProperties := @RestoreProperties;
|
|
IniPropStorage.StoredValues.Add.DisplayName := 'lsvwFile_Columns.Item0_Width';
|
|
IniPropStorage.StoredValues.Add.DisplayName := 'lsvwFile_Columns.Item1_Width';
|
|
IniPropStorage.StoredValues.Add.DisplayName := 'lsvwFile_Columns.Item2_Width';
|
|
|
|
if gMulRenShowMenuBarOnTop then
|
|
Menu := mmMainMenu
|
|
else
|
|
Menu := nil;
|
|
|
|
if not gIconsInMenus then
|
|
begin
|
|
mmMainMenu.Images := nil;
|
|
pmDynamicMasks.Images := nil;
|
|
pmEditDirect.Images := nil;
|
|
pmPresets.Images := nil;
|
|
end;
|
|
|
|
HMMultiRename := HotMan.Register(Self, HotkeysCategoryMultiRename);
|
|
HMMultiRename.RegisterActionList(actList);
|
|
|
|
cbExt.Items.Assign(glsRenameExtMaskHistory);
|
|
cbName.Items.Assign(glsRenameNameMaskHistory);
|
|
|
|
// Set default values for controls.
|
|
cm_ResetAll([sREFRESHCOMMANDS + '=0']);
|
|
|
|
// Initialize presets.
|
|
LoadPresetsXml(gConfig);
|
|
|
|
if (FParamPresetToLoadOnStart <> '') and (FMultiRenamePresetList.Find(FParamPresetToLoadOnStart) <> -1) then
|
|
begin
|
|
FillPresetsList(FParamPresetToLoadOnStart);
|
|
end
|
|
else
|
|
begin
|
|
case gMulRenLaunchBehavior of
|
|
mrlbLastMaskUnderLastOne: FillPresetsList(sLASTPRESET);
|
|
mrlbLastPreset: FillPresetsList(FLastPreset);
|
|
mrlbFreshNew: FillPresetsList(sFRESHMASKS);
|
|
end;
|
|
end;
|
|
|
|
PopulateMainMenu;
|
|
gSpecialDirList.PopulateMenuWithSpecialDir(pmPathToBeRelativeToHelper, mp_PATHHELPER, nil);
|
|
FPluginDispatcher := tfmFilename;
|
|
end;
|
|
|
|
{ TfrmMultiRename.FormCloseQuery }
|
|
procedure TfrmMultiRename.FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
|
begin
|
|
if not isOkToLosePresetModification then
|
|
CanClose := False;
|
|
end;
|
|
|
|
{ TfrmMultiRename.FormClose }
|
|
procedure TfrmMultiRename.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
|
begin
|
|
SavePreset(sLASTPRESET);
|
|
|
|
glsRenameExtMaskHistory.Assign(cbExt.Items);
|
|
glsRenameNameMaskHistory.Assign(cbName.Items);
|
|
|
|
CloseAction := caFree;
|
|
with StringGrid.Columns do
|
|
begin
|
|
IniPropStorage.StoredValue['lsvwFile_Columns.Item0_Width'] := IntToStr(Items[0].Width);
|
|
IniPropStorage.StoredValue['lsvwFile_Columns.Item1_Width'] := IntToStr(Items[1].Width);
|
|
IniPropStorage.StoredValue['lsvwFile_Columns.Item2_Width'] := IntToStr(Items[2].Width);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmMultiRename.FormShow(Sender: TObject);
|
|
var
|
|
APoint: TPoint;
|
|
begin
|
|
{$IF DEFINED(LCLQT5)}
|
|
gbPresets.Constraints.MaxHeight:= cbPresets.Height + (gbPresets.Height - gbPresets.ClientHeight) +
|
|
gbPresets.ChildSizing.TopBottomSpacing * 2;
|
|
{$ENDIF}
|
|
APoint:= TPoint.Create(cbUseSubs.Left, 0);
|
|
fneRenameLogFileFilename.BorderSpacing.Left:= gbFindReplace.ClientToParent(APoint, pnlOptionsRight).X;
|
|
end;
|
|
|
|
{ TfrmMultiRename.StringGridKeyDown }
|
|
procedure TfrmMultiRename.StringGridKeyDown(Sender: TObject; var Key: word; Shift: TShiftState);
|
|
var
|
|
tmpFile: TFile;
|
|
DestRow: integer;
|
|
begin
|
|
DestRow := StringGrid.Row;
|
|
|
|
if (Shift = []) then
|
|
begin
|
|
if Key = VK_DELETE then
|
|
begin
|
|
FFiles.Delete(DestRow - 1);
|
|
StringGrid.RowCount:= StringGrid.RowCount - 1;
|
|
|
|
if FFiles.Count = 0 then
|
|
begin
|
|
OnCloseQuery:= nil;
|
|
Close;
|
|
end
|
|
else begin
|
|
StringGridTopLeftChanged(StringGrid);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (Shift = [ssShift]) then
|
|
begin
|
|
case Key of
|
|
VK_UP:
|
|
begin
|
|
DestRow := StringGrid.Row - 1;
|
|
end;
|
|
VK_DOWN:
|
|
begin
|
|
DestRow := StringGrid.Row + 1;
|
|
end;
|
|
end;
|
|
|
|
if (DestRow <> StringGrid.Row) and (0 < DestRow) and (DestRow < StringGrid.RowCount) then
|
|
begin
|
|
tmpFile := FFiles.Items[DestRow - 1];
|
|
FFiles.Items[DestRow - 1] := FFiles.Items[StringGrid.Row - 1];
|
|
FFiles.Items[StringGrid.Row - 1] := tmpFile;
|
|
|
|
StringGridTopLeftChanged(StringGrid);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.StringGridMouseDown }
|
|
procedure TfrmMultiRename.StringGridMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
|
|
var
|
|
SourceCol: integer = 0;
|
|
begin
|
|
if (Button = mbLeft) then
|
|
begin
|
|
StringGrid.MouseToCell(X, Y, SourceCol, FSourceRow);
|
|
if (FSourceRow > 0) then
|
|
begin
|
|
FMoveRow := True;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.StringGridMouseUp }
|
|
procedure TfrmMultiRename.StringGridMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
|
|
begin
|
|
if Button = mbLeft then
|
|
begin
|
|
FMoveRow := False;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.StringGridSelection }
|
|
procedure TfrmMultiRename.StringGridSelection(Sender: TObject; aCol, aRow: integer);
|
|
var
|
|
tmpFile: TFile;
|
|
begin
|
|
if FMoveRow and (aRow <> FSourceRow) then
|
|
begin
|
|
tmpFile := FFiles.Items[aRow - 1];
|
|
FFiles.Items[aRow - 1] := FFiles.Items[FSourceRow - 1];
|
|
FFiles.Items[FSourceRow - 1] := tmpFile;
|
|
|
|
FSourceRow := aRow;
|
|
StringGridTopLeftChanged(StringGrid);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.StringGridTopLeftChanged }
|
|
procedure TfrmMultiRename.StringGridTopLeftChanged(Sender: TObject);
|
|
var
|
|
I, iRowCount: integer;
|
|
begin
|
|
iRowCount := StringGrid.TopRow + StringGrid.VisibleRowCount;
|
|
if iRowCount > FFiles.Count then
|
|
iRowCount := FFiles.Count;
|
|
for I := StringGrid.TopRow to iRowCount do
|
|
begin
|
|
StringGrid.Cells[0, I] := FFiles[I - 1].Name;
|
|
StringGrid.Cells[1, I] := FreshText(I - 1);
|
|
StringGrid.Cells[2, I] := FFiles[I - 1].Path;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cbNameStyleChange }
|
|
procedure TfrmMultiRename.cbNameStyleChange(Sender: TObject);
|
|
begin
|
|
StringGridTopLeftChanged(StringGrid);
|
|
if ActiveControl <> cbPresets then
|
|
SetConfigurationState(CONFIG_NOTSAVED);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cbPresetsChange }
|
|
procedure TfrmMultiRename.cbPresetsChange(Sender: TObject);
|
|
begin
|
|
if cbPresets.ItemIndex <> 0 then
|
|
cm_LoadPreset(['name=' + cbPresets.Items.Strings[cbPresets.ItemIndex]])
|
|
else
|
|
cm_LoadPreset(['name=' + sLASTPRESET]);
|
|
RefreshActivePresetCommands;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cbPresetsCloseUp }
|
|
procedure TfrmMultiRename.cbPresetsCloseUp(Sender: TObject);
|
|
begin
|
|
if cbName.Enabled and gbMaska.Enabled then ActiveControl := cbName;
|
|
cbName.SelStart := UTF8Length(cbName.Text);
|
|
end;
|
|
|
|
{ TfrmMultiRename.edFindChange }
|
|
procedure TfrmMultiRename.edFindChange(Sender: TObject);
|
|
begin
|
|
if cbRegExp.Checked then
|
|
FRegExp.Expression := CeUtf8ToUtf16(edFind.Text)
|
|
else
|
|
begin
|
|
FFindText.DelimitedText := edFind.Text;
|
|
end;
|
|
SetConfigurationState(CONFIG_NOTSAVED);
|
|
StringGridTopLeftChanged(StringGrid);
|
|
end;
|
|
|
|
{ TfrmMultiRename.edReplaceChange }
|
|
procedure TfrmMultiRename.edReplaceChange(Sender: TObject);
|
|
begin
|
|
if not cbRegExp.Checked then
|
|
begin
|
|
FReplaceText.DelimitedText := edReplace.Text;
|
|
end;
|
|
SetConfigurationState(CONFIG_NOTSAVED);
|
|
StringGridTopLeftChanged(StringGrid);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cbRegExpChange }
|
|
procedure TfrmMultiRename.cbRegExpChange(Sender: TObject);
|
|
begin
|
|
if cbRegExp.Checked then
|
|
cbUseSubs.Checked := boolean(cbUseSubs.Tag)
|
|
else
|
|
begin
|
|
cbUseSubs.Tag := integer(cbUseSubs.Checked);
|
|
cbUseSubs.Checked := False;
|
|
end;
|
|
cbUseSubs.Enabled := cbRegExp.Checked;
|
|
edFindChange(edFind);
|
|
edReplaceChange(edReplace);
|
|
end;
|
|
|
|
{ TfrmMultiRename.edPocChange }
|
|
procedure TfrmMultiRename.edPocChange(Sender: TObject);
|
|
var
|
|
c: integer;
|
|
begin
|
|
c := StrToIntDef(edPoc.Text, maxint);
|
|
if c = MaxInt then
|
|
with edPoc do //editbox only for numbers
|
|
begin
|
|
Text := '1';
|
|
SelectAll;
|
|
end;
|
|
SetConfigurationState(CONFIG_NOTSAVED);
|
|
StringGridTopLeftChanged(StringGrid);
|
|
end;
|
|
|
|
{ TfrmMultiRename.edIntervalChange }
|
|
procedure TfrmMultiRename.edIntervalChange(Sender: TObject);
|
|
var
|
|
c: integer;
|
|
begin
|
|
c := StrToIntDef(edInterval.Text, maxint);
|
|
if c = MaxInt then
|
|
with edInterval do //editbox only for numbers
|
|
begin
|
|
Text := '1';
|
|
SelectAll;
|
|
end;
|
|
SetConfigurationState(CONFIG_NOTSAVED);
|
|
StringGridTopLeftChanged(StringGrid);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cbLogClick }
|
|
procedure TfrmMultiRename.cbLogClick(Sender: TObject);
|
|
begin
|
|
fneRenameLogFileFilename.Enabled := cbLog.Checked;
|
|
actInvokeRelativePath.Enabled := cbLog.Checked;
|
|
actViewRenameLogFile.Enabled := cbLog.Checked;
|
|
cbLogAppend.Enabled := cbLog.Checked;
|
|
SetConfigurationState(CONFIG_NOTSAVED);
|
|
end;
|
|
|
|
{ TfrmMultiRename.actExecute }
|
|
procedure TfrmMultiRename.actExecute(Sender: TObject);
|
|
var
|
|
cmd: string;
|
|
begin
|
|
cmd := (Sender as TAction).Name;
|
|
cmd := 'cm_' + Copy(cmd, 4, Length(cmd) - 3);
|
|
Commands.ExecuteCommand(cmd, []);
|
|
end;
|
|
|
|
{ TfrmMultiRename.actInvokeRelativePathExecute }
|
|
procedure TfrmMultiRename.actInvokeRelativePathExecute(Sender: TObject);
|
|
begin
|
|
fneRenameLogFileFilename.SetFocus;
|
|
gSpecialDirList.SetSpecialDirRecipientAndItsType(fneRenameLogFileFilename, pfFILE);
|
|
pmPathToBeRelativeToHelper.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
|
|
end;
|
|
|
|
{ TfrmMultiRename.RestoreProperties }
|
|
procedure TfrmMultiRename.RestoreProperties(Sender: TObject);
|
|
begin
|
|
with StringGrid.Columns do
|
|
begin
|
|
Items[0].Width := StrToIntDef(IniPropStorage.StoredValue['lsvwFile_Columns.Item0_Width'], Items[0].Width);
|
|
Items[1].Width := StrToIntDef(IniPropStorage.StoredValue['lsvwFile_Columns.Item1_Width'], Items[1].Width);
|
|
Items[2].Width := StrToIntDef(IniPropStorage.StoredValue['lsvwFile_Columns.Item2_Width'], Items[2].Width);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.SetConfigurationState }
|
|
procedure TfrmMultiRename.SetConfigurationState(bConfigurationSaved: boolean);
|
|
begin
|
|
if not cbPresets.DroppedDown then
|
|
begin
|
|
if bConfigurationSaved or (cbPresets.ItemIndex > 0) then
|
|
begin
|
|
if cbPresets.Enabled <> bConfigurationSaved then
|
|
begin
|
|
cbPresets.Enabled := bConfigurationSaved;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.GetPresetNameForCommand }
|
|
// Wanted preset may be given via "name=presetname" or via "index=indexno".
|
|
function TfrmMultiRename.GetPresetNameForCommand(const Params: array of string): string;
|
|
var
|
|
Param, sValue: string;
|
|
iIndex: integer;
|
|
begin
|
|
Result := '';
|
|
|
|
for Param in Params do
|
|
begin
|
|
if GetParamValue(Param, 'name', sValue) then
|
|
Result := sValue
|
|
else
|
|
if GetParamValue(Param, 'index', sValue) then
|
|
begin
|
|
iIndex := StrToIntDef(sValue, -1);
|
|
if (iIndex >= 0) and (iIndex < cbPresets.items.Count) then
|
|
if iIndex = 0 then
|
|
Result := sLASTPRESET
|
|
else
|
|
Result := cbPresets.Items.Strings[iIndex];
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.LoadPresetsXml }
|
|
procedure TfrmMultiRename.LoadPresetsXml(AConfig: TXmlConfig);
|
|
var
|
|
PresetName: string;
|
|
AMultiRenamePreset: TMultiRenamePreset;
|
|
ANode: TXmlNode;
|
|
PresetIndex: integer;
|
|
begin
|
|
FMultiRenamePresetList.Clear;
|
|
|
|
ANode := AConfig.FindNode(AConfig.RootNode, sPresetsSection);
|
|
FLastPreset := AConfig.GetValue(ANode, 'LastPreset', sLASTPRESET);
|
|
|
|
ANode := AConfig.FindNode(ANode, 'Presets');
|
|
if Assigned(ANode) then
|
|
begin
|
|
ANode := ANode.FirstChild;
|
|
while Assigned(ANode) do
|
|
begin
|
|
if ANode.CompareName('Preset') = 0 then
|
|
begin
|
|
if AConfig.TryGetValue(ANode, 'Name', PresetName) then
|
|
begin
|
|
if FMultiRenamePresetList.Find(PresetName) = -1 then //Make sure we don't load preset with the same name.
|
|
begin
|
|
AMultiRenamePreset := TMultiRenamePreset.Create;
|
|
AMultiRenamePreset.PresetName := PresetName;
|
|
FMultiRenamePresetList.Add(AMultiRenamePreset);
|
|
|
|
AMultiRenamePreset.FileName := AConfig.GetValue(ANode, 'Filename', '[N]');
|
|
AMultiRenamePreset.Extension := AConfig.GetValue(ANode, 'Extension', '[E]');
|
|
AMultiRenamePreset.FileNameStyle := AConfig.GetValue(ANode, 'FilenameStyle', 0);
|
|
AMultiRenamePreset.ExtensionStyle := AConfig.GetValue(ANode, 'ExtensionStyle', 0);
|
|
|
|
if AConfig.TryGetAttr(ANode, 'Find/Value', PresetName) then
|
|
AMultiRenamePreset.Find := PresetName
|
|
else begin
|
|
AMultiRenamePreset.Find := AConfig.GetValue(ANode, 'Find', '');
|
|
end;
|
|
if AConfig.TryGetAttr(ANode, 'Replace/Value', PresetName) then
|
|
AMultiRenamePreset.Replace := PresetName
|
|
else begin
|
|
AMultiRenamePreset.Replace := AConfig.GetValue(ANode, 'Replace', '');
|
|
end;
|
|
|
|
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);
|
|
AMultiRenamePreset.OnlyFirst := AConfig.GetValue(ANode, 'OnlyFirst', False);
|
|
AMultiRenamePreset.Counter := AConfig.GetValue(ANode, 'Counter', '1');
|
|
AMultiRenamePreset.Interval := AConfig.GetValue(ANode, 'Interval', '1');
|
|
AMultiRenamePreset.Width := AConfig.GetValue(ANode, 'Width', 0);
|
|
AMultiRenamePreset.Log := AConfig.GetValue(ANode, 'Log/Enabled', False);
|
|
AMultiRenamePreset.LogAppend := AConfig.GetValue(ANode, 'Log/Append', False);
|
|
AMultiRenamePreset.LogFile := AConfig.GetValue(ANode, 'Log/File', '');
|
|
end;
|
|
end
|
|
else
|
|
DCDebug('Invalid entry in configuration: ' + AConfig.GetPathFromNode(ANode) + '.');
|
|
end;
|
|
ANode := ANode.NextSibling;
|
|
end;
|
|
end;
|
|
|
|
//Make sure the "sLASTPRESET" is at position 0.
|
|
PresetIndex := FMultiRenamePresetList.Find(sLASTPRESET);
|
|
if PresetIndex <> 0 then
|
|
begin
|
|
if PresetIndex <> -1 then
|
|
begin
|
|
//If it's present but not at zero, move it to 0.
|
|
FMultiRenamePresetList.Move(PresetIndex, 0);
|
|
end
|
|
else
|
|
begin
|
|
AMultiRenamePreset := TMultiRenamePreset.Create;
|
|
AMultiRenamePreset.PresetName := sLASTPRESET;
|
|
FMultiRenamePresetList.Insert(0, AMultiRenamePreset);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.isOkToLosePresetModification }
|
|
function TfrmMultiRename.isOkToLosePresetModification: boolean;
|
|
var
|
|
MyMsgResult: TMyMsgResult;
|
|
begin
|
|
Result := False;
|
|
|
|
if (cbPresets.ItemIndex <= 0) or (cbPresets.Enabled) or (not Visible) then
|
|
Result := True
|
|
else
|
|
begin
|
|
case gMulRenExitModifiedPreset of
|
|
mrempIgnoreSaveLast:
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
mrempSaveAutomatically:
|
|
begin
|
|
if cbPresets.ItemIndex > 0 then
|
|
cm_SavePreset(['name=' + cbPresets.Items.Strings[cbPresets.ItemIndex]]);
|
|
Result := True;
|
|
end;
|
|
|
|
mrempPromptUser:
|
|
begin
|
|
MyMsgResult := msgYesNoCancel(Format(rsMulRenSaveModifiedPreset, [cbPresets.Items.Strings[cbPresets.ItemIndex]]), msmbCancel);
|
|
case MyMsgResult of
|
|
mmrYes:
|
|
begin
|
|
cm_SavePreset([]);
|
|
Result := True;
|
|
end;
|
|
mmrNo: Result := True;
|
|
mmrCancel: ;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.SavePreset }
|
|
procedure TfrmMultiRename.SavePreset(PresetName: string);
|
|
var
|
|
PresetIndex: integer;
|
|
AMultiRenamePresetObject: TMultiRenamePreset;
|
|
begin
|
|
if PresetName <> '' then
|
|
begin
|
|
PresetIndex := FMultiRenamePresetList.Find(PresetName);
|
|
if PresetIndex = -1 then
|
|
begin
|
|
AMultiRenamePresetObject := TMultiRenamePreset.Create;
|
|
AMultiRenamePresetObject.PresetName := PresetName;
|
|
PresetIndex := FMultiRenamePresetList.Add(AMultiRenamePresetObject);
|
|
end;
|
|
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].FileName := cbName.Text;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Extension := cbExt.Text;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].FileNameStyle := cbNameMaskStyle.ItemIndex;
|
|
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;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].OnlyFirst := cbOnlyFirst.Checked;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Counter := edPoc.Text;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Interval := edInterval.Text;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Width := cmbxWidth.ItemIndex;
|
|
|
|
case gMulRenSaveRenamingLog of
|
|
mrsrlPerPreset:
|
|
begin
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Log := cbLog.Checked;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].LogFile := fneRenameLogFileFilename.FileName;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].LogAppend := cbLogAppend.Checked;
|
|
end;
|
|
|
|
mrsrlAppendSameLog:
|
|
begin
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Log := FbRememberLog;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].LogAppend := FbRememberAppend;
|
|
FMultiRenamePresetList.MultiRenamePreset[PresetIndex].LogFile := FsRememberRenameLogFilename;
|
|
end;
|
|
end;
|
|
|
|
SavePresets;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.SavePresetsXml }
|
|
procedure TfrmMultiRename.SavePresetsXml(AConfig: TXmlConfig);
|
|
var
|
|
i: integer;
|
|
ANode, SubNode: TXmlNode;
|
|
begin
|
|
ANode := AConfig.FindNode(AConfig.RootNode, sPresetsSection, True);
|
|
AConfig.ClearNode(ANode);
|
|
|
|
if cbPresets.ItemIndex = 0 then
|
|
AConfig.SetValue(ANode, 'LastPreset', sLASTPRESET)
|
|
else
|
|
AConfig.SetValue(ANode, 'LastPreset', cbPresets.Items.Strings[cbPresets.ItemIndex]);
|
|
|
|
ANode := AConfig.FindNode(ANode, 'Presets', True);
|
|
|
|
for i := 0 to pred(FMultiRenamePresetList.Count) do
|
|
begin
|
|
SubNode := AConfig.AddNode(ANode, 'Preset');
|
|
AConfig.AddValue(SubNode, 'Name', FMultiRenamePresetList.MultiRenamePreset[i].PresetName);
|
|
AConfig.AddValue(SubNode, 'Filename', FMultiRenamePresetList.MultiRenamePreset[i].FileName);
|
|
AConfig.AddValue(SubNode, 'Extension', FMultiRenamePresetList.MultiRenamePreset[i].Extension);
|
|
AConfig.AddValue(SubNode, 'FilenameStyle', FMultiRenamePresetList.MultiRenamePreset[i].FileNameStyle);
|
|
AConfig.AddValue(SubNode, 'ExtensionStyle', FMultiRenamePresetList.MultiRenamePreset[i].ExtensionStyle);
|
|
AConfig.SetAttr(SubNode, 'Find/Value', FMultiRenamePresetList.MultiRenamePreset[i].Find);
|
|
AConfig.SetAttr(SubNode, 'Replace/Value', 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);
|
|
AConfig.AddValue(SubNode, 'OnlyFirst', FMultiRenamePresetList.MultiRenamePreset[i].OnlyFirst);
|
|
AConfig.AddValue(SubNode, 'Counter', FMultiRenamePresetList.MultiRenamePreset[i].Counter);
|
|
AConfig.AddValue(SubNode, 'Interval', FMultiRenamePresetList.MultiRenamePreset[i].Interval);
|
|
AConfig.AddValue(SubNode, 'Width', FMultiRenamePresetList.MultiRenamePreset[i].Width);
|
|
AConfig.SetValue(SubNode, 'Log/Enabled', FMultiRenamePresetList.MultiRenamePreset[i].Log);
|
|
AConfig.SetValue(SubNode, 'Log/Append', FMultiRenamePresetList.MultiRenamePreset[i].LogAppend);
|
|
AConfig.SetValue(SubNode, 'Log/File', FMultiRenamePresetList.MultiRenamePreset[i].LogFile);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.SavePresets }
|
|
procedure TfrmMultiRename.SavePresets;
|
|
begin
|
|
SavePresetsXml(gConfig);
|
|
gConfig.Save;
|
|
end;
|
|
|
|
{ TfrmMultiRename.DeletePreset }
|
|
procedure TfrmMultiRename.DeletePreset(PresetName: string);
|
|
var
|
|
PresetIndex: integer;
|
|
begin
|
|
if PresetName <> '' then
|
|
begin
|
|
PresetIndex := FMultiRenamePresetList.Find(PresetName);
|
|
if PresetIndex <> -1 then
|
|
begin
|
|
FMultiRenamePresetList.Delete(PresetIndex);
|
|
SavePresets;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.FillPresetsList }
|
|
//We fill the preset drop list with the element in memory.
|
|
//If it's specified when called, will attempt to load the specified preset in parameter.
|
|
//If it's not specified, will attempt to re-select the one that was initially selected.
|
|
//If nothing is still selected, we'll select the [Last One].
|
|
procedure TfrmMultiRename.FillPresetsList(const WantedSelectedPresetName: string = '');
|
|
var
|
|
i: integer;
|
|
sRememberSelection, PresetName: string;
|
|
|
|
begin
|
|
sRememberSelection := '';
|
|
|
|
if WantedSelectedPresetName <> '' then
|
|
sRememberSelection := WantedSelectedPresetName;
|
|
|
|
if sRememberSelection = '' then
|
|
if cbPresets.ItemIndex <> -1 then
|
|
if cbPresets.ItemIndex < cbPresets.Items.Count then
|
|
sRememberSelection := cbPresets.Items.Strings[cbPresets.ItemIndex];
|
|
|
|
cbPresets.Clear;
|
|
cbPresets.Items.Add(rsMulRenLastPreset);
|
|
|
|
for i := 0 to pred(FMultiRenamePresetList.Count) do
|
|
begin
|
|
PresetName := FMultiRenamePresetList.MultiRenamePreset[i].PresetName;
|
|
if (PresetName <> sLASTPRESET) then
|
|
if cbPresets.Items.IndexOf(PresetName) = -1 then
|
|
cbPresets.Items.Add(PresetName);
|
|
end;
|
|
|
|
if (WantedSelectedPresetName = sLASTPRESET) or (WantedSelectedPresetName = sFRESHMASKS) then
|
|
cbPresets.ItemIndex := 0
|
|
else
|
|
if sRememberSelection <> '' then
|
|
if cbPresets.Items.IndexOf(sRememberSelection) <> -1 then
|
|
cbPresets.ItemIndex := cbPresets.Items.IndexOf(sRememberSelection);
|
|
|
|
if cbPresets.ItemIndex = -1 then
|
|
if cbPresets.Items.Count > 0 then
|
|
cbPresets.ItemIndex := 0;
|
|
|
|
if WantedSelectedPresetName <> sFRESHMASKS then
|
|
begin
|
|
cbPresetsChange(cbPresets);
|
|
RefreshActivePresetCommands;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.RefreshActivePresetCommands }
|
|
procedure TfrmMultiRename.RefreshActivePresetCommands;
|
|
begin
|
|
//"Load last preset" is always available since it's the [Last One].
|
|
actLoadPreset1.Enabled := (cbPresets.Items.Count > 1) and (cbPresets.Enabled);
|
|
actLoadPreset2.Enabled := (cbPresets.Items.Count > 2) and (cbPresets.Enabled);
|
|
actLoadPreset3.Enabled := (cbPresets.Items.Count > 3) and (cbPresets.Enabled);
|
|
actLoadPreset4.Enabled := (cbPresets.Items.Count > 4) and (cbPresets.Enabled);
|
|
actLoadPreset5.Enabled := (cbPresets.Items.Count > 5) and (cbPresets.Enabled);
|
|
actLoadPreset6.Enabled := (cbPresets.Items.Count > 6) and (cbPresets.Enabled);
|
|
actLoadPreset7.Enabled := (cbPresets.Items.Count > 7) and (cbPresets.Enabled);
|
|
actLoadPreset8.Enabled := (cbPresets.Items.Count > 8) and (cbPresets.Enabled);
|
|
actLoadPreset9.Enabled := (cbPresets.Items.Count > 9) and (cbPresets.Enabled);
|
|
actSavePreset.Enabled := (cbPresets.ItemIndex > 0);
|
|
//"Save as is always available so we may save the [Last One]
|
|
actRenamePreset.Enabled := (cbPresets.ItemIndex > 0);
|
|
actDeletePreset.Enabled := (cbPresets.ItemIndex > 0);
|
|
end;
|
|
|
|
{ TfrmMultiRename.InitializeMaskHelper }
|
|
procedure TfrmMultiRename.InitializeMaskHelper;
|
|
begin
|
|
if MaskHelpers[00].sMenuItem = '' then //"MaskHelpers" are no tin the object but generic, so we just need to initialize once.
|
|
begin
|
|
MaskHelpers[00].sMenuItem := MaskHelpers[00].sKeyword + ' ' + rsMulRenMaskName;
|
|
MaskHelpers[01].sMenuItem := MaskHelpers[01].sKeyword + ' ' + rsMulRenMaskCharAtPosX;
|
|
MaskHelpers[02].sMenuItem := MaskHelpers[02].sKeyword + ' ' + rsMulRenMaskCharAtPosXtoY;
|
|
MaskHelpers[03].sMenuItem := MaskHelpers[03].sKeyword + ' ' + rsMulRenMaskFullName;
|
|
MaskHelpers[04].sMenuItem := MaskHelpers[04].sKeyword + ' ' + rsMulRenMaskFullNameCharAtPosXtoY;
|
|
MaskHelpers[05].sMenuItem := MaskHelpers[05].sKeyword + ' ' + rsMulRenMaskParent;
|
|
MaskHelpers[06].sMenuItem := MaskHelpers[06].sKeyword + ' ' + rsMulRenMaskExtension;
|
|
MaskHelpers[07].sMenuItem := MaskHelpers[07].sKeyword + ' ' + rsMulRenMaskCharAtPosX;
|
|
MaskHelpers[08].sMenuItem := MaskHelpers[08].sKeyword + ' ' + rsMulRenMaskCharAtPosXtoY;
|
|
MaskHelpers[09].sMenuItem := MaskHelpers[09].sKeyword + ' ' + rsMulRenMaskCounter;
|
|
MaskHelpers[10].sMenuItem := MaskHelpers[10].sKeyword + ' ' + rsMulRenMaskGUID;
|
|
MaskHelpers[11].sMenuItem := MaskHelpers[11].sKeyword + ' ' + rsMulRenMaskVarOnTheFly;
|
|
MaskHelpers[12].sMenuItem := MaskHelpers[12].sKeyword + ' ' + rsMulRenMaskYear2Digits;
|
|
MaskHelpers[13].sMenuItem := MaskHelpers[13].sKeyword + ' ' + rsMulRenMaskYear4Digits;
|
|
MaskHelpers[14].sMenuItem := MaskHelpers[14].sKeyword + ' ' + rsMulRenMaskMonth;
|
|
MaskHelpers[15].sMenuItem := MaskHelpers[15].sKeyword + ' ' + rsMulRenMaskMonth2Digits;
|
|
MaskHelpers[16].sMenuItem := MaskHelpers[16].sKeyword + ' ' + rsMulRenMaskMonthAbrev;
|
|
MaskHelpers[17].sMenuItem := MaskHelpers[17].sKeyword + ' ' + rsMulRenMaskMonthComplete;
|
|
MaskHelpers[18].sMenuItem := MaskHelpers[18].sKeyword + ' ' + rsMulRenMaskDay;
|
|
MaskHelpers[19].sMenuItem := MaskHelpers[19].sKeyword + ' ' + rsMulRenMaskDay2Digits;
|
|
MaskHelpers[20].sMenuItem := MaskHelpers[20].sKeyword + ' ' + rsMulRenMaskDOWAbrev;
|
|
MaskHelpers[21].sMenuItem := MaskHelpers[21].sKeyword + ' ' + rsMulRenMaskDOWComplete;
|
|
MaskHelpers[22].sMenuItem := MaskHelpers[22].sKeyword + ' ' + rsMulRenMaskCompleteDate;
|
|
MaskHelpers[23].sMenuItem := MaskHelpers[23].sKeyword + ' ' + rsMulRenMaskHour;
|
|
MaskHelpers[24].sMenuItem := MaskHelpers[24].sKeyword + ' ' + rsMulRenMaskHour2Digits;
|
|
MaskHelpers[25].sMenuItem := MaskHelpers[25].sKeyword + ' ' + rsMulRenMaskMin;
|
|
MaskHelpers[26].sMenuItem := MaskHelpers[26].sKeyword + ' ' + rsMulRenMaskMin2Digits;
|
|
MaskHelpers[27].sMenuItem := MaskHelpers[27].sKeyword + ' ' + rsMulRenMaskSec;
|
|
MaskHelpers[28].sMenuItem := MaskHelpers[28].sKeyword + ' ' + rsMulRenMaskSec2Digits;
|
|
MaskHelpers[29].sMenuItem := MaskHelpers[29].sKeyword + ' ' + rsMulRenMaskCompleteTime;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.PopulateMainMenu }
|
|
// This main menu is not essential.
|
|
// But it does not occupy a lot of pixels and may benefit to user to help to both discover and remember the keyboard shortcut by visualizing them.
|
|
// Also, we populate it run-time to save work to valuable translators so they won't have to re-translate the same strings or to validate copies.
|
|
procedure TfrmMultiRename.PopulateMainMenu;
|
|
var
|
|
miPresets, miMasks, miSubMasks: TMenuItem;
|
|
begin
|
|
btnAnyNameMask.Action := actAnyNameMask;
|
|
btnAnyNameMask.Caption := '...';
|
|
btnAnyNameMask.Width := fneRenameLogFileFilename.ButtonWidth;
|
|
btnAnyExtMask.Action := actAnyExtMask;
|
|
btnAnyExtMask.Caption := '...';
|
|
btnAnyExtMask.Width := fneRenameLogFileFilename.ButtonWidth;
|
|
btnRelativeRenameLogFile.Action := actInvokeRelativePath;
|
|
btnRelativeRenameLogFile.Caption := '';
|
|
btnRelativeRenameLogFile.Width := fneRenameLogFileFilename.ButtonWidth;
|
|
btnRelativeRenameLogFile.Hint := actInvokeRelativePath.Caption;
|
|
btnViewRenameLogFile.Action := actViewRenameLogFile;
|
|
btnViewRenameLogFile.Caption := '';
|
|
btnViewRenameLogFile.Width := fneRenameLogFileFilename.ButtonWidth;
|
|
btnViewRenameLogFile.Hint := actViewRenameLogFile.Caption;
|
|
btnPresets.Action := actShowPresetsMenu;
|
|
btnPresets.Caption := '';
|
|
btnPresets.Hint := actShowPresetsMenu.Caption;
|
|
btnPresets.Constraints.MinWidth := fneRenameLogFileFilename.ButtonWidth;
|
|
|
|
miPresets := TMenuItem.Create(mmMainMenu);
|
|
miPresets.Caption := gbPresets.Caption;
|
|
mmMainMenu.Items.Add(miPresets);
|
|
BuildPresetsMenu(miPresets);
|
|
BuildPresetsMenu(pmPresets);
|
|
|
|
miMasks := TMenuItem.Create(mmMainMenu);
|
|
miMasks.Caption := gbMaska.Caption;
|
|
mmMainMenu.Items.Add(miMasks);
|
|
//We add the sub-menu for the filename masks
|
|
miSubMasks := TMenuItem.Create(miMasks);
|
|
miSubMasks.Caption := lbName.Caption;
|
|
miSubMasks.ImageIndex := GetImageIndexCategoryName(rmtuFilename);
|
|
miMasks.Add(miSubMasks);
|
|
PopulateFilenameMenu(miSubMasks);
|
|
|
|
//We add the sub-menu for the filename masks
|
|
miSubMasks := TMenuItem.Create(miMasks);
|
|
miSubMasks.Caption := lbExt.Caption;
|
|
miSubMasks.ImageIndex := GetImageIndexCategoryName(rmtuExtension);
|
|
miMasks.Add(miSubMasks);
|
|
PopulateExtensionMenu(miSubMasks);
|
|
end;
|
|
|
|
{ TfrmMultiRename.PopulateFilenameMenu }
|
|
procedure TfrmMultiRename.PopulateFilenameMenu(AMenuSomething: TComponent);
|
|
var
|
|
localMenuItem, miSubMenu, miMenuItem: TMenuItem;
|
|
begin
|
|
if AMenuSomething.ClassType = TPopupMenu then
|
|
localMenuItem := TPopupMenu(AMenuSomething).Items
|
|
else if AMenuSomething.ClassType = TMenuItem then
|
|
begin
|
|
localMenuItem := TMenuItem(AMenuSomething);
|
|
|
|
miMenuItem := TMenuItem.Create(localMenuItem);
|
|
miMenuItem.Action := actAnyNameMask;
|
|
localMenuItem.Add(miMenuItem);
|
|
miMenuItem := TMenuItem.Create(localMenuItem);
|
|
miMenuItem.Caption := '-';
|
|
localMenuItem.Add(miMenuItem);
|
|
end
|
|
else
|
|
exit;
|
|
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuFilename), GetImageIndexCategoryName(rmtuFilename));
|
|
BuildMaskMenu(miSubMenu, tfmFilename, rmtuFilename);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuExtension), GetImageIndexCategoryName(rmtuExtension));
|
|
BuildMaskMenu(miSubMenu, tfmFilename, rmtuExtension);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuCounter), GetImageIndexCategoryName(rmtuCounter));
|
|
BuildMaskMenu(miSubMenu, tfmFilename, rmtuCounter);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuDate), GetImageIndexCategoryName(rmtuDate));
|
|
BuildMaskMenu(miSubMenu, tfmFilename, rmtuDate);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuTime), GetImageIndexCategoryName(rmtuTime));
|
|
BuildMaskMenu(miSubMenu, tfmFilename, rmtuTime);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuPlugins), GetImageIndexCategoryName(rmtuPlugins));
|
|
BuildMaskMenu(miSubMenu, tfmFilename, rmtuPlugins);
|
|
AppendSubMenuToThisMenu(localMenuItem, '-', -1);
|
|
AppendActionMenuToThisMenu(localMenuItem, actClearNameMask);
|
|
AppendActionMenuToThisMenu(localMenuItem, actResetAll);
|
|
end;
|
|
|
|
{ TfrmMultiRename.PopulateExtensionMenu }
|
|
procedure TfrmMultiRename.PopulateExtensionMenu(AMenuSomething: TComponent);
|
|
var
|
|
localMenuItem, miSubMenu, miMenuItem: TMenuItem;
|
|
begin
|
|
if AMenuSomething.ClassType = TPopupMenu then
|
|
localMenuItem := TPopupMenu(AMenuSomething).Items
|
|
else if AMenuSomething.ClassType = TMenuItem then
|
|
begin
|
|
localMenuItem := TMenuItem(AMenuSomething);
|
|
|
|
miMenuItem := TMenuItem.Create(localMenuItem);
|
|
miMenuItem.Action := actAnyExtMask;
|
|
localMenuItem.Add(miMenuItem);
|
|
miMenuItem := TMenuItem.Create(localMenuItem);
|
|
miMenuItem.Caption := '-';
|
|
localMenuItem.Add(miMenuItem);
|
|
end
|
|
else
|
|
exit;
|
|
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuFilename), GetImageIndexCategoryName(rmtuFilename));
|
|
BuildMaskMenu(miSubMenu, tfmExtension, rmtuFilename);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuExtension), GetImageIndexCategoryName(rmtuExtension));
|
|
BuildMaskMenu(miSubMenu, tfmExtension, rmtuExtension);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuCounter), GetImageIndexCategoryName(rmtuCounter));
|
|
BuildMaskMenu(miSubMenu, tfmExtension, rmtuCounter);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuDate), GetImageIndexCategoryName(rmtuDate));
|
|
BuildMaskMenu(miSubMenu, tfmExtension, rmtuDate);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuTime), GetImageIndexCategoryName(rmtuTime));
|
|
BuildMaskMenu(miSubMenu, tfmExtension, rmtuTime);
|
|
miSubMenu := AppendSubMenuToThisMenu(localMenuItem, GetMaskCategoryName(rmtuPlugins), GetImageIndexCategoryName(rmtuPlugins));
|
|
BuildMaskMenu(miSubMenu, tfmExtension, rmtuPlugins);
|
|
AppendSubMenuToThisMenu(localMenuItem, '-', -1);
|
|
AppendActionMenuToThisMenu(localMenuItem, actClearExtMask);
|
|
AppendActionMenuToThisMenu(localMenuItem, actResetAll);
|
|
end;
|
|
|
|
{ TfrmMultiRename.BuildMaskMenu }
|
|
procedure TfrmMultiRename.BuildMaskMenu(AMenuSomething: TComponent; iTarget: tTargetForMask; iMenuTypeMask: tRenameMaskToUse);
|
|
var
|
|
iSeekIndex: integer;
|
|
AMenuItem, localMenuItem: TMenuItem;
|
|
actCategoryActionToAdd: TAction = nil;
|
|
begin
|
|
if AMenuSomething.ClassType = TPopupMenu then
|
|
localMenuItem := TPopupMenu(AMenuSomething).Items
|
|
else if AMenuSomething.ClassType = TMenuItem then
|
|
localMenuItem := TMenuItem(AMenuSomething)
|
|
else
|
|
exit;
|
|
|
|
localMenuItem.Clear;
|
|
|
|
if AMenuSomething.ClassType = TMenuItem then
|
|
begin
|
|
actCategoryActionToAdd := GetCategoryAction(iTarget, iMenuTypeMask);
|
|
if actCategoryActionToAdd <> nil then
|
|
begin
|
|
AMenuItem := TMenuItem.Create(AMenuSomething);
|
|
AMenuItem.Action := actCategoryActionToAdd;
|
|
localMenuItem.Add(AMenuItem);
|
|
|
|
AMenuItem := TMenuItem.Create(AMenuSomething);
|
|
AMenuItem.Caption := '-';
|
|
localMenuItem.Add(AMenuItem);
|
|
end;
|
|
end;
|
|
|
|
for iSeekIndex := 0 to pred(NBMAXHELPERS) do
|
|
begin
|
|
if MaskHelpers[iSeekIndex].iMenuType = iMenuTypeMask then
|
|
begin
|
|
AMenuItem := TMenuItem.Create(AMenuSomething);
|
|
AMenuItem.Caption := MaskHelpers[iSeekIndex].sMenuItem;
|
|
AMenuItem.Tag := (iSeekIndex shl 16) or Ord(iTarget);
|
|
AMenuItem.Hint := MaskHelpers[iSeekIndex].sKeyword;
|
|
AMenuItem.ImageIndex := GetImageIndexCategoryName(MaskHelpers[iSeekIndex].iMenuType);
|
|
|
|
case MaskHelpers[iSeekIndex].MenuActionStyle of
|
|
masStraight: AMenuItem.OnClick := @MenuItemStraightMaskClick;
|
|
masXCharacters, masXYCharacters: AMenuItem.OnClick := @MenuItemXCharactersMaskClick;
|
|
masAskVariable: AMenuItem.OnClick := @MenuItemVariableMaskClick;
|
|
masDirectorySelector: AMenuItem.OnClick := @MenuItemDirectorySelectorMaskClick;
|
|
end;
|
|
|
|
localMenuItem.Add(AMenuItem);
|
|
end;
|
|
end;
|
|
|
|
if rmtuPlugins = iMenuTypeMask then
|
|
begin
|
|
FPluginDispatcher := iTarget;
|
|
FillContentFieldMenu(AMenuSomething, @miPluginClick); //No need to clear "pmDynamicMasks" because "FillContentFieldMenu" do it itself.
|
|
|
|
if AMenuSomething.ClassType = TMenuItem then
|
|
begin
|
|
//We need to add the mask category menu item at the end since "FillContentFieldMenu" clears our "pmDynamicMasks".
|
|
AMenuItem := TMenuItem.Create(AMenuSomething);
|
|
AMenuItem.Caption := '-';
|
|
localMenuItem.Insert(0, AMenuItem);
|
|
|
|
AMenuItem := TMenuItem.Create(AMenuSomething);
|
|
AMenuItem.Action := actCategoryActionToAdd;
|
|
localMenuItem.Insert(0, AMenuItem);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.BuildPresetsMenu }
|
|
procedure TfrmMultiRename.BuildPresetsMenu(AMenuSomething: TComponent);
|
|
var
|
|
localMenuItem: TMenuItem;
|
|
begin
|
|
if AMenuSomething.ClassType = TPopupMenu then
|
|
localMenuItem := TPopupMenu(AMenuSomething).Items
|
|
else if AMenuSomething.ClassType = TMenuItem then
|
|
begin
|
|
localMenuItem := TMenuItem(AMenuSomething);
|
|
AppendActionMenuToThisMenu(localMenuItem, actShowPresetsMenu);
|
|
AppendSubMenuToThisMenu(localMenuItem, '-', -1);
|
|
end
|
|
else
|
|
exit;
|
|
|
|
AppendActionMenuToThisMenu(localMenuItem, actDropDownPresetList);
|
|
AppendSubMenuToThisMenu(localMenuItem, '-', -1);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadLastPreset);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadPreset1);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadPreset2);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadPreset3);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadPreset4);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadPreset5);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadPreset6);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadPreset7);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadPreset8);
|
|
AppendActionMenuToThisMenu(localMenuItem, actLoadPreset9);
|
|
AppendSubMenuToThisMenu(localMenuItem, '-', -1);
|
|
AppendActionMenuToThisMenu(localMenuItem, actSavePreset);
|
|
AppendActionMenuToThisMenu(localMenuItem, actSavePresetAs);
|
|
AppendActionMenuToThisMenu(localMenuItem, actRenamePreset);
|
|
AppendActionMenuToThisMenu(localMenuItem, actDeletePreset);
|
|
AppendActionMenuToThisMenu(localMenuItem, actSortPresets);
|
|
end;
|
|
|
|
{ TfrmMultiRename.BuildMenuAndPopup }
|
|
procedure TfrmMultiRename.BuildMenuAndPopup(iTarget: tTargetForMask; iMenuTypeMask: tRenameMaskToUse);
|
|
begin
|
|
BuildMaskMenu(pmDynamicMasks, iTarget, iMenuTypeMask);
|
|
case iTarget of
|
|
tfmFilename: PopupDynamicMenuAtThisControl(pmDynamicMasks, cbName);
|
|
tfmExtension: PopupDynamicMenuAtThisControl(pmDynamicMasks, cbExt);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.GetMaskCategoryName }
|
|
function TfrmMultiRename.GetMaskCategoryName(aRenameMaskToUse: tRenameMaskToUse): string;
|
|
begin
|
|
Result := '';
|
|
case aRenameMaskToUse of
|
|
rmtuFilename: Result := rsMulRenFilename;
|
|
rmtuExtension: Result := rsMulRenExtension;
|
|
rmtuCounter: Result := rsMulRenCounter;
|
|
rmtuDate: Result := rsMulRenDate;
|
|
rmtuTime: Result := rsMulRenTime;
|
|
rmtuPlugins: Result := rsMulRenPlugins;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.GetImageIndexCategoryName }
|
|
function TfrmMultiRename.GetImageIndexCategoryName(aRenameMaskToUse: tRenameMaskToUse): integer;
|
|
begin
|
|
Result := -1;
|
|
case aRenameMaskToUse of
|
|
rmtuFilename: Result := 20;
|
|
rmtuExtension: Result := 21;
|
|
rmtuCounter: Result := 22;
|
|
rmtuDate: Result := 23;
|
|
rmtuTime: Result := 24;
|
|
rmtuPlugins: Result := 25;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.GetCategoryAction }
|
|
function TfrmMultiRename.GetCategoryAction(TargetForMask: tTargetForMask; aRenameMask: tRenameMaskToUse): TAction;
|
|
begin
|
|
Result := nil;
|
|
case TargetForMask of
|
|
tfmFilename:
|
|
begin
|
|
case aRenameMask of
|
|
rmtuFilename: Result := actNameNameMask;
|
|
rmtuExtension: Result := actExtNameMask;
|
|
rmtuCounter: Result := actCtrNameMask;
|
|
rmtuDate: Result := actDateNameMask;
|
|
rmtuTime: Result := actTimeNameMask;
|
|
rmtuPlugins: Result := actPlgnNameMask;
|
|
end;
|
|
end;
|
|
|
|
tfmExtension:
|
|
begin
|
|
case aRenameMask of
|
|
rmtuFilename: Result := actNameExtMask;
|
|
rmtuExtension: Result := actExtExtMask;
|
|
rmtuCounter: Result := actCtrExtMask;
|
|
rmtuDate: Result := actDateExtMask;
|
|
rmtuTime: Result := actTimeExtMask;
|
|
rmtuPlugins: Result := actPlgnExtMask;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.AppendSubMenuToThisMenu }
|
|
function TfrmMultiRename.AppendSubMenuToThisMenu(ATargetMenu: TMenuItem; sCaption: string; iImageIndex: integer): TMenuItem;
|
|
begin
|
|
Result := TMenuItem.Create(ATargetMenu);
|
|
Result.ImageIndex := iImageIndex;
|
|
if sCaption <> '' then
|
|
Result.Caption := sCaption;
|
|
ATargetMenu.Add(Result);
|
|
end;
|
|
|
|
{ TfrmMultiRename.AppendActionMenuToThisMenu }
|
|
function TfrmMultiRename.AppendActionMenuToThisMenu(ATargetMenu: TMenuItem; paramAction: TAction): TMenuItem;
|
|
begin
|
|
Result := TMenuItem.Create(ATargetMenu);
|
|
Result.Action := paramAction;
|
|
ATargetMenu.Add(Result);
|
|
end;
|
|
|
|
{ TfrmMultiRename.MenuItemXCharactersMaskClick }
|
|
procedure TfrmMultiRename.MenuItemXCharactersMaskClick(Sender: TObject);
|
|
var
|
|
sSourceToSelectFromText, sPrefix: string;
|
|
sResultingMaskValue: string = '';
|
|
iMaskHelperIndex: integer;
|
|
begin
|
|
iMaskHelperIndex := TMenuItem(Sender).Tag shr 16;
|
|
|
|
if iMaskHelperIndex < length(MaskHelpers) then
|
|
begin
|
|
sSourceToSelectFromText := '';
|
|
case MaskHelpers[iMaskHelperIndex].iSourceOfInformation of
|
|
soiFilename:
|
|
begin
|
|
sSourceToSelectFromText := FFiles[pred(StringGrid.Row)].NameNoExt;
|
|
sPrefix := 'N';
|
|
end;
|
|
|
|
soiExtension:
|
|
begin
|
|
sSourceToSelectFromText := FFiles[pred(StringGrid.Row)].Extension;
|
|
sPrefix := 'E';
|
|
end;
|
|
|
|
soiFullName:
|
|
begin
|
|
sSourceToSelectFromText := FFiles[pred(StringGrid.Row)].FullPath;
|
|
sPrefix := 'A';
|
|
end;
|
|
end;
|
|
|
|
if ShowSelectTextRangeDlg(Self, Caption, sSourceToSelectFromText, sPrefix, sResultingMaskValue) then
|
|
InsertMask(sResultingMaskValue, tTargetForMask(TMenuItem(Sender).Tag and iTARGETMASK));
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.MenuItemDirectorySelectorMaskClick }
|
|
procedure TfrmMultiRename.MenuItemDirectorySelectorMaskClick(Sender: TObject);
|
|
var
|
|
sSourceToSelectFromText, sPrefix: string;
|
|
sResultingMaskValue: string = '';
|
|
iMaskHelperIndex: integer;
|
|
begin
|
|
iMaskHelperIndex := TMenuItem(Sender).Tag shr 16;
|
|
|
|
if iMaskHelperIndex < length(MaskHelpers) then
|
|
begin
|
|
sSourceToSelectFromText := '';
|
|
case MaskHelpers[iMaskHelperIndex].iSourceOfInformation of
|
|
soiPath:
|
|
begin
|
|
sSourceToSelectFromText := FFiles[pred(StringGrid.Row)].Path;
|
|
sPrefix := 'P';
|
|
end;
|
|
end;
|
|
|
|
if ShowSelectPathRangeDlg(Self, Caption, sSourceToSelectFromText, sPrefix, sResultingMaskValue) then
|
|
InsertMask(sResultingMaskValue, tTargetForMask(TMenuItem(Sender).Tag and iTARGETMASK));
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.MenuItemVariableMaskClick }
|
|
procedure TfrmMultiRename.MenuItemVariableMaskClick(Sender: TObject);
|
|
var
|
|
sVariableName: string;
|
|
begin
|
|
sVariableName := rsSimpleWordVariable;
|
|
if InputQuery(rsMulRenDefineVariableName, rsMulRenEnterNameForVar, sVariableName) then
|
|
begin
|
|
if sVariableName = '' then
|
|
sVariableName := rsSimpleWordVariable;
|
|
InsertMask('[V:' + sVariableName + ']', tTargetForMask(TMenuItem(Sender).Tag and iTARGETMASK));
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.MenuItemStraightMaskClick }
|
|
procedure TfrmMultiRename.MenuItemStraightMaskClick(Sender: TObject);
|
|
var
|
|
sMaks: string;
|
|
begin
|
|
sMaks := TMenuItem(Sender).Hint;
|
|
case tTargetForMask(TMenuItem(Sender).Tag and iTARGETMASK) of
|
|
tfmFilename:
|
|
begin
|
|
InsertMask(sMaks, cbName);
|
|
cbName.SetFocus;
|
|
end;
|
|
tfmExtension:
|
|
begin
|
|
InsertMask(sMaks, cbExt);
|
|
cbExt.SetFocus;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.PopupDynamicMenuAtThisControl }
|
|
procedure TfrmMultiRename.PopupDynamicMenuAtThisControl(APopUpMenu: TPopupMenu; AControl: TControl);
|
|
var
|
|
PopupPoint: TPoint;
|
|
begin
|
|
PopupPoint := AControl.Parent.ClientToScreen(Point(AControl.Left + AControl.Width - 5, AControl.Top + AControl.Height - 5));
|
|
APopUpMenu.PopUp(PopupPoint.X, PopupPoint.Y);
|
|
end;
|
|
|
|
{ TfrmMultiRename.miPluginClick }
|
|
procedure TfrmMultiRename.miPluginClick(Sender: TObject);
|
|
var
|
|
sMask: string;
|
|
MenuItem: TMenuItem absolute Sender;
|
|
begin
|
|
case MenuItem.Tag of
|
|
0:
|
|
begin
|
|
sMask := '[=DC().' + MenuItem.Hint + '{}]';
|
|
end;
|
|
1:
|
|
begin
|
|
sMask := '[=Plugin(' + MenuItem.Parent.Caption + ').' + MenuItem.Hint + '{}]';
|
|
end;
|
|
2:
|
|
begin
|
|
sMask := '[=Plugin(' + MenuItem.Parent.Parent.Caption + ').' + MenuItem.Parent.Hint + '{' + MenuItem.Hint + '}]';
|
|
end;
|
|
3:
|
|
begin
|
|
sMask := '[=DC().' + MenuItem.Parent.Hint + '{' + MenuItem.Hint + '}]';
|
|
end;
|
|
end;
|
|
|
|
case FPluginDispatcher of
|
|
tfmFilename:
|
|
begin
|
|
InsertMask(sMask, cbName);
|
|
cbName.SetFocus;
|
|
end;
|
|
tfmExtension:
|
|
begin
|
|
InsertMask(sMask, cbExt);
|
|
cbExt.SetFocus;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.InsertMask }
|
|
procedure TfrmMultiRename.InsertMask(const Mask: string; edChoose: TComboBox);
|
|
var
|
|
sTmp, sInitialString: string;
|
|
I: integer;
|
|
begin
|
|
sInitialString := edChoose.Text;
|
|
if edChoose.SelLength > 0 then
|
|
edChoose.SelText := Mask // Replace selected text
|
|
else
|
|
begin
|
|
sTmp := edChoose.Text;
|
|
I := edChoose.SelStart + 1; // Insert on current position
|
|
UTF8Insert(Mask, sTmp, I);
|
|
Inc(I, UTF8Length(Mask));
|
|
edChoose.Text := sTmp;
|
|
edChoose.SelStart := I - 1;
|
|
end;
|
|
if sInitialString <> edChoose.Text then
|
|
cbNameStyleChange(edChoose);
|
|
end;
|
|
|
|
{ TfrmMultiRename.InsertMask }
|
|
procedure TfrmMultiRename.InsertMask(const Mask: string; TargetForMask: tTargetForMask);
|
|
begin
|
|
case TargetForMask of
|
|
tfmFilename:
|
|
begin
|
|
InsertMask(Mask, cbName);
|
|
cbName.SetFocus;
|
|
end;
|
|
|
|
tfmExtension:
|
|
begin
|
|
InsertMask(Mask, cbExt);
|
|
cbExt.SetFocus;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{TfrmMultiRename.sReplace }
|
|
function TfrmMultiRename.sReplace(sMask: string; ItemNr: integer): string;
|
|
var
|
|
iStart, iEnd: integer;
|
|
begin
|
|
Result := '';
|
|
while Length(sMask) > 0 do
|
|
begin
|
|
iStart := Pos('[', sMask);
|
|
if iStart > 0 then
|
|
begin
|
|
iEnd := Pos(']', sMask, iStart + 1);
|
|
if iEnd > 0 then
|
|
begin
|
|
Result := Result + Copy(sMask, 1, iStart - 1) +
|
|
sHandleFormatString(Copy(sMask, iStart + 1, iEnd - iStart - 1), ItemNr);
|
|
Delete(sMask, 1, iEnd);
|
|
end
|
|
else
|
|
Break;
|
|
end
|
|
else
|
|
Break;
|
|
end;
|
|
Result := Result + sMask;
|
|
end;
|
|
|
|
{ TfrmMultiRename.sReplaceXX }
|
|
function TfrmMultiRename.sReplaceXX(const sFormatStr, sOrig: string): string;
|
|
var
|
|
iFrom, iTo, iDelim: integer;
|
|
begin
|
|
if Length(sFormatStr) = 1 then
|
|
Result := sOrig
|
|
else
|
|
begin
|
|
iDelim := Pos(':', sFormatStr);
|
|
if iDelim = 0 then
|
|
begin
|
|
iDelim := Pos(',', sFormatStr);
|
|
// Not found
|
|
if iDelim = 0 then
|
|
begin
|
|
iFrom := StrToIntDef(Copy(sFormatStr, 2, MaxInt), 1);
|
|
if iFrom < 0 then
|
|
iFrom := sOrig.Length + iFrom + 1;
|
|
iTo := iFrom;
|
|
end
|
|
// Range e.g. N1,3 (from 1, 3 symbols)
|
|
else
|
|
begin
|
|
iFrom := StrToIntDef(Copy(sFormatStr, 2, iDelim - 2), 1);
|
|
iDelim := Abs(StrToIntDef(Copy(sFormatStr, iDelim + 1, MaxSmallint), MaxSmallint));
|
|
if iFrom >= 0 then
|
|
iTo := iDelim + iFrom - 1
|
|
else
|
|
begin
|
|
iTo := sOrig.Length + iFrom + 1;
|
|
iFrom := Max(iTo - iDelim + 1, 1);
|
|
end;
|
|
end;
|
|
end
|
|
// Range e.g. N1:2 (from 1 to 2)
|
|
else
|
|
begin
|
|
iFrom := StrToIntDef(Copy(sFormatStr, 2, iDelim - 2), 1);
|
|
if iFrom < 0 then
|
|
iFrom := sOrig.Length + iFrom + 1;
|
|
iTo := StrToIntDef(Copy(sFormatStr, iDelim + 1, MaxSmallint), MaxSmallint);
|
|
if iTo < 0 then
|
|
iTo := sOrig.Length + iTo + 1;
|
|
;
|
|
if iTo < iFrom then
|
|
begin
|
|
iDelim := iTo;
|
|
iTo := iFrom;
|
|
iFrom := iDelim;
|
|
end;
|
|
end;
|
|
Result := UTF8Copy(sOrig, iFrom, iTo - iFrom + 1);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.sReplaceVariable }
|
|
function TfrmMultiRename.sReplaceVariable(const sFormatStr: string): string;
|
|
var
|
|
iDelim, iVariableIndex, iVariableSuggestionIndex: integer;
|
|
sVariableName: string = '';
|
|
sVariableValue: string = '';
|
|
begin
|
|
Result := '';
|
|
|
|
iDelim := Pos(':', sFormatStr);
|
|
if iDelim <> 0 then
|
|
sVariableName := copy(sFormatStr, succ(iDelim), length(sFormatStr) - iDelim)
|
|
else
|
|
sVariableName := rsSimpleWordVariable;
|
|
|
|
iVariableIndex := FslVariableNames.IndexOf(sVariableName);
|
|
if iVariableIndex = -1 then
|
|
begin
|
|
iVariableSuggestionIndex := FslVariableSuggestionName.IndexOf(sVariableName);
|
|
if iVariableSuggestionIndex <> -1 then
|
|
sVariableValue := FslVariableSuggestionValue.Strings[iVariableSuggestionIndex]
|
|
else
|
|
sVariableValue := sVariableName;
|
|
|
|
if InputQuery(rsMulRenDefineVariableValue, Format(rsMulRenEnterValueForVar, [sVariableName]), sVariableValue) then
|
|
begin
|
|
FslVariableNames.Add(sVariableName);
|
|
iVariableIndex := FslVariableValues.Add(sVariableValue);
|
|
if iVariableSuggestionIndex = -1 then
|
|
begin
|
|
FslVariableSuggestionName.Add(sVariableName);
|
|
FslVariableSuggestionValue.Add(sVariableValue);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
FActuallyRenamingFile := False;
|
|
exit;
|
|
end;
|
|
end;
|
|
Result := FslVariableValues.Strings[iVariableIndex];
|
|
end;
|
|
|
|
{ TfrmMultiRename.sReplaceBadChars }//Replace bad path chars in string
|
|
function TfrmMultiRename.sReplaceBadChars(const sPath: string): string;
|
|
const
|
|
{$IFDEF MSWINDOWS}
|
|
ForbiddenChars: set of char = ['<', '>', ':', '"', '/', '\', '|', '?', '*'];
|
|
{$ELSE}
|
|
ForbiddenChars: set of char = ['/'];
|
|
{$ENDIF}
|
|
var
|
|
Index: integer;
|
|
begin
|
|
Result := '';
|
|
for Index := 1 to Length(sPath) do
|
|
if not (sPath[Index] in ForbiddenChars) then
|
|
Result += sPath[Index]
|
|
else
|
|
Result += gMulRenInvalidCharReplacement;
|
|
end;
|
|
|
|
{ TfrmMultiRename.IsLetter }
|
|
function TfrmMultiRename.IsLetter(AChar: AnsiChar): boolean;
|
|
begin
|
|
Result := // Ascii letters
|
|
((AChar < #128) and
|
|
(((AChar >= 'a') and (AChar <= 'z')) or
|
|
((AChar >= 'A') and (AChar <= 'Z')))) or
|
|
// maybe Ansi or UTF8
|
|
(AChar >= #128);
|
|
end;
|
|
|
|
{ TfrmMultiRename.ApplyStyle }
|
|
// Applies style (uppercase, lowercase, etc.) to a string.
|
|
function TfrmMultiRename.ApplyStyle(InputString: string; Style: integer): string;
|
|
begin
|
|
case Style of
|
|
1: Result := UTF8UpperCase(InputString);
|
|
2: Result := UTF8LowerCase(InputString);
|
|
3: Result := FirstCharOfFirstWordToUppercaseUTF8(InputString);
|
|
4: Result := FirstCharOfEveryWordToUppercaseUTF8(InputString);
|
|
else
|
|
Result := InputString;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.FirstCharToUppercaseUTF8 }
|
|
// Changes first char to uppercase and the rest to lowercase
|
|
function TfrmMultiRename.FirstCharToUppercaseUTF8(InputString: string): string;
|
|
var
|
|
FirstChar: string;
|
|
begin
|
|
if UTF8Length(InputString) > 0 then
|
|
begin
|
|
Result := UTF8LowerCase(InputString);
|
|
FirstChar := UTF8Copy(Result, 1, 1);
|
|
UTF8Delete(Result, 1, 1);
|
|
Result := UTF8UpperCase(FirstChar) + Result;
|
|
end
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
{ TfrmMultiRename.FirstCharOfFirstWordToUppercaseUTF8 }
|
|
// Changes first char of first word to uppercase and the rest to lowercase
|
|
function TfrmMultiRename.FirstCharOfFirstWordToUppercaseUTF8(InputString: string): string;
|
|
var
|
|
SeparatorPos: integer;
|
|
begin
|
|
InputString := UTF8LowerCase(InputString);
|
|
Result := '';
|
|
|
|
// Search for first letter.
|
|
for SeparatorPos := 1 to Length(InputString) do
|
|
if IsLetter(InputString[SeparatorPos]) then
|
|
break;
|
|
|
|
Result := Copy(InputString, 1, SeparatorPos - 1) + FirstCharToUppercaseUTF8(Copy(InputString, SeparatorPos, Length(InputString) - SeparatorPos + 1));
|
|
end;
|
|
|
|
{ TfrmMultiRename.FirstCharOfEveryWordToUppercaseUTF8 }
|
|
// Changes first char of every word to uppercase and the rest to lowercase
|
|
function TfrmMultiRename.FirstCharOfEveryWordToUppercaseUTF8(InputString: string): string;
|
|
var
|
|
SeparatorPos: integer;
|
|
begin
|
|
InputString := UTF8LowerCase(InputString);
|
|
Result := '';
|
|
|
|
while InputString <> '' do
|
|
begin
|
|
// Search for first non-letter (word separator).
|
|
for SeparatorPos := 1 to Length(InputString) do
|
|
if not IsLetter(InputString[SeparatorPos]) then
|
|
break;
|
|
|
|
Result := Result + FirstCharToUppercaseUTF8(Copy(InputString, 1, SeparatorPos));
|
|
|
|
Delete(InputString, 1, SeparatorPos);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmMultiRename.LoadNamesFromList(const AFileList: TStrings);
|
|
begin
|
|
if AFileList.Count <> FFiles.Count then
|
|
begin
|
|
msgError(Format(rsMulRenWrongLinesNumber, [AFileList.Count, FFiles.Count]));
|
|
end
|
|
else
|
|
begin
|
|
FNames.Assign(AFileList);
|
|
|
|
gbMaska.Enabled := False;
|
|
gbPresets.Enabled := False;
|
|
gbCounter.Enabled := False;
|
|
|
|
StringGridTopLeftChanged(StringGrid);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.LoadNamesFromFile }
|
|
procedure TfrmMultiRename.LoadNamesFromFile(const AFileName: string);
|
|
var
|
|
AFileList: TStringListEx;
|
|
begin
|
|
AFileList := TStringListEx.Create;
|
|
try
|
|
AFileList.LoadFromFile(AFileName);
|
|
LoadNamesFromList(AFileList);
|
|
except
|
|
on E: Exception do
|
|
msgError(E.Message);
|
|
end;
|
|
AFileList.Free;
|
|
end;
|
|
|
|
{ TfrmMultiRename.FreshText }
|
|
function TfrmMultiRename.FreshText(ItemIndex: integer): string;
|
|
var
|
|
I: integer;
|
|
bError: boolean;
|
|
wsText: UnicodeString;
|
|
wsReplace: UnicodeString;
|
|
Flags: TReplaceFlags = [];
|
|
sTmpName, sTmpExt: string;
|
|
begin
|
|
bError := False;
|
|
|
|
if FNames.Count > 0 then
|
|
Result := FNames[ItemIndex]
|
|
else
|
|
begin
|
|
// Use mask
|
|
sTmpName := sReplace(cbName.Text, ItemIndex);
|
|
sTmpExt := sReplace(cbExt.Text, ItemIndex);
|
|
|
|
// Join
|
|
Result := sTmpName;
|
|
if sTmpExt <> '' then
|
|
Result := Result + '.' + sTmpExt;
|
|
end;
|
|
|
|
// 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(sTmpName);
|
|
wsReplace:= CeUtf8ToUtf16(edReplace.Text);
|
|
FRegExp.ModifierI := not cbCaseSens.Checked;
|
|
|
|
if not cbOnlyFirst.Checked then
|
|
begin
|
|
sTmpName := CeUtf16ToUtf8(FRegExp.Replace(wsText, wsReplace, cbUseSubs.Checked));
|
|
end
|
|
else if FRegExp.Exec(wsText) then
|
|
begin
|
|
Delete(wsText, FRegExp.MatchPos[0], FRegExp.MatchLen[0]);
|
|
if cbUseSubs.Checked then
|
|
Insert(FRegExp.Substitute(wsReplace), wsText, FRegExp.MatchPos[0])
|
|
else begin
|
|
Insert(wsReplace, wsText, FRegExp.MatchPos[0]);
|
|
end;
|
|
sTmpName:= CeUtf16ToUtf8(wsText);
|
|
end;
|
|
except
|
|
Result := rsMsgErrRegExpSyntax;
|
|
bError := True;
|
|
end
|
|
else begin
|
|
if not cbOnlyFirst.Checked then
|
|
Flags:= [rfReplaceAll];
|
|
if not cbCaseSens.Checked then
|
|
Flags+= [rfIgnoreCase];
|
|
// Many at once, split find and replace by |
|
|
if (FReplaceText.Count = 0) then
|
|
FReplaceText.Add('');
|
|
for I := 0 to FFindText.Count - 1 do
|
|
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;
|
|
|
|
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);
|
|
|
|
Result := sTmpName + sTmpExt;
|
|
end;
|
|
|
|
actRename.Enabled := not bError;
|
|
|
|
if bError then
|
|
begin
|
|
edFind.Color := clRed;
|
|
edFind.Font.Color := clWhite;
|
|
end
|
|
else
|
|
begin
|
|
edFind.Color := clDefault;
|
|
edFind.Font.Color := clDefault;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.sHandleFormatString }
|
|
function TfrmMultiRename.sHandleFormatString(const sFormatStr: string; ItemNr: integer): string;
|
|
var
|
|
aFile: TFile;
|
|
Index: int64;
|
|
Counter: int64;
|
|
Dirs: TStringArray;
|
|
begin
|
|
Result := '';
|
|
if Length(sFormatStr) > 0 then
|
|
begin
|
|
aFile := FFiles[ItemNr];
|
|
case sFormatStr[1] of
|
|
'[', ']':
|
|
begin
|
|
Result := sFormatStr;
|
|
end;
|
|
|
|
'N':
|
|
begin
|
|
Result := sReplaceXX(sFormatStr, aFile.NameNoExt);
|
|
end;
|
|
|
|
'E':
|
|
begin
|
|
Result := sReplaceXX(sFormatStr, aFile.Extension);
|
|
end;
|
|
|
|
'A':
|
|
begin
|
|
Result := sReplaceBadChars(sReplaceXX(sFormatStr, aFile.FullPath));
|
|
end;
|
|
|
|
'G':
|
|
begin
|
|
Result := GuidToString(DCGetNewGUID);
|
|
end;
|
|
|
|
'V':
|
|
begin
|
|
if FActuallyRenamingFile then
|
|
Result := sReplaceVariable(sFormatStr)
|
|
else
|
|
Result := '[' + sFormatStr + ']';
|
|
end;
|
|
|
|
'C':
|
|
begin
|
|
// Check for start value after C, e.g. C12
|
|
if not TryStrToInt64(Copy(sFormatStr, 2, MaxInt), Index) then
|
|
Index := StrToInt64Def(edPoc.Text, 1);
|
|
Counter := Index + StrToInt64Def(edInterval.Text, 1) * ItemNr;
|
|
Result := Format('%.' + cmbxWidth.Items[cmbxWidth.ItemIndex] + 'd', [Counter]);
|
|
end;
|
|
|
|
'P': // sub path index
|
|
begin
|
|
Index := StrToIntDef(Copy(sFormatStr, 2, MaxInt), 0);
|
|
Dirs := (aFile.Path + ' ').Split([PathDelim]);
|
|
Dirs[High(Dirs)] := EmptyStr;
|
|
if Index < 0 then
|
|
Result := Dirs[Max(0, High(Dirs) + Index)]
|
|
else
|
|
Result := Dirs[Min(Index, High(Dirs))];
|
|
end;
|
|
|
|
'=':
|
|
begin
|
|
Result := sReplaceBadChars(FormatFileFunction(UTF8Copy(sFormatStr, 2, UTF8Length(sFormatStr) - 1), FFiles.Items[ItemNr], FFileSource, True));
|
|
end;
|
|
|
|
else
|
|
begin
|
|
// Assume it is date/time formatting string ([h][n][s][Y][M][D]).
|
|
with FFiles.Items[ItemNr] do
|
|
if fpModificationTime in SupportedProperties then
|
|
try
|
|
Result := SysToUTF8(FormatDateTime(sFormatStr, ModificationTime));
|
|
except
|
|
Result := sFormatStr;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.SetFilePropertyResult }
|
|
procedure TfrmMultiRename.SetFilePropertyResult(Index: integer; aFile: TFile; aTemplate: TFileProperty; Result: TSetFilePropertyResult);
|
|
var
|
|
sFilenameForLog, S: string;
|
|
begin
|
|
with TFileNameProperty(aTemplate) do
|
|
begin
|
|
if cbLog.Checked then
|
|
if gMulRenFilenameWithFullPathInLog then
|
|
sFilenameForLog := aFile.FullPath
|
|
else
|
|
sFilenameForLog := aFile.Name;
|
|
|
|
case Result of
|
|
sfprSuccess:
|
|
begin
|
|
S := 'OK ' + sFilenameForLog + ' -> ' + Value;
|
|
if Index < FFiles.Count then
|
|
FFiles[Index].Name := Value // Write new name to the file object
|
|
else
|
|
begin
|
|
Index := StrToInt(aFile.Extension);
|
|
FFiles[Index].Name := Value; // Write new name to the file object
|
|
end;
|
|
end;
|
|
sfprError: S := 'FAILED ' + sFilenameForLog + ' -> ' + Value;
|
|
sfprSkipped: S := 'SKIPPED ' + sFilenameForLog + ' -> ' + Value;
|
|
end;
|
|
end;
|
|
if cbLog.Checked then
|
|
FLog.Add(S);
|
|
end;
|
|
|
|
{ TfrmMultiRename.SetOutputGlobalRenameLogFilename }
|
|
procedure TfrmMultiRename.SetOutputGlobalRenameLogFilename;
|
|
begin
|
|
if gMultRenDailyIndividualDirLog then
|
|
fneRenameLogFileFilename.FileName := mbExpandFileName(ExtractFilePath(gMulRenLogFilename) + IncludeTrailingPathDelimiter(EnvVarTodaysDate) + ExtractFilename(gMulRenLogFilename))
|
|
else
|
|
fneRenameLogFileFilename.FileName := gMulRenLogFilename;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_ResetAll }
|
|
procedure TfrmMultiRename.cm_ResetAll(const Params: array of string);
|
|
var
|
|
Param: string;
|
|
bNeedRefreshActivePresetCommands: boolean = True;
|
|
begin
|
|
for Param in Params do
|
|
GetParamBoolValue(Param, sREFRESHCOMMANDS, bNeedRefreshActivePresetCommands);
|
|
|
|
cbName.Text := '[N]';
|
|
cbName.SelStart := UTF8Length(cbName.Text);
|
|
cbExt.Text := '[E]';
|
|
cbExt.SelStart := UTF8Length(cbExt.Text);
|
|
edFind.Text := '';
|
|
edReplace.Text := '';
|
|
cbRepExt.Checked := True;
|
|
cbRegExp.Checked := False;
|
|
cbUseSubs.Checked := False;
|
|
cbCaseSens.Checked := False;
|
|
cbOnlyFirst.Checked := False;
|
|
cbNameMaskStyle.ItemIndex := 0;
|
|
cmbExtensionStyle.ItemIndex := 0;
|
|
edPoc.Text := '1';
|
|
edInterval.Text := '1';
|
|
cmbxWidth.ItemIndex := 0;
|
|
|
|
case gMulRenSaveRenamingLog of
|
|
mrsrlPerPreset:
|
|
begin
|
|
cbLog.Checked := False;
|
|
cbLog.Enabled := True;
|
|
cbLogAppend.Checked := False;
|
|
fneRenameLogFileFilename.Enabled := cbLog.Checked;
|
|
actInvokeRelativePath.Enabled := cbLog.Checked;
|
|
actViewRenameLogFile.Enabled := cbLog.Checked;
|
|
cbLogAppend.Enabled := cbLog.Checked;
|
|
if (FFiles.Count > 0) then
|
|
fneRenameLogFileFilename.FileName := FFiles[0].Path + sDEFAULTLOGFILENAME
|
|
else
|
|
fneRenameLogFileFilename.FileName := sDEFAULTLOGFILENAME;
|
|
end;
|
|
|
|
mrsrlAppendSameLog:
|
|
begin
|
|
cbLog.Checked := True;
|
|
cbLog.Enabled := False;
|
|
cbLogAppend.Checked := True;
|
|
cbLogAppend.Enabled := False;
|
|
fneRenameLogFileFilename.Enabled := False;
|
|
SetOutputGlobalRenameLogFilename;
|
|
actInvokeRelativePath.Enabled := False;
|
|
actViewRenameLogFile.Enabled := cbLog.Checked;
|
|
end;
|
|
end;
|
|
|
|
cbPresets.Text := '';
|
|
FNames.Clear;
|
|
gbMaska.Enabled := True;
|
|
gbPresets.Enabled := True;
|
|
cbPresets.ItemIndex := 0;
|
|
gbCounter.Enabled := True;
|
|
StringGridTopLeftChanged(StringGrid);
|
|
if bNeedRefreshActivePresetCommands then
|
|
RefreshActivePresetCommands;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_InvokeEditor }
|
|
procedure TfrmMultiRename.cm_InvokeEditor(const {%H-}Params: array of string);
|
|
begin
|
|
DCPlaceCursorNearControlIfNecessary(btnEditor);
|
|
pmEditDirect.PopUp;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadNamesFromFile }
|
|
procedure TfrmMultiRename.cm_LoadNamesFromFile(const {%H-}Params: array of string);
|
|
begin
|
|
dmComData.OpenDialog.FileName := EmptyStr;
|
|
dmComData.OpenDialog.Filter := AllFilesMask;
|
|
if dmComData.OpenDialog.Execute then
|
|
LoadNamesFromFile(dmComData.OpenDialog.FileName);
|
|
end;
|
|
|
|
procedure TfrmMultiRename.cm_LoadNamesFromClipboard(
|
|
const Params: array of string);
|
|
var
|
|
AFileList: TStringListEx;
|
|
begin
|
|
AFileList := TStringListEx.Create;
|
|
try
|
|
AFileList.Text := Clipboard.AsText;
|
|
LoadNamesFromList(AFileList);
|
|
except
|
|
on E: Exception do
|
|
msgError(E.Message);
|
|
end;
|
|
AFileList.Free;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_EditNames }
|
|
procedure TfrmMultiRename.cm_EditNames(const {%H-}Params: array of string);
|
|
var
|
|
I: integer;
|
|
AFileName: string;
|
|
AFileList: TStringListEx;
|
|
begin
|
|
AFileList := TStringListEx.Create;
|
|
AFileName := GetTempFolderDeletableAtTheEnd;
|
|
AFileName := GetTempName(AFileName, 'txt');
|
|
if FNames.Count > 0 then
|
|
AFileList.Assign(FNames)
|
|
else
|
|
begin
|
|
for I := 0 to FFiles.Count - 1 do
|
|
AFileList.Add(FFiles[I].Name);
|
|
end;
|
|
try
|
|
AFileList.SaveToFile(AFileName);
|
|
try
|
|
if ShowMultiRenameWaitForm(AFileName, Self) then
|
|
LoadNamesFromFile(AFileName);
|
|
finally
|
|
mbDeleteFile(AFileName);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
msgError(E.Message);
|
|
end;
|
|
AFileList.Free;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_EditNewNames }
|
|
procedure TfrmMultiRename.cm_EditNewNames(const {%H-}Params: array of string);
|
|
var
|
|
sFileName: string;
|
|
iIndexFile: integer;
|
|
AFileList: TStringListEx;
|
|
begin
|
|
AFileList := TStringListEx.Create;
|
|
try
|
|
for iIndexFile := 0 to pred(FFiles.Count) do
|
|
AFileList.Add(FreshText(iIndexFile));
|
|
sFileName := GetTempName(GetTempFolderDeletableAtTheEnd, 'txt');
|
|
try
|
|
AFileList.SaveToFile(sFileName);
|
|
try
|
|
if ShowMultiRenameWaitForm(sFileName, Self) then
|
|
LoadNamesFromFile(sFileName);
|
|
finally
|
|
mbDeleteFile(sFileName);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
msgError(E.Message);
|
|
end;
|
|
finally
|
|
AFileList.Free;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_Config }
|
|
procedure TfrmMultiRename.cm_Config(const {%H-}Params: array of string);
|
|
begin
|
|
frmMain.Commands.cm_Options(['TfrmOptionsMultiRename']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_Rename }
|
|
procedure TfrmMultiRename.cm_Rename(const {%H-}Params: array of string);
|
|
var
|
|
AFile: TFile;
|
|
NewName: string;
|
|
I, J, K: integer;
|
|
TempFiles: TStringList;
|
|
OldFiles, NewFiles: TFiles;
|
|
AutoRename: boolean = False;
|
|
Operation: TFileSourceOperation;
|
|
theNewProperties: TFileProperties;
|
|
LogFileStream: TFileStream;
|
|
begin
|
|
FActuallyRenamingFile := True;
|
|
try
|
|
if cbLog.Checked then
|
|
begin
|
|
if fneRenameLogFileFilename.FileName = EmptyStr then
|
|
fneRenameLogFileFilename.FileName := FFiles[0].Path + sDEFAULTLOGFILENAME;
|
|
mbForceDirectory(ExtractFileDir(mbExpandFileName(fneRenameLogFileFilename.FileName)));
|
|
FLog := TStringListEx.Create;
|
|
if cbLogAppend.Checked then
|
|
FLog.Add(';' + DateTimeToStr(Now) + ' - ' + rsMulRenLogStart);
|
|
end;
|
|
|
|
OldFiles := FFiles.Clone;
|
|
TempFiles := TStringList.Create;
|
|
NewFiles := TFiles.Create(EmptyStr);
|
|
FslVariableNames.Clear;
|
|
FslVariableValues.Clear; //We don't clear the "Suggestion" parts because we may re-use them as their original values if we ever re-do rename pass witht he same instance.
|
|
|
|
// OldNames
|
|
FOldNames.Clear;
|
|
for I := 0 to OldFiles.Count - 1 do
|
|
FOldNames.Add(OldFiles[I].Name, Pointer(PtrInt(I)));
|
|
|
|
try
|
|
FNewNames.Clear;
|
|
for I := 0 to FFiles.Count - 1 do
|
|
begin
|
|
AFile := TFile.Create(EmptyStr);
|
|
AFile.Name := FreshText(I);
|
|
|
|
//In "FreshText", if there was a "Variable on the fly / [V:Hint]" and the user aborted it, the "FActuallyRenamingFile" will be cleared and so we abort the actual renaming process.
|
|
if not FActuallyRenamingFile then
|
|
Exit;
|
|
|
|
// Checking duplicates
|
|
NewName := FFiles[I].Path + AFile.Name;
|
|
J := FNewNames.Find(NewName);
|
|
if J < 0 then
|
|
FNewNames.Add(NewName)
|
|
else
|
|
begin
|
|
if not AutoRename then
|
|
begin
|
|
if MessageDlg(rsMulRenWarningDuplicate + LineEnding +
|
|
NewName + LineEnding + LineEnding + rsMulRenAutoRename,
|
|
mtWarning, [mbYes, mbAbort], 0, mbAbort) <> mrYes then
|
|
Exit;
|
|
AutoRename := True;
|
|
end;
|
|
K := 1;
|
|
while J >= 0 do
|
|
begin
|
|
NewName := FFiles[I].Path + AFile.NameNoExt + ' (' + IntToStr(K) + ')';
|
|
if AFile.Extension <> '' then
|
|
NewName := NewName + ExtensionSeparator + AFile.Extension;
|
|
J := FNewNames.Find(NewName);
|
|
Inc(K);
|
|
end;
|
|
FNewNames.Add(NewName);
|
|
AFile.Name := ExtractFileName(NewName);
|
|
end;
|
|
|
|
// Avoid collisions with OldNames
|
|
J := FOldNames.Find(AFile.Name);
|
|
if (J >= 0) and (PtrUInt(FOldNames.List[J]^.Data) <> I) then
|
|
begin
|
|
NewName := AFile.Name;
|
|
// Generate temp file name, save file index as extension
|
|
AFile.FullPath := GetTempName(FFiles[I].Path, IntToStr(I));
|
|
TempFiles.AddObject(NewName, AFile.Clone);
|
|
end;
|
|
|
|
NewFiles.Add(AFile);
|
|
end;
|
|
|
|
// Rename temp files back
|
|
if TempFiles.Count > 0 then
|
|
begin
|
|
for I := 0 to TempFiles.Count - 1 do
|
|
begin
|
|
// Temp file name
|
|
OldFiles.Add(TFile(TempFiles.Objects[I]));
|
|
// Real new file name
|
|
AFile := TFile.Create(EmptyStr);
|
|
AFile.Name := TempFiles[I];
|
|
NewFiles.Add(AFile);
|
|
end;
|
|
end;
|
|
|
|
// Rename files
|
|
FillChar({%H-}theNewProperties, SizeOf(TFileProperties), 0);
|
|
Operation := FFileSource.CreateSetFilePropertyOperation(OldFiles, theNewProperties);
|
|
if Assigned(Operation) then
|
|
begin
|
|
with Operation as TFileSourceSetFilePropertyOperation do
|
|
begin
|
|
SetTemplateFiles(NewFiles);
|
|
OnSetFilePropertyResult := @SetFilePropertyResult;
|
|
end;
|
|
OperationsManager.AddOperationModal(Operation);
|
|
end;
|
|
InsertFirstItem(cbExt.Text, cbExt);
|
|
InsertFirstItem(cbName.Text, cbName);
|
|
finally
|
|
if cbLog.Checked then
|
|
begin
|
|
try
|
|
if (cbLogAppend.Checked) and (FileExists(mbExpandFileName(fneRenameLogFileFilename.FileName))) then
|
|
begin
|
|
LogFileStream := TFileStream.Create(mbExpandFileName(fneRenameLogFileFilename.FileName), fmOpenWrite);
|
|
try
|
|
LogFileStream.Seek(0, soEnd);
|
|
FLog.SaveToStream(LogFileStream);
|
|
finally
|
|
LogFileStream.Free;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
FLog.SaveToFile(mbExpandFileName(fneRenameLogFileFilename.FileName));
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
msgError(E.Message);
|
|
end;
|
|
FLog.Free;
|
|
end;
|
|
OldFiles.Free;
|
|
NewFiles.Free;
|
|
TempFiles.Free;
|
|
end;
|
|
finally
|
|
FActuallyRenamingFile := False;
|
|
end;
|
|
|
|
StringGridTopLeftChanged(StringGrid);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_Close }
|
|
procedure TfrmMultiRename.cm_Close(const {%H-}Params: array of string);
|
|
begin
|
|
Close;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_ShowPresetsMenu }
|
|
procedure TfrmMultiRename.cm_ShowPresetsMenu(const {%H-}Params: array of string);
|
|
begin
|
|
PopupDynamicMenuAtThisControl(pmPresets, btnPresets);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_DropDownPresetList }
|
|
procedure TfrmMultiRename.cm_DropDownPresetList(const {%H-}Params: array of string);
|
|
begin
|
|
if (not cbPresets.CanFocus) and (not cbPresets.Enabled) then
|
|
if isOkToLosePresetModification = True then
|
|
cbPresets.Enabled := True;
|
|
|
|
if cbPresets.CanFocus then
|
|
begin
|
|
cbPresets.SetFocus;
|
|
cbPresets.DroppedDown := True;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset }
|
|
procedure TfrmMultiRename.cm_LoadPreset(const Params: array of string);
|
|
var
|
|
sPresetName: string;
|
|
PresetIndex: integer;
|
|
begin
|
|
if isOkToLosePresetModification then
|
|
begin
|
|
//1.Get the preset name from the parameters.
|
|
sPresetName := GetPresetNameForCommand(Params);
|
|
|
|
//2.Make sure we got something.
|
|
if sPresetName <> '' then
|
|
begin
|
|
//3.Make sure it is in our list.
|
|
PresetIndex := FMultiRenamePresetList.Find(sPresetName);
|
|
if PresetIndex <> -1 then
|
|
begin
|
|
cbName.Text := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].FileName;
|
|
cbName.SelStart := UTF8Length(cbName.Text);
|
|
cbExt.Text := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Extension;
|
|
cbExt.SelStart := UTF8Length(cbExt.Text);
|
|
cbNameMaskStyle.ItemIndex := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].FileNameStyle;
|
|
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;
|
|
cbOnlyFirst.Checked := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].OnlyFirst;
|
|
edPoc.Text := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Counter;
|
|
edInterval.Text := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Interval;
|
|
cmbxWidth.ItemIndex := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Width;
|
|
|
|
case gMulRenSaveRenamingLog of
|
|
mrsrlPerPreset:
|
|
begin
|
|
cbLog.Checked := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Log;
|
|
cbLogAppend.Checked := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].LogAppend;
|
|
fneRenameLogFileFilename.FileName := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].LogFile;
|
|
end;
|
|
|
|
mrsrlAppendSameLog:
|
|
begin
|
|
FbRememberLog := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].Log;
|
|
FbRememberAppend := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].LogAppend;
|
|
FsRememberRenameLogFilename := FMultiRenamePresetList.MultiRenamePreset[PresetIndex].LogFile;
|
|
SetOutputGlobalRenameLogFilename;
|
|
end;
|
|
end;
|
|
|
|
//4.Preserved the last loaded setup.
|
|
FLastPreset := sPresetName;
|
|
|
|
//5.Refresh the whole thing.
|
|
edFindChange(edFind);
|
|
edReplaceChange(edReplace);
|
|
|
|
//6.We might come here with parameter "index=x" so make sure we switch also the preset combo box to the same index.
|
|
if PresetIndex >= cbPresets.Items.Count then
|
|
PresetIndex := 0;
|
|
if cbPresets.ItemIndex <> PresetIndex then
|
|
cbPresets.ItemIndex := PresetIndex;
|
|
|
|
//7.Since we've load the setup, activate things so we may change setup if necessary.
|
|
SetConfigurationState(CONFIG_SAVED);
|
|
|
|
//8. If we're from anything else the preset droplist itself, let's go to focus on the name ready to edit it if necessary..
|
|
if (ActiveControl <> cbPresets) and (ActiveControl <> cbName) and (cbName.Enabled and gbMaska.Enabled) then
|
|
begin
|
|
ActiveControl := cbName;
|
|
cbName.SelStart := UTF8Length(cbName.Text);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadLastPreset }
|
|
procedure TfrmMultiRename.cm_LoadLastPreset(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=0']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset1 }
|
|
procedure TfrmMultiRename.cm_LoadPreset1(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=1']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset2 }
|
|
procedure TfrmMultiRename.cm_LoadPreset2(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=2']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset3 }
|
|
procedure TfrmMultiRename.cm_LoadPreset3(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=3']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset4 }
|
|
procedure TfrmMultiRename.cm_LoadPreset4(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=4']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset5 }
|
|
procedure TfrmMultiRename.cm_LoadPreset5(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=5']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset6 }
|
|
procedure TfrmMultiRename.cm_LoadPreset6(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=6']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset7 }
|
|
procedure TfrmMultiRename.cm_LoadPreset7(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=7']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset8 }
|
|
procedure TfrmMultiRename.cm_LoadPreset8(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=8']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_LoadPreset9 }
|
|
procedure TfrmMultiRename.cm_LoadPreset9(const Params: array of string);
|
|
begin
|
|
cm_LoadPreset(['index=9']);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_SavePreset }
|
|
procedure TfrmMultiRename.cm_SavePreset(const Params: array of string);
|
|
begin
|
|
if cbPresets.ItemIndex > 0 then
|
|
begin
|
|
SavePreset(cbPresets.Items.Strings[cbPresets.ItemIndex]);
|
|
SetConfigurationState(CONFIG_SAVED);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_SavePresetAs }
|
|
procedure TfrmMultiRename.cm_SavePresetAs(const Params: array of string);
|
|
var
|
|
sNameForPreset: string;
|
|
bKeepGoing: boolean;
|
|
begin
|
|
sNameForPreset := GetPresetNameForCommand(Params);
|
|
if sNameForPreset <> '' then
|
|
begin
|
|
bKeepGoing := True;
|
|
end
|
|
else
|
|
begin
|
|
if (FLastPreset = '') or (FLastPreset = sLASTPRESET) then
|
|
sNameForPreset := rsMulRenDefaultPresetName
|
|
else
|
|
sNameForPreset := FLastPreset;
|
|
bKeepGoing := InputQuery(Caption, rsMulRenPromptForSavedPresetName, sNameForPreset);
|
|
if bKeepGoing then bKeepGoing := (sNameForPreset <> '');
|
|
end;
|
|
|
|
if bKeepGoing and (sNameForPreset <> FLastPreset) then
|
|
if FMultiRenamePresetList.Find(sNameForPreset) <> -1 then
|
|
if not msgYesNo(Format(rsMsgPresetAlreadyExists, [sNameForPreset]), msmbNo) then
|
|
bKeepGoing := False;
|
|
|
|
if bKeepGoing then
|
|
begin
|
|
SavePreset(sNameForPreset);
|
|
|
|
if cbPresets.Items.IndexOf(sNameForPreset) = -1 then
|
|
begin
|
|
cbPresets.Items.Add(sNameForPreset);
|
|
end;
|
|
|
|
if cbPresets.ItemIndex <> cbPresets.Items.IndexOf(sNameForPreset) then
|
|
cbPresets.ItemIndex := cbPresets.Items.IndexOf(sNameForPreset);
|
|
|
|
SetConfigurationState(CONFIG_SAVED);
|
|
RefreshActivePresetCommands;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_RenamePreset }
|
|
// It also allow the at the same time to rename for changing case like "audio files" to "Audio Files".
|
|
procedure TfrmMultiRename.cm_RenamePreset(const Params: array of string);
|
|
var
|
|
sCurrentName, sNewName: string;
|
|
PresetIndex: integer;
|
|
bKeepGoing: boolean;
|
|
begin
|
|
sCurrentName := cbPresets.Items.Strings[cbPresets.ItemIndex];
|
|
sNewName := sCurrentName;
|
|
bKeepGoing := InputQuery(Caption, rsMulRenPromptNewPresetName, sNewName);
|
|
if bKeepGoing and (sNewName <> '') and (sCurrentName <> sNewName) then
|
|
begin
|
|
PresetIndex := FMultiRenamePresetList.Find(sNewName);
|
|
if (PresetIndex = -1) or (SameText(sCurrentName, sNewName)) then
|
|
begin
|
|
if SameText(FMultiRenamePresetList.MultiRenamePreset[cbPresets.ItemIndex].PresetName, cbPresets.Items.Strings[cbPresets.ItemIndex]) then
|
|
begin
|
|
FMultiRenamePresetList.MultiRenamePreset[cbPresets.ItemIndex].PresetName := sNewName;
|
|
cbPresets.Items.Strings[cbPresets.ItemIndex] := sNewName;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if msgYesNo(rsMulRenPromptNewNameExists, msmbNo) then
|
|
begin
|
|
if SameText(FMultiRenamePresetList.MultiRenamePreset[PresetIndex].PresetName, cbPresets.Items.Strings[PresetIndex]) and SameText(FMultiRenamePresetList.MultiRenamePreset[cbPresets.ItemIndex].PresetName, cbPresets.Items.Strings[cbPresets.ItemIndex]) then
|
|
begin
|
|
FMultiRenamePresetList.MultiRenamePreset[cbPresets.ItemIndex].PresetName := sNewName;
|
|
cbPresets.Items.Strings[cbPresets.ItemIndex] := sNewName;
|
|
|
|
cbPresets.Items.Delete(PresetIndex);
|
|
FMultiRenamePresetList.Delete(PresetIndex);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_DeletePreset }
|
|
procedure TfrmMultiRename.cm_DeletePreset(const Params: array of string);
|
|
var
|
|
Index: integer;
|
|
sPresetName: string;
|
|
begin
|
|
sPresetName := GetPresetNameForCommand(Params);
|
|
|
|
if sPresetName = '' then
|
|
if cbPresets.ItemIndex > 0 then
|
|
sPresetName := cbPresets.Items.Strings[cbPresets.ItemIndex];
|
|
|
|
if sPresetName <> '' then
|
|
begin
|
|
if msgYesNo(Format(rsMsgPresetConfigDelete, [sPresetName]), msmbNo) then
|
|
begin
|
|
DeletePreset(sPresetName);
|
|
Index := cbPresets.Items.IndexOf(sPresetName);
|
|
if Index = cbPresets.ItemIndex then
|
|
cbPresets.ItemIndex := 0;
|
|
if Index <> -1 then
|
|
cbPresets.Items.Delete(Index);
|
|
FillPresetsList;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_SortPresets }
|
|
procedure TfrmMultiRename.cm_SortPresets(const Params: array of string);
|
|
var
|
|
slLocalPresets: TStringList;
|
|
iSeeker, iPresetIndex: integer;
|
|
begin
|
|
if isOkToLosePresetModification then
|
|
begin
|
|
if FMultiRenamePresetList.Count > 1 then
|
|
begin
|
|
slLocalPresets := TStringList.Create;
|
|
try
|
|
for iSeeker := 1 to pred(FMultiRenamePresetList.Count) do
|
|
slLocalPresets.Add(FMultiRenamePresetList.MultiRenamePreset[iSeeker].PresetName);
|
|
|
|
if HaveUserSortThisList(Self, rsMulRenSortingPresets, slLocalPresets) = mrOk then
|
|
begin
|
|
for iSeeker := 0 to pred(slLocalPresets.Count) do
|
|
begin
|
|
iPresetIndex := FMultiRenamePresetList.Find(slLocalPresets.Strings[iSeeker]);
|
|
if succ(iSeeker) <> iPresetIndex then
|
|
FMultiRenamePresetList.Move(iPresetIndex, succ(iSeeker));
|
|
end;
|
|
FillPresetsList(cbPresets.Items.Strings[cbPresets.ItemIndex]);
|
|
end;
|
|
finally
|
|
slLocalPresets.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_AnyNameMask }
|
|
procedure TfrmMultiRename.cm_AnyNameMask(const {%H-}Params: array of string);
|
|
begin
|
|
pmFloatingMainMaskMenu.Items.Clear;
|
|
PopulateFilenameMenu(pmFloatingMainMaskMenu);
|
|
PopupDynamicMenuAtThisControl(pmFloatingMainMaskMenu, btnAnyNameMask);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_NameNameMask }
|
|
procedure TfrmMultiRename.cm_NameNameMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmFilename, rmtuFilename);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_ExtNameMask }
|
|
procedure TfrmMultiRename.cm_ExtNameMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmFilename, rmtuExtension);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_CtrNameMask }
|
|
procedure TfrmMultiRename.cm_CtrNameMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmFilename, rmtuCounter);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_DateNameMask }
|
|
procedure TfrmMultiRename.cm_DateNameMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmFilename, rmtuDate);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_TimeNameMask }
|
|
procedure TfrmMultiRename.cm_TimeNameMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmFilename, rmtuTime);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_PlgnNameMask }
|
|
procedure TfrmMultiRename.cm_PlgnNameMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmFilename, rmtuPlugins);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_ClearNameMask }
|
|
procedure TfrmMultiRename.cm_ClearNameMask(const {%H-}Params: array of string);
|
|
begin
|
|
cbName.Text := '';
|
|
cbNameStyleChange(cbExt);
|
|
if cbName.CanFocus then
|
|
cbName.SetFocus;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_AnyExtMask }
|
|
procedure TfrmMultiRename.cm_AnyExtMask(const {%H-}Params: array of string);
|
|
begin
|
|
pmFloatingMainMaskMenu.Items.Clear;
|
|
PopulateExtensionMenu(pmFloatingMainMaskMenu);
|
|
PopupDynamicMenuAtThisControl(pmFloatingMainMaskMenu, btnAnyExtMask);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_NameExtMask }
|
|
procedure TfrmMultiRename.cm_NameExtMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmExtension, rmtuFilename);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_ExtExtMask }
|
|
procedure TfrmMultiRename.cm_ExtExtMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmExtension, rmtuExtension);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_CtrExtMask }
|
|
procedure TfrmMultiRename.cm_CtrExtMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmExtension, rmtuCounter);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_DateExtMask }
|
|
procedure TfrmMultiRename.cm_DateExtMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmExtension, rmtuDate);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_TimeExtMask }
|
|
procedure TfrmMultiRename.cm_TimeExtMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmExtension, rmtuTime);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_PlgnExtMask }
|
|
procedure TfrmMultiRename.cm_PlgnExtMask(const {%H-}Params: array of string);
|
|
begin
|
|
BuildMenuAndPopup(tfmExtension, rmtuPlugins);
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_ClearExtMask }
|
|
procedure TfrmMultiRename.cm_ClearExtMask(const {%H-}Params: array of string);
|
|
begin
|
|
cbExt.Text := '';
|
|
cbNameStyleChange(cbExt);
|
|
if cbExt.CanFocus then cbExt.SetFocus;
|
|
end;
|
|
|
|
{ TfrmMultiRename.cm_ViewRenameLogFile }
|
|
procedure TfrmMultiRename.cm_ViewRenameLogFile(const {%H-}Params: array of string);
|
|
var
|
|
sRenameLogFilename: string;
|
|
begin
|
|
sRenameLogFilename := mbExpandFileName(fneRenameLogFileFilename.FileName);
|
|
if FileExists(sRenameLogFilename) then
|
|
ShowViewerByGlob(sRenameLogFilename)
|
|
else
|
|
MsgError(Format(rsMsgFileNotFound, [sRenameLogFilename]));
|
|
end;
|
|
|
|
{ ShowMultiRenameForm }
|
|
// Will be in fact the lone function called externally to launch a MultiRename dialog.
|
|
function ShowMultiRenameForm(aFileSource: IFileSource; var aFiles: TFiles; const PresetToLoad: string = ''): boolean;
|
|
begin
|
|
Result := True;
|
|
try
|
|
with TfrmMultiRename.Create(Application, aFileSource, aFiles, PresetToLoad) do
|
|
begin
|
|
Show;
|
|
end;
|
|
except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
initialization
|
|
TFormCommands.RegisterCommandsForm(TfrmMultiRename, HotkeysCategoryMultiRename, @rsHotkeyCategoryMultiRename);
|
|
|
|
end.
|
|
|