Aperture Project IDs when multiple projects are selected - applescript

I am trying to get the Project IDs of multiple selected projects in the library. When only one project is selected, an image version is also selected in the browser so I can access the id with:
tell application "Aperture"
tell item 1 of (selection as list) to set projId to parent's id
end tell
However, when multiple projects are selected, no image version is selected in the browser so the above will not work. I know I can resort to UI to select a picture and then loop through to extract the id's but I would like to avoid doing so.
activate application "Aperture"
tell application "System Events"
tell process "Aperture"
keystroke (ASCII character 29) -- Right
end tell
end tell
What is the best way of getting project id's for the selected project or projects in Aperture?

Related

How do I tell if the frontmost window is a NSOpenPanel / file open dialog in MacOS using Applescript?

I'm trying to automatically change the directory of the frontmost "file open dialog" or NSOpenPanel dialog with AppleScript, whether that window is part of any application. The idea is that I hit a hotkey, and it will control that dialog to switch to a particular folder.
I can't seem to find out how to find the attributes of a window that would filter it for a "file open dialog". Using the Accessibility Inspector I can find that the "class" is NSOpenPanel. How can I get the class of a window using Applescript?
If you run the following AppleScript, you can see the properties of the foremost window:
tell application "anApp" to activate
delay 1
tell application "System Events"
tell process "anApp"
properties of window 1
end tell
end tell
The app has to be active to see the properties of the windows; You will not get consistent results if the app is in the background.
The NOOpenPanel ought to be recognizable by testing for some combination of the following properties:
role description:"dialog"
title:"Open"
subrole:"AXDialog"
name:"Open"
description:"dialog"
Personally, I'd probably rely on name and role description, which should be the same anytime an app throughs up a standard 'Open' dialog. 'Save' dialogs will be the same, except that title and name will be 'save' rather than 'open'.
If you have an app that presents a open or save sheet (a sub window attached to the titlebar), not a separate dialog, then you'll shift things a little. The AppleScript to get the properties looks like this:
tell application "anApp" to activate
delay 1
tell application "System Events"
tell process "anApp"
tell window 1
properties of sheet 1
end tell
end tell
end tell
and the relevant testable properties are as follows:
accessibility description:"save"
role description:"sheet"
role:"AXSheet"
description:"save"
You'll probably have to add logic to test whether the front window has a sheet, which should distinguish between dialogs and sheets.
Some apps use non-standard open/save dialogs, and you'll have to account for them on a case-by-case basis. There's no magic bullet for that.

Using AppleScript automation how can I get currently opened Adobe reader file name

I tried below code
activate application "Adobe Reader"
tell application "System Events"
tell process "Adobe Reader"
set currentFile to active Document
end tell
end tell
But I couldn't get active document name, I tried this code by already with opened document. I don't even find any dictionary for adobe reader in script Editor. Any suggestions will be much appreciated
The Adobe Reader app does not have an AppleScript dictionary file within it's application bundle and as such is not AppleScript scriptable beyond a very limited number of Standard Suite commands and UI Scripting its menu bar with System Events.
If you just want to get the name of the document that has focus, then the following example AppleScript code can do that:
if running of application id "com.adobe.Reader" then
try
tell application "System Events" to ¬
set docName to ¬
(get name of every menu item of menu 1 of menu bar item ¬
"Window" of menu bar 1 of application process ¬
"Acrobat Reader" whose value of ¬
attribute "AXMenuItemMarkChar" = "✓") as string
return docName
end try
end if
The use of return docName was for testing purposes and can be removed as appropriate. Additionally, it was not necessary for Adobe Reader to have focus and its window could even be minimized, the script still retrieved the name as shown on its Window menu.
Note: This was tested on macOS High Sierra using US English and Adobe Acrobat Reader DC (Continuous Release | Version 2019.021.20058.) and works as is. Adjustments may be needed for other languages and or different versions of Adobe Reader.
Note: The example AppleScript code is just that and does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.
Here are a few AppleScript options that may work for you. I don’t have Adobe Reader so I am not able to test the code.
tell application "Adobe Reader" to set currentFile to name of document 1
If that doesn’t work for you, you can try this…
tell application "Adobe Reader" to activate
repeat until application ""Adobe Reader" is frontmost
delay 0.1
end repeat
tell application (path to frontmost application as text) to set currentFile to name of document 1

Applescript API documentation

I want to make an AppleScript to automate the task of switching resolution on the MacBook Pro Retina.
Searching the internet for "applescript system preferences" I came across a page where some preferences are show. Being the scaled resolution thing new, it is not documented.
This brings to a bigger problem I have with AppleScript (mind that apart from copy-pasting something I never really programmed in it). Where is the documentation that tells me, for instance, tha the System Preferences object is actually called "System Preferences", that it has objects called "pane", that they have an id and that the expose id is "com.apple.preference.expose"?
It seems like there must be some sort of "secret" documentation for every program, and they must be huge, mapping all the object hierarchies and possible actions. In the end, AppleScript core is minimal and all you do is manipulate such programs. But where are they documented?
Ok this is how it works:
Where is the documentation that tells me, for instance, tha the System Preferences object is actually called "System Preferences"
The object is called "System Preferences" because that is the exact name of the application. What you're telling Applescript with this is I want to speak to the application named System Preferences (tell application "System Preferences" ...)
that it has objects called "pane"
Now it's the fun part. If you open your Library window (in Applescript Editor, Window > Library) you will see that there is a collection of scriptable applications available, the thing is that 'System Preferences' is not there. So let's find it: File > Open Dictionary > System Preferences. Now you got a window that both lets you drill down all available classes/commands/properties of the app and also a split window with relevant documentation (if you click on SSystem Preferences you'll see Cpane and by clicking on this you'll see Pid among others). The id of the pane for once more would be the name of the pane (lowercased and concatenated - I'm still looking into documentation for a strict definition on this). I hope that this will get you started.
S:Suite
C:Class
P:Property
(the 'C' inside a circle stands for Command)
You're exactly right. Each program does have its own documentation for applescript. It's called its applescript dictionary. You can see the dictionary of any application by any of the following...
1) in AppleScript Editor, under the File menu, choose "Open Dictionary...". You can select an application from there and it will show its dictionary.
2) drag/drop an application onto the AppleScript Editor's icon.
3) there's a list of frequently-used dictionaries for fast access. Under the Window menu in AppleScript Editor choose "Library". You can double-click an application in that list. You can also modify that list to contain dictionaries that you want in the list.
Good luck.
You can ask AppleScript to tell you the ids for each of the panes.
tell application "System Preferences" to get the id of every pane
This is particuarly handy as it will tell you the ids for any third-party preference panes you have installed. For instance, I was able to work out that the pane for my Microsoft Natural keyboard is called com.microsoft.microsoftkeyboard
I haven't really explored this much yet, but I would expect that similar syntax exists to identify the objects within any scriptable application.
I have another issue but you can have a look to my question as there is some hint in my script about your issue
HOW TO: display a check mark, disable a menu item, refresh a menubar
For instance:
tell application "System Preferences"
reveal anchor "displaysDisplayTab" of pane id "com.apple.preference.displays"
end tell
This code should directly put you in the resolution preferences of the system preference.
Then you can make a code to recuperate all the UI elements of the pane so that you now which action to trigger. Something like this should also work:
tell application "System Events"
tell application process "System Preferences"
set frontmost to true
delay 1
return every UI element of front window
return name of every UI element of front window
end tell
end tell
Hope it helps

Send all files on Desktop to Evernote then delete

Good morning,
I am trying to write an AppleScript that I can run that will send all the files on my desktop to Evernote, and then delete the files. My code to date is:
on run {input}
tell application "Finder"
select every file of desktop
end tell
tell application "Evernote"
repeat with SelectedFile in input
try
create note from file SelectedFile notebook "Auto Import"
end try
end repeat
end tell
tell application "Finder"
delete every file of desktop
end tell
end run
If I run this then the first and last 'tell' work fine (ie. the script highlights then deletes all the files on the desktop), but the middle 'tell' doesn't do anything.
However, if I manually highlight all the files on the desktop and then run just the middle 'tell' then it imports fine - each item into a separate note as intended.
As you can tell, I am new to AppleScript - I suspect I need to put the selected files in an array of some sort, but can't figure it out. Help!
Many thanks
Rich
Your code fails because there is no relation between your input variable and the selection of files via Finder – which means that your list is empty, and Evernote is not processing anything at all. You have obfuscated the problem by wrapping the Evernote import command in a try block without any error processing, which means all errors just go unnoticed (to avoid this kind of problem, it is good practice to always log the error message in an on error clause, if nothing else).
Also, you don’t actually need to select files on the Desktop via AppleScript to process them. The following code will grab all visible files (excluding pseudo-files like packages / apps):
tell application "System Events"
set desktopFiles to every disk item of (desktop folder of user domain) whose visible is true and class is file
end tell
Pass the list you retrieved that way to Evernote for processing:
repeat with aFile in desktopFiles as list
try
tell application "Evernote" to create note from file (aFile as alias) notebook "Auto Import"
tell application "System Events" to delete aFile
on error errorMessage
log errorMessage
end try
end repeat
and you are good to go.
Note that by judiciously placing the deletion command (right after the import command, inside the try block, inside the loop over all files), you make sure it is only called if Evernote does not error on import while avoiding having to iterate over the files several times.
A final note: you don’t have to use the block syntax for tell statements if there is only one command to execute – using tell <target> to <command> is easier and will keep you out of nested context hell.
Thanks #adayzone for corrections on list handling and alias coercion
Try
tell application "System Events" to set xxx to get every file of (desktop folder of user domain) whose visible is true
repeat with i from 1 to count of xxx
set SelectedFile to item i of xxx as alias
try
tell application "Evernote" to create note from file SelectedFile notebook "Auto Import"
tell application "Finder" to delete SelectedFile
end try
end repeat
Thanks #fanaugen

AppleScript -> Activate window of a non-scriptable application

I have opened 2 "Finder" window A & B, A is in the front while B underneath, the following snippet brings B to the front the topmost:
tell application "Finder"
activate
activate window 2
end tell
But for applications that do not support scripting, the code just mentioned won't help.
Any ideas for activating a window of non-scripting application.
You can usually turn to system events in these cases. System events knows about the windows of running processes and you can usually manipulate those windows. Something like this will show you some of the things you can do. Just play around with the code and see if you can do what you want.
tell application "System Events"
tell process "Whatever"
properties of windows
end tell
end tell
EDIT: One of the properties of a window is its "title". So you might be able to use that. This approach uses the fact that many applications have a "Window" menu and under that menu many times the name of the windows are listed and you can switch windows by clicking the approprite menu item. So something like this might work... my example uses TextEdit.
tell application "TextEdit" to activate
tell application "System Events"
tell process "TextEdit"
set windowTitle to title of window 2
click menu item windowTitle of menu 1 of menu bar item "Window" of menu bar 1
end tell
end tell
What is your definition of non-scriptable? Just about everything is scriptable to some degree, but for the sake of an example lets use, does not contain an AppleScript dictionary, e.g. AppName.sdef within its application bundle.
For example, the macOS included Stickies application does not contain the Stickies.sdef file, and when trying to add it to the Library in Script Editor is says, "Unable to add the item because it is not scriptable."
In a case such as this, then System Events is needed to talk to the application process, e.g.:
Example AppleScript code:
if running of application "Stickies" then
tell application "System Events"
tell application process "Stickies"
set frontmost to true
if exists window 2 then ¬
perform action "AXRaise" of window 2
end tell
end tell
end if
Notes:
I've included error handling in the example AppleScript code, which can be removed if you prefer.

Resources