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

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

Related Articles

Joes Revolver Map

Accreditation

Badge - Certified Zoho Creator Associate
Badge - Certified Zoho Creator Associate

Donate & Support

If you like my content, and would like to support this sharing site, feel free to donate using a method below:

Paypal:
Donate to Joel Lipman via PayPal

Bitcoin:
Donate to Joel Lipman with Bitcoin bc1qf6elrdxc968h0k673l2djc9wrpazhqtxw8qqp4

Ethereum:
Donate to Joel Lipman with Ethereum 0xb038962F3809b425D661EF5D22294Cf45E02FebF
© 2024 Joel Lipman .com. All Rights Reserved.