Scope of variables within on dialog ended handler


property itsDefaultButton : ""
property theResult : ""

on displayDialog(theMsg, theButtonsArray, theDefaultButton, theGivingUp, theIcon, theWindow)
	
	set itsDefaultButton to theDefaultButton
	
	script
		property itsMsg : theMsg
		property itsButtonsArray : theButtonsArray
		property itsGiveUp : theGivingUp
		property itsIcon : theIcon
		property itsWindow : theWindow

	on showItself()
			display dialog itsMsg buttons itsButtonsArray default button itsDefaultButton ¬
				giving up after itsGiveUp with icon itsIcon attached to window itsWindow
		end showItself
	end script
	
end displayDialog


on dialog ended theObject with reply dd
	
	if (gave up of dd) then
		set theResult to itsDefaultButton
	else
		set theResult to (button returned of dd)
	end if
	
end dialog ended

An example:


on allSaved(thisWindowObject)
	
	if (not gSaved) then
		set continueDlg to ¬
			my displayDialog("You have not finished calculating your Spreadsheet." & return & ¬
				"Do you wish to continue calculating?" & return & return, ¬
				{"Yes", "No"}, "Yes", 15, "stop", mainWindow)
		tell continueDlg to showItself()
		
		set gSaved to theResult is "No"
	end if
	display dialog theResult
	
	return gSaved
	
end allSaved

Where or where has my brain gone, because:

Let’s pretend that I clicked the “Yes” button.
The first display dialog shows empty for the initial property value = “”.
the 2nd display dialog shows “Yes”

… so, theResult is always one behind.

As I said, where or where has my brain gone.

So, you want this line…

display dialog theResult

… to display the value from the dialog ended handler that is caused by this line?

tell continueDlg to showItself()

Edit:

So theResult is defined but is not the expected value? That doesn’t sound like a scope problem.

You are correct, Bruce.

I cannot technically describe the problem better than what I’ve stated “theResult is always one behind” … and I have seen a similar description of other contributors to this BBS.

If I test for theResult within the on dialog ended handler, I get the correct answer. However, if I look at theResult in a statement following display dialog, I get the previous value. It appears that Studio continues with the code following display dialog without waiting for on dialog ended handler to finish.

After thinking about this, I have devised the following which definitely corrects this “feature” of AppleScript Studio:


property itsDefaultButton : "" -- Globals
property theResult : ""
property dlgEnded : false

on displayDialog(theMsg, theButtonsArray, theDefaultButton, theGivingUp, theIcon, theWindow)
	
	set itsDefaultButton to theDefaultButton
	set dlgEnded to false
	
	display dialog theMsg buttons theButtonsArray default button theDefaultButton ¬
		giving up after theGivingUp with icon theIcon attached to window theWindow
	
	repeat until dlgEnded
	end repeat
	
end displayDialog


on dialog ended theObject with reply dd
	
	if (gave up of dd) then
		set theResult to itsDefaultButton
	else
		set theResult to (button returned of dd)
	end if
	
	set dlgEnded to true
	
end dialog ended

set aDialog to displayDialog(...)

if (theResult is whatever) then ...
-- do something
else
-- do something else
end if

Bruce, any further insight you may have would be greatly appreciated.

The same repeat until approach must be used with display open panel:

a) I check dialog ended on the Window’s Inspector

b) I then have:


property panelEnded : true -- a Global

on waitUntilPanelGone()
	repeat until panelEnded
	end repeat
end waitUntilPanelGone

on showSomePanel(itsWindow)
	set panelEnded to false
	display window somePanel attached to window itsWindow
	waitUntilPanelGone()
end showSomePanel

on panel ended thePanel with result theResult
	set panelEnded to true

	if theResult is 1 then
		-- something else
	else if theResult is 2 then
		-- something
	-- etc
	end if
end panel ended

on clicked theObject
	set thisControl to title of theObject as string

	if thisControl is "control1" then
		close panel (window of theObject) with result 1
	else if thisControl is "control2" then
		close panel (window of theObject) with result 2
	else
		-- other controls in main window or in other windows
	end if
end clicked

Anyway, as always, thanks for the input during this conversation.