The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniGraffle Extras (http://forums.omnigroup.com/forumdisplay.php?f=7)
-   -   Select Descendants - using Applescript (http://forums.omnigroup.com/showthread.php?t=20309)

RobTrew 2011-03-02 01:54 AM

Select or modify Descendants - using Applescript
 
[B]Edit > Select > Descendants[/B] is one of the things I reach for most in the OmniGraffle menu.

(For example en route to reformatting a sub-tree with a [URL="http://forums.omnigroup.com/showpost.php?p=94229&postcount=2"]color-toggling script[/URL])

Here is a way of doing it in Applescript, perhaps as a preamble to some formatting code.

[CODE]-- EXTEND SELECTION TO ALL DESCENDANTS OF CURRENT SELECTION(s)

on run
tell application id "com.omnigroup.OmniGrafflePro"
try
tell front window
set lstSeln to its selection
set oCanvas to its canvas
end tell
on error
return
end try
set lngSelns to count of lstSeln
if lngSelns < 1 then return

-- GET THE WHOLE SET OF SUB-TREES (EACH SELECTION AND ALL THEIR DESCENDENTS)
set lstChiln to {}
set lstAncestors to {}
repeat with i from 1 to lngSelns
set oSeln to item i of lstSeln
if (class of oSeln = shape) then
set refLines to (a reference to outgoing lines of oSeln)
set lngLines to count of refLines
set end of lstAncestors to id of oSeln
if lngLines > 0 then set lstChiln to lstChiln & my GetDescendants(oCanvas, refLines, lngLines, lstAncestors)
end if
end repeat

-- AND EXTEND THE SELECTION TO ALL SHAPES IN THE SUBTREE.
set selection of front window to lstSeln & lstChiln
end tell
end run

-- GET THE SHAPES (AND THE DESCENDANTS OF THE SHAPES) AT THE END OF THESE LINES
on GetDescendants(oCanvas, refLines, lngLines, lstAncestors)
set lstChiln to {}
tell application id "com.omnigroup.OmniGrafflePro"
repeat with i from 1 to lngLines
set lstShapes to (shapes of oCanvas where incoming lines contains (item i of refLines))
set lngShapes to count of lstShapes
if lngShapes > 0 then
repeat with j from 1 to lngShapes
set oChild to item j of lstShapes
set strID to id of oChild
if lstAncestors does not contain strID then
set end of lstChiln to oChild
set lstChildLines to (outgoing lines of oChild)
set lngChildLines to count of lstChildLines
if lngChildLines > 0 then set lstChiln to lstChiln & my GetDescendants(oCanvas, lstChildLines, lngChildLines, lstAncestors & strID)
end if
end repeat
end if
end repeat
end tell
return lstChiln
end GetDescendants[/CODE]

RobTrew 2011-03-02 02:01 AM

For example, a script which toggles the color not only of selected shapes, but also of all their descendants.

[CODE]-- TOGGLE COLOR OF SELECTED SHAPES + AND ALL THEIR DESCENDANTS

property plstBlack : {0, 0, 0}
property plstGray : {32767, 32767, 32767}
property plstRed : {65534, 0, 0}

on run
tell application id "com.omnigroup.OmniGrafflePro"
try
tell front window
set lstSeln to its selection
set oCanvas to its canvas
end tell
on error
return
end try
set lngSelns to count of lstSeln
if lngSelns < 1 then return

-- GET THE WHOLE SET OF SUB-TREES (EACH SELECTION AND ALL THEIR DESCENDANTS)
set lstChiln to {}
set lstAncestors to {}
repeat with i from 1 to lngSelns
set oSeln to item i of lstSeln
if (class of oSeln = shape) then
set refLines to (a reference to outgoing lines of oSeln)
set lngLines to count of refLines
set end of lstAncestors to id of oSeln
if lngLines > 0 then set lstChiln to lstChiln & my GetDescendants(oCanvas, refLines, lngLines, lstAncestors)
end if
end repeat
set lstSubTree to lstSeln & lstChiln
set lngTree to length of lstSubTree


-- FIND THE FIRST SHAPE IN THE SUB-TREE WHICH HAS TEXT (IGNORE LINES)
set blnFound to false
repeat with i from 1 to lngTree
set oSeln to item i of lstSubTree
if (class of oSeln = shape) and (text of oSeln ≠ "") then
set blnFound to true
exit repeat
end if
end repeat

if blnFound then
-- GET THE NEXT COLOR IN THE SEQUENCE,
tell (text of oSeln)
set lstColor to its color
if lstColor = plstGray then
set lstNewColor to plstRed
else if lstColor = plstBlack then
set lstNewColor to plstGray
else
set lstNewColor to plstBlack
end if
end tell

-- AND APPLY THE NEW COLOR TO ALL SHAPES IN THE SUBTREE.
repeat with i from 1 to lngTree
tell (item i of lstSubTree)
if (its class = shape) and (its text ≠ "") then set color of its text to lstNewColor
end tell
end repeat
end if
end tell
end run

-- GET THE SHAPES (AND THE DESCENDANTS OF THE SHAPES) AT THE END OF THESE LINES
on GetDescendants(oCanvas, refLines, lngLines, lstAncestors)
set lstChiln to {}
tell application id "com.omnigroup.OmniGrafflePro"
repeat with i from 1 to lngLines
set lstShapes to (shapes of oCanvas where incoming lines contains (item i of refLines))
set lngShapes to count of lstShapes
if lngShapes > 0 then
repeat with j from 1 to lngShapes
set oChild to item j of lstShapes
set strID to id of oChild
if lstAncestors does not contain strID then
set end of lstChiln to oChild
set lstChildLines to (outgoing lines of oChild)
set lngChildLines to count of lstChildLines
if lngChildLines > 0 then set lstChiln to lstChiln & my GetDescendants(oCanvas, lstChildLines, lngChildLines, lstAncestors & strID)
end if
end repeat
end if
end repeat
end tell
return lstChiln
end GetDescendants

[/CODE]

RobTrew 2011-03-02 03:45 AM

I have edited both of these scripts to enable them to cope with diagrams containing cycles (in which a shape may be its own ancestor).


All times are GMT -8. The time now is 06:49 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.