How to add "Cancel" , "Rename" and "Overwrite" option?

Currently, I’ve been using the script below to move files to sub-folders of my filing folder. But currently, I only have the option of renaming a file if a file with the same name already exists in the folder it’s supposed to go into. That was fine before I needed to overwrite the old files, of which I have come across now.

Can anyone help out a newb here?

property baseFolder : missing value

on run
   set baseFolder to choose folder
end run

on open theFiles
   if baseFolder is missing value then set baseFolder to choose folder
   repeat with oneFile in theFiles
       set fileName to name of (info for oneFile)
       tell text 1 thru 3 of name of (info for oneFile) to set destinationfolder to (baseFolder as text) & text 1 & ":" & text 1 thru 2 & ":" & text 1 thru 3 & ":"
       repeat
           try
               destinationfolder & fileName as alias
               set fileName to text returned of (display dialog "file " & quote & (get fileName) & quote & " already exists." & return ¬
                   & "Please choose a different name" default answer (get fileName) buttons {"OK"} default button 1)
               tell application "Finder" to set name of (contents of oneFile) to fileName
           on error
               tell application "Finder" to move oneFile to folder destinationfolder
               exit repeat
           end try
       end repeat
   end repeat
end open

Thanks,
Jason

Try it this way:

display dialog "file " & quote & (get fileName) & quote & " already exists." & return ¬
	& "Please choose a different name" default answer (get fileName) buttons {"Overwrite", "OK"} default button 2
set {fileName, button_returned} to {text returned of result, button returned of result}

Hmmm…while the Overwrite button shows up, after I click “Overwrite” button, it returns an error that says “An item with the same name already exists in the destination.”

Am I not putting the code in the correct place?

property baseFolder : missing value

on run
	set baseFolder to choose folder
end run

on open theFiles
	if baseFolder is missing value then set baseFolder to choose folder
	repeat with oneFile in theFiles
		set fileName to name of (info for oneFile)
		tell text 1 thru 3 of name of (info for oneFile) to set destinationfolder to (baseFolder as text) & text 1 & ":" & text 1 thru 2 & ":" & text 1 thru 3 & ":"
		repeat
			try
				destinationfolder & fileName as alias
				set fileName to text returned of (display dialog "file " & quote & (get fileName) & quote & " already exists." & return ¬
					& "Please choose a different name" default answer (get fileName) buttons {"Overwrite", "OK"} default button 2)
				set {fileName, button_returned} to {text returned of result, button returned of result}
				tell application "Finder" to set name of (contents of oneFile) to fileName
			on error
				tell application "Finder" to move oneFile to folder destinationfolder
				exit repeat
			end try
		end repeat
	end repeat
end open

You need to test button_returned and take the appropriate action:

if button_returned="Overwrite" then
-- code to overwrite the file
else
-- code to save the file under new name. 
-- this code should test new name for existing file.
end if

Hi.

Your code’s in the right place, but you’re trying to get the ‘text returned’ and ‘button returned’ of ‘fileName’ and you’re not attempting to make any use of the results. That section should look something like this:

display dialog "file " & quote & fileName & quote & " already exists." & return ¬
	& "Please choose a different name" default answer fileName buttons {"Overwrite", "OK"} default button 2
set {fileName, button_returned} to {text returned of result, button returned of result}
if (button_returned is "Overwrite") then
	tell application "Finder" to move oneFile to folder destinationfolder with replacing
else
	tell application "Finder"
		set name of oneFile to fileName
		move oneFile to folder destinationfolder
	end tell
end if

Your original post said you wanted to add a “Cancel” button too. These usually generate a “User canceled.” error (number -128) which stops the script. However, since your dialog’s in a ‘try’ block, the error won’t stop the script. But you’ll need to trap it to prevent the move in the ‘on error’ section from taking place:

try
	destinationfolder & fileName as alias
	display dialog "file " & quote & fileName & quote & " already exists." & return ¬
		& "Please choose a different name" default answer fileName buttons {"Cancel", "Overwrite", "OK"} default button 3
	set {fileName, button_returned} to {text returned of result, button returned of result}
	if (button_returned is "Overwrite") then
		tell application "Finder" to move oneFile to folder destinationfolder with replacing
	else
		tell application "Finder"
			set name of oneFile to fileName
			move oneFile to folder destinationfolder
		end tell
	end if
on error number errNum
	if (errNum is not -128) then tell application "Finder" to move oneFile to folder destinationfolder
	exit repeat
end try

I’m not sure why you’ve got the ‘exit repeat’ in there, but I’ve left it.

A few observations about these two lines:

  1. The first line calls a function to get the name of the file and stores the name in a variable, so there’s no need to use the function again in the second line. You can get the text straight from the variable.

  2. ‘text 1 thru 2’ of ‘text 1 thru 3’ of the file name is the same as ‘text 1 thru 2’ of the file name itself, so the extra extraction isn’t necessary.

  3. ‘text 1’ of some text happens to work with Unicode text, but isn’t officially part of the language. You should use ‘character 1’ for the individual character. But ‘text’ is correct in a range reference such as ‘text 1 thru 3’ of the text.

set fileName to name of (info for oneFile)
tell fileName to set destinationfolder to (baseFolder as text) & character 1 & ":" & text 1 thru 2 & ":" & text 1 thru 3 & ":"

Thank you so much for you help on this, guys. I truly appreciate it.

So while I have updated the code to add the Cancel and Overwrite action to the script (which both work fine), but the process gets stuck in a repeat. You had mentioned about the “exit repeat” of which I removed and it didn’t help solve the problem and in fact, makes things worse by not letting me cancel the script. Also, even if I rename the file, it repeats the script to try to keep placing the file into the destination folder.

Does that make sense?

Thanks,
Jason

Hi, Jason.

Many apologies. I didn’t notice your inner repeat loop. If you remove the inner ‘repeat’ and ‘end repeat’ lines, the problem goes away. However, that inner repeat is probably there to allow the user to keep trying “different names” until a non-clashing one is found, in which case we need to take a step back to your original logic (which, although complex, was correct for the renaming). An ‘exit repeat’ is also needed after the overwrite move.

property baseFolder : missing value

on run
	set baseFolder to choose folder
end run

on open theFiles
	if baseFolder is missing value then set baseFolder to choose folder
	repeat with oneFile in theFiles
		set fileName to name of (info for oneFile)
		tell fileName to set destinationfolder to (baseFolder as text) & character 1 & ":" & text 1 thru 2 & ":" & text 1 thru 3 & ":"
		repeat
			try
				destinationfolder & fileName as alias
				display dialog "file " & quote & fileName & quote & " already exists." & return ¬
					& "Please choose a different name" default answer fileName buttons {"Cancel", "Overwrite", "OK"} default button 3
				set {fileName, button_returned} to {text returned of result, button returned of result}
				if (button_returned is "Overwrite") then
					tell application "Finder" to move oneFile to folder destinationfolder with replacing
					exit repeat -- File moved. Exit inner repeat.
				else
					tell application "Finder" to set name of oneFile to fileName -- File renamed. Do inner repeat to test new name.
				end if
			on error number errNum
				if (errNum is not -128) then tell application "Finder" to move oneFile to folder destinationfolder
				exit repeat -- File move. Exit inner repeat.
			end try
		end repeat
	end repeat
end open

The “Cancel” button still acts as a “Skip” button the way I’ve done it, but if you want it to stop the script entirely, that would be fairly easy to arrange. The renaming process ensures that the new name is unique, but not that it’s appropriate for the folder. If you rename “Fred.txt” to “Greta.txt”, it’ll still go in the “Fre” folder.

Edit: If you want the “Cancel” button to stop the script altogether, change this:

on error number errNum
	if (errNum is not -128) then tell application "Finder" to move oneFile to folder destinationfolder

. to this:

on error number -43  -- Catch the "File <name> wasn't found" error, but not "User Canceled".
	tell application "Finder" to move oneFile to folder destinationfolder

Nigel,
Your solution works perfectly. How you can solve these kind of problems so fast and accurately just boggles my mind. What does it take to “get it” when it comes to learning this kind of coding? HTML or CSS, no problem. They seem like child’s play compared to true programming like Applescript and other languages. I tried to get through the AppleScript For Absolute Starters by Bill Cheeseman, but got lost 3/4 the way through.

Any thoughts?

Thanks again for the help with this script that is now going to save me SOOOO much time. Cheers.