View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002267 | Double Commander | File operations | public | 2019-03-19 02:19 | 2021-10-29 23:21 |
Reporter | CryHam | Assigned To | Alexx2000 | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Projection | none | ETA | none | ||
Product Version | 1.0.0 (trunk) | Product Build | r8738 | ||
Fixed in Version | 1.0.0 | ||||
Summary | 0002267: [Patch] Multi Rename - Avoid collisions with OldFiles | ||||
Description | So TC handles multi renames even if new names collide. E.g. if old files names are 001 to 005 and new names 004 to 008, then renaming 001 to 004 would overwrite already existing file 004. I'm not sure how TC does it, but I did it in DC like so: 1. Added TStringHashList OldNames and filled with all OldFiles. 2. Before adding to rename operation I check if new name exists in OldNames, if so then I'm adding a @ at end of file name, before extension (if any). So first there will be 004@ and 005@ files. 3. Then after operation finishes, I'm iterating all again and (again checking) then renaming them back, removing @ char from name. The code in patch works, but surely is far from great. I tried before to use that TFileSourceOperation, but it complained that it can't rename 004@ to 004 back, etc. IDK why. Then I tried duplicating that code, to have second operation after the first finished, but this way also had the same issue. Also I guess, points 2 and 3 could probably be coded to execute faster. | ||||
Tags | No tags attached. | ||||
Attached Files | fmultirename.pas.patch (2,146 bytes)
Index: fmultirename.pas =================================================================== --- fmultirename.pas (revision 8738) +++ fmultirename.pas (working copy) @@ -996,10 +996,11 @@ procedure TfrmMultiRename.RenameFiles; var - AFile: TFile; + AFile,OFile: TFile; NewName: String; - I, J, K: Integer; + I, J, K, L: Integer; OldFiles, NewFiles: TFiles; + OldNames: TStringHashList; AutoRename: Boolean = False; Operation: TFileSourceOperation; theNewProperties: TFileProperties; @@ -1016,11 +1017,29 @@ NewFiles:= TFiles.Create(EmptyStr); try + // OldNames + OldNames:= TStringHashList.Create(True); + OldNames.Clear; + for I:= 0 to OldFiles.Count -1 do + OldNames.Add(OldFiles[I].Name); + FNewNames.Clear; for I:= 0 to FFiles.Count - 1 do begin AFile:= TFile.Create(EmptyStr); AFile.Name:= FreshText(I); + + // Avoid collisions with OldNames + L:= OldNames.Find(AFile.Name); + if L >= 0 then + begin + // Add @ at end of name + if AFile.Extension = '' then + AFile.Name:= AFile.NameNoExt + '@' + else + AFile.Name:= AFile.NameNoExt + '@.' + AFile.Extension; + end; + // Checking duplicates NewName:= FFiles[I].Path + AFile.Name; J:= FNewNames.Find(NewName); @@ -1073,6 +1092,30 @@ NewFiles.Free; end; + // Rename files back, remove @ + for I:= 0 to FFiles.Count - 1 do + begin + AFile:= TFile.Create(EmptyStr); + AFile.Name:= FreshText(I); + OFile:= AFile.Clone; + + L:= OldNames.Find(AFile.Name); + if L >= 0 then + begin + if AFile.Extension = '' then + begin + OFile.Name:= FFiles[I].Path + AFile.NameNoExt + '@'; + RenameFile(FFileSource, OFile, AFile.NameNoExt, True); + end else begin + OFile.Name:= FFiles[I].Path + AFile.NameNoExt + '@.' + AFile.Extension; + RenameFile(FFileSource, OFile, AFile.NameNoExt + '.' + AFile.Extension, True); + end; + FFiles[I].Name := AFile.Name; + end; + AFile.Free; + OFile.Free; + end; + StringGridTopLeftChanged(StringGrid); end; | ||||
Fixed in Revision | 8850, 8852 | ||||
Operating system | Windows | ||||
Widgetset | Win32 | ||||
Architecture | 64-bit | ||||
|
Patch is on svn revision 8738. I tested only on Windows. And I didn't test log to file (doesn't work) or for any file access errors during renaming in point 3. Lastly I assumed that there won't be any same files with that @ symbol at end already existing. |
|
I made alternative implementation. |
Date Modified | Username | Field | Change |
---|---|---|---|
2019-03-19 02:19 | CryHam | New Issue | |
2019-03-19 02:19 | CryHam | File Added: fmultirename.pas.patch | |
2019-03-19 02:23 | CryHam | Note Added: 0003104 | |
2019-03-19 02:24 | CryHam | Note Edited: 0003104 | |
2019-05-19 21:03 | Alexx2000 | Fixed in Revision | => 8850 |
2019-05-19 21:03 | Alexx2000 | Note Added: 0003163 | |
2019-05-19 21:03 | Alexx2000 | Status | new => resolved |
2019-05-19 21:03 | Alexx2000 | Fixed in Version | => 1.0.0 |
2019-05-19 21:03 | Alexx2000 | Resolution | open => fixed |
2019-05-19 21:03 | Alexx2000 | Assigned To | => Alexx2000 |
2019-05-19 21:06 | Alexx2000 | Relationship added | related to 0002054 |
2019-05-21 21:00 | Alexx2000 | Fixed in Revision | 8850 => 8850, 8852 |
2021-10-29 23:21 | Alexx2000 | Status | resolved => closed |