The Omni Group Forums

The Omni Group Forums (
-   OmniGraffle Extras (
-   -   Help with scripting (

Sophie 2011-11-14 03:21 PM

Help with scripting
I am using MacRuby to script Omnigraffle Pro (infinitely easier and nicer than Applescript). I can easily get a handle on the app, document, canvas, etc. Now want to add / manipulate shapes on the canvas.

framework 'ScriptingBridge'

$omni = SBApplication.applicationWithBundleIdentifier("com.omnigroup.OmniGrafflePro")

$document = $[0].document

$canvas = $[0].canvas


=> [:adjustsPages, :"assembleSubgraph:tableShape:", .... :verticalPages]

The AppleScript dictionary report:
make v : Make a new object.
new type : The class of the new object.
[at location specifier] : The location at which to insert the object.
[with data any] : The initial data for the object.
[with properties record] : The initial values for properties of the object.
→ specifier

And Omnigraffle "Copy as Applescript" suggests this:
tell application "OmniGraffle Professional"
tell canvas of front window
make new shape at end of graphics
with properties {size: {10,80}, origin: {9,9}}
end tell
end tell

I cannot find the "make new <type> ..." method on Canvas.

- Where is this method?
- What other resources (e.g. Objective-C header files? Anything else?) can I use to find out about valid parameter values (e.g. is it a numeric code for "Shape"? "Rectangle"? How do I say "at <end of graphics>"?


RobTrew 2011-11-14 08:18 PM

Mmm ... sounds a bit annoying ...

The struggle to discover these things has always been the main human-time expense of Mac application scripting this is why I tend to fall back to doing these things in Applescript, and calling particular functions in python, perl, bash, ksh or whatever, when I need them, through [I]do shell script[/I].

I notice that the Applescript code below successfully makes four shapes, so it seems to be possible to call [I]make[/I] as a method of any of the objects in the chain, from application down to layer ...

Good luck !

[CODE]tell application id "OGfl"
set oApp to it
set oDoc to front document
set oCanvas to front canvas of oDoc
set oLayer to front layer of oCanvas

set lngPosn to 50
repeat with oObj in {oApp, oDoc, oCanvas, oLayer}
tell oObj to make new shape at end of graphics of oCanvas with properties {size:{10, 80}, origin:{lngPosn, lngPosn}}
set lngPosn to lngPosn + 10
end repeat
end tell[/CODE]

RobTrew 2011-11-14 08:43 PM

PS I would tend to try first with the application, on the model of:
[CODE]te ="")
te.make(:new => :document)[/CODE]

or perhaps more relevantly:
[CODE]te ="")
te.make(:new => :document, :with_properties => {:text => "Hello, World!"})
te.make(:new => :word, :with_data => "Wonderful ", :at => te.documents[1].words[1].after)[/CODE]



tcoimbra 2013-08-28 04:07 PM

Grouping shapes
I'm trying to get data from a database and build objects in Omnigraffle 5.4.4 pro based on that. For this, I use scriptingBridge and macRuby. I'm able to build some shapes in Omnigraffle but I need to group them altogether and I'm stuck at this point since 2 weeks.

Did somebody already figured out how to group shapes ? I used sdef to get the scripting definitions and I saw the methode "- (OmniGraffleProfessional5Group *) assembleSubgraph:(BOOL)subgraphtableShape:(NSArray *)tableShape; // Group graphics". Seems like I need to use this one but I really have an issue with this method. Looks like it returns nothing. Maybe I use it wrongly. I also tried to create a group and initialise it with an array of shapes but I cannot make it work too.

Anybody has an idea ?

Here is my code:
#!/usr/bin/env macruby
#framework 'Cocoa'
framework 'Foundation'
framework 'ScriptingBridge'
load_bridge_support_file 'OmniGraffleProfessional5.bridgesupport'

graffle = SBApplication.applicationWithBundleIdentifier("com.omnigroup.OmniGrafflePro")

# Omnigraffle scriptingBridge header
# sdef /Applications/OmniGraffle\ Professional\ | sdp -fh -o ./ -A --basename OmniGraffleProfessional
# .bridgesupport file
# gen_bridge_metadata -c '-I.' OmniGraffleProfessional.h -o ./OmniGraffleProfessional.bridgesupport
# And include that bridgsupport file in your script with

pixelRatio = 28.3465
# origin in cm
originX = 1 * pixelRatio
originY = 1 * pixelRatio

win =
canvas = win.canvas
# data to fill into object
template="template name"
# CMS version
cms_version = "1.0"
# or use query: select name from info_version where version_type='config' and is_current_version=1; (but need to check with R&D)
notes = ""
# object config
data = []

# headers
objectHeader = OmniGraffleProfessional5Shape.alloc.initWithProperties({:text=>{:alignment=>"1330929969", :color=>[1,1,1], :font=>"Helvetica-Bold", :size=>11, :text=>header}, :textPlacement=>"Center", :name=>"Rectangle", :origin=>[originX, originY], :size=>[9*pixelRatio, 0.5*pixelRatio], :drawsShadow=>0, :drawsStroke=>1, :fillColor=>[0.0972915, 0.188266, 0.434028], :strokeColor=>[0.0972915, 0.188266, 0.434028], :sidePadding=>2})
objectNameHeader = OmniGraffleProfessional5Shape.alloc.initWithProperties({:text=>{:alignment=>"left", :color=>[0,0,0], :font=>"Helvetica", :size=>9, :text=>"Name"}, :textPlacement=>"Center", :name=>"Rectangle", :origin=>[originX, originY+0.5*pixelRatio], :size=>[2*pixelRatio, 0.5*pixelRatio], :drawsShadow=>0, :drawsStroke=>1, :fillColor=>[0.329412,0.490181,0.737255], :strokeColor=>[0.0972915, 0.188266, 0.434028], :sidePadding=>2})
objectTemplateHeader = OmniGraffleProfessional5Shape.alloc.initWithProperties({:text=>{:alignment=>"left", :color=>[0,0,0], :font=>"Helvetica", :size=>9, :text=>"Template"}, :textPlacement=>"Center", :name=>"Rectangle", :origin=>[originX, originY+1*pixelRatio], :size=>[2*pixelRatio, 1*pixelRatio], :drawsShadow=>0, :drawsStroke=>1, :fillColor=>[0.329412,0.490181,0.737255], :strokeColor=>[0.0972915, 0.188266, 0.434028], :sidePadding=>2})
objectVersionHeader = OmniGraffleProfessional5Shape.alloc.initWithProperties({:text=>{:alignment=>"left", :color=>[0,0,0], :font=>"Helvetica", :size=>9, :text=>"CMS version"}, :textPlacement=>"Center", :name=>"Rectangle", :origin=>[originX, originY+2*pixelRatio], :size=>[2*pixelRatio, 0.5*pixelRatio], :drawsShadow=>0, :drawsStroke=>1, :fillColor=>[0.329412,0.490181,0.737255], :strokeColor=>[0.0972915, 0.188266, 0.434028], :sidePadding=>2})
# data
objectName = OmniGraffleProfessional5Shape.alloc.initWithProperties({:text=>{:alignment=>"left", :color=>[0,0,0], :font=>"Helvetica", :size=>9, :text=>"<to configure>"}, :textPlacement=>"Center", :name=>"Rectangle", :origin=>[originX+2*pixelRatio, originY+0.5*pixelRatio], :size=>[7*pixelRatio, 0.5*pixelRatio], :drawsShadow=>0, :drawsStroke=>1, :fillColor=>[1,1,1], :strokeColor=>[0.0972915, 0.188266, 0.434028], :sidePadding=>2})
objectTemplate = OmniGraffleProfessional5Shape.alloc.initWithProperties({:text=>{:alignment=>"left", :color=>[0,0,0], :font=>"Helvetica", :size=>9, :text=>template}, :textPlacement=>"Center", :name=>"Rectangle", :origin=>[originX+2*pixelRatio, originY+1*pixelRatio], :size=>[7*pixelRatio, 1*pixelRatio], :drawsShadow=>0, :drawsStroke=>1, :fillColor=>[1,1,1], :strokeColor=>[0.0972915, 0.188266, 0.434028], :sidePadding=>2})
objectVersion = OmniGraffleProfessional5Shape.alloc.initWithProperties({:text=>{:alignment=>"left", :color=>[0,0,0], :font=>"Helvetica", :size=>9, :text=>cms_version}, :textPlacement=>"Center", :name=>"Rectangle", :origin=>[originX+2*pixelRatio, originY+2*pixelRatio], :size=>[7*pixelRatio, 0.5*pixelRatio], :drawsShadow=>0, :drawsStroke=>1, :fillColor=>[1,1,1], :strokeColor=>[0.0972915, 0.188266, 0.434028], :sidePadding=>2})
# make group

# adding shapes to canvas because otherwise I get an error: "object has not been added to a container yet; selector not recognised"

# making an array of all shapes
shapesToGroup = NSArray.arrayWithObjects(objectHeader, objectNameHeader, objectTemplateHeader, objectVersionHeader, objectName, objectTemplate, objectVersion, nil)

puts shapesToGroup.className
# => __NSArrayI

# grouping shapes. The output should be a group
objectGroup = canvas.assembleSubgraph(false,:tableShape=>shapesToGroup)

puts objectGroup.className
# => NSNull
#=> NSInvalidArgumentException: *** -[SBElementArray addObject:]: can't add an object that already exists. (RuntimeError)



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

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