[AppleScript] - Sketchup PrintRight
-
@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 -
@driven said:
I should probably head for bed, it's gone 1am already
johnwait what? you're british?
i mistook you as american.. sorry -
@driven said:
I only tested 17 of the 19 I had open, guess which I missed...
It's easy to miss: from what I can tell, the Entity Info window is the only window besides any open drawing windows that will retain the focus of SU when it is made frontmost by the "Activate" action, & only if the cursor was in one of its regular editable text fields when it was last frontmost. (It won't even retain the focus if the cursor was in the layer field.)
However, if any window besides a drawing window or the Entity Info window with a text field selected last had the focus, both our scripts show that no window has the focus when the script makes SU frontmost again. At first I thought this was some quirk of GUI Scripting or the "Activate" action or something like that, but now I think it is a quirk of SU itself.
I haven't worked out all the details yet but it appears that if SU is made frontmost by any other method besides clicking on one of its windows (like via a script's "Activate" action or clicking on its icon in the Dock when it is already open), it can go into a weird, 'indefinite focus' state.
For instance, if I click on a group in the drawing window & then click on the "name" field in the Entity Info window, the focus shifts to the Entity Info window, as expected. But if I then click on some other open app in the Dock & then click on the SU icon in the Dock, the focus isn't on either the Entity Info window or any drawing window. It actually seems to be on the "Large Tool Set" palette (if it is present), because for instance if I type "a" for the arc tool, the arc icon highlights in that palette … but not in the toolbar of the drawing window. At this point, the drawing window isn't frontmost or the focus: Moreover, the mouse pointer has not been updated with the arc icon, & even after clicking in the drawing window to get it & even after drawing an arc, the toolbar icon in the drawing window remains "stuck" on the select tool's arrow icon.
-
@livemixer said:
I think it is a quirk of SU itself.
not so much a quick, but how Su specifies the Nib files for all the sub-windows
the majority are NSPanels that have been left as 'click thru' so that they 'don't' take 'focus' when clicked.this is why 'Toolbars' work immediately, but a button in a 'Webdialog'[ has 'click thru' off by default ] needs 'click' to 'focus'; 'click' to 'activate'; 'click' to 'de-focus'; making 'webDialog' toolbars on a mac a pain.
Can you test this in 'Ruby Console', it's an old 'what works here' script that I automated with Applescript...
Draw a cube the paste in console and return, should generate a list of all SU names for tools used...
if it baulks at anything, comment that line out with a #
def runASclk runAppleScript=Thread.new{ `osascript <<EOF 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 winName to ((get name of thisWindow) as string) set winTitle to ((get title of thisWindow) as string) if description of thisWindow is "alert" then delay 0.5 click button "OK" of thisWindow end if end repeat end tell end tell end EOF` } runAppleScript.kill end # runASclk list=<<-HereDoc Sketchup.send_action('showRubyPanel;') Sketchup.send_action('viewZoomToSelection;') Sketchup.send_action('editUndo;') Sketchup.send_action('viewBack;') Sketchup.send_action('editRedo;') Sketchup.send_action('viewBottom;') Sketchup.send_action('editHide;') Sketchup.send_action('viewFront;') Sketchup.send_action('editUnhide;') #! dosn't work on mac Sketchup.send_action('viewIso;') Sketchup.send_action('editUnhideLast;') #* does work on mac Sketchup.send_action('viewLeft;') Sketchup.send_action('viewUndo;') Sketchup.send_action('editUnhideAll;') #* does work on mac Sketchup.send_action('viewRight;') !Sketchup.send_action('viewShowAxes;') #* does work on mac Sketchup.send_action('viewTwoPointPerspective;') #* does work on mac Sketchup.send_action('renderShaded;') Sketchup.send_action('viewTop;') Sketchup.send_action('viewPerspective;') Sketchup.send_action('viewParallelProjection;') #* does work on mac Sketchup.send_action('renderWireframe;') Sketchup.send_action('renderMonochrome:') Sketchup.send_action('viewShowAxes;') Sketchup.send_action('viewShowGuides;') #* does work on mac !Sketchup.send_action('viewShowGuides;') #* does work on mac !Sketchup.send_action('viewShowHidden;') #* does work on mac Sketchup.send_action('pageAdd;') Sketchup.send_action('viewSectionPlanes;') #? Sketchup.send_action('viewZoomExtents;') Sketchup.send_action('selectOrbitTool;') Sketchup.send_action('selectPositionCameraTool;') Sketchup.send_action('selectDollyTool;') Sketchup.send_action('selectTurnTool;') Sketchup.send_action('selectWalkTool;') Sketchup.send_action('selectZoomTool;') Sketchup.send_action('selectFieldOfViewTool;') Sketchup.send_action('selectZoomWindowTool;') Sketchup.send_action('pageUpdate;') Sketchup.send_action('pageNext;') Sketchup.send_action('pagePrevious;') Sketchup.send_action('pageDelete;') Sketchup.send_action('renderHiddenLine;') Sketchup.send_action('renderTextures;') Sketchup.send_action('selectArcTool;') Sketchup.send_action('selectAxisTool;') Sketchup.send_action('selectCircleTool;') Sketchup.send_action('selectEraseTool;') Sketchup.send_action('selectFreehandTool;') Sketchup.send_action('selectLineTool;') Sketchup.send_action('selectMeasureTool;') Sketchup.send_action('selectMoveTool;') Sketchup.send_action('selectOffsetTool;') Sketchup.send_action('selectPaintTool;') Sketchup.send_action('selectPolygonTool;') Sketchup.send_action('selectProtractorTool;') Sketchup.send_action('selectPushPullTool;') Sketchup.send_action('selectRectangleTool;') Sketchup.send_action('selectRotateTool;') Sketchup.send_action('selectScaleTool;') Sketchup.send_action('selectSectionPlaneTool;') Sketchup.send_action('selectTextTool;') Sketchup.send_action('selectDimensionTool;') Sketchup.send_action('selectExtrudeTool;') Sketchup.send_action('selectSelectionTool;') Sketchup.send_action('fixNonPlanarFaces;') Sketchup.send_action('addBuilding;') Sketchup.send_action('getPhotoTexture;') Sketchup.send_action('selectImageIglooTool;') Sketchup.send_action('selectNorthTool;') Sketchup.send_action('viewShowHidden;') HereDoc list.split("\n") t1=Time.now.dup list.each { |l| UI.start_timer(1) {UI.messagebox(l.to_s) reply=(IO.readlines("/private/tmp/SketchUpUndo0.log"))[-1] puts reply;p (Time.now-t1); eval(l.chomp!); runASclk } }
EDIT: I added # to stop it pausing on black lines... didn't help so removed blank lines
john -
@driven said:
Can you test this in 'Ruby Console', it's an old 'what works here' script that I automated with Applescript...
Draw a cube the paste in console and return, should generate a list of all SU names for tools used...
if it baulks at anything, comment that line out with a #...
When I run this, I get a very long succession of dialog boxes with various messages & just an OK button. Sometimes the message is just "#," sometimes "##," & sometimes something more descriptive. Sometimes the dialog boxes auto-dismiss themselves, sometimes I have to click "OK" to get things moving again.
After letting it run ~ 10 minutes, I started clicking furiously on the "OK" button as soon as it appeared & it finally finished. Only then could I could scroll through the RC window's hundreds of lines of output. A few of them ended with "#* does work on mac" or "#! dosn't work on mac" EDIT: which I see now are just part of your script.
I haven't looked at it too closely but it seems to repeat everything several times, almost as if it was stuck in an infinite loop.
I'll PM you the RC output as a Textedit file -- it's too long to post here.
EDIT: aside from the output in the RC window, nothing else happened. What should have?
-
@driven said:
not so much a quick, but how Su specifies the Nib files for all the sub-windows
the majority are NSPanels that have been left as 'click thru' so that they 'don't' take 'focus' when clicked.To be honest, I understand almost none of that but the 'quirk' as best as I can explain it is under the circumstances I described, the focus doesn't 'click thru' to anything.
It is as if the programmers are relying on a click in some window to set the focus explicitly when the app becomes frontmost, but did not consider that there is no click involved when a tool is selected via a keyboard shortcut. So in this case nothing 'takes' the focus, & the toolbar & pointer in the drawing window aren't updated properly.
Does that make any sense?
Advertisement