I'd like to reload files (.png, .pdf) in Preview after they have been updated. How can this be accomplished?
In OS X 10.5 and 10.6, it was as simple as switching to Preview - it would automatically reload the new file. Alternatively, you could use open -a Preview *.png
or something similar. In 10.7, auto-reloading doesn't work (see this post).
My first attempt is an applescript script run from the command line:
/usr/bin/osascript -e 'tell application "Preview.app" to activate
tell application "Preview.app" to open "'$PWD/$*'"'
This works for a single file, but fails with multiple files for obvious reasons. I did a little more research and tried using a more complicated applescript involving set
and a list, but this results in permissions errors:
Here's the python script I used (my bash scripting skills were not up to the task of string parsing):
#!/usr/bin/env python
import optparse
import os
parser=optparse.OptionParser()
options,args = parser.parse_args()
pwd = os.getcwd()
cmd = '/usr/bin/osascript -e '
scriptcmd = "tell application \"Preview.app\" to activate\n"
flist = [ fn if fn[0]=='/' else pwd+"/"+fn for fn in args]
scriptcmd += "set myList to {\"%s\"}\n" % ( '","'.join(flist) )
scriptcmd += "tell application \"Preview.app\" to open myList"
print("%s \'%s\'" % (cmd,scriptcmd))
os.system("%s \'%s\'" % (cmd,scriptcmd))
I'm not even sure this script would have solved my original problem - reloading images without seeing a gray screen - but I'd like to know if there's any way to simply open a list of files with osascript
instead of open
.
EDIT: Attempted to fix applescript, but this code gets "missing value" errors:
tell application "Preview.app" to activate
set myListOfImages to {":Users:adam:work:code:test.png"}
tell application "Preview.app" to open myListOfImages
Here's a simple applescript that works for me in 10.7.
set picsFolder to (choose folder with prompt "Choose the folder to search...") as text
tell application "Finder"
set theImages to (files of folder picsFolder whose name extension is "jpg") as alias list
end tell
tell application "Preview"
activate
open theImages
end tell
I see a few errors in the osascript command listed in your post. First the osascript command is not formed properly. Second, you're trying to use posix-style paths (eg. slash delimited) in an applescript command. Applescript requires applescript-style paths (eg. colon delimited). There's other issues too. Anyway, here's an osascript that you can run from the command line and it works by searching the current working directory as you were trying to do...
/usr/bin/osascript -e 'set posix_picsFolder to do shell script "PWD"' -e 'set picsFolder to (POSIX file posix_picsFolder) as text' -e 'if picsFolder does not end with ":" then set picsFolder to picsFolder & ":"' -e 'tell application "Finder" to set theImages to (files of folder picsFolder whose name extension is "jpg") as alias list' -e 'tell application "Preview"' -e 'activate' -e 'open theImages' -e 'end tell'
NOTE: my code looks for jpg files, so just change jpg to png or whatever other file extension you want.
EDIT: to answer your additional questions from the comments
If you want to search for multiple extensions you can use "or" like this...
tell application "Finder"
set theImages to (files of folder picsFolder whose name extension is "jpg" or name extension is "png") as alias list
end tell
To find the proper ":" delimited path, here's a short applescript which will show them to you. If you want a "folder" path instead of a "file", just change the words in the code. You will notice these style paths always start with the name of you hard drive.
set colonDelimitedPath to (choose file) as text
And if you have a posix-style path that you want to convert to an applescript-style path use this.
set posixPath to "/Applications/"
set macPath to (POSIX file posixPath) as text
Since Dec 2011, OS X system scripting has evolved such that another option exists. OS X now includes JavaScript for Automation (JXA) with an ObjC bridge.
(caveat: OS X 10.7 of 2011 would need to be updated to 10.10 to use JXA)
Although I've not done a measured benchmark, ObjC bridge seems to respond quicker than the AppleScript Apple Events bridge in this case.
#!/usr/bin/env osascript -l JavaScript
ObjC.import('AppKit');
var urls = getSelectedFiles();
// withAppBundleIdentifier:(NSString *)appBundleIdentifier
var appBundleIdentifier = $.NSString.alloc.initWithUTF8String('com.apple.Preview');
// options:(NSWorkspaceLaunchOptions)options
var options = $.NSWorkspaceLaunchWithoutActivation | $.NSWorkspaceLaunchWithErrorPresentation;
// additionalEventParamDescriptor:(NSAppleEventDescriptor *)descriptor
var nilDescriptor = $(); // bridged nil
// launchIdentifiers:(NSArray **)identifiers ... not used
var nilIdentifiers = $(); // bridged nil
// $.NSWorkspace.openURLs:withAppBundleIdentifier:options:additionalEventParamDescriptor:launchIdentifiers()
var ws = $.NSWorkspace.sharedWorkspace;
ws.openURLsWithAppBundleIdentifierOptionsAdditionalEventParamDescriptorLaunchIdentifiers(
urls,
appBundleIdentifier,
options,
nilDescriptor,
nilIdentifiers
);
function getSelectedFiles() {
var appFinder = Application("Finder");
var selection = [].slice.call(appFinder.selection());
var list = $.NSMutableArray.alloc.initWithCapacity(selection.length);
for (key in selection) {
var path = decodeURI(selection[key].url());
path = path.replace(/file:\/\//,"");
var nsurl = $.NSURL.fileURLWithPath(path);
list.addObject(nsurl);
}
return $.NSArray.alloc.initWithArray(list);
}
A JXA approach without the Objective-C bridge can also be used:
var appPreview = Application("Preview");
var appFinder = Application("Finder");
var selection = [].slice.call(appFinder.selection());
var paths = new Array(0);
for (key in selection) {
paths.push(decodeURI(selection[key].url()));
}
appPreview.activate();
for (key in paths) {
console.log(paths[key]);
appPreview.open(Path(paths[key]));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With