// (c) Copyright 2005. Adobe Systems, Incorporated. All rights reserved. // This JavaScript is to be read by Bridge, Photoshop, and other Adobe apps at // launch. It enables some Photoshop-Bridge integration, such as installing // the Photoshop automate commands in the Bridge menus, and generally exposes // a larger Photoshop dom to the other apps. // debug level: 0-2 (0:disable, 1:break on error, 2:break at beginning) $.level = 0; // debugger; // launch debugger on next line // on localized builds we pull the $$$/Strings from a .dat file $.localize = true; //================================================================= // Setup/Support // This first portion of the script sets up an object to provide // scope for all Photoshop BridgeTalk related routines to prevent // name collision with other groups' scripts, defines some common // utility functions, and adds some Photoshop related commands // to the Bridge menus. //================================================================= try { // Overall try catch //----------------------------------------------------------------- // A Note About Exception Handling //----------------------------------------------------------------- // If execution of the body of a BridgeTalk message throws an // exception, it will be silently swept under the carpet and not // reported to the user. Therefore, many of the functions in here // which are run as the body of a BridgeTalk message due to a user // request have an overall try-catch to report such errors. // // Exceptions thrown out of Bridge MenuElement onSelect methods are // also not reported, so they are wrapped in try-catch statements // here. // // The X-DOM functions are not wrapped in try-catch statements so // it is up to the caller to handle any exceptions if calling X-DOM // functions via BridgeTalk. //----------------------------------------------------------------- //----------------------------------------------------------------- // Guard against loading script if matching version of PS is not // installed. //----------------------------------------------------------------- if (BridgeTalk.getTargets (9.0).join ().indexOf ('photoshop') == -1) throw "Version of Photoshop matching this script not installed."; //----------------------------------------------------------------- // Guard against loading multiple revisions of the same startup // script. The latest revision will take precedence. //----------------------------------------------------------------- if (typeof photoshop9 != "undefined") { if ((photoshop9.revision == undefined) || (photoshop9.revision < 4)) // In-sync: revision # of current startup script delete photoshop9; else // Bail out right here. throw "Object photoshop9 has been defined. Older version ignored."; } //----------------------------------------------------------------- // Define photoshop9 object. //----------------------------------------------------------------- var photoshop9 = new Object; photoshop9.revision = 4; // In-sync: revision # of current startup script. // Set the generic photoshop object equal to photoshop9 if that is // the highest installed version on this machine. if (BridgeTalk.getTargets (0).join ().indexOf ('photoshop-9.0') != -1) photoshop = photoshop9; //----------------------------------------------------------------- // Throughout this script commands are set up to be added to the // Tools > Photoshop menu in Bridge. Since Bridge's menu API does // not support automatic alphabetizing of menu items, we create // an array with all the necessary menu item info in it, then sort // it at the end of this script and create all the menu items. //----------------------------------------------------------------- photoshop9.menuItemInfoArray = new Array (); //----------------------------------------------------------------- // This routine sets the argument menu node to be enabled. //----------------------------------------------------------------- photoshop9.alwaysEnabled = function () { this.enabled = true; } //----------------------------------------------------------------- // This routine takes an array of thumbnails and returns an array of the // files represented by those thumbnail objects. //----------------------------------------------------------------- photoshop9.thumbnailArrayToFileArray = function (/* array of thumbnails */ thumbnails, requireTwoFiles) { var thumbsArray = new Array (); var preflightUrls = new Array (); var filesArray = new Array (); var foundFolder = false; for (var index = 0; index < thumbnails.length; index++ ) { // Don't add containers to the list, but note if any were found. if (thumbnails[index].container) foundFolder = true; else { thumbsArray.push (thumbnails[index]); preflightUrls.push (thumbnails[index].path); } } if (thumbsArray.length == 0) { if (foundFolder) Window.alert (localize ("$$$/PSBI/Automate/FoldersNotAllowed=Folders cannot be used for this command.")); else Window.alert (localize ("$$$/PSBI/Automate/NoFiles=There are no files to process.")); } else if (requireTwoFiles && (thumbsArray.length == 1)) { Window.alert (localize ("$$$/PSBI/Automate/MoreThanOneRequired=More than one file is required for this command.")); } else { // We have adequate files, now preflight them (make sure VC files have // a local replica) and then grab the file specs. app.preflightFiles (preflightUrls); for (var index = 0; index < thumbsArray.length; index++ ) { filesArray.push (thumbsArray[index].spec); } } return filesArray; } //----------------------------------------------------------------- // This routine returns the selected files, or if no files are selected, // all the files. //----------------------------------------------------------------- photoshop9.getBridgeFileListForAutomateCommand = function (requireTwoFiles) { var files = new Array; if (app.document.thumbnail != undefined) { if (app.document.selections.length > 0) { files = photoshop9.thumbnailArrayToFileArray (app.document.selections, requireTwoFiles); } else if (app.document.visibleThumbnails.length > 0) { files = photoshop9.thumbnailArrayToFileArray (app.document.visibleThumbnails, requireTwoFiles); } else Window.alert (localize ("$$$/PSBI/Automate/NoFiles=There are no files to process.")); } return files; } //----------------------------------------------------------------- // This routine tries to return an array of File objects created // from the 'files' argument. It will convert a single File object // or a single string into an array of File objects, or it will // convert an array of string and File objects into an array of // file objects. //----------------------------------------------------------------- photoshop9.ExtractFileArray = function (files) { var fileArray = new Array; // If it isn't an array, make it a length one array. if (!(files instanceof Array)) files = new Array (files); // Turn each item in the array into a File, or remove it. for (index = 0; index < files.length; ++index) { var file = files[index]; if (file instanceof File) fileArray.push (file); else if (typeof file == 'string') fileArray.push (File (file)); else { // do nothing } } return fileArray; } //----------------------------------------------------------------- // This routine executes the specified action. If 'settingsFileName' // is provided, it uses any saved settings combined with the new // file list, then saves the updated settings. //----------------------------------------------------------------- photoshop9.runActionCommand = function (eventString, files, settingsFileName) { var eventDesc = null; // Read in the old settings, if asked. if (settingsFileName != null) eventDesc = photoshop9.readDescriptor (settingsFileName); // If this is the first time we've run, there won't be a settings // file, so create a new blank descriptor. if (eventDesc == null) eventDesc = new ActionDescriptor (); if (files != null) { // Create an action list with the provided files and add them // to the descriptor, overriding any previous ones that might // have been there. var filesListKey = stringIDToTypeID ('filesList'); var filesList = new ActionList (); for (var index = 0; index < files.length; index++) filesList.putPath (files[index]); eventDesc.putList (filesListKey, filesList); } // Force it to record. var forceRecordKey = stringIDToTypeID ('forceRecording'); eventDesc.putBoolean (forceRecordKey, true); // Run the action. var eventKey = stringIDToTypeID (eventString); var resultDesc = executeAction (eventKey, eventDesc, DialogModes.ALL); // Save the descriptor for next time, if asked. if (settingsFileName != null) photoshop9.saveDescriptor (settingsFileName, resultDesc); } //----------------------------------------------------------------- // This routine saves the given descriptor to a settings file using // the given name. //----------------------------------------------------------------- photoshop9.saveDescriptor = function (name, descriptor) { // try-catch this routine so if something goes terribly wrong // we can still run the command. try { if ((descriptor == null) || (descriptor.count == 0)) return; var folder = photoshop9.getActionCmdSettingsFolder (); if (!folder.exists && !folder.create ()) return; var stream = descriptor.toStream (); var file = new File (folder.fsName + "/" + name + '.psp'); if (file.open ('w')) { file.encoding = 'BINARY'; file.write (stream); file.close (); } } catch (e) { return null; } } //----------------------------------------------------------------- // This routine retrieves a descriptor from a settings file using // the given name. A descriptor ought to have been previously saved // under the same name using saveDescriptor (). //----------------------------------------------------------------- photoshop9.readDescriptor = function (name) { // try-catch this routine so if something goes terribly wrong // we can still run the command. try { var folder = photoshop9.getActionCmdSettingsFolder (); var file = new File (folder.fsName + "/" + name + '.psp'); if (!file.exists) return null; if (!file.open ('r')) return null; file.encoding = 'BINARY'; var stream = file.read (file.length); file.close (); var descriptor = new ActionDescriptor (); descriptor.fromStream (stream); return descriptor; } catch (e) { return null; } } //----------------------------------------------------------------- // This routine retrieves a descriptor from a settings file using // the given name. A descriptor ought to have been previously saved // under the same name using saveDescriptor (). //----------------------------------------------------------------- photoshop9.getActionCmdSettingsFolder = function () { var settingsFolder = new Folder (app.preferencesFolder); if (!settingsFolder.exists) settingsFolder.create (); return settingsFolder; } //================================================================= // CrossDOM/X-DOM // Implements Photoshop's cross DOM API - the a small set of // operations that are common to all Adobe apps. //================================================================= //----------------------------------------------------------------- // executeScript (script) - Performs an "eval" on the given script. // // return value Object The value of evaling the last line // of the script // script String The script to be evaled //----------------------------------------------------------------- photoshop9.executeScript = function (script) { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // executeScript. var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.executeScript (" + script.toSource () + ");"; btMessage.send(); } else { // This is Photoshop, so just call our DOM routine eval (script); } } //----------------------------------------------------------------- // open (files) - Performs the equivalent of File->Open on the // requested paths. Accepts either an Array object or a single // path. // // return value Array of File an array of all the // successfully opened // files // files File or Array of File files to open //----------------------------------------------------------------- photoshop9.open = function (files) { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // open. var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.open (" + files.toSource () + ");"; btMessage.send(); } else { // This is Photoshop, so just call our DOM routine with the files var fileArray = photoshop9.ExtractFileArray (files); for (index = 0; index < fileArray.length; ++index) { var file = fileArray[index]; app.open (file); } } } //----------------------------------------------------------------- // openAsNew ([creation-options]*) - Performs the equivalent of // File->New. The creation-options are app-specific and should // ideally map on to the app's new() function. PS has no creation // options. // // return value Boolean true if successful //----------------------------------------------------------------- photoshop9.openAsNew = function ()// ([creation-options]) { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // open. var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.openAsNew ();"; btMessage.send(); } else { // This is Photoshop, so just call our DOM routine app.documents.add (); } } //----------------------------------------------------------------- // print (files) - Performs the equivalent of File->Print on the // requested files. // // return value Array of File the array of files // successfully // printed // files File or Array of File files to be printed //----------------------------------------------------------------- photoshop9.print = function (files) { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // open. var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.print (" + files.toSource () + ");"; btMessage.send(); } else { // This is Photoshop, so just call our DOM routine with the files var fileArray = photoshop9.ExtractFileArray (files); for (index = 0; index < fileArray.length; ++index) { var file = fileArray[index]; var document = app.open (file); if (document != undefined) { var rememberDialogModes = displayDialogs; displayDialogs = DialogModes.ALL; document.print (); displayDialogs = rememberDialogModes; } } } } //----------------------------------------------------------------- // quit () - Performs the equivalent of File->Exit or File->Close. // // return value undefined //----------------------------------------------------------------- photoshop9.quit = function () { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // open. var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.quit ();"; btMessage.send(); } else { // This is Photoshop, so just call our DOM var quitID = stringIDToTypeID ('quit'); var desc = new ActionDescriptor (); executeAction (quitID, desc, DialogModes.NO); } } //----------------------------------------------------------------- // reveal (file) - Gives the target app focus and brings the // specified document to the foreground if it is already open. // // return value Boolean true if the file was open and was // successfully brought to the // foreground // file File file to be revealed //----------------------------------------------------------------- photoshop9.reveal = function (file) { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // open. var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.reveal (" + file.toSource () + ");"; btMessage.send(); } else { // This is Photoshop, so just call our DOM routine with the files // Loop through the open documents looking for the one // we want to reveal. If it is found, make it the active // document. var docNum = app.documents.length - 1; while (docNum >= 0) { var document = app.documents[docNum]; // If document is a new unsaved document, accessing // document.fullName results in an error. Comparing // it to undefined also results in an error, so it // is in a try-catch instead. try { if (document.fullName.fsName == file.fsName) { app.activeDocument = document; break; } } catch (e) { // ignore. } --docNum; } } } //================================================================= // Invoking Bridge // Is called by Photoshop to invoke Bridge. //================================================================= photoshop9.invokeBridge = function (newWindow, maximize, path) { // Bring Bridge to the foreground. if (BridgeTalk.isRunning ('bridge')) BridgeTalk.bringToFront ("bridge"); // Send an appropriate message to Bridge to tell it what to do. var bt = photoshop9.getInvokeBridgeMessage (newWindow, maximize, path); bt.send (); } photoshop9.getInvokeBridgeMessage = function (newWindow, maximize, path) { var bt = new BridgeTalk; bt.target = 'bridge'; // If there is no path, we want to pass nothing to Bridge's routines, // not an empty File object. var file = ''; // toSource is our friend. The 'path' string may have quotes (single or double) // in it that start messing things up if we want to use it as part of a bigger // string (in particular part of a BridgeTalk message body); specifically, string // literals can get terminated early leading to syntax errors. So, we create // a File object out of it and call toSource on the File object to get back a // string that can be used as part of a larger string (nasty characters like // quotes will be replaced with URL friendly equivalents). if (path != null && path != '') file = File (path).toSource (); if (BridgeTalk.isRunning ('bridge')) { if (newWindow) { bt.body = "app.browseTo (" + file + ");"; } else { bt.body = "if (app.documents.length == 0)" + " app.browseTo (" + file + ");" + " else" + " {" + " app.document.thumbnail = new Thumbnail (" + file + ");" + " app.document.bringToFront ();" + " }"; } } else { bt.body = "app.document.thumbnail = new Thumbnail (" + file + ");"; if ($.os.charAt (0) == 'W') { // On Windows, holding any key down when launching an app makes it // launch behind the current one. Since we support modifiers when // invoking bridge, this is problematic. To avoid this unwanted // behavior, we get Bridge to send a message back to Photoshop with // the body "BridgeTalk.bringToFront ('bridge')". If a key was held // down then Photoshp still has focus and the call will bring Bridge // to the foreground. If a key was not held down, then the call does // nothing. bt.body += "var bt = new BridgeTalk;" + "bt.target = 'photoshop';" + "bt.body = '" + 'BridgeTalk.bringToFront ("bridge")' + "';" + "bt.send ();"; } } if (maximize) bt.body += "app.document.maximize ();"; return bt; } //================================================================= // Launching Bridge // Is called by Photoshop to launch Bridge in the background at // startup. //================================================================= photoshop9.launchBridgeInBackground = function () { if (!BridgeTalk.isRunning ('bridge')) { // On Mac we are able to effectively launch Bridge without Photoshop // losing focus, so all we have to do is launch Bridge. On Windows we // are not so lucky and must employ some trickery to avoid having // Bridge take over as the active app. if ($.os.charAt (0) == 'M') { BridgeTalk.launch ('bridge', 'background'); return; } // Get the version number of Bridge so we can locate its // app/user specific startup directory. var bridgeSpecifier = BridgeTalk.getSpecifier('bridge'); var bridgeVersion = null; if (bridgeSpecifier != null) bridgeVersion = bridgeSpecifier.match (/[0-9\.]+/); // Define a function that will be run inside of Bridge to make // Photoshop come to the foreground. This script will be // written to a temporary startup script and will self-delete // after run. var launchBridgeBehindScript = function (bridgeVersion) { // This guard shouldn't matter because only Bridge should // ever read this startup script, but include anyway. if (BridgeTalk.appName == 'bridge') { // On Windows, bringToFront is only effective if the calling app is // the foreground app, so it can't be called until Bridge has created // a window. To accomplish this, we insert a handler function that // deletes itself after one execution. var bringPSForwardOnceHandler = function (event) { // Run on document creation. if (event.object.constructor.name == 'Document' && event.type == 'create') { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ('photoshop'); // Remove this handler once it has run. for (var index = 0; index < app.eventHandlers.length; index++) { if (app.eventHandlers[index] == this) { app.eventHandlers[index] = null; break; } } } // Return false so Bridge will keep calling other event handlers. return { handled: false }; } // Install the event handler. app.eventHandlers.push ({handler: bringPSForwardOnceHandler}); // Delete the startup script file that this script is written into // (and being executed from). var thisScriptFile = new File (Folder.userData + '/Adobe/StartupScripts/bridge/' + bridgeVersion + '/bringPSForward.jsx'); thisScriptFile.remove (); } // BridgeTalk.appName == 'bridge' } // launchBridgeBehindScript // This helper routine will return a folder for the version/app/user specific // startup scripts folder for Bridge, creating the folder hierarchy as // necessary. May return null. var createBridgeSSFolder = function (bridgeVersion) { var folder = new Folder (Folder.userData + '/Adobe'); if (!folder.exists && !folder.create ()) return null; folder = new Folder (folder.fsName + '/StartupScripts'); if (!folder.exists && !folder.create ()) return null; folder = new Folder (folder.fsName + '/bridge'); if (!folder.exists && !folder.create ()) return null; folder = new Folder (folder.fsName + "/" + bridgeVersion); if (!folder.exists && !folder.create ()) return null; return folder; } // createBridgeSSFolder // Get the startup scripts folder and write the function defined above into it // so Bridge will execute it when it launches. if (bridgeVersion != null) { var folder = createBridgeSSFolder (bridgeVersion); if (folder != null) { var file = new File (folder.fsName + '/bringPSForward.jsx'); if (file.open ('w')) { file.encoding = 'TEXT'; file.write ('var func = ' + launchBridgeBehindScript.toString () + 'func ("' + bridgeVersion + '");'); file.close (); } } } // Everything is set; launch Bridge. BridgeTalk.launch ('bridge', 'background'); } // !BridgeTalk.isRunning ('bridge') } //================================================================= // Print Online via Bridge // Is called by Photoshop to get Bridge to print the given file // online using OLS. //================================================================= photoshop9.printOnlineViaBridge = function (path, newWindow, maximize) { // Bring Bridge to the foreground. if (BridgeTalk.isRunning ('bridge')) BridgeTalk.bringToFront ("bridge"); // Use the standard invoke Bridge message, but preceed it with additional // code to get OLS called. var bt = photoshop9.getInvokeBridgeMessage (newWindow, maximize, path); // The code already in the BridgeTalk body message will select the file, but // this happens asynchronously. Sometimes, particularly if Bridge is not // already launched when we send this message, just calling OLS right away // will fail. So, we install an event handler that will call OLS when the // selection is about to be made. At this point the thumbnail should be // sufficiently loaded for OLS to use. var callOnlineServicesPrintOnline = function (event) { // Run on Thumbnail select if (event.object.constructor.name == 'Thumbnail' && event.type == 'select') { // Remove this handler so it doesn't get called again. Do before the // work of the handler incase that work triggers another of these events. for (var index = 0; index < app.eventHandlers.length; index++) { if (app.eventHandlers[index] == this) { app.eventHandlers[index] = null; break; } } // Pass in an array containing the Thumbnail object for the file // being printed because app.document.selections will not be updated // until after this handler exits. onlineservices.printOnline (new Array (event.object)); } // Return false so Bridge will keep calling other event handlers. return { handled: false }; } // First make sure nothing is selected (incase the file being printed was already // selected), then install the handler. After that, run the code that tells Bridge // to go select the given file (already in bt.body). bt.body = 'var callOnlineServicesPrintOnline = ' + callOnlineServicesPrintOnline.toString () + 'if (app.documents.length > 0)' + ' app.document.deselectAll ();' + 'app.eventHandlers.push ({handler: callOnlineServicesPrintOnline});' + bt.body; bt.send (); } //================================================================= // Place // Sets up Place in Photoshop command in Bridge's Place menu. //================================================================= //----------------------------------------------------------------- // Performs the equivalent of the File->Place // command on the requested file. //----------------------------------------------------------------- photoshop9.place = function (file) { try { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // open. var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.place (" + file.toSource () + ");"; btMessage.send(); } else { // This is Photoshop, so just call our DOM routine with the files if (app.documents.length > 0) { var fileArray = photoshop9.ExtractFileArray (file); if (fileArray.length > 0) { var theFile = fileArray[0]; // Set up generic placement information. var offsetID = stringIDToTypeID ('offset'); var horizID = stringIDToTypeID ('horizontal'); var vertID = stringIDToTypeID ('vertical'); var distUnitID = stringIDToTypeID ('distanceUnit'); var offsetDesc = new ActionDescriptor (); offsetDesc.putUnitDouble (horizID, distUnitID, 0.000000); offsetDesc.putUnitDouble (vertID, distUnitID, 0.000000); var nullID = charIDToTypeID ('null'); var ftcenterID = stringIDToTypeID ('freeTransformCenterState'); var quadCenterID = stringIDToTypeID ('quadCenterState'); var avgID = stringIDToTypeID ('QCSAverage'); var placeInfoDesc = new ActionDescriptor (); placeInfoDesc.putEnumerated (ftcenterID, quadCenterID, avgID); placeInfoDesc.putObject (offsetID, offsetID, offsetDesc); // Set up the file. placeInfoDesc.putPath (nullID, theFile); // Suppress choose file dialog. var overrideOpenID = stringIDToTypeID ('overrideOpen'); placeInfoDesc.putBoolean (overrideOpenID, true); // Force it to record. var forceRecordKey = stringIDToTypeID ('forceRecording'); placeInfoDesc.putBoolean (forceRecordKey, true); // Do the Place. var placeID = stringIDToTypeID ('placeEvent'); executeAction (placeID, placeInfoDesc, DialogModes.ALL); } if (fileArray.length > 1) alert (localize ("$$$/PSBI/Place/OnlyFirstFile=Only the first file was placed.")); } else alert (localize ("$$$/PSBI/Place/NoDoc=There is no document to place into.")); } } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // The code below inserts the Place in Photoshop menu item into the // place menu and sets up the onSelect and onDisplay routines for // it. //----------------------------------------------------------------- if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // insert a new PDF Presentation menu item into the Place submenu. var placeMenuItem = MenuElement.create ("command", localize ("$$$/PSBI/Menu/Place/InPhotoshop=In Photoshop"), 'at the end of submenu/Place', 'PlaceInPhotoshop'); placeMenuItem.onDisplay = function () { this.enabled = false; if (BridgeTalk.isRunning ('photoshop') && (app.document != undefined) && (app.document.selections.length == 1)) { if (!app.document.selections[0].container) this.enabled = true; } } placeMenuItem.onSelect = function () { try { if ((app.document.selections.length == 1) && !app.document.selections[0].container) { var thumb = app.document.selections[0]; app.preflightFiles (Array (thumb.path)); photoshop9.place (thumb.spec); } else Window.alert (localize ("$$$/PSBI/Place/SelectOneFile=Please select a single file.")); } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } } photoshop9.tempFunction (); delete photoshop9.tempFunction; } //================================================================= // PDF Presentation // Sets up Photoshop's PDF Presentation automation command to be // accessed from the Bridge. //================================================================= //----------------------------------------------------------------- // This routine takes an array of files. If called by Photoshop, // it will invoke PDF Presentation with the files. If called by // any other app, it will send a BridgeTalk message to Photoshop // to invoke this routine with the same arguments. //----------------------------------------------------------------- photoshop9.pdfPresentation = function (/* Array */ files) { try { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // PDF Presentation with the selected files var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.pdfPresentation (" + files.toSource () + ");"; btMessage.send(); } else { photoshop9.runActionCommand ('PDFExport', files); } } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // This routine is called when the Bridge's PDF Presentation menu // item is chosen. //----------------------------------------------------------------- photoshop9.pdfPresentationFromBridge = function () { try { var files = photoshop9.getBridgeFileListForAutomateCommand (false); if (files.length != 0) photoshop9.pdfPresentation (files); } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // The code below inserts the PDF Presentation menu item into the // Bridge menus. //----------------------------------------------------------------- if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // Set up the info necessary for inserting this item into the Bridge's menus later. var menuItemInfo = new Object; menuItemInfo.text = localize ("$$$/PSBI/Menu/Automate/PDFPres=PDF Presentation..."); menuItemInfo.name = 'PdfPresentation'; menuItemInfo.onDisplay = photoshop9.alwaysEnabled; menuItemInfo.onSelect = photoshop9.pdfPresentationFromBridge; photoshop9.menuItemInfoArray.push (menuItemInfo); } photoshop9.tempFunction (); delete photoshop9.tempFunction; } //================================================================= // Photomerge // Sets up Photoshop's Photomerge automation command to be // accessed from the Bridge. //================================================================= //----------------------------------------------------------------- // This routine takes an array of files. If called by Photoshop, // it will invoke Photomerge with the files. If called by // any other app, it will send a BridgeTalk message to Photoshop // to invoke this routine with the same arguments. //----------------------------------------------------------------- photoshop9.photomerge = function (/* Array */ files) { try { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // Photomerge with the selected files var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.photomerge (" + files.toSource () + ");"; btMessage.send (); } else { photoshop9.runActionCommand ('AdobePhotomerge0001', files); } } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // This routine is called when the Bridge's Photomerge menu item is // chosen. //----------------------------------------------------------------- photoshop9.photomergeFromBridge = function () { try { var files = photoshop9.getBridgeFileListForAutomateCommand (true); if (files.length != 0) photoshop9.photomerge (files); } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // The code below inserts the Photomerge menu item into the // Bridge menus. //----------------------------------------------------------------- if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // Set up the info necessary for inserting this item into the Bridge's menus later. var menuItemInfo = new Object; menuItemInfo.text = localize ("$$$/PSBI/Menu/Automate/Photomerge=Photomerge..."); menuItemInfo.name = 'Photomerge'; menuItemInfo.onDisplay = photoshop9.alwaysEnabled; menuItemInfo.onSelect = photoshop9.photomergeFromBridge; photoshop9.menuItemInfoArray.push (menuItemInfo); } photoshop9.tempFunction (); delete photoshop9.tempFunction; } //================================================================= // Contact Sheet // Sets up Photoshop's Contact Sheet automation command to be // accessed from the Bridge. //================================================================= //----------------------------------------------------------------- // This routine takes an array of files. If called by Photoshop, // it will invoke Contact Sheet with the files. If called by // any other app, it will send a BridgeTalk message to Photoshop // to invoke this routine with the same arguments. //----------------------------------------------------------------- photoshop9.contactSheet = function (/* Array */ files) { try { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // Contact Sheet with the selected files var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.contactSheet (" + files.toSource () + ");"; btMessage.send (); } else { photoshop9.runActionCommand ('0B71D221-F8CE-11d2-B21B-0008C75B322C', files); } } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // This routine is called when the Bridge's Contact Sheet menu item // is chosen. //----------------------------------------------------------------- photoshop9.contactSheetFromBridge = function () { try { var files = photoshop9.getBridgeFileListForAutomateCommand (false); if (files.length != 0) photoshop9.contactSheet (files); } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // The code below inserts the Contact Sheet menu item into the // Bridge menus. //----------------------------------------------------------------- if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // Set up the info necessary for inserting this item into the Bridge's menus later. var menuItemInfo = new Object; menuItemInfo.text = localize ("$$$/PSBI/Menu/Automate/ContactSheet=Contact Sheet II..."); menuItemInfo.name = 'ContactSheet'; menuItemInfo.onDisplay = photoshop9.alwaysEnabled; menuItemInfo.onSelect = photoshop9.contactSheetFromBridge; photoshop9.menuItemInfoArray.push (menuItemInfo); } photoshop9.tempFunction (); delete photoshop9.tempFunction; } //================================================================= // Picture Package // Sets up Photoshop's Picture Package automation command to be // accessed from the Bridge. //================================================================= //----------------------------------------------------------------- // This routine takes an array of files. If called by Photoshop, // it will invoke Picture Package with the files. If called by // any other app, it will send a BridgeTalk message to Photoshop // to invoke this routine with the same arguments. //----------------------------------------------------------------- photoshop9.picturePackage = function (/* Array */ files) { try { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // Picture Package with the selected files var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.picturePackage (" + files.toSource () + ");"; btMessage.send (); } else { photoshop9.runActionCommand ('4C1ABF40-DD82-11d2-B20F-0008C75B322C', files); } } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // This routine is called when the Bridge's Picture Package menu // item is chosen. //----------------------------------------------------------------- photoshop9.picturePackageFromBridge = function () { try { var files = photoshop9.getBridgeFileListForAutomateCommand (false); if (files.length != 0) photoshop9.picturePackage (files); } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // The code below inserts the PicturePackage menu item into the // Bridge menus. //----------------------------------------------------------------- if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // Set up the info necessary for inserting this item into the Bridge's menus later. var menuItemInfo = new Object; menuItemInfo.text = localize ("$$$/PSBI/Menu/Automate/PicturePackage=Picture Package..."); menuItemInfo.name = 'PicturePackage'; menuItemInfo.onDisplay = photoshop9.alwaysEnabled; menuItemInfo.onSelect = photoshop9.picturePackageFromBridge; photoshop9.menuItemInfoArray.push (menuItemInfo); } photoshop9.tempFunction (); delete photoshop9.tempFunction; } //================================================================= // Batch // Sets up Photoshop's Batch automation command to be // accessed from the Bridge. //================================================================= //----------------------------------------------------------------- // This routine takes an array of files. If called by Photoshop, // it will invoke Batch with the files. If called by // any other app, it will send a BridgeTalk message to Photoshop // to invoke this routine with the same arguments. //----------------------------------------------------------------- photoshop9.batch = function (/* Array */ files) { try { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // Batch with the selected files var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.batch (" + files.toSource () + ");"; btMessage.send (); } else { photoshop9.runActionCommand ('batch', files, localize ("$$$/PSBI/Automate/BatchSettingsFile=Batch via Bridge Settings")); } } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // This routine is called when the Bridge's Batch menu item is // chosen. //----------------------------------------------------------------- photoshop9.batchFromBridge = function () { try { var files = photoshop9.getBridgeFileListForAutomateCommand (false); if (files.length != 0) photoshop9.batch (files); } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // The code below inserts the Batch menu item into the Bridge menus. //----------------------------------------------------------------- if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // Set up the info necessary for inserting this item into the Bridge's menus later. var menuItemInfo = new Object; menuItemInfo.text = localize ("$$$/PSBI/Menu/Automate/Batch=Batch..."); menuItemInfo.name = 'Batch'; menuItemInfo.onDisplay = photoshop9.alwaysEnabled; menuItemInfo.onSelect = photoshop9.batchFromBridge; photoshop9.menuItemInfoArray.push (menuItemInfo); } photoshop9.tempFunction (); delete photoshop9.tempFunction; } //================================================================= // Web Photo Gallery // Sets up Photoshop's Web Photo Gallery automation command to be // accessed from the Bridge. //================================================================= //----------------------------------------------------------------- // This routine takes an array of files. If called by Photoshop, // it will invoke Web Photo Gallery with the files. If called by // any other app, it will send a BridgeTalk message to Photoshop // to invoke this routine with the same arguments. //----------------------------------------------------------------- photoshop9.webPhotoGallery = function (files) { try { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // Web Photo Gallery with the selected files var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.webPhotoGallery (" + files.toSource () + ");"; btMessage.send (); } else { photoshop9.runActionCommand ('4C1ABF41-DD82-11d2-B20F-0008C75B322C', files); } } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // This routine is called when the Bridge's Web Photo Gallery menu // item is chosen. //----------------------------------------------------------------- photoshop9.webPhotoGalleryFromBridge = function () { try { var files = photoshop9.getBridgeFileListForAutomateCommand (false); if (files.length != 0) photoshop9.webPhotoGallery (files); } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // The code below inserts the Web Photo Gallery menu item into the // Bridge menus. //----------------------------------------------------------------- if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // Set up the info necessary for inserting this item into the Bridge's menus later. var menuItemInfo = new Object; menuItemInfo.text = localize ("$$$/PSBI/Menu/Automate/WPG=Web Photo Gallery..."); menuItemInfo.name = 'WebPhotoGallery'; menuItemInfo.onDisplay = photoshop9.alwaysEnabled; menuItemInfo.onSelect = photoshop9.webPhotoGalleryFromBridge; photoshop9.menuItemInfoArray.push (menuItemInfo); } photoshop9.tempFunction (); delete photoshop9.tempFunction; } //================================================================= // Merge to HDR // Sets up Photoshop's Merge to HDR automation command to be // accessed from the Bridge. //================================================================= //----------------------------------------------------------------- // This routine takes an array of files. If called by Photoshop, // it will invoke Merge to HDR with the files. If called by // any other app, it will send a BridgeTalk message to Photoshop // to invoke this routine with the same arguments. //----------------------------------------------------------------- photoshop9.mergeToHDR = function (files) { try { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // Merge to HDR with the selected files var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.mergeToHDR (" + files.toSource () + ");"; btMessage.send (); } else { photoshop9.runActionCommand ('AdobeExposuremerge', files); } } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // This routine is called when the Bridge's Merge to HDR menu // item is chosen. //----------------------------------------------------------------- photoshop9.mergeToHDRFromBridge = function () { try { var files = photoshop9.getBridgeFileListForAutomateCommand (true); if (files.length != 0) photoshop9.mergeToHDR (files); } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // The code below inserts the Merge to HDR menu item into the // Bridge menus. //----------------------------------------------------------------- if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // Set up the info necessary for inserting this item into the Bridge's menus later. var menuItemInfo = new Object; menuItemInfo.text = localize ("$$$/PSBI/Menu/Automate/MergeToHDR=Merge to HDR..."); menuItemInfo.name = 'MergeToHDR'; menuItemInfo.onDisplay = photoshop9.alwaysEnabled; menuItemInfo.onSelect = photoshop9.mergeToHDRFromBridge; photoshop9.menuItemInfoArray.push (menuItemInfo); } photoshop9.tempFunction (); delete photoshop9.tempFunction; } //================================================================= // ImageProcessor // Sets up Photoshop's Image Processor JavaScript to be // accessed from the Bridge. //================================================================= //----------------------------------------------------------------- // This routine takes an array of files. If called by Photoshop, // it will invoke Image Processor with the files. If called by // any other app, it will send a BridgeTalk message to Photoshop // to invoke this routine with the same arguments. //----------------------------------------------------------------- photoshop9.imageprocessor = function (files) { try { if (BridgeTalk.appName != "photoshop") { // Bring Photoshop to the foreground. BridgeTalk.bringToFront ("photoshop"); // Create a new BridgeTalk message for Photoshop to invoke // Image Processor with the selected files var btMessage = new BridgeTalk; btMessage.target = "photoshop"; btMessage.body = "photoshop9.imageprocessor (" + files.toSource () + ");"; btMessage.send (); } else { // Image Processor script will recognize this and use it var gFilesFromBridge = files; var strPresets = localize ("$$$/ApplicationPresetsFolder/Presets=Presets"); var strScripts = localize ("$$$/PSBI/Automate/ImageProcessor/Photoshop/Scripts=Scripts"); var strImageProcessor = localize ("$$$/PSBI/Automate/ImageProcessor/Photoshop/FileName=Image Processor.jsx"); var ipFile = new File (app.path + "/" + strPresets + "/" + strScripts + "/" + strImageProcessor); var rememberDialogModes = displayDialogs; displayDialogs = DialogModes.ALL; if (ipFile.exists) { if (ipFile.open ('r')) { var script = ipFile.read (); ipFile.close (); eval (script); } else alert (localize ("$$$/PSBI/Automate/ImageProcessor/CouldNotOpen=Image Processor.jsx could not be opened.")); } else alert (localize ("$$$/PSBI/Automate/ImageProcessor/NotFound=Image Processor.jsx could not be found.")); displayDialogs = rememberDialogModes; } } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // This routine is called when the Bridge's Image Processor menu // item is chosen. //----------------------------------------------------------------- photoshop9.imageprocessorFromBridge = function () { try { var files = photoshop9.getBridgeFileListForAutomateCommand (false); if (files.length != 0) photoshop9.imageprocessor (files); } catch (error) { if (error.number != 8007) // Don't report user cancelled errors. alert (error); } } //----------------------------------------------------------------- // The code below inserts the Image Processor menu item into the // Bridge menus. //----------------------------------------------------------------- if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // Set up the info necessary for inserting this item into the Bridge's menus later. var menuItemInfo = new Object; menuItemInfo.text = localize ("$$$/PSBI/Menu/Automate/ImageProcessor=Image Processor..."); menuItemInfo.name = 'ImageProcessor'; menuItemInfo.onDisplay = photoshop9.alwaysEnabled; menuItemInfo.onSelect = photoshop9.imageprocessorFromBridge; photoshop9.menuItemInfoArray.push (menuItemInfo); } photoshop9.tempFunction (); delete photoshop9.tempFunction; } //================================================================= // Setup Tools > Photoshop menu in Bridge. // Creates the menu, then sorts all the menu items we want to // create before actually adding them to the menu. //================================================================= if (BridgeTalk.appName == "bridge") { // Use temp function to keep vars out of global namespace. photoshop9.tempFunction = function () { // The 'Photoshop Services' menu is installed by OLS, the 'Photoshop' menu // in installed either by this script, or by the Workflow Automation Scripts // (AdobeLibrary1.jsx) which also install menus for other apps. To get the // menus in the correct order, all three scripts cooperate - so make sure // you are aware of what's happening before changing this code. var psServicesMenuExists = MenuElement.find ('Tools/PhotoshopServices') != null; // Add a new Photoshop submenu in the Bridge's Tools menu. photoshopSubMenu = MenuElement.create ( "menu", localize ("$$$/PhotoshopJSX/Menu/Photoshop=Photoshop"), psServicesMenuExists ? "-after Tools/PhotoshopServices" : '-after submenu/VersionCue', 'tools/ps'); photoshopSubMenu.onDisplay = photoshop9.alwaysEnabled; // Define a function that will sort the menu items for us. function menuTextOrder (a, b) { // Pass 'a' into 'b' to get reverse sort order so that they can be // added at the top of the menu and still be in alphabetical order // (the WAS scripts install additional menu items that end up below // these). return b.text.toLocaleLowerCase ().localeCompare (a.text.toLocaleLowerCase ()); } // Sort the menu items photoshop9.menuItemInfoArray.sort (menuTextOrder); // Add the menu items to the Photoshop menu. for (var index = 0; index < photoshop9.menuItemInfoArray.length; index++) { var menuItemInfo = photoshop9.menuItemInfoArray[index]; var menuItem = MenuElement.create ( 'command', menuItemInfo.text, 'at the beginning of tools/ps', menuItemInfo.name); menuItem.onDisplay = menuItemInfo.onDisplay; menuItem.onSelect = menuItemInfo.onSelect; } delete photoshop9.menuItemInfoArray; } photoshop9.tempFunction (); delete photoshop9.tempFunction; } } // Overall try catch catch (e) { // Debugging //alert (e); }