[AppleScript] - Sketchup PrintRight
-
quick check gave
"System Events got an error: Can’t get text field 1 of window 9 of process "SketchUp". Invalid index."
I need to sleep, so i'll have a look later.
it's easier to get applescript/system to do stuff from SU than the other way round, and even then there's things that don't fly.
it's also easier to get SU to do SU things and to only add missing or fix broken stuff. [eg. change fov is a one liner, print to scale is broken]
SU is the environment your scripts needs to work in so for example if you call system to kill sketchup from inside SU you get an endless loop.
Have a look inside those sumac.app scripts I posted ages ago, that's why I made them Menu Bar apps.
john
-
@driven said:
quick check gave
"System Events got an error: Can’t get text field 1 of window 9 of process "SketchUp". Invalid index."
I need to sleep, so i'll have a look later.
that's probably because you had more than one sketchup window open when you tried it..
the order the sketchup windows appear (entity info etc dialogs first, then the toolbars, finally the drawing window) really make gui scripting sketchup difficult (+, say you have 10 total windows then open a new drawing window.. the new one becomes #10 then the other window becomes #11 and moves to the back ).. i think i have a way to separate the drawing windows from the rest of the stuff then using the frontmost of those so it will work with multiple windows open.. haven't tried to implement it yet.. it's on the cleanup list if i can ever get this to work out..(fwiw- the desired target you're seeing the error for is the measurement box when in a state that user input is possible)
@unknownuser said:
it's easier to get applescript/system to do stuff from SU than the other way round, and even then there's things that don't fly.
it's also easier to get SU to do SU things and to only add missing or fix broken stuff. [eg. change fov is a one liner, print to scale is broken]
SU is the environment your scripts needs to work in so for example if you call system to kill sketchup from inside SU you get an endless loop.
Have a look inside those sumac.app scripts I posted ages ago, that's why I made them Menu Bar apps.
john
i've tried to find the sumac stuff before and i just can't got a link?
also just thought of an easy, though not too elegant way to use su ruby commands via an applescript... the ruby console
it might actually work out ok.. gonna mess around with it in a little while. -
@unknownuser said:
also just thought of an easy, though not too elegant way to use su ruby commands via an applescript... the ruby console
it might actually work out ok.. gonna mess around with it in a little while.ha.. it works pretty good..
and i can move forward now using that code you posted earlier (the
view = view.zoom factor
stuff)..and the zoom factor is way nicer than what i was trying which was with a set FOV then changing the FOV to fit the window.. zoom factor works regardless of the user's fov setting (but there's no way i could figure out how to change the zoom factor within sketchup itself other than with a mouse so that option was out.. using it now via ruby )
[EDIT] oh.. and more importantly.. you can use the zoom factor in parallel projection while you can't change the FOV (which is what i previously needed to do) in parallel projection.. the fov option is greyed out in normal SU if parallel projecting and i actually crashed SU once or twice trying to change it via ruby while viewing parallel projection
-
here's the same thing i was trying above except it now uses ruby for the zoom factor instead of messing around with the camera's FOV.. so i'm now able to work with 3D objects instead of just flat ones..
i think it's just some weird math and a few dialogs to do then this whole idea might actually work` tell application "SketchUp"
activate
tell application "System Events" to tell process "SketchUp"set drawwin to count of windows set AppleScript's text item delimiters to {" "} --set the camera to Parallel Projection by checking if Field Of View is enabled --(FOV will NOT be greyed out if Perspective or 2pt Perspective) if enabled of menu item "Field of View" of menu 1 of menu bar item "Camera" of menu bar 1 is true then click menu item "Parallel Projection" of menu 1 of menu bar item "Camera" of menu bar 1 end if -- Zoom extents then use ruby console to scale zoom by a factor of 1.05405 click menu item "Zoom Extents" of menu "Camera" of menu bar 1 click menu item "Ruby Console" of menu "Window" of menu bar 1 keystroke "view = Sketchup.active_model.active_view view = view.zoom 1.05405" & return -- close ruby console click button 1 of window "Ruby Console" end tell
end tell`
[edit].. hmm.. that's not compiling properly once i copy/paste it from the forum back into applescript editor.. the ruby part should look like this in applescript editor :
maybe if i break it down into separate keystroke entries i'll be able to post it properly here?
here's the .scpt instead:
SU_ZOOMRUBY.zip -
jeff heres a sumac download link, dmg installerhttp://homepage.mac.com/johnboundy/filechute/sumac_dev_2011-03-01-002859.dmg.zip
I need to go back out for an hour or so, I'll have another look at your stuff.
What I see as being really good with what your trying is the idea...
and you've cracked what can't be done from SU ruby.. i.e manipulate the window size and position the window.
ruby can handle all the other bits really easily, without opening dialogs or console at all, it can even send the applescript to system and avoid an external file altogether.
What I find interesting is the possibility of doing other things to other SU windows, so if you click a button, Applescript could get the position and pass that info to a ruby WebDialog that then appears in that spot, hiding the button in the process.
In that WD you could say I want 8 A4 sheets of this drawing, size and zoom the window for accurate printing, and have ruby move camera, save and name image 8 times.more later
john -
Hey Jeff,
lets bump this Applescript stuff and get more people in on the act...
I've been re-reading all the SketchUp Applescript 'google' hits and I think it's time to make it all work.
One of the past problems was no-one seemed to know how to get Applescript to do this sort of thing from INSIDE a ruby script... e.g. »» RUN IN AppleScript Editor
activate application "Sketchup" tell application "System Events" tell process "SketchUp" click menu item "Weld" of menu "Plugins" of menu bar 1 end tell end tell
Although you could get other apps to run from SU using 'osascript' e.g. »» RUN IN Ruby Console
`osascript -e 'activate application "Safari"'`
Previously, as soon as you changed the app to SketchUp you beach-balled...
well, I finally got it working e.g. »» RUN IN RubyrunAppleScript=Thread.new{ `osascript <<EOF activate application "Sketchup" tell application "System Events" tell process "SketchUp" click menu item "Weld" of menu "Plugins" of menu bar 1 end tell end tell EOF ` } runAppleScript.kill
the missing ingredient was a new Thread... and a HEREDOC to simplify the osascript
so where does that all lead us?
if it has a menu item you can activate it from rubyso if you have "Arc: Center and 2 points"
#--# UI;;Toolbar why would you want a custom set of menu items? # def aplscrpt_TB aplscrpt_tb = UI;;Toolbar.new "aplscrpt_TB" # This command when clicked cmd = UI;;Command.new("aplscrpt_TB-Test") { runAppleScript=Thread.new{ `osascript <<EOF activate application "Sketchup" tell application "System Events" tell process "SketchUp" click menu item "Arc; Center and 2 points" of menu "Draw" of menu bar item "Draw" of menu bar 1 end tell end tell EOF ` } runAppleScript.kill } aplscrpt_tb.add_item cmd aplscrpt_tb.show end # aplscrpt_TB # #--#
you can have a button even though it's an encrypted file...
but there's even more we can do with this,
I've worked out how to 'mine' the menu items, and how to 'activate' them from a ruby script, but I'm trying to optimise the parsing to html for use in a 'WebDialog'.
The best way to explain my goal, is a floating 'localised', 'dynamic' menu/toolbar that can be edited (via option boxes) to show only the items you want, and be positioned anywhere, i.e. another monitor.
I use full screen mode alot, and I find getting menu items is a pain. There are only so many shortcut keys I can remember...
Another advantage is it can be 'Stay Open', eg. if you want to check all available camera views in advanced camera tools.
I have made 'html' that looks like a menu, and others that look like toolbar buttons. but I need to full it all together.
and then there's window positioning and sizing, a lot can be gain on using Applescripts strengths from inside ruby...
@ Jeff, if you don't want the highjack, split this to a new thread, but I think it's as good a place as any, mainly cause I like watching RC type itself....
john -
I've been working on returning AppleScript Dialogs from SU ruby osascript, [incase it's desired/needed] and I got most of it working, launches and shows in 'SU' but writes result to tmp file.
This is an experiment something we were trying to get externally... for soemthing like this you would most likely just use in a larger AppleScript, rather than return it to ruby...
»»RUN in RUBY CONSOLE# get the target ratio from the user with an option box %x(rm "/private/tmp/Prnt_Format") runAppleScript=Thread.new{ %x(osascript -so > /private/tmp/Prnt_Format <<SU tell application "SketchUp" activate set Land to "Landscape" set Portr to "Portrait" choose from list {¬ "'A'-Series " & Land, ¬ "'A'-Series " & Portr, ¬ "Architectural " & Land, ¬ "Architectural " & Portr, ¬ "'US' Letter " & Land, ¬ "'US' Letter " & Portr, ¬ "Square", ¬ "Use Printer Settings"} ¬ with title ¬ "Print Format" with prompt ¬ "Choose one format" OK button name ¬ "Format View" cancel button name ¬ "Cancel" default items {"Use Printer Settings"} ¬ -- with multiple selections allowed end tell SU ) }; runAppleScript.kill;
then to read back
(`cat /private/tmp/Prnt_Format`)
john
-
Jeff:
I don't know if you still have any interest in this project, but if you do please check out the script below (based on one of your earlier ones) & see if it works for you like it does for me.
tell application "SketchUp" -- more robust to error trap for SketchUp not running before telling it anything! activate tell application "System Events" to tell process "SketchUp" set drawwin to count of windows click menu item "page setup..." of menu "file" of menu bar 1 repeat while focused of window drawwin = false try set psz to name of static text 2 of sheet 1 of window drawwin (* To dismiss the page setup sheet as soon as it appears, uncomment the 'click button' line below. May be useful if allowing user changes is not needed & the script just needs to get current values & continue?*) -- click button "OK" of sheet 1 of window drawwin end try end repeat end tell end tell (* Bring the AppleScript Editor to the front; manually check its Result pane for the expected psz text. Demonstrates that it can be processed outside the 'tell SketchUp' loop *) activate me psz
From what I understand, one of the things you wanted to do was drop down the page setup sheet & let users change its settings before continuing. It seems a little weird, but in my testing the inverted logic "repeat while focused of window drawwin = false" line accomplishes that. Here is (I think) how it works:
The 'Events' pane of the AppleScript Editor shows the script looping through the repeat over & over, grabbing the current 'psz' value on each pass, just as one might expect. But the unexpected part is that SU doesn't seem to return 'focused = true' to the script even if a user changes something in the sheet. That only happens when a button in the sheet is clicked. That causes an error in the repeat loop (because sheet 1 is no longer there) so the script exits the loop & continues with the 'psz' value from the last "good" repeat.
To keep things simple & make testing easier, I didn't do any processing of the 'psz' text in the script. If you run it from Script Editor, it should bring the script window back to the front as soon as you click "OK" in the SU sheet & the text should be the only thing in the 'Result' pane.
That also avoids the distraction of a 'Display Dialog' window & messing with AppleScript's Text Item Delimiters (which really should be saved before a change & restored to the saved value ASAP afterwards so the change won't screw up some other script that expects the default or its own changed value).
-
yeah.. i'm pretty much over this project.. i have a version of it which i do use but making it work on pre-lion OSes was too much of a pain for me..
i use the part which can resize the actual drawing window to a desired aspect ratio as well as the part which gives a true zoom extents.. the rest of it was an attempt at automation for others but i dunno.. i guess i lost the drive to make that happen..
that said.. i do have another applescript idea brewing but i haven't really dug into it yet.. maybe you guys want to try some stuff with the idea.. i was going to call it TightenUp.. what it would do is grab all the various windows/toolbars then put them in exact locations.. the only thing missing for me is the algorithm (if that's even what it's called in this case).. but i think we've already figured out how to get bounds of everything and how to move them around etc..
here's the basic idea.. on the left is my typical looking sketchup.. on the right is after running the script (and it would also be useful for people with lost panels etc.. better than sketchup's 'reset workspace' thing..
-
@livemixer said:
see if it works for you like it does for me.
not Jeff, but gave it a whirl anyway... it didn't work here... and took a little while to see why.
basically I had 2 drawings open, without realising it and it was screwing with the count of windows...
This is actually one of the reasons I'm pursuing the ruby interaction...
suWin = Sketchup.active_model.title if suWin.to_a.length == 1 then suWin = suWin else suWin = "Untitled" end #if if Sketchup.is_pro? @suW =(suWin + ".skp - SketchUp Pro").inspect else @suW =(suWin + ".skp - SketchUp").inspect end #if
returns**"2Arcs_36sided.skp - SketchUp Pro"**
if I have the other model forefront I get, "Untitled.skp - SketchUp Pro"
if your not runing pro it should chop "Pro"
if thats used in the AppleScript there's no ambiguity, which easily, can be a show stopper.
also the value is then easier to get...get the value of text field 1 of sheet 1 of window "2Arcs_36sided.skp - SketchUp Pro"
john
@Jeff I do have scripts that do that sort of thing, but integrating them into ruby will make then more portable.
you want to split this into the dev forum and we might get more help??
john -
@unknownuser said:
@Jeff I do have scripts that do that sort of thing, but integrating them into ruby will make then more portable.
you want to split this into the dev forum and we might get more help??
johnha.. crazy but last time this thread was going, i left for a job then i personally fizzled out on pursuing it further..
and yesterday, i flew to a job.. then i go home for 2 days.. then to nashville for a few weeks after that..
so all my energy is zapped for at least a month or so -
@unknownuser said:
so all my energy is zapped for at least a month or so
Ok, know how it feels, the next film I had got put back when the lead actor pulled out so I have a reprieve at the moment..., 'sort of luckily' while the money holds out...
I'll start a Dev Forum thread, cause i need help with the ruby anyway and have been PM-ing a-lot, so it makes sense.
I chucked it here because you kicked me into gear the last time, so try out some of this stuff when you get a mo, I think it's going to be worth it, I wrote a quasi "grasshopper" script using AppleScript from ruby the other day, and although it was minor league it was great fun seeing it work...
john -
@driven said:
not Jeff, but gave it a whirl anyway... it didn't work here... and took a little while to see why.
basically I had 2 drawings open, without realising it and it was screwing with the count of windows...
I knew that using 'count of windows' as a reference to the frontmost document window could cause problems if the app had more than one of them open. I was really just trying to call attention to the fact that System Events apparently 'sees' the focused property of the app change to the sheet of a document window only when one of the sheet's buttons is clicked & not (for example) when one of its text fields or some other UI element is changed. That seems strange since the app's focus has to be on a UI element to enable users to change it … right?
-
@livemixer said:
@driven said:
not Jeff, but gave it a whirl anyway... it didn't work here... and took a little while to see why.
basically I had 2 drawings open, without realising it and it was screwing with the count of windows...
I knew that using 'count of windows' as a reference to the frontmost document window could cause problems if the app had more than one of them open.
i worked on some of this stuff later than posted in the thread and i'm not really sure where i left off but.. going through some of the scripts i have, i found i was doing this for dealing with multiple drawing windows..
it will give you the frontmost window even if there are others opened behind it..tell application "SketchUp" activate tell application "System Events" to tell process "SketchUp" --identify the frontmost drawing window set drawwin to 0 set cw to 1 + (count of windows) repeat until drawwin ≠ 0 set cw to (cw - 1) if value of attribute "AXmain" of window cw is true then set drawwin to cw end if end repeat end tell end tell
i'll try to go through some of my scripts over the next few days to see if there are any other things i might of tried of interest
-
@unknownuser said:
i found i was doing this for dealing with multiple drawing windows...
Very interesting! Long ago I tried to work out a good general way to get the frontmost document window when using GUI scripting but I never thought of using the attribute class & never got anywhere without it. Thanks very much for that!
Another problem with GUI scripting I've never been able to solve is how to reliably detect if the frontmost app window has changed during the execution of the script, like when the script is in a loop waiting for some user action in the app to trigger exiting the loop. That can cause problems even with a foolproof way to get an unambiguous reference to what is frontmost before the script enters the loop.
Oh well. One step at a time, I guess.
-
FWIW, here is yet another AppleScript idea for getting the frontmost window, or more accurately the one that has the app's focus:
tell application "SketchUp" activate tell application "System Events" to tell process "SketchUp" set Focus_Is to "nothing" repeat with i from (count of windows) to 1 by -1 if focused of window i then set Focus_Is to name of window i exit repeat end if end repeat end tell end tell activate me {Focus_Is, i}
Unlike Jeff's method using the "AXmain" attribute, this script will return whatever window currently has the focus, even if it isn't a drawing document window. It handles multiple drawing windows & even no drawing windows without problems. As is, I assume it will not handle the unusual case in which absolutely no SU windows are open (counting from zero to 1 by -1 isn't going to work!) but except for that I think it is pretty bulletproof (as long as SU is running when it is called, of course.)
Aside from that, if anyone can get it to stop on an error, please let me know.
I wrote it mostly to explore the conditions in which System Events doesn't get the right focus (like when the page setup sheet is open & users change something in it, as I noted earlier) but maybe it will be useful for something else as well….
-
hi,
the problem with using 'focused' is that I can only ever get main window to return true, regardless of what's actully focusedtell application "Sketchup" to activate delay 0.5 tell application "System Events" tell process "SketchUp" set winCount to count windows repeat with n from 1 to winCount set thisWindow to window n --set winSize to size of thisWindow --set sw to item 1 of winSize --set sh to item 2 of winSize --set winPosition to position of thisWindow --set pw to item 1 of winPosition --set ph to item 2 of winPosition --set winName to ((get name of thisWindow) as string) --set winTitle to ((get title of thisWindow) as string) set winFocus to ((get focused of thisWindow) as string) --set winRole to ((get role of thisWindow) as string) --set winDisc to description of thisWindow --set winProps to (get properties of thisWindow) --set winCont to get the entire contents of thisWindow end repeat end tell end tell
another problem is using 'name' v 'title', if an item has neither, 'name' returns nothing and 'title' returns an empty string, which you can at lease use to dig deeper...
a question- if using 'set winProps to (get properties of thisWindow)' how can you filter out missing value?
john -
@driven said:
hi,
the problem with using 'focused' is that I can only ever get main window to return true, regardless of what's actully focusedOdd. That doesn't happen for me. For instance, if I select an arc in a new, unsaved draw window named "Untitled - SketchUp" & then click on the Entity Info "Segments:" box, in part the events/replies for your script shows the following :
get focused of window "Entity Info" of application process "SketchUp" --> true get focused of window "Untitled - SketchUp" of application process "SketchUp" --> false
In this case my script results shows
{"Entity Info", 2}
Interestingly, the Outliner window gives different results. If I select a group in the Outliner list or click in its search/filter box, it is clearly the focus, but both scripts indicate that 'focused' is true for no window. It is this kind of behavior that prompted me to write my script in the first place.
@unknownuser said:
another problem is using 'name' v 'title', if an item has neither, 'name' returns nothing and 'title' returns an empty string, which you can at lease use to dig deeper...
True, but my script was intended to only to look for application windows that might have the focus. AFAIK only named windows in SU can do that.
@unknownuser said:
a question- if using 'set winProps to (get properties of thisWindow)' how can you filter out missing value?
I have never found a very elegant general method for dealing with 'missing value' properties, mostly because I don't know how to do that without explicitly using the property's name (like "whose size is not missing value"), which leads to a separate line for each property of interest.
Along those lines, something like this might work for you:
tell application "SketchUp" activate tell application "System Events" to tell process "SketchUp" set HasSize to {} set HasName to {} -- etc. repeat with n from 1 to count of windows set WinProps to properties of window n if size of WinProps is not missing value then set end of HasSize to n if name of WinProps is not missing value then set end of HasName to n -- etc. end repeat end tell end tell activate me {HasSize, HasName}
That will give you lists of window numbers that exclude those with missing values for one specific property each. You can use each of them in a 'repeat with loopVariable in list' type loop (like "repeat with i in HasSize") to process just the windows that have values.
Just an idea.
-
I been distracted getting this to work... and just had success!!!
# get the name of current window to use in Applescript using window -- set size (item 2) of window "#{@suW}" suWin = Sketchup.active_model.title if suWin.to_a.length == 1 then @suW = ' "' + suWin + '.skp - SketchUp"' end #if if suWin.to_a.length == 1 && Sketchup.is_pro? then @suW = ' "' + suWin + '.skp - SketchUp Pro"' end #if if suWin.to_a.length == 0 then @suW = 's whose name begins with "Untitled"' end #if # test in osascript... harder than imagined- you need to 'write the osascript in the 'main thread' to collect the variables from ruby, # but you need to run it in a separate thread to avoid 'blocking' the main thread when you 'tell' SketchUp, eval works, but is it a problem? appleScript=(<<MT runAS=Thread.new{ `osascript -ss <<ST tell application "Sketchup" to activate delay 0.5 tell application "System Events" tell process "SketchUp" set size of window#{@suW} to {1000, 1000} end tell end tell end ST` } MT ) eval appleScript;
can you give it a try while I grab a coffee and mull over my reply?
EDIT: re-jigged top to pickup 'Pro' more reliably
-
@livemixer said:
get focused of window "Entity Info" of application process "SketchUp" > --> true > get focused of window "Untitled - SketchUp" of application process "SketchUp" > --> false
In this case my script results shows
{"Entity Info", 2}...
I only tested 17 of the 19 I had open, guess which I missed...
@unknownuser said:
True, but my script was intended to only to look for application windows that might have the focus. AFAIK only named windows in SU can do that....
I think 'title' and 'description' give all the info needed to re-size, re-position, or dig deeper using 'entire contents' [seems to be 4 different types of window and if the title is empty it's an SU Toolbar!!!]
@unknownuser said:
I have never found a very elegant general method for dealing with 'missing value' properties,...
I keep forgetting it's a constant and try to test for it...
I should probably head for bed, it's gone 1am already
john
Advertisement