Series of Sheets Clash -- how to close the first before showing the ne

[This post is recreated after this forum seems to have crashed and deleted the original thread!?]

I use Shane’s NSOpenSave+MyriadHelpers using makeOpenAt_… But the showOver_calling_ causes me trouble if I need to put up another sheet as a result of the previous one. Example:

[b]showOver_calling_(myWindow, "sheetDone:")[/b]

The ReadMe file says that it “shows an open or save panel as a sheet over the specified window, calling a handler when the sheet is closed”. But the sheet is not really closed until AFTER the handler sheetDone: has finished, which means I can’t put up a new warning sheet until it is finished!

Example of the sheetDone_:

on sheetDone_(theResult)
	if theResult is not missing value then
		set output to readfile_(theResult)
		return false --i.e user cancelled
	end if
	if output is "" then
		--<here I want to raise an alert if output is empty, but I can't do that since the previous sheet has not yet been closed!>
	end if
end sheetDone_

Ideally, I would like to close the sheet already before the file is being read (since it might take time), but I don’t see how I can do that. In any case, it is absolutely necessary to close the sheet before I show the alert.

Xcode has a rather difficult-to-digest section called “Presenting a Series of Sheets”, but I can’t make use of it.

Also, there is a notification that an NSWindow delegate can automatically receive, namely by using: windowDidEndSheet_, but it is not overly useful since it does not contain any info about which sheet did end (only which window and name of notif).

So, what do I do?

rdelmar responded to this, but when I clicked the link in the notification mail from the forum, the forum said “Bad request. The link you followed is incorrect or outdated”. But luckily, the mail contained some essential lines, so I recreate what Ric wrote:

You could use the following method, and then put your alert in the “showAlert” method:
if output is “” then
performSelector_withObject_afterDelay_(“showAlert”, missing value, 0.1)

Because the forum deleted the whole thread, I mailed Ric, who then added:
". but that is not the best way. You just need to add: myOpenPanel’s orderOut_(me) as the first line in your sheetDone_ method.

That’s a good method that works!
It does however have the drawback that I need to make the variable myOpenPanel global, since the sheetDone_ does not know the reference to the sheet (unless I can query it in some way).

Since I think the whole issue has a general interest to people, I decided to recreate the thread in this post. Maybe someone has additional comments.
The forum software seems to be unreliable. I hope it doesn’t delete more threads…


Hello heb,

In fact, they have destroyed my first user log and all my threads :slight_smile: and yesterday there were none of my posts validated because “You have an error in your SQL syntax” (but the topic appears in the list) :confused:

Nevertheless, thanks for your post, I had some problems with “sheetDone” too (possibly due to a bug on MY side) and it’s good to know there could be a problem with multiple (let’s say two) sheets.

myOpenPanel’s orderOut_(me) does not release the window/panel, it moves it offscreen - but in which “layering” of other invisible windows? That may not be a problem if a window is always shown on top of hierarchy, but…

And does a sheet called over an invisible window do? One day or another, I’ll be confronted to this. Stay tuned.


The orderOut_ does not release the sheet, and it does not even close it, but it doesn’t have to, since the sheetDone_ will attempt to close it when it finishes, and the sheet does not have to be visible to be closed. So the order of windows etc does not matter, as long as the old sheet becomes invisible so as to “make room” for the alert sheet to attach to the window, which it provably does perfectly well.

So, Ric’s proposal works very well. The only inelegance is that I need to declare the variable myOpenPanel to be global in both handlers – a bit ugly form of passing an “argument”, but it works. Maybe one could customize the showOver_calling_ handler so as to be able to pass also the sheet object myOpenPanel to the sheetDone_ as an extra argument(?) I looked into the objective-C code for that, but I felt it looked a bit too gnarly for my taste, probably not worth the effort, although it would be elegant.

Elegance is always worth the effort – especially for a repeatedly called method, and for software built to last many years (hopefully).

I’m not Objective-C programer, I can just decipher the methods and transpose them into ApplescriptObjC, wherever it’s possible. So good luck and let me know if you find a better way (passing a global variable as an argument is a contradictory and discouraged practice in any language that I know).


Can you tell me why you need to know the panel in the called handler? I’m just curious…

Now I get curious if you wonder why I need it – maybe there is better method. But after the various ways I tried to close the panel, the following, using (and experimenting with) Ric’s proposal, was the only one that I found effective (here showing simplified code with “anonymized” names):

--in the handler that creates a sheet for an open panel I have:
tell current application's NSOpenPanel to set myOpenPanel to makeOpenAt_xxx(xxx)
tell thePanel to showOver_calling_(theBigWindow, {"sheetDone:", me})
--end of this handler

on sheetDone_(theResult)
	global myOpenPanel --refers to the sheet attached to the big window
	if theResult is not missing value then
		set output to readfile_(theResult) --the desired useful work
		return false --i.e user cancelled
	end if
	if output is "" then
		myOpenPanel's orderOut_(me) --'me' is the sender, but it is myOpenPanel that is closed
		tell current application's NSAlert to set theAlert to makeAlert_buttons_text_(xxx)
		tell theAlert to showOver_calling_(theBigWindow, {"alertDone:", me})
	end if
end sheetDone_

You have theBigWindow, so you can just call attachedSheet() on it.

Ahh! I had looked all over in NSWindow searching for a method to give me the sheet or set its sheet to close and all kinds of what-not, but never found the needle in the large ant-hill. In hindsight, I feel as if having been a bit blind. But attachedSheet() does work great, thanks!