{ Seksi Commander ---------------------------- Licence : GNU GPL v 2.0 Author : Pavel Letko (letcuv@centrum.cz) Advanced multi rename tool contributors: Copyright (C) 2007-2009 Koblov Alexander (Alexx2000@mail.ru) } unit fMultiRename; {$mode objfpc}{$H+} interface uses LResources, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, Menus, Buttons, SynRegExpr, LCLType, uClassesEx, uFileList, StringHashList; type PMultiRenamePreset = ^TMultiRenamePreset; TMultiRenamePreset = record FileName: String; Extension: String; FileNameStyle: Integer; ExtensionStyle: Integer; Find: String; Replace: String; RegExp: Boolean; UseSubs: Boolean; Counter: String; Interval: String; Width: Integer; Log: Boolean; LogFile: String; end; { TfrmMultiRename } TfrmMultiRename = class(TForm) btnLoadPreset: TButton; btnSavePreset: TButton; btnDeletePreset: TButton; cbRegExp: TCheckBox; cbUseSubs: TCheckBox; cmbExtensionStyle: TComboBox; cbPresets: TComboBox; gbPresets: TGroupBox; lsvwFile: TListView; gbMaska: TGroupBox; lbName: TLabel; lbExt: TLabel; edName: TEdit; edExt: TEdit; btnNameMenu: TButton; btnExtMenu: TButton; gbFindReplace: TGroupBox; lbFind: TLabel; lbReplace: TLabel; edFind: TEdit; edReplace: TEdit; cmbNameStyle: TComboBox; gbCounter: TGroupBox; lbStNb: TLabel; lbInterval: TLabel; lbWidth: TLabel; edPoc: TEdit; edInterval: TEdit; cmbxWidth: TComboBox; btnRename: TButton; btnClose: TButton; gbLog: TGroupBox; edFile: TEdit; cbLog: TCheckBox; btnRestore: TButton; ppNameMenu: TPopupMenu; miNextName: TMenuItem; miName: TMenuItem; miNameX: TMenuItem; miNameXX: TMenuItem; N1: TMenuItem; miNextExtension: TMenuItem; Extension: TMenuItem; miExtensionX: TMenuItem; miExtensionXX: TMenuItem; N2: TMenuItem; miCounter: TMenuItem; N3: TMenuItem; miNext: TMenuItem; miYear: TMenuItem; miMonth: TMenuItem; miDay: TMenuItem; N4: TMenuItem; miHour: TMenuItem; miMinute: TMenuItem; miSecond: TMenuItem; procedure btnLoadPresetClick(Sender: TObject); procedure btnSavePresetClick(Sender: TObject); procedure btnDeletePresetClick(Sender: TObject); procedure cbRegExpChange(Sender: TObject); procedure cmbNameStyleChange(Sender: TObject); procedure edPocChange(Sender: TObject); procedure edIntervalChange(Sender: TObject); procedure btnRenameClick(Sender: TObject); procedure btnCloseClick(Sender: TObject); procedure btnRestoreClick(Sender: TObject); procedure btnNameMenuClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure miDayClick(Sender: TObject); procedure miHourClick(Sender: TObject); procedure miMinuteClick(Sender: TObject); procedure miMonthClick(Sender: TObject); procedure miSecondClick(Sender: TObject); procedure miYearClick(Sender: TObject); procedure NameClick(Sender: TObject); procedure NameXClick(Sender: TObject); procedure NameXXClick(Sender: TObject); procedure ExtensionClick(Sender: TObject); procedure CounterClick(Sender: TObject); procedure btnExtMenuClick(Sender: TObject); procedure cbLogClick(Sender: TObject); procedure ExtensionXClick(Sender: TObject); procedure ExtensionXXClick(Sender: TObject); procedure ppNameMenuPopup(Sender: TObject); private IniPropStorage: TIniPropStorageEx; FLastPreset: String; FFileList: TFileList; FPresets: TStringHashList; // of PMultiRenamePreset {Function sReplace call sReplaceXX with parametres} function sReplace(sMask:string;count:integer):string; {sReplaceXX doing Nx,Nx:x and Ex,Ex:x} function sReplaceXX(sMask,sSymbol,sOrig:string):string; {sReplaceDateTime doing Y,M,D and h,m,s} function sReplaceDateTime(sMask: String; dtDateTime: TDateTime): String; {InsertMask is for write key symbols from buttons} procedure InsertMask(Mask:string;edChoose:Tedit); {Main function for write into lsvwFile} procedure FreshText; {Executes the main operation of renaming files} procedure RenameFiles; {Changes first char to uppercase and the rest to lowercase} function FirstCharToUppercaseUTF8(InputString: String): String; {Changes first char of first word to uppercase and the rest to lowercase} function FirstCharOfFirstWordToUppercaseUTF8(InputString: String): String; {Changes first char of every word to uppercase and the rest to lowercase} function FirstCharOfEveryWordToUppercaseUTF8(InputString: String): String; {Returns true if a byte represents a letter.} function IsLetter(AChar: AnsiChar): Boolean; {Applies style (uppercase, lowercase, etc.) to a string} function ApplyStyle(InputString: String; Style: Integer): String; {Load preset configuration} procedure LoadPresets; {Save preset configuration} procedure SavePresets; {Loads specified preset from the configuration} procedure LoadPreset(PresetName: String); {Saves specified preset to the configuration} procedure SavePreset(PresetName: String); {Delete specified preset from configuration} procedure DeletePreset(PresetName: String); {Fills presets list with preset from configuration} procedure FillPresetsList; {Removes all presets from the presets list} procedure ClearPresetsList; public { Public declarations } constructor Create(TheOwner: TComponent; FileList: TFileList); reintroduce; destructor Destroy; override; end; {initialization function} function ShowMultiRenameForm(const srcFileList: TFileList):Boolean; implementation uses LCLProc, FileUtil, uLng, uGlobs, uFileProcs, uDCUtils, uOSUtils, uShowMsg; const sPresetsSection = 'MultiRenamePresets'; function ShowMultiRenameForm(const srcFileList: TFileList):Boolean; begin Result:= True; try with TfrmMultiRename.Create(Application, srcFileList) do begin Show; end; except Result:= False; end; end; constructor TfrmMultiRename.Create(TheOwner: TComponent; FileList: TFileList); begin FPresets := TStringHashList.Create(False); FFileList := FileList; inherited Create(TheOwner); end; destructor TfrmMultiRename.Destroy; begin inherited; ClearPresetsList; FreeAndNil(FPresets); end; procedure TfrmMultiRename.FormCreate(Sender: TObject); var i: Integer; begin // Localize File name style ComboBox ParseLineToList(rsMulRenFileNameStyleList, cmbNameStyle.Items); ParseLineToList(rsMulRenFileNameStyleList, cmbExtensionStyle.Items); // Initialize property storage IniPropStorage:= InitPropStorage(Self); IniPropStorage.StoredValues.Add.DisplayName:= 'lsvwFile_Columns.Item0_Width'; IniPropStorage.StoredValues.Add.DisplayName:= 'lsvwFile_Columns.Item1_Width'; IniPropStorage.StoredValues.Add.DisplayName:= 'lsvwFile_Columns.Item2_Width'; // Fill the files list. for i := 0 to FFileList.Count - 1 do with lsvwFile.Items do begin Add; Item[i].Caption := ExtractFileName(FFileList.GetItem(i)^.sName); Item[i].SubItems.Add(''); Item[i].SubItems.Add(ExcludeTrailingBackslash(FFileList.GetItem(i)^.sPath)); end; // Set default values for controls. btnRestoreClick(nil); // Initialize presets. LoadPresets; FillPresetsList; cbPresets.Text := FLastPreset; LoadPreset(FLastPreset); end; procedure TfrmMultiRename.FormShow(Sender: TObject); begin with lsvwFile.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; procedure TfrmMultiRename.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin SavePresets; CloseAction:= caFree; with lsvwFile.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; if Assigned(FFileList) then FreeAndNil(FFileList); end; procedure TfrmMultiRename.miDayClick(Sender: TObject); begin if ppNameMenu.Tag=0 then InsertMask('[D]',edName) else InsertMask('[D]',edExt); end; procedure TfrmMultiRename.miHourClick(Sender: TObject); begin if ppNameMenu.Tag=0 then InsertMask('[h]',edName) else InsertMask('[h]',edExt); end; procedure TfrmMultiRename.miMinuteClick(Sender: TObject); begin if ppNameMenu.Tag=0 then InsertMask('[n]',edName) else InsertMask('[n]',edExt); end; procedure TfrmMultiRename.miMonthClick(Sender: TObject); begin if ppNameMenu.Tag=0 then InsertMask('[M]',edName) else InsertMask('[M]',edExt); end; procedure TfrmMultiRename.miSecondClick(Sender: TObject); begin if ppNameMenu.Tag=0 then InsertMask('[s]',edName) else InsertMask('[s]',edExt); end; procedure TfrmMultiRename.miYearClick(Sender: TObject); begin if ppNameMenu.Tag=0 then InsertMask('[Y]',edName) else InsertMask('[Y]',edExt); end; procedure TfrmMultiRename.FreshText; var bError: Boolean; c:integer; sTmpAll,sTmpName,sTmpExt:string; begin bError:= False; for c:=0 to lsvwFile.Items.Count-1 do begin //use mask sTmpName:=sReplace(edName.Text,c); sTmpExt:=sReplace(edExt.Text,c); //join sTmpAll := sTmpName; if sTmpExt <> '' then sTmpAll := sTmpAll + '.' + sTmpExt; //find and replace if cbRegExp.Checked and (edFind.Text <> '') then try sTmpAll:= ReplaceRegExpr(edFind.Text, sTmpAll, edReplace.Text, cbUseSubs.Checked); except sTmpAll:= rsMsgErrRegExpSyntax; bError:= True; end else sTmpAll:=StringReplace(sTmpAll,edFind.Text,edReplace.Text,[rfReplaceAll,rfIgnoreCase]); //file name style sTmpName := ExtractOnlyFileName(sTmpAll); sTmpExt := ExtractFileExt(sTmpAll); sTmpName := ApplyStyle(sTmpName, cmbNameStyle.ItemIndex); sTmpExt := ApplyStyle(sTmpExt, cmbExtensionStyle.ItemIndex); sTmpAll := sTmpName + sTmpExt; //save new name file lsvwFile.Items[c].SubItems.Strings[0]:=sTmpAll; end; btnRename.Enabled:= not bError; if bError then begin edFind.Color := clRed; edFind.Font.Color := clWhite; end else begin edFind.Color := clWindow; edFind.Font.Color := clWindowText; end; end; procedure TfrmMultiRename.cmbNameStyleChange(Sender: TObject); begin FreshText; end; 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; FreshText; end; procedure TfrmMultiRename.btnLoadPresetClick(Sender: TObject); begin LoadPreset(cbPresets.Text); end; procedure TfrmMultiRename.btnSavePresetClick(Sender: TObject); begin if cbPresets.Text <> '' then begin if FPresets.Find(cbPresets.Text) <> -1 then begin if msgYesNo(Format(rsMsgPresetAlreadyExists, [cbPresets.Text])) = False then Exit; end; SavePreset(cbPresets.Text); if cbPresets.Items.IndexOf(cbPresets.Text) = -1 then cbPresets.Items.Add(cbPresets.Text); end; end; procedure TfrmMultiRename.btnDeletePresetClick(Sender: TObject); var Index: Integer; begin if cbPresets.Text <> '' then begin DeletePreset(cbPresets.Text); Index := cbPresets.Items.IndexOf(cbPresets.Text); if Index <> -1 then cbPresets.Items.Delete(Index); cbPresets.Text := ''; end; end; 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; FreshText; end; 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; FreshText; end; procedure TfrmMultiRename.InsertMask(Mask:string;edChoose:Tedit); var sTmp:string; i:integer; begin if edChoose.SelLength>0 then edChoose.Text:=''; //selected text clear sTmp:=edChoose.Text; i:=edChoose.SelStart+2; //insert on current position System.Insert(Mask,sTmp,i); inc(i); edChoose.Text:=sTmp; edChoose.SelStart:=i; end; procedure TfrmMultiRename.btnRestoreClick(Sender: TObject); begin edName.Text:='[N]'; edName.SelStart:=length(edName.Text); edExt.Text:='[E]'; edExt.SelStart:=length(edExt.Text); edFind.Text:=''; edReplace.Text:=''; cbRegExp.Checked:=False; cbUseSubs.Checked:=False; cmbNameStyle.ItemIndex:=0; cmbExtensionStyle.ItemIndex:=0; edPoc.Text:='1'; edInterval.Text:='1'; cmbxWidth.ItemIndex:=0; cbLog.Checked:=False; edFile.Enabled:=cbLog.Checked; edFile.Text:=IncludeTrailingBackslash(lsvwFile.Items.Item[0].SubItems[1])+'default.log'; edFile.SelStart:=length(edFile.Text); cbPresets.Text:=''; FLastPreset:=''; end; function TfrmMultiRename.sReplace(sMask:string;count:integer):string; var sNew,sTmp,sOrigName,sOrigExt:string; i:integer; begin sOrigName:=ChangeFileExt(lsvwFile.Items[count].Caption,''); sOrigExt:=ExtractFileExt(lsvwFile.Items[count].Caption); delete(sOrigExt,1,1); //type [E] sNew:=StringReplace(sMask,'[E]', sOrigExt,[rfReplaceAll]); //type [N] sNew:=StringReplace(sNew,'[N]', sOrigName,[rfReplaceAll]); //type [C] i:=StrToInt(edPoc.Text)+StrToInt(edInterval.Text)*count; sTmp:=format('%.'+ cmbxWidth.Items[cmbxWidth.ItemIndex]+'d',[i]); sNew:=StringReplace(sNew,'[C]', sTmp,[rfReplaceAll,rfIgnoreCase]); //type[Nxx] sNew:=sReplaceXX(sNew,'[N',sOrigName); //type[Exx] sNew:=sReplaceXX(sNew,'[E',sOrigExt); //type [h][m][s][Y][M][D] sNew:= sReplaceDateTime(sNew, FFileList.GetItem(count)^.fTimeI); Result:=sNew; end; function TfrmMultiRename.sReplaceXX(sMask,sSymbol,sOrig:string):string; var p:array [0..2] of integer; sTmp,sTmp2:string; c,c1:integer; Begin while Pos(sSymbol,UpperCase(sMask))>0 do begin p[0]:=Pos(sSymbol,UpperCase(sMask)); p[1]:=Pos(':',sMask); p[2]:=Pos(']',sMask); //incorect type if (p[2]=0)or(p[0]>p[2]) then break; //type [Symbolx] if (p[1]=0)or(p[1]>p[2])or(p[1]c1)or(c<1) then break; if (c1>length(sOrig))then c1:=length(sOrig); sMask:=StringReplace(sMask,copy(sMask,p[0],(p[2]+1)-(p[0])), copy(sOrig,c,(c1+1)-c),[rfIgnoreCase]); end; end; result:=sMask; end; function TfrmMultiRename.sReplaceDateTime(sMask: String; dtDateTime: TDateTime): String; var iStart, iEnd: Integer; sTmp: String; begin Result:= sMask; repeat iStart:= Pos('[', Result); iEnd:= Pos(']', Result); if (iStart = 0) or (iEnd = 0) then Exit; sTmp:= Copy(Result, iStart+1, iEnd-iStart-1); sTmp:= SysToUTF8(FormatDateTime(sTmp, dtDateTime)); Delete(Result, iStart, iEnd-iStart+1); Insert(sTmp, Result, iStart); until False; end; procedure TfrmMultiRename.btnNameMenuClick(Sender: TObject); begin ppNameMenu.AutoPopup:=false; ppNameMenu.Popup(gbMaska.Parent.Left+gbMaska.Left+ btnNameMenu.Left,gbMaska.Parent.Top+ gbMaska.Top+btnNameMenu.Top); ppNameMenu.Tag:=0; end; procedure TfrmMultiRename.btnExtMenuClick(Sender: TObject); begin ppNameMenu.AutoPopup:=false; ppNameMenu.Popup(gbMaska.Parent.Left+gbMaska.Left+ btnExtMenu.Left,gbMaska.Parent.Top+ gbMaska.Top+btnExtMenu.Top); ppNameMenu.Tag:=1; end; procedure TfrmMultiRename.NameClick(Sender: TObject); begin if ppNameMenu.Tag=0 then InsertMask('[N]',edName) else InsertMask('[N]',edExt); end; procedure TfrmMultiRename.NameXClick(Sender: TObject); begin if ppNameMenu.Tag=0 then InsertMask('[N1]',edName) else InsertMask('[N1]',edExt); end; procedure TfrmMultiRename.NameXXClick(Sender: TObject); var c,i:integer; begin i:=0; for c:=0 to lsvwFile.Items.Count-1 do if i '+Item[c].SubItems[0]); end; finally if cbLog.Checked then FileClose(hFile); end; FreshText; end; 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; 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; 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; 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; 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; procedure TfrmMultiRename.LoadPresets; var i: Integer; PresetIndex: Integer; PresetName: String; sPresetNr: String; PresetsCount: Integer; IniFile: TIniFileEx; begin IniFile := gIni; ClearPresetsList; FLastPreset := IniFile.ReadString(sPresetsSection, 'LastPreset', ''); PresetsCount := IniFile.ReadInteger(sPresetsSection, 'Presets', -1); for i := 0 to PresetsCount - 1 do begin sPresetNr := 'Preset' + IntToStr(I + 1); PresetName := IniFile.ReadString(sPresetsSection, sPresetNr + 'PresetName', ''); if PresetName <> '' then begin PresetIndex := FPresets.Add(PresetName, New(PMultiRenamePreset)); with PMultiRenamePreset(FPresets.List[PresetIndex]^.Data)^ do begin FileName := IniFile.ReadString(sPresetsSection, sPresetNr + 'Filename', '[N]'); Extension := IniFile.ReadString(sPresetsSection, sPresetNr + 'Extension', '[E]'); FileNameStyle := IniFile.ReadInteger(sPresetsSection, sPresetNr + 'FilenameStyle', 0); ExtensionStyle := IniFile.ReadInteger(sPresetsSection, sPresetNr + 'ExtensionStyle', 0); Find := IniFile.ReadString(sPresetsSection, sPresetNr + 'Find', ''); Replace := IniFile.ReadString(sPresetsSection, sPresetNr + 'Replace', ''); RegExp := IniFile.ReadBool(sPresetsSection, sPresetNr + 'RegExp', False); UseSubs := IniFile.ReadBool(sPresetsSection, sPresetNr + 'UseSubs', False); Counter := IniFile.ReadString(sPresetsSection, sPresetNr + 'Counter', '1'); Interval := IniFile.ReadString(sPresetsSection, sPresetNr + 'Interval', '1'); Width := IniFile.ReadInteger(sPresetsSection, sPresetNr + 'Width', 0); Log := IniFile.ReadBool(sPresetsSection, sPresetNr + 'Log', False); LogFile := IniFile.ReadString(sPresetsSection, sPresetNr + 'LogFile', ''); end; end; end; end; procedure TfrmMultiRename.SavePresets; var IniFile: TIniFileEx; i: Integer; sPresetNr: String; begin IniFile := gIni; IniFile.EraseSection(sPresetsSection); IniFile.WriteString(sPresetsSection, 'LastPreset', FLastPreset); IniFile.WriteInteger(sPresetsSection, 'Presets', FPresets.Count); for i := 0 to FPresets.Count - 1 do with PMultiRenamePreset(FPresets.List[i]^.Data)^ do begin sPresetNr := 'Preset' + IntToStr(I + 1); IniFile.WriteString(sPresetsSection, sPresetNr + 'PresetName', FPresets.List[i]^.Key); IniFile.WriteString(sPresetsSection, sPresetNr + 'Filename', FileName); IniFile.WriteString(sPresetsSection, sPresetNr + 'Extension', Extension); IniFile.WriteInteger(sPresetsSection, sPresetNr + 'FilenameStyle', FileNameStyle); IniFile.WriteInteger(sPresetsSection, sPresetNr + 'ExtensionStyle', ExtensionStyle); IniFile.WriteString(sPresetsSection, sPresetNr + 'Find', Find); IniFile.WriteString(sPresetsSection, sPresetNr + 'Replace', Replace); IniFile.WriteBool(sPresetsSection, sPresetNr + 'RegExp', RegExp); IniFile.WriteBool(sPresetsSection, sPresetNr + 'UseSubs', UseSubs); IniFile.WriteString(sPresetsSection, sPresetNr + 'Counter', Counter); IniFile.WriteString(sPresetsSection, sPresetNr + 'Interval', Interval); IniFile.WriteInteger(sPresetsSection, sPresetNr + 'Width', Width); IniFile.WriteBool(sPresetsSection, sPresetNr + 'Log', Log); IniFile.WriteString(sPresetsSection, sPresetNr + 'LogFile', LogFile); end; end; procedure TfrmMultiRename.LoadPreset(PresetName: String); var PresetIndex: Integer; begin if PresetName <> '' then begin PresetIndex := FPresets.Find(PresetName); if PresetIndex = -1 then PresetIndex := FPresets.Add(PresetName, New(PMultiRenamePreset)); with PMultiRenamePreset(FPresets.List[PresetIndex]^.Data)^ do begin edName.Text := FileName; edExt.Text := Extension; cmbNameStyle.ItemIndex := FileNameStyle; cmbExtensionStyle.ItemIndex := ExtensionStyle; edFind.Text := Find; edReplace.Text := Replace; cbRegExp.Checked := RegExp; cbUseSubs.Checked := UseSubs; edPoc.Text := Counter; edInterval.Text := Interval; cmbxWidth.ItemIndex := Width; cbLog.Checked := Log; edFile.Text := LogFile; end; FLastPreset := PresetName; FreshText; end; end; procedure TfrmMultiRename.SavePreset(PresetName: String); var PresetIndex: Integer; begin if PresetName <> '' then begin PresetIndex := FPresets.Find(PresetName); if PresetIndex = -1 then PresetIndex := FPresets.Add(PresetName, New(PMultiRenamePreset)); with PMultiRenamePreset(FPresets.List[PresetIndex]^.Data)^ do begin FileName := edName.Text; Extension := edExt.Text; FileNameStyle := cmbNameStyle.ItemIndex; ExtensionStyle := cmbExtensionStyle.ItemIndex; Find := edFind.Text; Replace := edReplace.Text; RegExp := cbRegExp.Checked; UseSubs := cbUseSubs.Checked; Counter := edPoc.Text; Interval := edInterval.Text; Width := cmbxWidth.ItemIndex; Log := cbLog.Checked; LogFile := edFile.Text; end; FLastPreset := PresetName; SavePresets; end; end; procedure TfrmMultiRename.DeletePreset(PresetName: String); var PresetIndex: Integer; begin if PresetName <> '' then begin PresetIndex := FPresets.Find(PresetName); if PresetIndex <> -1 then begin Dispose(PMultiRenamePreset(FPresets.List[PresetIndex]^.Data)); FPresets.Remove(PresetName); FLastPreset := ''; SavePresets; end; end; end; procedure TfrmMultiRename.FillPresetsList; var i: Integer; PresetName: String; begin cbPresets.Clear; for i := 0 to FPresets.Count - 1 do begin PresetName := FPresets.List[i]^.Key; if cbPresets.Items.IndexOf(PresetName) = -1 then cbPresets.Items.Add(PresetName); end; end; procedure TfrmMultiRename.ClearPresetsList; var i: Integer; begin for i := 0 to FPresets.Count - 1 do Dispose(PMultiRenamePreset(FPresets.List[i]^.Data)); FPresets.Clear; end; initialization {$I fmultirename.lrs} end.