The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniGraffle General (http://forums.omnigroup.com/forumdisplay.php?f=10)
-   -   Script: Zoom all canvases to fit whole diagram (http://forums.omnigroup.com/showthread.php?t=22924)

RobTrew 2011-12-20 07:12 AM

Script: Zoom all canvases to fit whole diagram
 
A draft script:

[CODE]-- ZOOM ALL CANVASES IN CURRENT OMNIGRAFFLE DOCUMENT TO FIT WHOLE DIAGRAM

property pTitle : "Zoom All Canvases to Fit"
property pVer : "0.8"

property plstMenuItem : {"View", "Zoom", "Zoom to Selection"}

-- ADJUST THIS TO A VALUE SLIGHTLY BELOW 1.0 TO DECREASE THE DEFAULT LEVEL OF ZOOM
property pZoomScale : 0.9

on run
if not GUIEnabled() then return

-- GET A REFERENCE TO VIEW > ZOOM > ZOOM TO SELECTION
set mnuZoomFit to GetMenuItem("OGfl", plstMenuItem)

-- LOOP THRU EACH CANVAS,
-- SELECTING ALL GRAPHICS AND ZOOMING TO SELECTION,
-- AND ALLOWING FOR A FRACTIONAL ADJUSTMENT OF THE DEGREE OF ZOOM
-- (THEN RESTORE ORIGINAL SELECTION)
tell application id "OGfl"
activate
tell front window
try
set oFrontCanvas to its canvas
on error
return
end try

repeat with oCanv in canvases of its document
set canvas of it to oCanv

-- RECORD EXISTING SELECTION
set lstSeln to its selection

-- ZOOM TO FIT WHOLE DIAGRAM
set its selection to graphics of oCanv
tell application id "sevs" to click mnuZoomFit
if pZoomScale ≠ 1.0 then set its zoom to (its zoom) * pZoomScale

-- RESTORE ORIGINAL SELECTION
set its selection to lstSeln
end repeat
set its canvas to oFrontCanvas
end tell
end tell
end run


-- RETURNS A REFERENCE TO A CLICKABLE MENU ITEM
-- E.G. set mnuZoomFit to GetMenuItem("OGfl", {"View", "Zoom", "Zoom to Selection"})
on GetMenuItem(strAppCode, lstMenu)
set lngChain to length of lstMenu
if lngChain < 2 then return missing value

tell application id "sevs"
set lstApps to application processes where its creator type = strAppCode
if length of lstApps < 1 then return missing value
tell first item of lstApps
-- GET THE TOP LEVEL MENU
set strMenu to item 1 of lstMenu
set oMenu to menu strMenu of menu bar item strMenu of menu bar 1

-- TRAVEL DOWN THROUGH ANY SUB-MENUS
repeat with i from 2 to (lngChain - 1)
set strMenu to item i of lstMenu
set oMenu to menu strMenu of menu item strMenu of oMenu
end repeat

-- AND RETURN THE FINAL MENU ITEM
return menu item (item -1 of lstMenu) of oMenu
end tell
end tell
end GetMenuItem

on GUIEnabled()
tell application id "sevs"
if UI elements enabled then
return true
else
activate
display dialog "This script depends on enabling access for assistive devices in system preferences" buttons "OK" default button "OK" with title pTitle & " " & pVer
tell application id "sprf"
activate
set current pane to pane id "com.apple.preference.universalaccess"
end tell
return false
end if
end tell
end GUIEnabled
[/CODE]

Nigelw 2011-12-20 07:39 AM

GUI scripting eh? Thanks again for your work on this.

RobTrew 2011-12-20 08:27 AM

Well, 'whatever works' ... :-)

( High-minded principle is all very well, but it wasn't the Enlightenment that doubled the human population during the 18c – it was the potato, with a little help from the peanut ).

Happy feasting !

Nigelw 2011-12-21 09:00 AM

Made some tweaks to the above script as my needs are slightly simpler. As opposed to zooming each page to the maximum size to fit all objects, my edit simply goes through each page and hits the "Fit in Window" menu command. I realised afterwards this was my mistake for requesting the wrong menu command in the first place. Taking out the object selection saving/select all/zoom/reset selection code also had the side effect of speeding it up a bit.

Thanks again for your script. This is a huge timesaver for me.

[CODE]-- ZOOM ALL CANVASES IN CURRENT OMNIGRAFFLE DOCUMENT TO FIT IN WINDOW

property pTitle : "Zoom All Canvases to Fit"
property pVer : "0.7"

property pMenu : "View"
property pSubMenu : "Zoom"
property pCmd : "Fit in Window"

on run
if not GUIEnabled() then return

tell application id "OGfl"
activate
tell application id "sevs"
set lstApps to application processes where name contains "OmniGraffle"
if length of lstApps < 1 then return
tell first item of lstApps
tell menu bar 1
tell menu pMenu of menu bar item pMenu
tell menu pSubMenu of menu item pSubMenu
set mnuZoomFit to menu item pCmd
end tell
end tell
end tell
end tell
end tell
tell front window
try
set oFrontCanvas to its canvas
on error
return
end try

repeat with oCanv in canvases of its document
set canvas of it to oCanv
-- ZOOM TO FIT
tell application id "sevs" to click mnuZoomFit
end repeat
set its canvas to oFrontCanvas
end tell
end tell
end run

on GUIEnabled()
tell application id "sevs"
if UI elements enabled then
return true
else
activate
display dialog "This script depends on enabling access for assistive devices in system preferences" buttons "OK" default button "OK" with title pTitle & " " & pVer
tell application "System Preferences"
activate
set current pane to pane id "com.apple.preference.universalaccess"
end tell
return false
end if
end tell
end GUIEnabled[/CODE]

RobTrew 2011-12-21 09:42 AM

Good idea.

I've added that one to my keyboard macros too.

(I've also generalized the original to make it easier to get a reference to a GUI menu item nested, to arbitrary depth, inside sub-menus).

It uses a function like this:

[CODE]-- RETURNS A REFERENCE TO A CLICKABLE MENU ITEM
-- E.G. set mnuZoomFit to GetMenuItem("OGfl", {"View", "Zoom", "Zoom to Selection"})
on GetMenuItem(strAppCode, lstMenu)
set lngChain to length of lstMenu
if lngChain < 2 then return missing value

tell application id "sevs"
set lstApps to application processes where its creator type = strAppCode
if length of lstApps < 1 then return missing value
tell first item of lstApps
-- GET THE TOP LEVEL MENU
set strMenu to item 1 of lstMenu
set oMenu to menu strMenu of menu bar item strMenu of menu bar 1

-- TRAVEL DOWN THROUGH ANY SUB-MENUS
repeat with i from 2 to (lngChain - 1)
set strMenu to item i of lstMenu
set oMenu to menu strMenu of menu item strMenu of oMenu
end repeat

-- AND RETURN THE FINAL MENU ITEM
return menu item (item -1 of lstMenu) of oMenu
end tell
end tell
end GetMenuItem[/CODE]

Nigelw 2011-12-21 11:58 AM

Neat modification - have applied it to my script.

I've found this doesn't work in Lion's fullscreen mode – I'm assuming because it messes with the concept of a frontmost window and things like that. Are there workarounds to this, or is it a limitation of fullscreen mode?

Nigelw 2011-12-21 12:30 PM

In order not to have the script fail silently in fullscreen mode, I've borrowed and modified a function from Doug's iTunes applescripts. Below is the latest complete version of the script I'm using. It now shows an error if run in fullscreen mode.

Hope this is helpful to others.

[CODE]-- ZOOM ALL CANVASES IN CURRENT OMNIGRAFFLE DOCUMENT TO FIT IN WINDOW

property pTitle : "Zoom All Canvases to Fit"
property pVer : "0.8"


on run
-- Make sure "Enable access for assistive devices" is switched on in System Preferences
if not GUIEnabled() then return

-- Check whether app is running in full screen mode. If yes, display alert and upon dismissal of alert, quit script.
if isFullScreen("OGfl") then
delay 0.1
set opt to (display alert "OmniGraffle Professional is in full screen mode." message "This script cannot run while OmniGraffle Professional is in full screen mode.

You can quit and re-launch this script after exiting full screen mode." buttons "OK" default button "OK" as warning giving up after 30)
tell application id "OGfl" to activate
return false
end if

-- Set the menu command to run on each canvas in the document
set mnuZoomFit to GetMenuItem("OGfl", {"View", "Zoom", "Fit in Window"})

-- Perform menu command on each canvas in the document
tell application id "OGfl"
activate
tell front window
try
set oFrontCanvas to its canvas
on error
return
end try

repeat with oCanv in canvases of its document
set canvas of it to oCanv
-- ZOOM TO FIT
tell application id "sevs" to click mnuZoomFit
end repeat
set its canvas to oFrontCanvas
end tell
end tell
end run

-- Checks whether Accessibility Preferences have been set to "Enable access for assistive devices"
on GUIEnabled()
tell application id "sevs"
if UI elements enabled then
return true
else
activate
display dialog "This script depends on enabling access for assistive devices in system preferences" buttons "OK" default button "OK" with title pTitle & " " & pVer
tell application "System Preferences"
activate
set current pane to pane id "com.apple.preference.universalaccess"
end tell
return false
end if
end tell
end GUIEnabled

-- Checks whether an application is in full screen mode in Lion
on isFullScreen(strAppCode)
try
tell application id "sevs"
set lstApps to application processes where its creator type = strAppCode
if length of lstApps < 1 then return missing value
tell first item of lstApps
return (get value of attribute "AXFullScreen" of window 1)
end tell
end tell
on error
return false
end try
end isFullScreen

-- Returns a reference to a clickable menu item
-- E.G. set mnuZoomFit to GetMenuItem("OGfl", {"View", "Zoom", "Zoom to Selection"})
on GetMenuItem(strAppCode, lstMenu)
set lngChain to length of lstMenu
if lngChain < 2 then return missing value

tell application id "sevs"
set lstApps to application processes where its creator type = strAppCode
if length of lstApps < 1 then return missing value
tell first item of lstApps
-- Get the top level menu
set strMenu to item 1 of lstMenu
set oMenu to menu strMenu of menu bar item strMenu of menu bar 1

-- Travel down through any sub-menus
repeat with i from 2 to (lngChain - 1)
set strMenu to item i of lstMenu
set oMenu to menu strMenu of menu item strMenu of oMenu
end repeat

-- And return the final menu item
return menu item (item -1 of lstMenu) of oMenu
end tell
end tell
end GetMenuItem[/CODE]

RobTrew 2011-12-21 02:16 PM

[QUOTE=Nigelw;105313]this doesn't work in Lion's fullscreen mode I'm assuming because it messes with the concept of a frontmost window [/QUOTE]

I'm keeping away from Lion, so FullScreen is one of my scripting blind spots. My understanding is that, as you suggest, the Full Screen window is not necessarily the first member of the window collection.

Can't test this (attribute "AXFullScreen" is undefined and trips an error on 10.6) but I wonder if you can run code along these lines:
[CODE]tell application id "sevs"
set lstApps to application processes where its creator type = "OGfl"
if length of lstApps < 1 then return missing value
tell first item of lstApps
set oWin to missing value
try
set oWin to first window where value of attribute "AXFullScreen" is true
end try

if oWin is not missing value then
-- work with this full screen window ?
end if
end tell
end tell[/CODE]

Nigelw 2011-12-22 06:58 AM

Hm, well I may have an error in the modification I tried to make to your code, but this is what I got.

I first tried displaying a dialog, like so:

[CODE]on isFullScreen(strAppCode)
try
tell application id "sevs"
set lstApps to application processes where its creator type = "OGfl"
if length of lstApps < 1 then return missing value
tell first item of lstApps
set oWin to missing value
try
set oWin to first window where value of attribute "AXFullScreen" is true
end try

if oWin is not missing value then
display dialog "This is a test" buttons "OK" default button "OK" with title pTitle & " " & pVer
end if
end tell
end tell
on error
return false
end try
end isFullScreen[/CODE]

This was successful. I then replaced the dialog with the "Fit in Window" loop:

[CODE]on isFullScreen(strAppCode)
try
tell application id "sevs"
set lstApps to application processes where its creator type = "OGfl"
if length of lstApps < 1 then return missing value
tell first item of lstApps
set oWin to missing value
try
set oWin to first window where value of attribute "AXFullScreen" is true
end try

if oWin is not missing value then
repeat with oCanv in canvases of its document
set canvas of it to oCanv
-- ZOOM TO FIT
tell application id "sevs" to click mnuZoomFit
end repeat
end if
end tell
end tell
on error
return false
end try
end isFullScreen[/CODE]

This didn't seem to do anything. I'd play around more but work calls.

By the way, fullscreen OmniGraffle is something to look forward to if/when you upgrade to Lion. It's a far bigger improvement than I imagined it would be.

RobTrew 2011-12-22 07:33 AM

You would probably need to make sure that 'it' refers to the window. Sth like:

[CODE]if oWin is not missing value then
tell oWin
repeat with oCanv in canvases of its document
set canvas of it to oCanv
-- ZOOM TO FIT
tell application id "sevs" to click mnuZoomFit
end repeat
end tell
end if[/CODE]


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

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