How to read a property of a value passed by reference? - applescript

I am trying to script OmniGraffle 5.3.6 where I try to read the layers element of a canvas that I have passed to a function (or handler, in AppleScript parlance). When I run the following:
on exportToPng(theCanvas)
set layerCount to count of layers of theCanvas
end exportToPng
tell application "OmniGraffle Professional 5"
set theDocument to front document
set allCanvases to canvases of theDocument
set theCanvas to item 1 of allCanvases
my exportToPng(theCanvas)
end tell
I get the following error:
error "OmniGraffle Professional 5 got an error: Can’t make |layers| of
canvas id 1 of document \"base-dependency-diagram.graffle\" into type reference."
number -1700 from |layers| of canvas id 1 of document
"base-dependency-diagram.graffle" to reference
However, if I were to inline my function, then everything works fine:
tell application "OmniGraffle Professional 5"
set theDocument to front document
set allCanvases to canvases of theDocument
set theCanvas to item 1 of allCanvases
set layerCount to count of layers of theCanvas
end tell
I read Passing by Reference Versus Passing by Value, but I did not find it helpful. It's pretty sparse.

You can pass by reference. However, wherever you pass it must also have "tell application" so that application can handle the passed reference. So you will want your function like this...
on exportToPng(theCanvas)
tell application "OmniGraffle Professional 5"
set layerCount to count of layers of theCanvas
end tell
end exportToPng
After all, only "OmniGraffle Professional 5" knows how to get the layers from theCanvas.

Related

How to get selected ui element in applescript?

I'm trying to create script for application which doesn't have dictionary. How to get selected list item?
I need something like this
tell application "System Events"
tell process "process"
get selected item of list 1 of splitter group 1 of window 1
end tell
end tell
_
choose from list list 1... fails with 1700 error (can't convert to string)
Unfortunately the selected property of each of those particular elements (which are static text UI Elements) seems to be inaccessible.
Doing the following:
activate application "SongOfGod_1_2"
--(this line above is just to make sure
-- we don't miss anything by not having the app frontmost;
--for many commands it is unnecessary)
tell application "System Events"
tell process "SongOfGod"
properties of static text 2 of list 1 of splitter group 1 of group 1 of splitter group 1 of window 1
end tell
end tell
returns:
{class:static text, minimum value:missing value, orientation:missing value, position:{595, 259}, accessibility description:"2. And the earth was without form, and void; and darkness was upon the face of the deep. And the Spirit of God moved upon the face of the waters.", role description:"text", focused:false, title:missing value, size:{1605, 18}, help:missing value, entire contents:{}, enabled:true, maximum value:missing value, role:"AXStaticText", value:missing value, subrole:missing value, selected:missing value, name:missing value, description:"2. And the earth was without form, and void; and darkness was upon the face of the deep. And the Spirit of God moved upon the face of the waters."}
You'll notice, if you scroll way out there, that the selected property returns missing value, which means you cannot determine if it is selected. I also tried focused, which doesn't work. Nor do click or select work. Trying to get the selected property of the list containing it also doesn't work.
You apparently cannot get what you want out of this app, I'm sorry to say.

Apply current selection as a layer mask to the current layer

I have saved a selection as a channel called "circle".
I want to apply this selection as a layer mask to all layers
This is the script I have so far
tell application "Adobe Photoshop CC 2015.5"
activate
set theDOC to the current document
tell theDOC
set totalLayers to count each layer
repeat with indice from 1 to totalLayers by 1
tell layer indice
-- load the channel
tell theDOC
load selection of it from channel "circle" of it
end tell
-- I now need a magic command to apply the "circle" selection that is active now, to the current layer as a layer mask, inside this loop
end tell
end repeat
end tell
end tell
After a deep research I conclude that there is no way to do that, thanks to Adobe. The solution I have for this is:
create an action on Photoshop to add the selection as a mask.
call that action inside the loop using
do action "mask" from "Default Actions"
change mask and Default Actions with your action name and set where the action is stored.
Enjoy.

Applescript to check App Store

Thanks for taking the time to read my question.
It's pretty simple, but i am a complete noobie to this, so am having some trouble.
Is it possible to have an applescript that will check the mac app store for updates, and if there are, output the number of updates to someplace?
A good example of this is (if you are aware of it) the geeklets that check for unread mail, and then outputs it to the desktop.
EDIT:
I downloaded a geeklet for the unread mail (as referenced above), and using that as a starting point, I tried to write my own script.
set run_bool to 1
tell application "System Events"
set run_bool to count (every process whose name is "App Store")
end tell
if run_bool is 1 then
tell application "App Store"
set update_count to 0
set output_string to ""
repeat with upd in Apps in Updates
if upd's download is not true then
set update_count to update_count + 1
end if
end repeat
if update_count is 0 then
set output_string to "zero"
else if update_count is 1 then
set output_string to "one"
else
set output_string to "two"
end if
end tell
else
set output_string to "not running"
end if
return output_string
now this is not my final code, but simply to check to see if it will work and what the output would be.
On compilation I get an error saying
error "The variable Updates is not defined." number -2753 from "Updates"
as well as
Syntax Error
Expected end of line but found unknown token
Also, when I stopped compilation, this appeared below the last line in my code
tell application "GeekTool Helper"
activate
«event ascrgsdf»
Any help is appreciated.
#foo is pretty right on with his idea. This code only requires one line. In the second line, I used display notification, but you substitute it with you preferred method to pass on the value.
tell application "System Events" to tell (first application process whose ¬
frontmost is true) to set returnValue to title of ((first menu item whose title ¬
begins with "App Store") of menu "Apple" of menu bar 1)
display notification returnValue
Result:
"App Store…, 1 update"
menu bar items are accessible everywhere (e.g. windowed/numeral desktop mode, fullscreen mode, dock hidden/disabled).
Make sure accessibility is enabled for Script Editor, or whichever app you use to invoke the script, to gain access to the UI.
There is just one weird thing: if I had used begins with "App Store..." instead of begins with "App Store", the code would be a dud. I don't know why - it might has to do with escaped characters and the .... Anyone who knows please enlighten me with a comment.
As for your code, I can tell from AppleScript Dictionary that Updates is not a property of App Store.app. Nor is any other categories in the UI. To get to the Dictionary, open Script Editor and press CMD+SHIFT+O
In addition, if you want to use return statement, you need an explicit handler. In other words, you need to wrap the code between on run and end run.

PowerPoint Applescript Menu giving different result than AppleScript Editor

The following script, when run in AppleScript Editor returns as text the autoshape type of the objects on the page. However, when run from the applescript menu from within PowerPoint, it returns a script constant instead.
I'm using a more complicated version of this to send properties of the objects to different applications based on what auto shape type it is... tables go one place, placeholders another, and rectangles et al to third. I'm also launching this from within PPT to push out the data, and can't really pull it from any of the other apps, so the AppleScript menu would be where I want it to be.
Can anyone tell me why the same script gives two results?
Thanks,
Alex
tell application "Microsoft PowerPoint"
set currentSlideNumber to slide index of slide range of selection of document window 1
set theSlide to slide currentSlideNumber of active presentation
end tell
getProperty(theSlide)
to getProperty(theSlide)
tell application "Microsoft PowerPoint"
repeat with thisShape in (get every shape of theSlide)
set shapeType to shape type of thisShape
set shapeContent to content of text range of text frame of thisShape
display alert (shapeType as string)
end repeat
end tell
end getProperty
Converting constants (or application properties which standard applescript doesn't understand) to text is tricky. My guess is that when in the powerpoint menu the script understands the constant better and thus you see that.
In any case, I had the same issue with Finder constants and decided to handle the conversion to text myself with an if statement. It's a cumbersome solution because you have to account for every constant but at least you know it will happen properly.
Here's an example. Suppose there is a shape constant of "rect" which stands for a rectangle, and "circ" standing for circle.
NOTE: you can probably use the name of the actual property instead of the constant in the code.
to getProperty(theSlide)
tell application "Microsoft PowerPoint"
repeat with thisShape in (get every shape of theSlide)
set shapeType to shape type of thisShape
if shapeType is <<rect>> then
set shapeTypeText to "rectangle"
else if shapeType is <<circ>> then
set shapeTypeText to "circle"
end if
set shapeContent to content of text range of text frame of thisShape
display alert (shapeTypeText)
end repeat
end tell
end getProperty

Using AXIdentifier in UI Scripting for Applescript

10.7.4 OSX Lion
Applescript
I am working with an application (built in house and has no Applescript dictionary) that has a static text element I want to copy to the clipboard and send to another app but I'm having a hard time getting it to work.
The script I was using for targeting the element looked like this:
Tell application "System Events" to set frontmost of process "*application*" to true
Tell application "System Events"
Tell process "*application*"
Tell static text 1 of tab view 1 scroll area 1 of splitter group 1 of splitter group 1 of splitter group 1 of window 1
keystroke "a" using command down
delay 0.1
keystroke "c" using command down
delay 0.1
end tell
end tell
end tell
end tell
What would happen was that the wrong text from the wrong element was copied to the clipboard every time I clicked in a different spot on the application (there are numerous text fields).
I noticed in UI Accessor/Accessibility Accessor that each UI element in the application has a unique AXIdentifier value when you mouse over them.
Is there anyway to accomplishing what I am trying to do, using AXIdentifier values to target that element and copy the text from it?
Thanks for all the help this is my first post and I hope it was worthy! ~TheLarkInn
You can do this by using AppleScript's filtering. For example, to get the From: pop-up menu in a message composition window in Apple Mail, there is no accessibility description you can match on, however there is a unique AXIdentifier which you can match as follows:
tell application "System Events"
tell application process "Mail"
tell window 1
get first pop up button whose value of attribute "AXIdentifier" is "popup_from"
end tell
end tell
end tell
This is more efficient than looping in AppleScript as it only involves sending one Apple Event to System Events.
I don't think there is a way to directly do what you're trying to do. It seems like you can only access attributes once you have a handle on an element via selector. Here is a very ugly solution that does what you're asking by iterating over all UI elements, but it is really slow with bigger UIs and probably not ideal for any production level code.
tell application "System Events"
tell process "Some Process"
set tElements to entire contents of window "Some Window"
repeat with tElement in tElements
if (exists attribute "AXIdentifier" of tElement) then
if value of attribute "AXIdentifier" of tElement = "Some AXIdentifier" then set tText to value of tElement
end if
end repeat
end tell
end tell
tText
I think using UIElementInspector or Accessibility Inspector from Xcode to build a selector string is the way to go!
Tell application "*application*" to activate
Tell application "System Events"
Tell application process "*application*"
set textStaticTextValue to value of static text 1 of tab view 1 scroll area 1 of splitter group 1 of splitter group 1 of splitter group 1 of window 1
end tell
end tell

Resources