AppleScript_ The Definitive Guide - Matt Neuburg [233]
A question arises of how to interrupt a time-consuming applet. (This problem, and its solution, were suggested to me by Paul Berkowitz.) Suppose the run handler takes a long time and the user wishes to stop it and quit. The user can press Command-. (period), which raises an error (-128, "User canceled") that stops the run handler dead in its tracks, but the user might not know this. The Quit menu item doesn't work; if the user chooses it, the applet doesn't quit—if it has a quit handler, the quit handler is called, but when the quit handler says continue quit, the applet goes right back to executing the run handler where it left off! (I regard this as a bug.) There is also the question of how you can make sure that any required clean-up actions are performed as the applet quits. The best strategy is probably something like this:
global shouldQuit
global didCleanup
on run
set shouldQuit to false
set didCleanup to false
try
-- lengthy operation goes here
repeat with x from 1 to 10
if shouldQuit then error
say (x as string)
delay 5
end repeat
on error
tell me to quit
end try
end run
on quit
if not didCleanup then
-- cleanup operation goes here
say "cleaning up"
set didCleanup to true
end if
set shouldQuit to true
continue quit
end quit
When the user chooses Quit from the menu bar, our quit handler is called, but when we say continue quit we will merely resume the run handler, so we also set a global indicating that the user is trying to quit. The resumed run handler notices this and deliberately errors out, and we catch the error and call our own quit handler, and quit in good order. We would perform our cleanup operations twice in this case, but that is prevented by another global. It's all very ingenious, but it's messy, and ultimately not very satisfactory. If the user chooses Quit from the applet's Dock menu, our applet's quit menu handler isn't called (another bug), and if the user force-quits our applet then of course no cleanup is performed.
Droplets
A droplet is an applet onto whose icon the user can drop Finder items (files and folders). Internally, it is simply an applet with an open event handler:
open
An open event handler, if present, will be called when items are dropped in the Finder onto the droplet's icon. It should take one parameter, through which your code will receive a list of aliases to the items dropped.
If a droplet is started up by double-clicking it from the Finder, then its run handler is executed and its open handler is not. But if it is started up by dropping items on it in the Finder, then it's the other way around: its open handler is executed and its run handler is not. Once a droplet is running (assuming it is a stay-open droplet), the open handler can be executed by dropping items onto the droplet's icon in the Finder. The open handler is also scriptable, using the open command, whose parameter should be a list of aliases.
In this simple example , the droplet reports how many folders were dropped on its icon:
on open what
set total to 0
repeat with f in what
if folder of (info for f size no) then set total to total + 1
end repeat
display dialog (total as string) & " folder(s)"
end open
Persistence
Persistence of top-level entities (see Chapter 8) works in an applet. The script is resaved when the applet quits, maintaining the state of its top-level environment.
So, for example, the following modification to the previous example would cause an applet to report the count of folders that had ever been dropped