Using Applescript to align / distribute objects in PowerPoint - applescript

I am trying to write an Applescript to distribute / align objects on a PowerPoint slide. So far I managed to address the selected objects. But I can't figure out a way how to then distribute / align them.
Here's what I have so far:
tell application "Microsoft PowerPoint"
set theShapeRange to shape range of selection of active window
distribute shapes with properties
{distribute type:distribute horizontally}
end tell
Thanks!

In Outlook 2016, you do the following:
tell application "Microsoft PowerPoint"
set theShapeRange to shape range of selection of active window
distribute theShapeRange distribute type distribute vertically without relative to slide
end tell
Alignment has similar syntax (align theShapeRange align type align lefts).
The Dictionary entry for distribute indicates that the without relative to slide parameter is optional, but the script throws an error if I omit that. The Dictionary actually lists the parameter as relative to slide <boolean>, but Script Editor swapped it for the other format. The align command didn't have that issue (i.e., I could omit the optional last parameter).

Related

Get "Position" (Not Resolution) of macOS Extended Display

I have an extended display set up like this:
In the extended display, I have a Finder window positioned on the left half of the extended screen:
When I call this AppleScript:
tell application "System Events"
tell process "Finder"
{position of window 1, size of window 1}
end tell
end tell
I can get the position of the Finder window:
224, 1331, 881, 1075
However, if I move the bottom screen to the left:
The same AppleScript call now provides a different window position:
10, 1331, 881, 1075
How can I get the "position" of the extended screen?
I know I can get the bounds of the desktop using:
tell application "Finder" to get bounds of window of desktop
But that returns the exact same result for both extended display positions:
0, 0, 2304, 2416
I also know I can get the display resolution using
system_profiler SPDisplaysDataType
But that doesn't seem to tell me anything about the extended display's "position", just its resolution.
That same link suggests the command
defaults read /Library/Preferences/com.apple.windowserver.plist
Which looks promising because it has UnmirroredOriginX and UnmirroredOriginY listed for displays. The problem with that file is that I don't see a way to figure out which one of the 17 (in my case) settings is currently active.
For background, my motivation for this question is to derive window positions like left, right, and center 1/3rds and comparable 1/4ths and half positions for windows in an extended display no matter where the extended display is "positioned" relative to the main display. I am trying to replicate the behavior of a program like Rectangle except programmatically. That way windows can automatically be opened and sent to certain positions when certain scripts are run.
I would just send keystrokes to Rectangle itself but it has no way of specifying main or extended display (only "Next" and "Previous" display), so there is no deterministic way to guarantee which display the window will go to as far as I know.
I would also be happy to hear about any other CLI accessible program that can position any window to any 1/2, 1/3, or 1/4 positions in a specific (main or extended) display.
The solution I came up with was to get the resolution using a regex on the output of
system_profiler SPDisplaysDataType
for lines matching
Resolution: (\d+) x (\d+)
I divide both of those numbers by 2 because I always use retina / 4K monitors. This calculation seems to exactly match the AppleScript position values for the 4K displays but not retina. Luckily for me, the 4K display is the only one I need to be completely accurate.
Because I always scale my main monitor to higher resolution than my laptop screen, I can infer that the larger number is the monitor and thus the main display and the smaller is the extended display.
I then call
tell application "System Events"
tell process "%s"
{position of window 1, size of window 1}
end tell
end tell
On whatever target application's window needs to be positioned, which for me is always the frontmost (usually newly opened) window.
Because I always have the main monitor positioned on top of the extended display (laptop), if the returned Y position for the window is higher than the resolution height (divided by 2) of the main monitor, I assume it is in the extended display.
From there, I can keystroke the "Next Display" hotkey in Rectangle if it is in the wrong display. Then I can keystroke the appropriate 1/2, 1/3, 1/4 hotkey in Rectangle.

Deselecting a file from a selection in Finder via AppleScript

I've been searching everywhere for around 6 hours to find a way to deselect file items from a previously selected array of items in Finder via AppleScript via Automator with a Quick Action. I've seen deselect all items, I've seen add items to a selection/list for process, but not remove items from a selection...
The goal: I usually have to process a lot of images and get them approved by supervisors before providing them on our servers for use. All of which come in a set of a transparent PNG and an opaque JPG. I only need to upload the JPG files over for approval. So, let's say I have 30 images. 15 of which are JPGs, 15 of which are PNGs. I would love to be able to select all 30 images, and deselect the 15 of which are PNGs (via the script), left with a selection of all the JPGs.
There are other ways to achieve this, but it would be exceptionally helpful if I could just select the images, run the script, and then move them over for upload (website upload). That appears to be the fastest (by hand) way to go about achieving the end result.
What I know: The selection property. Through my research, I've seen the selection property called in a small amount of different ways, but am unsure how to properly manipulate it. I've tried converting the selection to a string and splitting that by detecting a word to split from (like "Macintosh HD") allowing them to be manipulated in a list, and then potentially removing them from a selection...? I'm also very unsure how to just properly manipulate a property as-is...
I've also attempted to just use the given files via input through Automator AppleScript. But alas, that still leads to knowing how to remove/deselect a file from the current selection.
Anybody know how to achieve this?
I appreciate all the time spend and information in advance. Thank you.
There are two approaches you can use for this, one in pure AppleScript, the other using Automator actions.
The pure AppleScript solution is take the selection as a list of files, copy the JPG files to another list, and set the selection to that new list, like so:
set new_selection_list to {}
tell application "Finder"
set selection_list to selection
repeat with this_item in selection_list
if name extension of this_item is "jpg" then
copy this_item to end of new_selection_list
end if
end repeat
set selection to new_selection_list
end tell
Of course, if you're passing these files in through the input variable in automator, you'd use that rather than testing the selection again, but the principle still stands.
Alternately, you can set up your workflow with a Filter Finder Items action, like so:
I'd recommend the second approach. It's likely significantly faster, and takes less programming.
Although not really deselecting items per se, the Finder has a reveal command that will show the specified items. One approach would be to edit the list of selected items, and then reveal the result.
Note that the sorting of selected items varies depending on whether it is from an Automator action (sorted by name) or a Finder tell statement (the order selected), and items mixed from multiple folders (as can happen in an Automator workflow), will result in multiple Finder windows.
The following Automator Quick Action example will remove the first two items from the input items and reveal the rest of the items in the Finder window:
Workflow receives current files or folders in Finder.app
Run AppleScript:
on run {input, parameters}
set newSelection to input
if (count input) > 2 then -- guard for following statement(s)
set newSelection to items 3 thru -1 of input -- or whatever keep/remove criteria
end if
tell application "Finder" to reveal newSelection
return newSelection
end run

How can I get a reference to the currently selected text in keynote into a variable in applescript

I would really like to drop MS Office and switch to the Apple apps but I have some applescripts for powerpoint that I need to replace. I need to do things like change the font or the opacity of the currently SELECTED text. I can't figure out how to get access to the selected text so that I can change its attributes.
Help would be appreciated.
David
For PowerPoint: the text range property, of the selection object, has a property called font that includes a transparency property described as a real number.
For Keynote: the slide object inherits from iWork container that contains text items that have an opacity property described as a percent.
I got this from the respective application dictionaries.
Upon further review based on comments, there does not seem to be an indicator in the Keynote app that delivers the currently selected object of a container (shape, text object, etc.) automagically.
What I'm thinking is that you could send the menu events to perform a copy of whatever is selected and then iterate through the properties and contained objects of the slide to find a match. This is ugly but I am at a loss otherwise.

Limit on window height when resizing with Applescript

I have a multi-monitor Mac desktop (4 displays each of 1920x1080 arranged in a 4x4 rectangle) and can use a mouse to open a window across all monitors, filling the whole four screen desktop.
(am running Mavericks and have disabled the "Displays have separate Spaces" checkbox)
I want to be able to so this automatically, so used AppleScript. However, the window will not open to a height greater than one of the displays (1080 pixels), even though the displays are arranged in a 4x4 matrix so that the total height of the desktop is reported as 2160 pixels. Window width is no problem and the script opens nicely across displays horizontally.
Here is the key part of the AppleScript:
tell application "Finder"
set bounds of first window to {0, 0, 3840, 1800}
end tell
There seems to be some kind of limit on the vertical size of the window. Any ideas how I can achieve automation?
Googling has pulled endless gripes about multi-monitor support on Mavericks but I can't find anything related to this particular issue.
Thanks in advance
BACKGROUND
I've tried this on two multi-monitor display configurations:
Early 2014 Mac Pro.
Four external 1920x1080 monitors arranged landscape in a 2x2 rectangle.
Reported desktop size is {0, 0, 3840, 2160}
MacBook Pro Retina Late 2013:
Two external 1920x1200 monitors arranged one above the other
(and the laptop's own 2880x1800 internal display of course)
Reported desktop size is {0, 0, 3360, 2400}
I don't have multiple monitors to test this, but on my one monitor the (0, 0) point is the upper left corner of my screen. Maybe you need to adjust the second number of your bounds. My suggestion would be to open a window manually by hand. Then run this code to get the bounds. Then try to set the bounds with the returned values. Of course I still don't know if this will work but at least you'll know you're working with the proper bounds. Good luck.
tell application "Finder"
return bounds of window 1
end tell
EDIT: once you know the proper bounds, you might try using System Events to resize the window. System Events doesn't know "bounds", but it does know "position" (the first 2 numbers in your bounds) and "size" (the second 2 numbers in your bounds). Try this with your numbers.
tell application "System Events"
tell process "Finder"
set position of window 1 to {0, 400}
set size of window 1 to {800, 500}
end tell
end tell
Not to revive a dead subject, but with some external dependencies it is possible to resize larger than the monitor resolution. You need a program called MegaZoomer [https://github.com/ianh/megazoomer] ... and you need EasySIMBL [https://github.com/norio-nomura/EasySIMBL].
Install EasySIMBL first, (can be downloaded from http://www.macupdate.com/app/mac/44354/easysimbl ). Then pull down MegaZoomer from (http://www.macupdate.com/app/mac/21275/megazoomer) ... copy the megazoomer package into the EasySIMBL packages dir. You will need to enable the package in SIMBL. You may have to reboot. Then run your applescript and it should work.

Applescript, multiple monitors and maximum window sizes

I'm looking into windows management on OS X (trying to achieve something like WinSplit Revolution), and I need to use applescript to pull out the maximum size of a window on a given monitor. Currently I've found:
tell application "Safari"
set screen_width to (do JavaScript "screen.availWidth" in document 1)
set screen_height to (do JavaScript "screen.availHeight" in document 1)
end tell
This works for the main monitor on a multiple monitor setup, but doesn't provide at all for secondary monitors. I've also read into the method detailed here, and this obviously doesn't work for multiple displays in an efficient manner. Is there an effective way to get the maximum window size of multiple displays with applescript?
There have been many attempts to get monitor dimensions by reading system plist files. See http://macscripter.net/viewtopic.php?id=15425
If you have access to AppleScript studio (ASS) terms, you can make method calls into NSScreen to get all the monitors then ask them for their sizes. The easiest way to use ASS terms in a plain AppleScript is to compile an empty ASS application in Xcode. In this example, I've created a simple ASS app name ASSAccess which gives me access to ASS terms:
tell application "ASSAccess"
-- The first item in this list will be your main monitor
set screensArray to call method "screens" of class "NSScreen"
set Displays to {}
if {} is not screensArray then
repeat with displayNo from 1 to (count screensArray)
-- call visibleFrame instead to take into account the Dock and menubar
set dims to call method "frame" of (item displayNo of screensArray)
copy dims to end of Displays
end repeat
end if
end tell
Now, the issue I run into with these dimensions is the coordinate system. NSScreen's frame method gives you a rectangle with the origin in the LOWER left hand corner of the main monitor. Then, any secondary screens are given relative to that origin. If you are trying to determine if a window is within these bounds, window position is giving within a coordinate system with the origin at the UPPER left hand corner. This is a whole mess of conversion that I haven't figure out yet.

Resources