/* File Funnel -A DC coding snack Author - Target updated - Nov 2009 Description - copies files from a folder or folders (and it's subfolders) to a single folder select a drive from the drop down list (script will scan available drives every 15 seconds and update the list or click to R button to manually refresh the list) add a folder to the list by right clicking in the tree (or space bar if navigating by the keyboard) - also supports drag + drop filter the copied files by adding the xtn's to the filter field (comma separated, NO SPACES) choose to ignore or rename duplicates press go to process renamed files are tagged with a numerical increment, ie first duplicate would be XXX_01.XTN, second would be XXX_02,XTN, etc Target folder can be set by manually typing it into the text box, or through the standard folder select dialog (click the button) The target folder path is validated at copy stage - invalid paths halt the process with a prompt to create non existent folders. If the script is unable to create the folder the process will halt and the user will be prompted to check the path before trying again The target folder is persistent between sessions. Clicking on the 'Target:' label opens the target folder Credits to: Zaelia from the AHK forum for the treeview code - http://www.autohotkey.com/forum/topic20254.html Skwire for advice Fred Nerd for feedback */ #singleinstance setbatchlines -1 process, exist MyPID:= errorlevel settimer, ListDrives, 15000 root= C: TreeViewWidth := 280 filter:= ignore:=1 ifnotexist, funnel.ini { iniwrite, "c:\temp",funnel.ini, Output_Dir, Target Target:= "c:\temp" } else iniread, target, funnel.ini, output_dir, target gosub, listdrives gui, add, dropdownlist, w50 sort vDList gNewTree, %drives% gui, add, button, x+5 gListDrives, R Gui, Add, TreeView, r23 w%TreeViewWidth% y+10 x5 altsubmit vMyTree gMyTree gui, add, button, x+10 w280 h25 gClearList, Clear List Gui, add, Listview, r16 y+10 w280 grid sort -hdr vMyListView, Folder gui, add, text, y+10, Filters: Gui, add, edit, -wrap w245 x+5 vFilter gSetMe, %Filter% gui, add, groupbox, y+5 xp-35 w280 h45, Duplicates gui, add, radio, yp+20 xp+60 checked vdupes gSetMe, Ignore gui, add, radio, x+50 gSetMe, Rename gui, add, button, y+20 x295 w280 h25 gFunnel, GO gui, add, groupbox, y+7 x5 w40 h29 gui, add, text, yp+10 xp+2 gOpenTarg, Target: Gui, add, edit, -wrap w504 yp-3 x+5 vTarget gsetme, %target% gui, add, button, yp-1 x+5 gGetTarget, ... Gui, Add, StatusBar sb_setparts(190, 190) AddSubFoldersToTree(root) guicontrol, +bs_flat, Target Gui, Show,, File Funnel return ListDrives: OldList:= drives driveget, DrvLst, list ;, fixed loop, parse, drvLst { if a_index = 1 Drives:= a_loopfield . ":" else Drives.= "|" . a_loopfield . ":" } stringreplace, drives, drives, C:, C:| if oldlist = %drives% return else guicontrol,text, DList, |%Drives% gui, submit, nohide return AddSubFoldersToTree(Folder, ParentItemID = 0) { ID:=tv_add(folder,ID) Loop %Folder%\*.*, 2 ; Retrieve all of Folder's sub-folders. { IX:=tv_add(a_LoopFileName, ID) tv_gettext(FnameX,IX) loop, %folder%\%a_loopfilename%\*.*, 2 tv_add(a_loopfilename,IX) } } Space:: ifWinNotActive ahk_pid %MyPID% ; File Funnel { sendplay {space} return } P1:=tv_getselection() gosub treespace return MyTree: ; This subroutine handles user actions (such as clicking). Tree_Events = +,Normal if tree_events contains %a_guievent% { TV_Modify(a_eventinfo) TV_GetText(SelectedItemText, A_EventInfo) ParentID := A_EventInfo Loop { ParentID := TV_GetParent(ParentID) if not ParentID break TV_GetText(ParentText, ParentID) SelectedItemText = %ParentText%\%SelectedItemText% } SelectedFullPath = %SelectedItemText%\ StringReplace, SelectedFullPath, SelectedFullPath, \\ , \ IY := tv_getselection() Loop { IYC := TV_GetChild(IY) if not IYC break TV_delete(IYC) } Loop %SelectedFullPath%\*.*, 2 { IX := TV_Add(A_LoopFileName, IY) TV_gettext(FileNameX, IX) loop %SelectedFullPath%\%FileNameX%\*.*, 2 TV_Add(A_LoopFileName, IX ) } } treespace: if a_guievent = rightclick p1:= a_eventinfo if not P1 return tv_gettext(selected, p1) Loop { P1:=tv_getparent(P1) if not P1 break tv_gettext(ParPath,p1) selected:= parpath . "\" . selected } LV_Add("", Selected) GuiControl, +Redraw, MyListView p1:= return GuiClose: ExitApp NewTree: gui, submit, nohide root:= dlist driveget, DrvStat, status, %root% if drvstat contains NotReady,Invalid,Unknown { msgbox, Drive is inaccessible or not ready return } tv_delete() AddSubFoldersToTree(dlist) return ClearList: if lv_getcount("selected") { loop % lv_getcount("selected") { RowNo:=lv_getnext(0,selected) lv_delete(rowno) } } else lv_delete() return GetTarget: fileselectfolder,Target,Myfold:= "::{20d04fe0-3aea-1069-a2d8-08002b30309d}",3 guicontrol, ,target, %target% if Target = return ifnotexist, %target% return iniwrite, %target%,funnel.ini, Output_Dir, Target gui, submit, nohide return SetMe: gui, submit, nohide return guidropfiles: loop, parse, a_guievent, `n { lv_add("",a_loopfield) } return OpenTarg: run, %target% return funnel: f_Count_Tot:= 0 f_size_Tot:= 0 F_size_cop:= 0 F_count_Cop:= 0 collisions:=0 sb_settext("",1) sb_settext("",2) ifnotexist, %target% { msgbox, 36, Error, target folder does not exist - create? ifmsgbox, no { msgbox, no files copied! return } else filecreatedir, %target% if errorlevel { msgbox, unable to create folder, please check your path and try again return } } loop % lv_getcount() { lv_gettext(mypath, a_index) loop, %mypath%\*.* , 0, 1 { f_Count_Tot:= a_index f_size_Tot+= a_loopfilesizeKB sb_settext(f_count_Tot . "files - " . f_size_tot . "Kb", 1) sb_settext(f_count_Cop . "files - " . f_size_Cop . "Kb", 2) if filter = filecopy, %a_loopfilefullpath%, %target%, 0 else if filter contains %a_loopfileext% filecopy, %a_loopfilefullpath%, %target%, 0 if errorlevel = 0 { F_size_Cop+= %A_loopfilesizeKB% F_count_cop++ } else { ; if filter contains %a_loopfileext% collisions++ if dupes = 2 { tmpfile:= exfile:= target . "`\" . a_loopfilename stringtrimright, exfile, exfile, 4 loop { if a_index < 10 tmpfile:= exfile . "_0" . a_index . "`." . a_loopfileext else tmpfile:= exfile . "_" . a_index . "`." . a_loopfileext ifnotexist, %tmpfile% break } filecopy, %a_loopfilefullpath%, %tmpfile%, 0 F_size_Cop+= %a_loopfilesizeKB% F_count_cop++ collisions-- } } errorlevel:=0 } } f_size_cop/=1024 F_size_tot/=1024 sb_settext(f_count_Tot . " files - " . f_size_tot . "Mb", 1) sb_settext(f_count_Cop . " files copied - " . f_size_Cop . "Mb", 2) sb_settext(collisions . " duplicates", 3) return #R:: reload