AppleScript Help: Select all children

Greg Titus greg at omnigroup.com
Mon Apr 28 16:54:01 PDT 2003


Hi Gavin,

I apologize. You've run into a bug in OmniGraffle's AppleScript 
support. I'm fixing it now and it will be in our next release.

On Saturday, April 26, 2003, at 08:29  PM, Gavin Kistner wrote:
> SO...
> 1) Using JS or AS -- how do I select an object?

Adding it to the selection list is the right thing to do, and will work 
once I fix this bug.

> 2) (If you only know AS): why are the sample AS scripts above giving 
> an error?

> tell application "OmniGraffle Professional"
> 	the count of graphics of the first layer of the first document
> 	--"OmniGraffle Professional got an error: NSCannotCreateScriptCommand"
> end tell

This is failing because a document doesn't have layers, a page has 
layers. This should work:

	the count of graphics of the first layer of the first page of the 
first document

> tell the front window of application "OmniGraffle Professional"
> 	count of selection -- this works
> 	the first item of selection -- this fails...doesn't like 'item' here
> end tell

This is failing because AppleScript has a somewhat odd distinction 
between events that are handled by the application you are talking to, 
and events handled by the script itself. Sometimes AppleScript succeeds 
in hiding this distinction from the scripter, but in this case it is 
biting you. OmniGraffle doesn't know anything about "items", "items" 
are generic entries in a list (handled by the script, not the 
application).

So if you wanted OmniGraffle to do this you'd use:
	the first selection

This tells OG to return the first entry in its selection list to the 
script. (And yes, that syntax is strange. See the answer to your 
question 5.)

Or if you wanted the script to do it, you would use:
	the first item of (selection as list)
		or
	set aList to selection
	the first item of aList

Either of these tells OG to return the whole list of selected graphics 
to the script, and then the script picks out the first entry.

Questions 3 and 4 you figured out for yourself, which brings us to:

> 5) [For OmniGroup] Having a unique class called 'selection', with a 
> plural of 'selection', which has the exact same properties as the 
> 'graphic' class feels really bizarre. Couldn't there be some better 
> way in AS of expressing a collection of selected items?

Yes, this is/was an odd way to express it. Along with fixing the set 
selection behavior, I've changed OmniGraffle's scripting dictionary so 
that "selection" is a property of a window that returns a list. That 
will work more how you expected in the first place.

So the script you want will look like the below. It could have been 
somewhat shorter but I split out functions for getting all the children 
of a graphic (one level below) and all the descendants of a graphic 
(all levels below), which you might find useful in other scripts. Note 
that in the version of OmniGraffle you have now, this will still fail 
on the last "set selection" line - I'll get that bug fixed. Also note 
that this script doesn't attempt to do any checking that you really do 
have a tree structure. If you ran it on a graph that had loops in it it 
would run forever, until you cancelled it. Making a script that handled 
loops would certainly be possible, just a bit more complicated than 
this one.

on getChildren for aGraphic
	set childList to {}
	tell application "OmniGraffle Professional"
		repeat with aLine in outgoing lines of aGraphic
			set childList to childList & {destination of aLine}
		end repeat
	end tell
	return childList
end getChildren

on getDescendants for aGraphic
	set childList to getChildren of me for aGraphic
	set descendantList to childList
	repeat with aChild in childList
		set itsDescendants to getDescendants of me for aChild
		set descendantList to descendantList & itsDescendants
	end repeat
	return descendantList
end getDescendents

tell application "OmniGraffle Professional"
	set selectedGraphics to selection of the front window
	set newSelection to selectedGraphics
	repeat with aGraphic in selectedGraphics
		set itsDescendents to getDescendants of me for aGraphic
		set newSelection to newSelection & itsDescendents
	end repeat
	set selection of the front window to newSelection
end tell

Hope this helps,
	- Greg




More information about the OmniGraffle-Users mailing list