You are not logged in.
Hello experts,
maybe this question has been raised before, but I couldn´t find any specific postings. So I started this new topic, hoping you will be able to help me out of my misery.
What I am trying to do is create a little backup program for my most important folders. I want it to be flexible, so I would like to implement a choose folder dialog (only folders are involved). Here is what I have so far:
Applescript:
script DelOldBck
on DelOldBck()
set OldDefault to alias "Macintosh HD:Users:XXX:Desktop:"
set OldFolders to (choose folder with prompt "Choose Folders to delete:" default location OldDefault with multiple selections allowed)
tell application "Finder" to set theOLdFold to every folder of OldFolders as alias list
repeat with _folder in theOLdFold
delete _folder
end repeat
end DelOldBck
end script
tell DelOldBck to DelOldBck()
So basically I would like to select something which then gets passed on to another functionality, in this particular case the trash. But it might as well be a functionality to duplicate the selected folders to a different location instead of the trash. Or the bin, as you may call it..
I have done some research on POSIX, etc. and have already done some testing with different setups in this regard. Everything failed and threw an error, the above coding is the one that does not throw any errors, but doesn´t do anything either.
From what I have seen in the standard ScriptEditor, the selection is stored as an array of aliases, does that have anything to do with the problems that arise here? I am working with Catalina by the way.
Please share your knowledge on this one. If you have a solution I would also be interested why your code works. Thanks in advance!
Offline
Like this?
Applescript:
script DelOldBck
property backupFolder : path to temporary items
property OldDefault : path to desktop folder
property OldFolders : {}
on DelOldBck()
set OldFolders to (choose folder with prompt "Choose Folders to delete:" default location OldDefault with multiple selections allowed)
repeat with _folder in OldFolders -- repeat with every folder of the list OldFolders
tell application "Finder" to delete _folder -- tell to Finder to delete current alias (send to trash)
end repeat
end DelOldBck
on emptyTrash()
tell application "Finder" to empty trash
end emptyTrash
on backupFolders()
tell application "Finder" to duplicate _folder to backupFolder replacing yes
end backupFolders
end script
DelOldBck's DelOldBck()
-- DelOldBck's emptyTrash() -- uncomment to empty the trash
-- DelOldBck's backupFolders() -- uncomment to backup the folders
return {DelOldBck's backupFolder, DelOldBck's OldDefault, DelOldBck's OldFolders}
Now, replace the code after end script with this and note what happens. The script (that is, script object named "DelOldBck") changes little the behaviour, when you change it's properties:
Applescript:
set DelOldBck's OldDefault to downloads folder
DelOldBck's DelOldBck()
Last edited by KniazidisR (2020-03-25 06:07:24 am)
Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 13.1
Ram: 4 GB
Offline
What a quick response, I think I understand what you are doing here.
Besides, everything you stated worked fine in my tests, thanks a lot!
There is one issue though that I couldn´t catch with for example a try statement. If in the choose folder dialog I select folders all the rest runs fine. If I don´t select anything AppleScript throws an error and quits, do you have any thoughts on how to keep the program running?
And one last question on your return remark. In my tests I could use variables defined in a particular script only in that script. So I assume that returning the variables makes them reusable again in any other script that attempts to use them? That would be a great advantage, I just did not have any time yet to test that. It would make the variables accessible on a global level.
Offline
There is one issue though that I couldn´t catch with for example a try statement. If in the choose folder dialog I select folders all the rest runs fine. If I don´t select anything AppleScript throws an error and quits, do you have any thoughts on how to keep the program running?
You can do something like this:
Applescript:
script DelOldBck
property backupFolder : path to temporary items
property OldDefault : path to desktop folder
property OldFolders : {}
on DelOldBck()
try
set OldFolders to (choose folder with prompt "Choose Folders to delete:" default location OldDefault with multiple selections allowed)
repeat with _folder in OldFolders -- repeat with every folder of the list OldFolders
tell application "Finder" to delete _folder -- tell to Finder to delete current alias (send to trash)
end repeat
on error number -128
display notification "Errorr number -128: User cancelled. Only This call will terminated. Not the next"
end try
end DelOldBck
on emptyTrash()
tell application "Finder" to empty trash
end emptyTrash
on backupFolders()
tell application "Finder" to duplicate _folder to backupFolder replacing yes
end backupFolders
end script
DelOldBck's DelOldBck() -- Cancelled
DelOldBck's emptyTrash() -- Executed
And one last question on your return remark. In my tests I could use variables defined in a particular script only in that script. So I assume that returning the variables makes them reusable again in any other script that attempts to use them? That would be a great advantage, I just did not have any time yet to test that. It would make the variables accessible on a global level.
You can get value of variable Var1 of script A into variable passedValue of script B. To be this available Var1 should be declared as property of script A.
Applescript:
script A
property Var1 : "I am special variable of script A"
end script
script B
on passVariable()
set passedValue to A's Var1
end passVariable
end script
return B's passVariable()
You can return passVariable not using B's method (as in the previous example), but using B's property as well:
Applescript:
script A
property Var1 : "I am special variable of script 1"
end script
script B
property passedValue : A's Var1
end script
return B's passedValue
Last edited by KniazidisR (2020-03-25 11:52:40 pm)
Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 13.1
Ram: 4 GB
Offline
Sorry for the delay. I had to do a little research on passing values between subroutines and during runtime. Now I think I got the hang of it So that should be clear.
I did some other stuff and then came back to testing the Choose dialog functionality again, if you still remember. Your solution to catching the error number is great, but it means that the standard Cancel button would no longer work the way it is intended to.
So I would rather leave it as it is: Clicking Cancel should mean quit and not continue. I was not able to catch any error number when clicking Choose without selecting anything, so I could not use your method in that way.
But I would want it to be like that - clicking the standard Choose button without selecting anything should mean continue anyway and not raise an error by default. A third button would of course be an option as well, so Cancel and Choose could remain standard buttons and unchanged. But I was not able to create a third button in this standard dialog, I do not think that this would be possible.
What I did notice while testing was that maybe something does get passed on as a value anyway if no selection was made and before the error is issued. So I tried to program around that and surprisingly enough the standard error did not show up anymore. It was replaced by my dialog that way. Unfortunately, if something does get selected it does not get recognised by my test coding either. But it may lead to an alternative way, any suggestions on that?
Applescript:
property OldDefault : path to desktop as alias
property OldFolders : {}
-- Calling Subroutines
DelOldBck(OldDefault)
EmptyTrash()
-- Subroutines
on DelOldBck(OldDefault)
set OldFolders to (choose folder with prompt "Choose Folders to delete:" default location OldDefault with multiple selections allowed)
set OldFoldCount to count of items of OldFolders
if (OldFoldCount > 1) then
repeat with _folder in OldFolders
tell application "Finder" to delete _folder
end repeat
else
display dialog "No folders in selection!"
end if
end DelOldBck
on EmptyTrash()
tell application "Finder"
open the trash
set TrashCount to count of items of the trash
if (TrashCount > 0) then
display dialog "Empty the trash?" buttons {"Cancel", "OK"} with icon caution
empty the trash
else
display dialog "The trash is empty!" buttons {"Cancel", "OK"} default button 2 with icon caution
end if
delay 3
end tell
end EmptyTrash
Offline
I edited four instructions.
Applescript:
if (OldFoldCount > 0) then -- EDITED, was erroneously >1
display dialog "No folders in selection!" buttons {"OK"} default button 1 -- no need for the 2 buttons given by default
display dialog "Empty the trash?" buttons {"Cancel", "OK"} default button 2 cancel button 1 with icon caution -- EDITED mainly for cancel button
display dialog "The trash is empty!" buttons {"OK"} default button 1 with icon caution -- no need for the 2 buttons given by default
Yesterdays, in the thread <https://macscripter.net/viewtopic.php?id=47535> I described in details why I added "cancel button 1".
HAPPILY, all users aren't using English and it's (quite) only on machines using this language that a button named "Cancel" issue an error number -128 when it's triggered.
With your original code, clicking "Cancel" or clicking "OK" gave the same behavior, on my French system, the trash was emptied.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 4 avril 2020 21:12:33
Last edited by Yvan Koenig (2020-04-04 01:21:05 pm)
Offline
One important conclusion follows from Yvan Koenig's observations: it is better to always indicate the Cancel button explicitly. For universality of raising error -128.
Last edited by KniazidisR (2020-04-04 03:35:48 pm)
Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 13.1
Ram: 4 GB
Offline
Some times ago I used an other scheme.
I grabbed the localized string for Cancel and used it in the dialogs.
This way, inserting the instruction cancel button xy wasn't required.
It worked but the result was sometimes an awful mess.
When the script displayed all its own messages in English, having a single French word in the dialogs was at least ridiculous.
So I dropped this way and switched to the cancel button xy road which, all in all, is easier to apply.
Having localized tools is fine but a bit of consistency in their GUI is good too.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 5 avril 2020 10:35:54
Offline
Hey people, I see you started a discussion about adding Cancel buttons explicitly.. This may be important in views of localisation, etc. - in my case I do not think it is. This is for private use only, and there will be no major adaptions to this localised version of mac os. Anyways, for other people it may be important.
Still, you focused too much on the empty trash part in my opinion. My question was about the choose folder dialog process, the empty trash part was just so that something useful might happen in the coding example.
Speaking of explicitly, that is why I had done this part:
Applescript:
if (OldFoldCount > 1) then
That is because doing it like this:
Applescript:
if (OldFoldCount > 0) then
will create the error that I am trying to avoid. With Count > 1 it works sort of, but not really when you select anything. Any thoughts on that? I also believe you will agree that placing a third custom button in this standard dialog will not be possible.
Offline
Hey people, I see you started a discussion about adding Cancel buttons explicitly.. This may be important in views of localisation, etc. - in my case I do not think it is. This is for private use only, and there will be no major adaptions to this localised version of mac os. Anyways, for other people it may be important.
Still, you focused too much on the empty trash part in my opinion. My question was about the choose folder dialog process, the empty trash part was just so that something useful might happen in the coding example.
Speaking of explicitly, that is why I had done this part:Applescript:
if (OldFoldCount > 1) then
That is because doing it like this:
Applescript:
if (OldFoldCount > 0) then
will create the error that I am trying to avoid. With Count > 1 it works sort of, but not really when you select anything. Any thoughts on that? I also believe you will agree that placing a third custom button in this standard dialog will not be possible.
When you write "when you select anything", I guess that you mean : "when you click cancel or press Escape"
In such case, given the fact that your display dialog instruction doesn't specify the buttons, the system use its own default pair which is
OK with its shortcut return
Cancel with its shortcut Escape.
Logically, when you click Cancel you get the designed error number -128.
Try to use :
Applescript:
-- property OldDefault : path to desktop as alias --no need for a property
-- property OldFolders : {} -- Useless
-- Calling Subroutines
set OldDefault to path to desktop -- is ALREADY an alias !! --as alias
set maybe to my DelOldBck(OldDefault)
-- return true is you clicked OK or pressed Return after selecting at leas a folder
-- return false if you clicked Cancel or pressed Escape
if maybe then my EmptyTrash()
-- Subroutines
on DelOldBck(OldDefault)
try
set OldFolders to choose folder with prompt "Choose Folders to delete:" default location OldDefault with multiple selections allowed
-- you will be here if you click OK after selecting one or several folder(s)
set OldFoldCount to count of items of OldFolders
-- No need for a test upon OldFoldCount which will be ≥1
repeat with _folder in OldFolders
tell application "Finder" to delete _folder
end repeat
return true
on error errMsg number errNbr
-- you will be here if you click Cancel after selecting nothing
try -- try/end try, in case you remove the setting of your own set of button
display dialog "No folders in selection!" & linefeed & errMsg & linefeed & "number #" & errNbr buttons {"OK"} default button 1
end try
return false
end try
end DelOldBck
on EmptyTrash()
tell application "Finder"
open the trash
set TrashCount to count of items of the trash
if TrashCount > 0 then
try
display dialog "Empty the trash?" with icon caution
-- you will be here if you click OK or pressed Return
empty the trash
on error
-- you will be here if you click Cancel or pressed Cancel
end try
else
display dialog "The trash is empty!" buttons {"OK"} default button 1 with icon caution
end if
delay 3
end tell
end EmptyTrash
Oops, I forgot your late question.
Applescript:
set altButton to "alternate"
set cancelButton to "Cancel"
set OKbutton to "OK"
try
set myChoice to button returned of (display dialog "Make your choice" buttons {altButton, cancelButton, OKbutton} default button OKbutton cancel button cancelButton)
on error
-- Here if you click Cancel which will issue error number -128
return
end try
if myChoice is OKbutton then
-- do some task, for instance :
error "I clicked the button " & OKbutton
else -- Here if you clicked alternateButton
-- do alternate task, for instance :
error "I clicked the button " & altButton
end if
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 5 avril 2020 14:49:02
Last edited by Yvan Koenig (2020-04-05 07:09:49 am)
Offline
Hello again, thank you very much for looking into the matter so thoroughly.
We are getting close… I have noticed and understood what you are doing with the dialog and three buttons involved. Still, this is not the right type of dialog, but the right way of displaying buttons. I was asking if the standard choose folder dialog could display more than the standard buttons in the way your dialog does. Anyway, this problem is solved for me, I just assume that this is not possible to merge.
Regarding the Choose folder dialog, this is the code that works for me:
Applescript:
set OldDefault to path to desktop
set maybe to my DelOldBck(OldDefault)
if maybe then my EmptyTrash()
-- Subroutines
on DelOldBck(OldDefault)
try
set OldFolders to choose folder with prompt "Choose Folders to delete:" default location OldDefault with multiple selections allowed
set OldFoldCount to count of items of OldFolders
repeat with _folder in OldFolders
tell application "Finder" to delete _folder
end repeat
return true
on error errMsg number errNbr
try
-- display dialog "No folders in selection!" & linefeed & errMsg & linefeed & "number #" & errNbr buttons {"OK"} default button 1 -- Too much information ;-)
display dialog "No folders in selection!" buttons {"OK"} default button 1
end try
return true — This change means dialog and further processing
end try
end DelOldBck
on EmptyTrash()
tell application "Finder"
open the trash
set TrashCount to count of items of the trash
if TrashCount > 0 then
try
display dialog "Empty the trash?" with icon caution
empty the trash
on error
end try
else
display dialog "The trash is empty!" buttons {"OK"} default button 1 with icon caution
end if
delay 3
end tell
end EmptyTrash
I have made only one relevant change to your coding, and that was setting the return to true when getting the error of clicking Cancel when not choosing anything in the first dialog. That means that a dialog is displayed and the program will resume, no matter what. In the next dialog you still have the chance to escape it all again or continue to empty the trash. I sometimes start this program and delete items, only to quit the program afterwards, do something else and start it all over again, and then there is nothing to delete anymore, that is what this part is for actually. Just a means of having the program continue, when nothing gets selected.
Funny enough, when you click Choose you still get the error that I was not able to catch. After displaying the error, AppleScript keeps running in the background and after a while continues by itself and enters the empty trash part. This would help and must be some kind of feature, not bad, but the delay until the program resumes automatically is just too long, so this is not an alternative.
Instead, your way of catching the error and continue earlier is the way to go for me. So this topic is solved and closed as far as I am concerned.
Thanks again for your reliable expertise everyone, much appreciated.
Offline