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