Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you reload files in mac preview 10.7?

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:

errors seen when using advanced script

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
like image 574
keflavich Avatar asked Nov 04 '22 09:11

keflavich


2 Answers

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
like image 189
regulus6633 Avatar answered Nov 15 '22 06:11

regulus6633


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]));
}
like image 41
l --marc l Avatar answered Nov 15 '22 06:11

l --marc l