The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniGraffle General (http://forums.omnigroup.com/forumdisplay.php?f=10)
-   -   Calling the script of another object? (http://forums.omnigroup.com/showthread.php?t=30665)

realbrick 2013-08-10 11:24 PM

Calling the script of another object?
 
Hi -

Is it possible to call handlers in script of another object?

For example, I'm working on a group that contains objects whose scripts run when clicked, and I'd like the scripts of these clicked objects to call handlers held in the script of their parent group object, rather than copy/pasting these handlers into each clicked object.

I see in the dictionary there is a "script" property, but I've tried about every way i can think of to access handlers in another object's script, and I'm coming up empty.

Anyone have any experience with this?

RobTrew 2013-08-11 01:33 PM

You can get the script of a shape as a string, and evaluate that code string at run-time with [I]run script[/I]

[CODE]tell application id "OGfl"
tell front canvas of front document
set shpHasScript to first shape
run script (script of shpHasScript) as string
end tell
end tell[/CODE]

If the script returns an object, you should be able to use an idiom like:

[CODE]Set oScript to (run script strScript)[/CODE]

and then use the methods and properties of that script object.

RobTrew 2013-08-11 01:40 PM

An example of creating a script object with [I]run script[/I] and then using a method of that object:

[CODE]-- Toggle between a flat and a folder-indented sidebar
-- (An experiment in conditional compilation, as latest Sneaky Peaks
-- offer quicker (and more rationally ordered)
-- flattening of the project list)

property pstrNewScript : "
script
on GetProjects(oDoc)
using terms from application \"OmniFocus\"
return flattened projects of oDoc
end using terms from
end GetProjects
end script
"

property pstrOldScript : "
script
on GetProjects(oParent)
using terms from application \"OmniFocus\"
tell oParent
-- ADJUST THE WHERE QUERIES TO MATCH THE PURPOSE
set lstProjects to projects
set lstFolders to folders
end tell
repeat with oFolder in lstFolders
set lstProjects to lstProjects & my GetProjects(oFolder)
end repeat
return lstProjects
end using terms from
end GetProjects
end script
"

tell application id "com.omnigroup.OmniFocus"
set oDoc to default document
set oWin to front document window of oDoc

if my IsNarrowed(focus of oWin) then
set focus of oWin to {}
else
if build number ≥ "77.57.0.134152" then
set oScript to run script pstrNewScript
else
set oScript to run script pstrOldScript
end if
set lstProjects to GetProjects(oDoc) of oScript
set focus of oWin to lstProjects
end if
end tell

-- Detect whether the sidebar has a narrowed focus
on IsNarrowed(oFocus)
repeat with oObj in oFocus
return true
end repeat
return false
end IsNarrowed[/CODE]

realbrick 2013-08-11 04:55 PM

Thank's Rob -

Thanks!

This works for running the script of the other object. But what I'm hoping to do is call methods within the script of that other object.

OmniGraffle returns scripts as strings, and it sounds like you're saying that I need a script object to call methods it contains.

Am I stuck, or is the a way to create a script object out of a script in a string?

RobTrew 2013-08-11 10:30 PM

Something like:

[CODE]set strScript to "script" & linefeed & (script of oShape) as string & linefeed & "end script"

set objScript to run script strScript[/CODE]

You can than call methods from the script object which you have created from the shape's script using the [I]of[/I] idiom.

[CODE]FnSomeHandler() of objScript[/CODE]

RobTrew 2013-08-11 10:40 PM

PS OGfl shape action code assumes the application context as given, so within your [I]script .... end script[/I] bracketing of the source code (for the purposes of [I]run script[/I]) you may also need to explicitly add [I]tell application ... end tell[/I] bracketing.

(See the OmniFocus example above for the details of escaping the double quotes in the application name within a script string which is to be evaluated at run-time).

realbrick 2013-08-12 04:01 PM

Thanks, Rob - that worked like a champ!

Here's the method I rolled your suggestions up into. Note that this is within a shape, so [I]tell application id "OGfl"[/I] is implicit.

on getScriptFromObject(_object)
set _textScript to (script of _object) as text
set _scriptObject to "script" & linefeed & _textScript & linefeed & "end script"
return run script _scriptObject
end getScriptFromObject

Example of calling the method foo() in the script of an object referenced by the variable "o"

set oScript to getScriptFromObject(o)
get foo() of oScript


All times are GMT -8. The time now is 05:08 PM.

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