AutoHotkey: App GUI Listview to Rename Files

Applies to:
  • Microsoft Windows 7 Professional - Service Pack 1
  • AutoHotkey v1.1.33.02
What?
So this is the documentation for a snippet of code that will list files of a directory using an AutoHotkey GUI and display what it will name them. The app needs to rename files but append an incremented count if the name of a file already exists. The original file needs to keep its original name.

What I have
copyraw
EDIT 0_00 0_30 My File 1 00_00 00_30.txt
edIT 0_00 0_31 My File 2 00_00 00_30.txt
eDIT 0_00 0_30 My File 3 00_00 00_31.wav
My File 3.wav
My File 3 - Copy.wav
  1.  EDIT 0_00 0_30 My File 1 00_00 00_30.txt 
  2.  edIT 0_00 0_31 My File 2 00_00 00_30.txt 
  3.  eDIT 0_00 0_30 My File 3 00_00 00_31.wav 
  4.  My File 3.wav 
  5.  My File 3 - Copy.wav 
What I want
copyraw
My File 1.txt
My File 2.txt
My File 3 (2).wav
My File 3.wav
My File 3 (3).wav
  1.  My File 1.txt 
  2.  My File 2.txt 
  3.  My File 3 (2).wav 
  4.  My File 3.wav 
  5.  My File 3 (3).wav 

How?
So if you copy the following code into an AutoHotkey file and execute it, it will popup an app with 3 buttons: 1st to generate or populate a list of the files in the script directory, the 2nd to do the actual renaming. A text field is provided (defaults to A_ScriptDir) to specify what folder to scan for files. The 3rd button simply reloads the app (used mostly for testing/development). Lastly, a listview that has 2 columns: the 1st lists the files in that directory, the 2nd displays the new filenames of the files.
;
; Language:     English
; Platform:     Microsoft Windows 7 Professional
; AutoHotkey:   v1.33.02
; Author:       -
; Description:  This program will remove the word EDIT and words containing an underscore (eg. 01_23)
;               and then add an increment to the file name if a file with the same name exists.
;
; Date (v1.0):  8 July 2020
;               - Initial Release
; Date (v1.1):  10 August 2020
;               - Checks for duplicates done by searching its own column.
;               - Also checks for duplicates if file exists.
;               - Leaves original file as is.
;
; --------------------------------------------------------------------------------------
; Set program Defaults
; --------------------------------------------------------------------------------------

#NoEnv                          ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input                  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%     ; Ensures a consistent starting directory.

; --------------------------------------------------------------------------------------
; Set program Defaults
; --------------------------------------------------------------------------------------

Title   := "File List Renamer"
Desc    := "This program will remove the word EDIT and words containing an underscore (eg. 01_23)"
Desc    .= " and then add an increment to the file name if a file with the same name exists."
Version := "1.1"
Width   := 600
Height  := 600
BgColor := "EEEEEE"
FgColor := "34495E"
Options := "+Caption +Border +OwnDialogs"
DefltDir:= A_ScriptDir

; --------------------------------------------------------------------------------------
; Create GUI

Gui, New, %Options%, %Title% v%Version%
Gui, Color, %BgColor%
Gui, Font, s8, Verdana
Gui, Add, Button, Default w110 h30 x10 y10 gGenerateList vButton1, 1. Generate List
; 0x1000 adds a grooved border
; 0x200 aligns horizontal to left and vertically centered (0x201: center center, 0x202: right center)
Gui, Add, Text, w350 h28 x120 y11 -Multi vSelectedDir gBrowseFolders 0x1000 +0x200, %DefltDir%
Gui, Add, Button, w110 h30 x480 y10 gRenameList, 2. Rename
;Gui, Add, Button, w110 h30 x480 y10 gRestart, Reload
Gui, Add, ListView, w600 h528 +Hdr +Grid x0 y50, Old Name|New Name
Gui, Font, s7, Verdana
Gui, Add, StatusBar,, Ready.
Gui, Show, w%Width% h%Height% x10 y10
Return

; --------------------------------------------------------------------------------------
; Function: CountExistingInColumn2: Find in list view occurrences of new names column

CountExistingInColumn2( v_Filename )
{
    v_AlreadyExists := 0
    Loop, % LV_GetCount()
    {
        LV_GetText(v_Text, A_Index, 2)
        if (v_Text == v_Filename)
            v_AlreadyExists++
    }
    Return v_AlreadyExists
}

; --------------------------------------------------------------------------------------
; SubRoutine: GenerateList: Generate/Populate list of files and their proposed new names

GenerateList:
    SB_SetText("Generating...")
    LV_Delete()
    v_RowCount := 0
    GuiControlGet, SelectedDir
    v_FilesPath := SelectedDir "\*"
    Loop, Files, %v_FilesPath%
    {
        ; skip if file ext is not media
        if A_LoopFileExt not contains wav,mp3,avi,flv,mkv,mov,mp4,mpeg,mpg,wmv
            continue

        ; get name of file without its extension
        v_ThisFileName := A_LoopFileName
        v_ThisFileName := StrReplace( A_LoopFileName, "." A_LoopFileExt, "")
        a_ThisFileName := StrSplit( v_ThisFileName, A_Space, ".")

        ; remove converter comments from file name
        v_NewName := ""
        Loop % a_ThisFileName.MaxIndex()
        {
            v_FoundUnderScore := InStr( a_ThisFileName[A_Index], "_")
            if( a_ThisFileName[A_Index] != "EDIT" && v_FoundUnderScore < 1)
                v_NewName := v_NewName A_Space a_ThisFileName[A_Index]
        }

        ; filter words
        a_FilterOutWords := [" (1)"," (2)"," (3)"," (4)","- Copy"]
        Loop % a_FilterOutWords.MaxIndex()
            v_NewName := StrReplace( v_NewName, a_FilterOutWords[ A_Index ], "")

        ; loop until there are no more double spaces
        while InStr( v_NewName, "  ")
            v_NewName := StrReplace( v_NewName, "  ", " ")

        ; trim any leading/trailing spaces and put back the extension
        v_NewName := Trim( v_NewName )
        v_NewNameWithExt := v_NewName "." A_LoopFileExt
        v_OldNameWithExt := v_NewName "." A_LoopFileExt
        v_NewNameWithPath := SelectedDir "\" v_NewName "." A_LoopFileExt

        ; *******************************************************************************************
        ; the clever bit: loop while incrementing checking if the value is not already in the list
        ; also check whether proposed file name matches the original file exists and is an exception for renaming.
        v_Increment := 1
        b_KeepLooping := true
        while ( b_KeepLooping || CountExistingInColumn2( v_NewNameWithExt ) > 0 )
        {
            v_Increment++
            b_FileExists:= FileExist( SelectedDir "\" v_NewNameWithExt ) ? true : false
            b_IsOriginal:=  v_NewNameWithExt == A_LoopFileName ? true : false
            b_InColumn  := CountExistingInColumn2( v_NewNameWithExt ) > 0 ? true : false

            ; if file exists or is in column and is not original then increment
            if ( b_FileExists || b_InColumn) && (!b_IsOriginal) {
                v_NewNameWithExt := Trim( v_NewName ) " (" v_Increment ")." A_LoopFileExt
            } else {
                break
            }
        }

        ; add to the list view
        LV_Add("", A_LoopFileName, v_NewNameWithExt )

        ; update for the status bar
        v_RowCount++
        SB_SetText("Generating entry #" v_RowCount ".")
    }

    ; auto fit columns
    LV_Modifycol(1, "AutoHdr")
    LV_Modifycol(2, "AutoHdr")

    ; update status bar
    v_Grammar := v_RowCount == 1 ? "y" : "ies"
    SB_SetText("Ready. Generated " v_RowCount " entr" v_Grammar ".")
Return

; --------------------------------------------------------------------------------------
; SubRoutine: RenameList: Do the actual renaming of the files

RenameList:
    SB_SetText("Renaming...")
    v_RowCount := 0
    GuiControlGet, SelectedDir
    v_FolderPath := SelectedDir "\"
    Loop, % LV_GetCount()
    {
        LV_GetText( v_OldFileName, A_Index, 1)
        LV_GetText( v_NewFileName, A_Index, 2)
        v_Source := v_FolderPath v_OldFileName
        v_Target := v_FolderPath v_NewFileName
        ; MsgBox %v_Source%`rto`r%v_Target%
        FileMove, %v_Source%, %v_Target%
        v_RowCount++
        SB_SetText("Renaming & Moving Entry #" v_RowCount ".")
    }
    v_Grammar := v_RowCount == 1 ? "y" : "ies"
    SB_SetText("Ready. Renamed/Moved " v_RowCount " Entr" v_Grammar ".")
Return

; --------------------------------------------------------------------------------------
; SubRoutine: BrowseFolders: Open a prompt to change the folder to scan

BrowseFolders:
    FileSelectFolder, SelectedFolder , *%A_ScriptDir%, 0, Select a folder to scan...
    if (SelectedFolder != "")
    {
        ; remove trailing slash (could use RTrim instead)
        SelectedFolder := RegExReplace(SelectedFolder, "\\$")
        GuiControl, Text, SelectedDir, %SelectedFolder%
    }
    else
        GuiControl, Text, SelectedDir, %A_ScriptDir%
Return

; --------------------------------------------------------------------------------------
; Closing

Restart:
    Reload
Return

GuiClose:
CloseMe:
    ExitApp
Category: AutoHotkey :: Article: 723

Add comment

Your rating:

Submit

Credit where Credit is Due:


Feel free to copy, redistribute and share this information. All that we ask is that you attribute credit and possibly even a link back to this website as it really helps in our search engine rankings.

Disclaimer: Please note that the information provided on this website is intended for informational purposes only and does not represent a warranty. The opinions expressed are those of the author only. We recommend testing any solutions in a development environment before implementing them in production. The articles are based on our good faith efforts and were current at the time of writing, reflecting our practical experience in a commercial setting.

Thank you for visiting and, as always, we hope this website was of some use to you!

Kind Regards,

Joel Lipman
www.joellipman.com

Please publish modules in offcanvas position.