• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to save in other formats?? Automate/Scripts Question (CS6)

Explorer ,
Oct 14, 2022 Oct 14, 2022

Copy link to clipboard

Copied

I am trying to batch edit and export using automate/scripts.

 

When I go through the automate function, there is no slide down menu where I can select the different file types. Instead, there are three rows of two adjacent bars that I am supposed to use to name my document. The bars are prompts that double as drop down menus, and here there are two options that catch the eye: "EXTENSION" in all caps and "extension"in lowercase letters. I click on one, and it automatically decides for me that it is in the gif format I am going to be saving my file. I tried manually typing in ".png" (because I wanted to save in png) but in trying to proceed the notification pop up kept telling me to specify an extension, so I am guessing that is not how it's done.

 

In scripts, on the other hand, I am given a much more intuitive interface to work with. Three checkboxes, enabling me to choose among the jpg, psd, and tiff formats. The issue here was the absence of a png option.

 

Can I recieve some help with understanding how to work this thing?

 

TOPICS
Actions and scripting , macOS

Views

1.6K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Oct 15, 2022 Oct 15, 2022

You just need to use extension or EXTENSION - not the actual extension, Batch knows that the format is PNG, just ignore the .GIF it is just an example.

 

batch-action-png.png

 

https://helpx.adobe.com/au/photoshop/using/processing-batch-files.html#process_a_batch_of_files

 

Votes

Translate

Translate
Adobe
Community Expert ,
Oct 15, 2022 Oct 15, 2022

Copy link to clipboard

Copied

The first option sounds like File > Automate > Batch

 

This interface batches an Action, the Action would include the file format options.

 

The second option you mentioned is Image Processor, which as you say doesn't include the PNG option.

 

 I'll post links for other alternatives later (Image Processor Pro and others).

 

EDIT: Here are the links to various scripts:

 

Image Processor Pro:

https://sourceforge.net/projects/ps-scripts/files/Image%20Processor%20Pro/


Picture Processor:

https://github.com/Paul-Riggott/PS-Scripts/blob/master/Picture%20Processor.jsx


Raw Image Converter (a reworking of Image Processor, with PNG saving):

https://github.com/SetTrend/Raw-Image-Converter


Batch Multi Save:

https://www.marspremedia.com/software/photoshop/batch-multi-save

 

Info on saving/downloading/installing:

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

As you use CS6, these scripts may or may not work in such an old version.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 15, 2022 Oct 15, 2022

Copy link to clipboard

Copied

Thank you so much for the reply!

How would I get the action to include file format options? Does this mean I need to record the steps I would take to save the file in the action as well to begin with?

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 15, 2022 Oct 15, 2022

Copy link to clipboard

Copied

Annotation 2022-10-15 174337.pngunnamed.png

 

I included saving it as a png in the action but I don't think it is working

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 15, 2022 Oct 15, 2022

Copy link to clipboard

Copied

You just need to use extension or EXTENSION - not the actual extension, Batch knows that the format is PNG, just ignore the .GIF it is just an example.

 

batch-action-png.png

 

https://helpx.adobe.com/au/photoshop/using/processing-batch-files.html#process_a_batch_of_files

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 15, 2022 Oct 15, 2022

Copy link to clipboard

Copied

The late Mike Hale modified the Image Processor script, however, when the PS-SCRIPTS site went down and was later resurrected, it appears that the attachment was lost.

 

https://www.ps-scripts.com/viewtopic.php?f=51&t=10225&p=54270&hilit=Image+Processor+with+PNG+support...

 

Perhaps somebody has a copy?

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

Copied

I'll check it out, thank you so much!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

Copied

Sadly, nothing to see...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

Copied

This one?

// 06/18/2008 09:00
// c2007 Adobe Systems, Inc. All rights reserved.
// Produced and Directed by Dr. Brown ( a.k.a Russell Preston Brown )
// Written by Tom Ruark
// UI Design by Julie Meridian
// Added PNG-24 support 11/10/2009 by Mike Hale
// Added support for CMYK JPEG
/*
@@@BUILDINFO@@@ Image Processor.jsx 1.0.0.24
*/

/*

// BEGIN__HARVEST_EXCEPTION_ZSTRING

<javascriptresource>
<name>$$$/JavaScripts/ImageProcessor/Menu=Image Processor...</name>
<category>aaaThisPutsMeAtTheTopOfTheMenu</category>
</javascriptresource>

// END__HARVEST_EXCEPTION_ZSTRING

*/

// enable double clicking from the Macintosh Finder or the Windows Explorer
#target photoshop

// debug level: 0-2 (0:disable, 1:break on error, 2:break at beginning)
// $.level = 1;
// debugger; // launch debugger on next line

// on localized builds we pull the $$$/Strings from a .dat file, see documentation for more details
$.localize = true;

// the main routine
// the ImageProcessor object does most of the work
try { 

	GlobalVariables();

	CheckVersion();
	
	if ( IsWindowsOS() ) {
		gShortFileNameLength = gShortFileNameLengthWin;
	}

	var gIP = new ImageProcessor();

	gIP.LoadParamsFromDisk( GetDefaultParamsFile() );

	gIP.CreateDialog();
	
	if ( gRunButtonID == gIP.RunDialog() ) {

		gIP.Execute();
		
		gIP.SaveParamsToDisk( GetDefaultParamsFile() );
	} else {
       	gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
	}
	
	gIP.ReportErrors();
	
	$.gc(); // fix crash on quit
}

// Lot's of things can go wrong
// Give a generic alert and see if they want the details
catch( e ) {
	if ( e.number != 8007 ) { // don't report error on user cancel
		if ( confirm( strSorry ) ) {
			alert( e + " : " + e.line );
		}
	}
   	gScriptResult = 'cancel'; // quit, returning 'cancel' (dont localize) makes the actions palette not record our script
}

// restore the dialog modes
app.displayDialogs = gSaveDialogMode;

// must be the last thing
gScriptResult; 

//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////
// Function: GlobalVariables
// Usage: all of my globals
// Input: <none>
// Return: <none>
///////////////////////////////////////////////////////////////////////////////
function GlobalVariables() {

	// a version for possible expansion issues
	gVersion = 1;
	
	gScriptResult = undefined;

	// ok and cancel button
	gRunButtonID = 1;
	gCancelButtonID = 2;
	gMaxResizeTIFF = 300000;
	gMaxResize = 30000;

	// A list of file extensions and types PS can read
	gFileExtensionsToRead = app.windowsFileTypes;
	gFileTypesToRead = app.macintoshFileTypes;

	// A list of camera raw extensions, keep them upper case
	gFilesForCameraRaw = Array( "TIF", "CRW", "NEF", "RAF", "ORF", "MRW", "DCR", "MOS", "SRF", "PEF", "DCR", "CR2", "DNG", "ERF", "X3F", "RAW" );

	// limit the length of text in edit boxes by this length
	// this needs to be calculated on the fly!
	// the problem is we have non mono space fonts! 
	// 10 iiiiiiiiii != 10 MMMMMMMMMM 
	gShortFileNameLengthWin = 35;
	gShortFileNameLengthMac = 27;
	gShortFileNameLength = gShortFileNameLengthMac;

	// remember the dialog modes
	gSaveDialogMode = app.displayDialogs;
	app.displayDialogs = DialogModes.NO;

	gClassActionSet = charIDToTypeID( 'ASet' );
	gClassAction = charIDToTypeID( 'Actn' );
	gKeyName = charIDToTypeID( 'Nm  ' );
	gKeyNumberOfChildren = charIDToTypeID( 'NmbC' );
	
	gOpenedFirstCR = false;
	gFoundFileToProcess = false;

	// all the strings that need localized
	// Set this string to private since we don't localize 'Presets' folder in CS4
	// strPresets = localize( "$$$/Private/JavaScripts/ImageProcessor/Presets=Presets" );
	strTitle = localize( "$$$/JavaScript/ImageProcessor/Title=Image Processor" );
	strLabelSource = localize( "$$$/JavaScripts/ImageProcessor/Source=Select the images to process" );
	strNoImagesSelected = localize( "$$$/JavaScripts/ImageProcessor/NoImagesSelected=No images have been selected" );
	strNoFolderSelected = localize( "$$$/JavaScripts/ImageProcessor/NoFolderSelected=No folder has been selected" );
	strLabelSourceHelp = localize( "$$$/JavaScripts/ImageProcessor/SourceHelp=Location of files to process" );
	strLabelDestination = localize( "$$$/JavaScripts/ImageProcessor/Destination=Select location to save processed images" );
	strSaveInSameLocation = localize( "$$$/JavaScripts/ImageProcessor/SaveInSameLocation=S&ave in Same Location" );
	strSaveInSameLocationHelp = localize( "$$$/JavaScripts/ImageProcessor/SaveInSameLocationHelp=Save the new documents next to the original documents" );
	strUseOpen = localize( "$$$/JavaScripts/ImageProcessor/UseOpen=Use Open &Images" );
	strUseOpenHelp = localize( "$$$/JavaScripts/ImageProcessor/UseOpenHelp=Use the images that are currently open" );
	strButtonBrowse1 = localize( "$$$/JavaScripts/ImageProcessor/Browse1=Select &Folder..." );
	strButtonBrowse2 = localize( "$$$/JavaScripts/ImageProcessor/Browse2=Sele&ct Folder..." );
	strButtonRun = localize( "$$$/JavaScripts/ImageProcessor/Run=Run" );
	strOpenFirst = localize( "$$$/JavaScripts/ImageProcessor/OpenFirst=&Open first image to apply settings" );
	strOpenFirstHelp = localize( "$$$/JavaScripts/ImageProcessor/OpenFirstHelp=Show the Camera RAW dialog on the first image to apply settings" );
	strBridge = localize( "$$$/JavaScripts/ImageProcessor/Bridge=Process files from Bridge only" );
	strBridgeHelp = localize( "$$$/JavaScripts/ImageProcessor/BridgeHelp=Selected files from Bridge will be processed" );
	strButtonCancel = localize("$$$/JavaScripts/ImageProcessor/Cancel=Cancel");
	strButtonLoad = localize("$$$/JavaScripts/ImageProcessor/Load=&Load...");
	strButtonLoadHelp = localize("$$$/JavaScripts/ImageProcessor/LoadHelp=Load a settings file from disk");
	strButtonSave = localize("$$$/JavaScripts/ImageProcessor/Save=&Save...");
	strButtonSaveHelp = localize("$$$/JavaScripts/ImageProcessor/SaveHelp=Save the current dialog settings to disk");
	strICC = localize( "$$$/JavaScripts/ImageProcessor/ICC=Inclu&de ICC Profile" );
	strICCHelp = localize( "$$$/JavaScripts/ImageProcessor/ICCHelp=Include the ICC Profile when saving the file" );
	strFileType = localize( "$$$/JavaScripts/ImageProcessor/FileType=File Type" );
	strPreferences = localize( "$$$/JavaScripts/ImageProcessor/Preferences=Preferences" );
	strRunAction = localize( "$$$/JavaScripts/ImageProcessor/RunAction=R&un Action:" );
	strActionHelp = localize( "$$$/JavaScript/ImageProcessor/ActionHelp=Select an action set and an action" );
	strSaveAsJPEG = localize( "$$$/JavaScripts/ImageProcessor/SaveAsJPEG=Save as &JPEG" );
	strSaveAsJPEGHelp = localize( "$$$/JavaScripts/ImageProcessor/SaveAsJPEGHelp=Save a file to the JPEG format" );
	strQuality = localize( "$$$/JavaScripts/ImageProcessor/Quality=Quality:" );
	strConvertICC = localize( "$$$/JavaScripts/ImageProcessor/Convert=Con&vert Profile to sRGB" );
	strConvertICCHelp = localize( "$$$/JavaScripts/ImageProcessor/ConvertHelp=Convert the ICC profile to sRGB before saving" );
	strResizeToFit1 = localize( "$$$/JavaScripts/ImageProcessor/ResizeToFit1=&Resize to Fit" );
	strResizeToFit2 = localize( "$$$/JavaScripts/ImageProcessor/ResizeToFit2=R&esize to Fit" );
	strResizeToFit3 = localize( "$$$/JavaScripts/ImageProcessor/ResizeToFit3=Resi&ze to Fit" );
	strResizeToFitHelp = localize( "$$$/JavaScripts/ImageProcessor/ResizeToFitHelp=Select to resize for this format" );
	strSaveAsPSD = localize( "$$$/JavaScripts/ImageProcessor/SaveAsPSD=Save as &PSD" );
	strSaveAsPSDHelp = localize( "$$$/JavaScripts/ImageProcessor/SaveAsPSDHelp=Save a file to the PSD format" );
	strMaximize = localize( "$$$/JavaScripts/ImageProcessor/Maximize=&Maximize Compatibility" );
	strMaximizeHelp = localize( "$$$/JavaScripts/ImageProcessor/MaximizeHelp=Maximize compatibility when saving to PSD format" );
	strSaveAsTIFF = localize( "$$$/JavaScripts/ImageProcessor/SaveAsTIFF=Save as &TIFF" );
	strSaveAsTIFFHelp = localize( "$$$/JavaScripts/ImageProcessor/SaveAsTIFFHelp=Save a file to the TIFF format" );
	strLZW = localize( "$$$/JavaScripts/ImageProcessor/LZW=LZ&W Compression" );
	strLZWHelp = localize( "$$$/JavaScripts/ImageProcessor/LZWHelp=Use LZW compression when saving in TIFF format" );
	strCopyright = localize( "$$$/JavaScripts/ImageProcessor/Copyright=Copyright Info:" );
	strCopyrightHelp = localize( "$$$/JavaScripts/ImageProcessor/CopyrightHelp=Add copyright metadata to your images" );
	strW = localize( "$$$/JavaScripts/ImageProcessor/W=W:" );
	strWHelp = localize( "$$$/JavaScripts/ImageProcessor/WHelp=Type in a width to resize image" );
	strH = localize( "$$$/JavaScripts/ImageProcessor/H=H:" );
	strHHelp = localize( "$$$/JavaScripts/ImageProcessor/HHelp=Type in a height to resize image" );
	strPX = localize( "$$$/JavaScripts/ImageProcessor/PX=px" );
	strPresets = localize( "$$$/Private/JavaScripts/ImageProcessor/Presets=Presets" );
	strPickXML = localize( "$$$/JavaScripts/ImageProcessor/PickXML=Pick an XML file to load" );
	strPickXMLWin = localize( "$$$/JavaScripts/ImageProcessor/PickXMLWin=XML Files: *.xml" );
	strPickXMLSave = localize( "$$$/JavaScripts/ImageProcessor/PickXMLSave=Pick an XML file to save" );
	strPickSource = localize( "$$$/JavaScripts/ImageProcessor/PickSource=Pick a source folder" );
	strPickDest = localize( "$$$/JavaScripts/ImageProcessor/PickDest=Pick a destination folder" );
	strSpecifySource = localize( "$$$/JavaScripts/ImageProcessor/SpecifySource=Please specify a source folder." );
	strSpecifyDest = localize( "$$$/JavaScripts/ImageProcessor/SpecifyDest=Please specify a destination folder." );
	strJPEGQuality = localize( "$$$/JavaScripts/ImageProcessor/JPEGQuality=JPEG Quality must be between 0 and 12." );
	strJPEGWandH = localize( "$$$/JavaScripts/ImageProcessor/JPEGWandH=You must specify width and height when using resize image options for JPEG." );
	strTIFFWandH = localize( "$$$/JavaScripts/ImageProcessor/TIFFWandH=You must specify width and height when using resize image options for TIFF." );
	strPSDWandH = localize( "$$$/JavaScripts/ImageProcessor/PSDWandH=You must specify width and height when using resize image options for PSD." );
	strOneType = localize( "$$$/JavaScripts/ImageProcessor/OneType=You must save to at least one file type." );
	strWidthAndHeight = localize( "$$$/JavaScripts/ImageProcessor/WidthAndHeight=Width and Height must be defined to use FitImage function!" );
	strMustUse = localize( "$$$/JavaScripts/ImageProcessor/MustUse=You must use Photoshop CS 2 or later to run this script!" );
	strSorry = localize( "$$$/JavaScripts/ImageProcessor/Sorry=Sorry, something major happened and I can't continue! Would you like to see more info?" );
	strCouldNotProcess = localize( "$$$/JavaScripts/ImageProcessor/CouldNotProcess=Sorry, I could not process the following files:\r" );
	strMustSaveOpen = localize( "$$$/JavaScripts/ImageProcessor/MustSaveOpen=Open files must be saved before they can be used by the Image Processor." );
	strFollowing = localize( "$$$/JavaScripts/ImageProcessor/Following=The following files will not be saved." );
	strNoOpenableFiles = localize( "$$$/JavaScripts/ImageProcessor/NoOpenableFiles=There were no source files that could be opened by Photoshop." );
	strCannotWriteToFolder = localize( "$$$/JavaScripts/ImageProcessor/CannotWriteToFolder=I am unable to create a file in this folder. Please check your access rights to this location " );
	strKeepStructure = localize( "$$$/JavaScripts/ImageProcessor/KeepStructure=Keep folder structure" );
	strIncludeAllSubfolders = localize( "$$$/JavaScripts/ImageProcessor/IncludeAll=Include All sub-folders" );
	strIncludeAllSubfoldersHelp =  localize( "$$$/JavaScripts/ImageProcessor/IncludeAllHelp=Process all the folders within the source folder" );
	
	// some strings that need localized to define the preferred sizes of items for different languages
	strwAndhEtLength = localize( "$$$/locale_specific/JavaScripts/ImageProcessor/EditTextWandHLength=40" );
	strqEtLength = localize( "$$$/locale_specific/JavaScripts/ImageProcessor/QEditTextLength=30" );
	strsourceAndDestLength = localize( "$$$/locale_specific/JavaScripts/ImageProcessor/SourceAndDestLength=210" );
	stractionDropDownLength = localize( "$$$/locale_specific/JavaScripts/ImageProcessor/ActionDropDownLength=140" );
	
	// PNG strings
	strSaveAsPNG = localize( "$$$/JavaScripts/ImageProcessor/SaveAsPNG=Save as &PNG" );
	strSaveAsPNGHelp = localize( "$$$/JavaScripts/ImageProcessor/SaveAsPNGHelp=Save a file to the PNG-24 format" );
	strPNGWandH = localize( "$$$/JavaScripts/ImageProcessor/PNGWandH=You must specify width and height when using resize image options for PNG." );
	strInterlace = localize( "$$$/JavaScripts/ImageProcessor/Interlace=Interlace" );
	strInterlaceHelp = localize( "$$$/JavaScripts/ImageProcessor/InterlaceHelp=Interlace rows" );
	// overwrite icc help string 
	strConvertICCHelp = localize( "$$$/JavaScripts/ImageProcessor/ConvertICCHelp=Convert the ICC profile for RGB files to sRGB before saving" );

	
	// CMYK JPEG
	strKeepCMYK = localize( "$$$/JavaScripts/ImageProcessor/KeepCMYK=Keep CMYK" );
	strKeepCMYKHelp = localize( "$$$/JavaScripts/ImageProcessor/KeepCMYKHelp=Do not convert CMYK to RGB" );

	
}

// given a file name and a list of extensions
// determine if this file is in the list of extensions
function IsFileOneOfThese( inFileName, inArrayOfFileExtensions ) {
	var lastDot = inFileName.toString().lastIndexOf( "." );
	if ( lastDot == -1 ) {
		return false;
	}
	var strLength = inFileName.toString().length;
	var extension = inFileName.toString().substr( lastDot + 1, strLength - lastDot );
	extension = extension.toUpperCase();
	for (var i = 0; i < inArrayOfFileExtensions.length; i++ ) {
		if ( extension == inArrayOfFileExtensions[i] ) {
			return true;
		}
	}
	return false;
}

// given a file name and a list of types
// determine if this file is one of the provided types. Always returns false on platforms other than Mac.
function IsFileOneOfTheseTypes( inFileName, inArrayOfFileTypes ) {
	if ( ! IsMacintoshOS() ) {
		return false;
		}
	var file = new File (inFileName);
	for (var i = 0; i < inArrayOfFileTypes.length; i++ ) {
		if ( file.type == inArrayOfFileTypes[i] ) {
			return true;
		}
	}
	return false;
}

// see if i can write to this folder by making a temp file then deleting it
// what I really need is a "readonly" on the Folder object but that only exists
// on the File object
function IsFolderWritable( inFolder ) {
	var isWritable = false;
	var f = File( inFolder + "deleteme.txt" );
	if ( f.open( "w", "TEXT", "????" ) ) {
		if ( f.write( "delete me" ) ) {
			if ( f.close() ) {
				if ( f.remove() ) {
					isWritable = true;
				}
			}
		}
	}
	return isWritable;
}

// the main class
function ImageProcessor() {

	// load my params from the xml file on disk if it exists
	// this.params["myoptionname"] = myoptionvalue
	// I wrote a very simple xml parser, I'm sure it needs work
	this.LoadParamsFromDisk = function( loadFile ) {
		if ( loadFile.exists ) {
			loadFile.open( "r" );
			var projectSpace = ReadHeader( loadFile );
			if ( projectSpace == GetScriptNameForXML() ) {
				while ( ! loadFile.eof ) {
					var starter = ReadHeader( loadFile );
					var data = ReadData( loadFile );
					var ender = ReadHeader( loadFile );
					if ( ( "/" + starter ) == ender ) {
						this.params[starter] = data;
					}
					// force boolean values to boolean types
					if ( data == "true" || data == "false" ) {
						this.params[starter] = data == "true";
					}
				}
			}
			loadFile.close();
			if ( this.params["version"] != gVersion ) {
				// do something here to fix version conflicts
				// this should do it
				this.params["version"] = gVersion;
			}
		} 
	}

	// save out my params, this is much easier
	this.SaveParamsToDisk = function( saveFile ) {
		saveFile.encoding = "UTF8";
		saveFile.open( "w", "TEXT", "????" );
		// unicode signature, this is UTF16 but will convert to UTF8 "EF BB BF"
		saveFile.write("\uFEFF"); 
		var scriptNameForXML = GetScriptNameForXML();
		saveFile.writeln( "<" + scriptNameForXML + ">" );
		for ( var p in this.params ) {
			saveFile.writeln( "\t<" + p + ">" + this.params[p] + "</" + p + ">" );
		}
		saveFile.writeln( "</" + scriptNameForXML + ">" );
		saveFile.close();
	}

	this.CreateDialog = function() {
	
		// create the main dialog window, this holds all our data
		this.dlgMain = new Window( 'dialog', strTitle );
		
		// create a shortcut for easier typing
		var d = this.dlgMain;
		
        // match our dialog background(s) and foreground(s) with color of the host application
		var brush = d.graphics.newBrush(d.graphics.BrushType.THEME_COLOR, "appDialogBackground");
        d.graphics.backgroundColor = brush;
        d.graphics.disabledBackgroundColor = brush;
		d.graphics.foregroundColor = d.graphics.newPen(d.graphics.PenType.SOLID_COLOR, [1-brush.color[0], 1-brush.color[1], 1-brush.color[2]], brush.color[3]);
		d.graphics.disabledForegroundColor = d.graphics.newPen(d.graphics.PenType.SOLID_COLOR, [brush.color[0]/1.5, brush.color[1]/1.5, brush.color[2]/1.5], brush.color[3]);
		
		d.orientation = 'row';
		d.alignChildren = 'fill';
		
		// to keep everything as compatible as possible with Dr. Brown's Image Processor
		// I will keep most of the important dialog items at the same level
		// and use auto layout

		// some interesting numbers to help the auto layout, real numbers are in the zstrings
		var wAndhEtLength = StrToIntWithDefault( strwAndhEtLength, 40 );
		var qEtLength = StrToIntWithDefault( strqEtLength, 30 );
		var sourceAndDestLength = StrToIntWithDefault( strsourceAndDestLength, 210 );
		var actionDropDownLength = StrToIntWithDefault( stractionDropDownLength, 140 );
		
		var squeezePlay = 5;
		
		d.marginLeft = 15;

		// I use some hidden items to help auto layout
		// change this to see them
		var showHidden = false;
		
		d.grpLeft = d.add( 'group' );
		
		// create a shortcut for easier typing
		var l = d.grpLeft;
		
		l.orientation = 'column';
		l.alignChildren = 'fill';
		l.spacing = 3;
		
		// section 1

		l.grp1 = l.add( 'group' );
		l.grp1.orientation = 'row';
		l.grp1.alignChildren = 'center';

		d.icnOne = l.grp1.add( 'image', undefined, 'Step1Icon' );
		d.icnOne.helpTip = strLabelSource;

		d.stSourceLabel = l.grp1.add( 'statictext', undefined, strLabelSource );
		d.stSourceLabel.helpTip = strLabelSource;

		l.grp1Info = l.add( 'group' );
		l.grp1Info.orientation = 'row';
		l.grp1Info.alignChildren = 'fill';
		l.grp1Info.margins = [d.marginLeft, 0, 0, 0];

		l.grp1Info.grpLeft = l.grp1Info.add( 'group' );
		l.grp1Info.grpLeft.orientation = 'row';
		l.grp1Info.grpLeft.alignChildren = 'fill';

		d.icnSource = l.grp1Info.grpLeft.add( 'image', undefined, 'SourceFolderIcon' );
		d.icnSource.helpTip = strLabelSource;

		l.grp1Info.grpRight = l.grp1Info.add( 'group' );
		l.grp1Info.grpRight.orientation = 'column';
		l.grp1Info.grpRight.alignChildren = 'left';
		l.grp1Info.grpRight.spacing = squeezePlay;

		if ( this.runningFromBridge ) {
			d.stBridge = l.grp1Info.grpRight.add( 'statictext', undefined, strBridge + " (" + this.filesFromBridge.length + ")" );
			d.stBridge.helpTip = strBridgeHelp;
		} else {
			
			l.grpOpenOptions = l.grp1Info.grpRight.add( 'group' );
			l.grpOpenOptions.orientation = 'row';
			l.grpOpenOptions.alignChildren = 'center';

			d.rbUseOpen = l.grpOpenOptions.add( 'radiobutton', undefined, strUseOpen );
			d.rbUseOpen.helpTip = strUseOpenHelp;
			
			d.cbIncludeSubFolders = l.grpOpenOptions.add( 'checkbox', undefined, strIncludeAllSubfolders );
	        d.cbIncludeSubFolders.helpTip = strIncludeAllSubfoldersHelp;

			l.grpSelect = l.grp1Info.grpRight.add( 'group' );
			l.grpSelect.orientation = 'row';
			l.grpSelect.alignChildren = 'fill';

			d.rbUseFolder = l.grpSelect.add( 'radiobutton', undefined, '' );
			d.rbUseFolder.helpTip = strUseOpenHelp;
			
			d.btnSource = l.grpSelect.add( 'button', undefined, strButtonBrowse1 );
			d.btnSource.helpTip = strLabelSource;
			
			d.stSource = l.grpSelect.add( 'statictext', undefined, strNoImagesSelected, { truncate:'middle' } );
			d.stSource.helpTip = strLabelSourceHelp;
			d.stSource.preferredSize.width = sourceAndDestLength;
		}

		d.cbOpenFirst = l.grp1Info.grpRight.add( 'checkbox', undefined, strOpenFirst );
		d.cbOpenFirst.helpTip = strOpenFirstHelp;

		d.line1 = l.add( 'panel', undefined, undefined, {borderStyle: 'sunken'} );
		
		// section 2

		l.grp2 = l.add( 'group' );
		l.grp2.orientation = 'row';
		l.grp2.alignChildren = 'center';

		d.icnTwo = l.grp2.add( 'image', undefined, 'Step2Icon' );
		d.icnTwo.helpTip = strLabelDestination;

		d.stDestination = l.grp2.add( 'statictext', undefined, strLabelDestination );
		d.stDestination.helpTip = strLabelDestination;

		l.grp2Info = l.add( 'group' );
		l.grp2Info.orientation = 'row';
		l.grp2Info.alignChildren = 'fill';
		l.grp2Info.margins = [d.marginLeft, 0, 0, 0];

		l.grp2Info.grpLeft = l.grp2Info.add( 'group' );
		l.grp2Info.grpLeft.orientation = 'row';
		l.grp2Info.grpLeft.alignChildren = 'left';

		d.icnDest = l.grp2Info.grpLeft.add( 'image', undefined, 'DestinationFolderIcon' );
		d.icnDest.helpTip = strLabelDestination;

		l.grp2Info.grpRight = l.grp2Info.add( 'group' );
		l.grp2Info.grpRight.orientation = 'column';
		l.grp2Info.grpRight.alignChildren = 'left';
		l.grp2Info.grpRight.spacing = squeezePlay;

		l.grpSaveOptions = l.grp2Info.grpRight.add( 'group' );
		l.grpSaveOptions.orientation = 'row';
		l.grpSaveOptions.alignChildren = 'center';

		d.rbSaveInSame = l.grpSaveOptions.add( 'radiobutton', undefined, strSaveInSameLocation );
		d.rbSaveInSame.helpTip = strSaveInSameLocationHelp;

		if ( ! this.runningFromBridge ) {
			
			d.cbKeepStructure = l.grpSaveOptions.add( 'checkbox', undefined, strKeepStructure );
			d.cbKeepStructure.helpTip = strKeepStructure;
		}
	
		l.grpDestBrowse = l.grp2Info.grpRight.add( 'group' );
		l.grpDestBrowse.orientation = 'row';
		l.grpDestBrowse.alignChildren = 'center';

		d.rbSaveInNew = l.grpDestBrowse.add( 'radiobutton', undefined, '' );
		d.rbSaveInNew.helpTip = strLabelDestination;

		d.btnDest = l.grpDestBrowse.add( 'button', undefined, strButtonBrowse2 );
		d.btnDest.helpTip = strLabelDestination;
		
		d.stDest = l.grpDestBrowse.add( 'statictext', undefined, strNoFolderSelected, { truncate:'middle' } );
		d.stDest.helpTip = strLabelDestination;
		d.stDest.preferredSize.width = sourceAndDestLength;

		d.line2 = l.add( 'panel', undefined, undefined, {borderStyle: 'sunken'} );
		
		// section 3
		
		l.grp3 = l.add( 'group' );
		l.grp3.orientation = 'row';
		l.grp3.alignChildren = 'center';

		d.icnThree = l.grp3.add( 'image', undefined, 'Step3Icon' );
		d.icnThree.helpTip = strFileType;

		d.stFileType = l.grp3.add( 'statictext', undefined, strFileType );
		d.stFileType.helpTip = strFileType;

		l.grp3Info = l.add( 'group' );
		l.grp3Info.orientation = 'row';
		l.grp3Info.alignChildren = 'fill';
		l.grp3Info.margins = [d.marginLeft, 0, 0, 0];

		l.grp3Info.grpLeft = l.grp3Info.add( 'group' );
		l.grp3Info.grpLeft.orientation = 'column';
		l.grp3Info.grpLeft.alignChildren = 'left';
		l.grp3Info.grpLeft.spacing = squeezePlay;

		d.icnSpace = l.grp3Info.grpLeft.add( 'image', undefined, 'DestinationFolderIcon' );
		d.icnSpace.helpTip = strLabelDestination;
		d.icnSpace.visible = showHidden;

		l.grp3Info.grpRight = l.grp3Info.add( 'group' );
		l.grp3Info.grpRight.orientation = 'column';
		l.grp3Info.grpRight.alignChildren = 'left';
		l.grp3Info.grpRight.spacing = squeezePlay;

		d.grpFileType = l.grp3Info.grpRight.add( 'group', undefined, strFileType );
		
		// more shortcuts
		var p = d.grpFileType;
		
		p.orientation = 'column';
		p.alignChildren = 'fill';
		p.spacing = squeezePlay;
		
		p.grpJPEG = p.add( 'group' );
		p.grpJPEG.orientation = 'row';
		p.grpJPEG.alignChildren = 'fill';

		p.grpJPEG.grpLeft = p.grpJPEG.add( 'group' );
		p.grpJPEG.grpLeft.orientation = 'column';
		p.grpJPEG.grpLeft.alignChildren = 'fill';

		d.cbJPEG = p.grpJPEG.grpLeft.add( 'checkbox', undefined, strSaveAsJPEG );
		d.cbJPEG.helpTip = strSaveAsJPEGHelp;

		p.grpJPEG.grpLeft.grpJPEG = p.grpJPEG.grpLeft.add( 'group' );
		p.grpJPEG.grpLeft.grpJPEG.orientation = 'column';
		p.grpJPEG.grpLeft.grpJPEG.alignChildren = 'left';
		p.grpJPEG.grpLeft.grpJPEG.margins = [d.marginLeft, 0, 0, 0];

		p.grpJPEG.grpLeft.grpQ = p.grpJPEG.grpLeft.grpJPEG.add( 'group' );
		p.grpJPEG.grpLeft.grpQ.orientation = 'row';
		p.grpJPEG.grpLeft.grpQ.alignChildren = 'center';

		d.stQuality = p.grpJPEG.grpLeft.grpQ.add( 'statictext', undefined, strQuality );
		d.etQuality = p.grpJPEG.grpLeft.grpQ.add( 'edittext' );
		d.etQuality.preferredSize.width = qEtLength;
		d.etQuality.graphics.disabledBackgroundColor = brush;
		
		p.grpJPEG.grpLeft.grpJPEG.grpICC = p.grpJPEG.grpLeft.grpJPEG.add( 'group' );
		p.grpJPEG.grpLeft.grpJPEG.grpICC.orientation = 'row';
		p.grpJPEG.grpLeft.grpJPEG.grpICC.alignChildren = 'center';
		
		d.cbConvertICC = p.grpJPEG.grpLeft.grpJPEG.grpICC.add( 'checkbox', undefined, strConvertICC );
		d.cbConvertICC.helpTip = strConvertICCHelp;
//
		d.cbKeepCMYK = p.grpJPEG.grpLeft.grpJPEG.grpICC.add( 'checkbox', undefined, strKeepCMYK );
		d.cbKeepCMYK.helpTip = strKeepCMYKHelp;
//
		
		d.hidden1 = p.grpJPEG.grpLeft.grpJPEG.grpICC.add( 'edittext' );
		d.hidden1.preferredSize.width = 1;
		d.hidden1.visible = showHidden;

		p.grpJPEG.grpRight = p.grpJPEG.add( 'group' );
		p.grpJPEG.grpRight.orientation = 'column';
		p.grpJPEG.grpRight.alignChildren = 'left';
		
		d.cbResizeJPEG = p.grpJPEG.grpRight.add( 'checkbox', undefined, strResizeToFit1 );
		d.cbResizeJPEG.helpTip = strResizeToFitHelp;

		p.grpJPEG.grpRight.grpW = p.grpJPEG.grpRight.add( 'group' );
		p.grpJPEG.grpRight.grpW.orientation = 'row';
		p.grpJPEG.grpRight.grpW.alignChildren = 'center';
		p.grpJPEG.grpRight.grpW.spacing = 1;
		p.grpJPEG.grpRight.grpW.margins = [d.marginLeft, 0, 0, 0];

		d.stResizeJPEGW = p.grpJPEG.grpRight.grpW.add( 'statictext', undefined, strW );
		d.stResizeJPEGW.helpTip = strWHelp;
		d.stResizeJPEGW.justify = 'right';
		d.etResizeJPEGW = p.grpJPEG.grpRight.grpW.add( 'edittext' );
		d.etResizeJPEGW.helpTip = strWHelp;
		d.etResizeJPEGW.preferredSize.width = wAndhEtLength;
		d.etResizeJPEGW.graphics.disabledBackgroundColor = brush;
		d.stResizeJPEGPXW = p.grpJPEG.grpRight.grpW.add( 'statictext', undefined, strPX );

		p.grpJPEG.grpRight.grpH = p.grpJPEG.grpRight.add( 'group' );
		p.grpJPEG.grpRight.grpH.orientation = 'row';
		p.grpJPEG.grpRight.grpH.alignChildren = 'center';
		p.grpJPEG.grpRight.grpH.spacing = 1;
		p.grpJPEG.grpRight.grpH.margins = [d.marginLeft, 0, 0, 0];

		d.stResizeJPEGH = p.grpJPEG.grpRight.grpH.add( 'statictext', undefined, strH );
		d.stResizeJPEGH.helpTip = strHHelp;
		d.stResizeJPEGH.justify = 'right';
		d.etResizeJPEGH = p.grpJPEG.grpRight.grpH.add( 'edittext' );
		d.etResizeJPEGH.helpTip = strHHelp;
		d.etResizeJPEGH.preferredSize.width = wAndhEtLength;
		d.etResizeJPEGH.graphics.disabledBackgroundColor = brush;
		d.stResizeJPEGPXH = p.grpJPEG.grpRight.grpH.add( 'statictext', undefined, strPX );
		
		p.line1 = p.add( 'panel', undefined, undefined, {borderStyle: 'sunken'} );
		p.line1.alignment = 'fill';
////
		p.grpPNG = p.add( 'group' );
		p.grpPNG.orientation = 'row';
		p.grpPNG.alignChildren = 'fill';

		p.grpPNG.grpLeft = p.grpPNG.add( 'group' );
		p.grpPNG.grpLeft.orientation = 'column';
		p.grpPNG.grpLeft.alignChildren = 'fill';

		d.cbPNG = p.grpPNG.grpLeft.add( 'checkbox', undefined, strSaveAsPNG );
		d.cbPNG.helpTip = strSaveAsPNGHelp;

		p.grpPNG.grpLeft.grpPNG = p.grpPNG.grpLeft.add( 'group' );
		p.grpPNG.grpLeft.grpPNG.orientation = 'column';
		p.grpPNG.grpLeft.grpPNG.alignChildren = 'left';
		p.grpPNG.grpLeft.grpPNG.margins = [d.marginLeft, 0, 0, 0];

		p.grpPNG.grpLeft.grpQ = p.grpPNG.grpLeft.grpPNG.add( 'group' );
		p.grpPNG.grpLeft.grpQ.orientation = 'row';
		p.grpPNG.grpLeft.grpQ.alignChildren = 'center';

		//d.stQuality = p.grpPNG.grpLeft.grpQ.add( 'statictext', undefined, strQuality );
		//d.etQuality = p.grpPNG.grpLeft.grpQ.add( 'edittext' );
		//d.etQuality.preferredSize.width = qEtLength;
		//d.etQuality.graphics.disabledBackgroundColor = brush;
		
		p.grpPNG.grpLeft.grpPNG.grpICC = p.grpPNG.grpLeft.grpPNG.add( 'group' );
		p.grpPNG.grpLeft.grpPNG.grpICC.orientation = 'row';
		p.grpPNG.grpLeft.grpPNG.grpICC.alignChildren = 'center';
		
		d.cbInterlace = p.grpPNG.grpLeft.grpPNG.grpICC.add( 'checkbox', undefined, strInterlace );
		d.cbInterlace.helpTip = strInterlaceHelp;
		
		d.hidden1 = p.grpPNG.grpLeft.grpPNG.grpICC.add( 'edittext' );
		d.hidden1.preferredSize.width = 1;
		d.hidden1.visible = showHidden;

		p.grpPNG.grpRight = p.grpPNG.add( 'group' );
		p.grpPNG.grpRight.orientation = 'column';
		p.grpPNG.grpRight.alignChildren = 'left';
		
		d.cbResizePNG = p.grpPNG.grpRight.add( 'checkbox', undefined, strResizeToFit1 );
		d.cbResizePNG.helpTip = strResizeToFitHelp;

		p.grpPNG.grpRight.grpW = p.grpPNG.grpRight.add( 'group' );
		p.grpPNG.grpRight.grpW.orientation = 'row';
		p.grpPNG.grpRight.grpW.alignChildren = 'center';
		p.grpPNG.grpRight.grpW.spacing = 1;
		p.grpPNG.grpRight.grpW.margins = [d.marginLeft, 0, 0, 0];

		d.stResizePNGW = p.grpPNG.grpRight.grpW.add( 'statictext', undefined, strW );
		d.stResizePNGW.helpTip = strWHelp;
		d.stResizePNGW.justify = 'right';
		d.etResizePNGW = p.grpPNG.grpRight.grpW.add( 'edittext' );
		d.etResizePNGW.helpTip = strWHelp;
		d.etResizePNGW.preferredSize.width = wAndhEtLength;
		d.etResizePNGW.graphics.disabledBackgroundColor = brush;
		d.stResizePNGPXW = p.grpPNG.grpRight.grpW.add( 'statictext', undefined, strPX );

		p.grpPNG.grpRight.grpH = p.grpPNG.grpRight.add( 'group' );
		p.grpPNG.grpRight.grpH.orientation = 'row';
		p.grpPNG.grpRight.grpH.alignChildren = 'center';
		p.grpPNG.grpRight.grpH.spacing = 1;
		p.grpPNG.grpRight.grpH.margins = [d.marginLeft, 0, 0, 0];

		d.stResizePNGH = p.grpPNG.grpRight.grpH.add( 'statictext', undefined, strH );
		d.stResizePNGH.helpTip = strHHelp;
		d.stResizePNGH.justify = 'right';
		d.etResizePNGH = p.grpPNG.grpRight.grpH.add( 'edittext' );
		d.etResizePNGH.helpTip = strHHelp;
		d.etResizePNGH.preferredSize.width = wAndhEtLength;
		d.etResizePNGH.graphics.disabledBackgroundColor = brush;
		d.stResizePNGPXH = p.grpPNG.grpRight.grpH.add( 'statictext', undefined, strPX );
		
		p.line1 = p.add( 'panel', undefined, undefined, {borderStyle: 'sunken'} );
		p.line1.alignment = 'fill';
////
		p.grpPSD = p.add( 'group' );
		p.grpPSD.orientation = 'row';
		p.grpPSD.alignChildren = 'fill';

		p.grpPSD.grpLeft = p.grpPSD.add( 'group' );
		p.grpPSD.grpLeft.orientation = 'column';
		p.grpPSD.grpLeft.alignChildren = 'fill';

		d.cbPSD = p.grpPSD.grpLeft.add( 'checkbox', undefined, strSaveAsPSD );
		d.cbPSD.helpTip = strSaveAsPSDHelp;
		
		p.grpPSD.grpLeft.grpPSD = p.grpPSD.grpLeft.add( 'group' );
		p.grpPSD.grpLeft.grpPSD.orientation = 'column';
		p.grpPSD.grpLeft.grpPSD.alignChildren = 'left';
		p.grpPSD.grpLeft.grpPSD.margins = [d.marginLeft, 0, 0, 0];

		p.grpPSD.grpLeft.grpPSD.grpMax = p.grpPSD.grpLeft.grpPSD.add( 'group' );
		p.grpPSD.grpLeft.grpPSD.grpMax.orientation = 'row';
		p.grpPSD.grpLeft.grpPSD.grpMax.alignChildren = 'center';

		d.cbMaximize = p.grpPSD.grpLeft.grpPSD.grpMax.add( 'checkbox', undefined, strMaximize );
		d.cbMaximize.helpTip = strMaximizeHelp;
		
		d.hidden2 = p.grpPSD.grpLeft.grpPSD.grpMax.add( 'edittext' );
		d.hidden2.preferredSize.width = 1;
		d.hidden2.visible = showHidden;

		p.grpPSD.grpRight = p.grpPSD.add( 'group' );
		p.grpPSD.grpRight.orientation = 'column';
		p.grpPSD.grpRight.alignChildren = 'left';

		d.cbResizePSD = p.grpPSD.grpRight.add( 'checkbox', undefined, strResizeToFit2 );
		d.cbResizePSD.helpTip = strResizeToFitHelp;
		
		p.grpPSD.grpRight.grpW = p.grpPSD.grpRight.add( 'group' );
		p.grpPSD.grpRight.grpW.orientation = 'row';
		p.grpPSD.grpRight.grpW.alignChildren = 'center';
		p.grpPSD.grpRight.grpW.spacing = 1;
		p.grpPSD.grpRight.grpW.margins = [d.marginLeft, 0, 0, 0];

		d.stResizePSDW = p.grpPSD.grpRight.grpW.add( 'statictext', undefined, strW );
		d.stResizePSDW.helpTip = strWHelp;
		d.stResizePSDW.justify = 'right';
		d.etResizePSDW = p.grpPSD.grpRight.grpW.add( 'edittext' );
		d.etResizePSDW.helpTip = strWHelp;
		d.etResizePSDW.preferredSize.width = wAndhEtLength;
		d.etResizePSDW.graphics.disabledBackgroundColor = brush;
		d.stResizePSDPXW = p.grpPSD.grpRight.grpW.add( 'statictext', undefined, strPX );
		
		p.grpPSD.grpRight.grpH = p.grpPSD.grpRight.add( 'group' );
		p.grpPSD.grpRight.grpH.orientation = 'row';
		p.grpPSD.grpRight.grpH.alignChildren = 'center';
		p.grpPSD.grpRight.grpH.spacing = 1;
		p.grpPSD.grpRight.grpH.margins = [d.marginLeft, 0, 0, 0];

		d.stResizePSDH = p.grpPSD.grpRight.grpH.add( 'statictext', undefined, strH );
		d.stResizePSDH.helpTip = strHHelp;
		d.stResizePSDH.justify = 'right';
		d.etResizePSDH = p.grpPSD.grpRight.grpH.add( 'edittext' );
		d.etResizePSDH.helpTip = strHHelp;
		d.etResizePSDH.preferredSize.width = wAndhEtLength;
		d.etResizePSDH.graphics.disabledBackgroundColor = brush;
		d.stResizePSDPXH = p.grpPSD.grpRight.grpH.add( 'statictext', undefined, strPX );
		
		p.line2 = p.add( 'panel', undefined, undefined, {borderStyle: 'sunken'} );
		p.line2.alignment = 'fill';
		
		p.grpTIFF = p.add( 'group' );
		p.grpTIFF.orientation = 'row';
		p.grpTIFF.alignChildren = 'fill';

		p.grpTIFF.grpLeft = p.grpTIFF.add( 'group' );
		p.grpTIFF.grpLeft.orientation = 'column';
		p.grpTIFF.grpLeft.alignChildren = 'fill';

		d.cbTIFF = p.grpTIFF.grpLeft.add( 'checkbox', undefined, strSaveAsTIFF );
		d.cbTIFF.helpTip = strSaveAsTIFFHelp
		
		p.grpTIFF.grpLeft.grpTIFF = p.grpTIFF.grpLeft.add( 'group' );
		p.grpTIFF.grpLeft.grpTIFF.orientation = 'column';
		p.grpTIFF.grpLeft.grpTIFF.alignChildren = 'left';
		p.grpTIFF.grpLeft.grpTIFF.margins = [d.marginLeft, 0, 0, 0];

		p.grpTIFF.grpLeft.grpTIFF.grpLZW = p.grpTIFF.grpLeft.grpTIFF.add( 'group' );
		p.grpTIFF.grpLeft.grpTIFF.grpLZW.orientation = 'row';
		p.grpTIFF.grpLeft.grpTIFF.grpLZW.alignChildren = 'center';

		d.cbTIFFLZW = p.grpTIFF.grpLeft.grpTIFF.grpLZW.add( 'checkbox', undefined, strLZW );
		d.cbTIFFLZW.helpTip = strLZWHelp;
		
		d.hidden3 = p.grpTIFF.grpLeft.grpTIFF.grpLZW.add( 'edittext' );
		d.hidden3.preferredSize.width = 1;
		d.hidden3.visible = showHidden;

		p.grpTIFF.grpRight = p.grpTIFF.add( 'group' );
		p.grpTIFF.grpRight.orientation = 'column';
		p.grpTIFF.grpRight.alignChildren = 'left';

		d.cbResizeTIFF = p.grpTIFF.grpRight.add( 'checkbox', undefined, strResizeToFit3 );
		d.cbResizeTIFF.helpTip = strResizeToFitHelp;

		p.grpTIFF.grpRight.grpW = p.grpTIFF.grpRight.add( 'group' );
		p.grpTIFF.grpRight.grpW.orientation = 'row';
		p.grpTIFF.grpRight.grpW.alignChildren = 'center';
		p.grpTIFF.grpRight.grpW.spacing = 1;
		p.grpTIFF.grpRight.grpW.margins = [d.marginLeft, 0, 0, 0];

		d.stResizeTIFFW = p.grpTIFF.grpRight.grpW.add( 'statictext', undefined, strW );
		d.stResizeTIFFW.helpTip = strWHelp;
		d.stResizeTIFFW.justify = 'right';
		d.etResizeTIFFW = p.grpTIFF.grpRight.grpW.add( 'edittext' );
		d.etResizeTIFFW.helpTip = strWHelp;
		d.etResizeTIFFW.preferredSize.width = wAndhEtLength;
		d.etResizeTIFFW.graphics.disabledBackgroundColor = brush;
		d.stResizeTIFFPXW = p.grpTIFF.grpRight.grpW.add( 'statictext', undefined, strPX );

		p.grpTIFF.grpRight.grpH = p.grpTIFF.grpRight.add( 'group' );
		p.grpTIFF.grpRight.grpH.orientation = 'row';
		p.grpTIFF.grpRight.grpH.alignChildren = 'center';
		p.grpTIFF.grpRight.grpH.spacing = 1;
		p.grpTIFF.grpRight.grpH.margins = [d.marginLeft, 0, 0, 0];

		d.stResizeTIFFH = p.grpTIFF.grpRight.grpH.add( 'statictext', undefined, strH );
		d.stResizeTIFFH.helpTip = strHHelp;
		d.stResizeTIFFH.justify = 'right';
		d.etResizeTIFFH = p.grpTIFF.grpRight.grpH.add( 'edittext' );
		d.etResizeTIFFH.helpTip = strHHelp;
		d.etResizeTIFFH.preferredSize.width = wAndhEtLength;
		d.etResizeTIFFH.graphics.disabledBackgroundColor = brush;
		d.stResizeTIFFPXH = p.grpTIFF.grpRight.grpH.add( 'statictext', undefined, strPX );

		d.line3 = l.add( 'panel', undefined, undefined, {borderStyle: 'sunken'} );
		d.line3.alignment = 'fill';

		// section 4 

		l.grp4 = l.add( 'group' );
		l.grp4.orientation = 'row';
		l.grp4.alignChildren = 'top';
		
		l.grp4.grpLeft = l.grp4.add( 'group' );
		l.grp4.grpLeft.orientation = 'column';
		l.grp4.grpLeft.alignChildren = 'left';

		d.icnFour = l.grp4.grpLeft.add( 'image', undefined, 'Step4Icon' );
		d.icnFour.helpTip = strPreferences;

		l.grp4.grpRight = l.grp4.add( 'group' );
		l.grp4.grpRight.orientation = 'column';
		l.grp4.grpRight.alignChildren = 'left';

		d.stPreferences = l.grp4.grpRight.add( 'statictext', undefined, strPreferences );
		d.stPreferences.helpTip = strPreferences;

		l.grp4Info = l.grp4.grpRight.add( 'group' );
		l.grp4Info.orientation = 'row';
		l.grp4Info.alignChildren = 'top';
		
		l.grp4Info.grpLeft = l.grp4Info.add( 'group' );
		l.grp4Info.grpLeft.orientation = 'column';
		l.grp4Info.grpLeft.alignChildren = 'left';
		l.grp4Info.grpLeft.spacing = 5;

		l.grpAction = l.grp4Info.grpLeft.add( 'group' );
		l.grpAction.orientation = 'row';
		l.grpAction.alignChildren = 'center';

		d.cbAction = l.grpAction.add( 'checkbox' );
		d.cbAction.text = strRunAction;
		d.cbAction.helpTip = strActionHelp;
		
		d.hidden4 = l.grpAction.add( 'dropdownlist' );
		d.hidden4.preferredSize.width = 1;
		d.hidden4.visible = showHidden;

		l.grp4Info.grpRight = l.grp4Info.add( 'group' );
		l.grp4Info.grpRight.orientation = 'column';
		l.grp4Info.grpRight.alignChildren = 'left';
		l.grp4Info.grpRight.spacing = 5;

		l.grpDropDowns = l.grp4Info.grpRight.add( 'group' );
		l.grpDropDowns.orientation = 'row';
		l.grpDropDowns.alignChildren = 'center';

		d.ddSet = l.grpDropDowns.add( 'dropdownlist' );
		d.ddSet.helpTip = strActionHelp;
		d.ddSet.preferredSize.width = actionDropDownLength;
		
		d.ddAction = l.grpDropDowns.add( 'dropdownlist' );
		d.ddAction.helpTip = strActionHelp;
		d.ddAction.preferredSize.width = actionDropDownLength;

		l.grpCopyright = l.grp4Info.grpLeft.add( 'group' );
		l.grpCopyright.orientation = 'row';
		l.grpCopyright.alignChildren = 'center';
		
		d.stCopyrightInfo = l.grpCopyright.add( 'statictext', undefined, strCopyright );
		d.stCopyrightInfo.helpTip = strCopyrightHelp;
		
		d.hidden5 = l.grpCopyright.add( 'edittext' );
		d.hidden5.preferredSize.width = 1;
		d.hidden5.visible = showHidden;

		d.etCopyrightInfo = l.grp4Info.grpRight.add( 'edittext' );
		d.etCopyrightInfo.helpTip = strCopyrightHelp;
		d.etCopyrightInfo.alignment = 'fill';
		d.etCopyrightInfo.preferredSize.width = actionDropDownLength * 2;

		d.cbIncludeICC = l.grp4.grpRight.add( 'checkbox', undefined, strICC );
		d.cbIncludeICC.helpTip = strICCHelp;

		// buttons on the right side of the dialog
		
		d.grpRight = d.add( 'group' );
		d.grpRight.orientation = 'column';
		d.grpRight.alignChildren = 'fill';
		d.grpRight.alignment = 'fill';

		d.btnRun = d.grpRight.add( 'button', undefined, strButtonRun );
		d.btnCancel = d.grpRight.add( 'button', undefined, strButtonCancel );
		d.stFake = d.grpRight.add( 'statictext', undefined, '' );
		d.btnLoad = d.grpRight.add( 'button', undefined, strButtonLoad );
		d.btnLoad.helpTip = strButtonLoadHelp;
		d.btnSave = d.grpRight.add( 'button', undefined, strButtonSave );
		d.btnSave.helpTip = strButtonSaveHelp;

		d.defaultElement = d.btnRun;
		d.cancelElement = d.btnCancel;
	}

	this.InitParams = function() {
		var params = new Object();
		params["version"] = gVersion;
		params["useopen"] = false;
		params["includesub"] = false;
		params["source"] = "";
		params["open"] = false;
		params["saveinsame"] = true;
		params["dest"] = "";
		params["jpeg"] = true;
		params["keepcmyk"] = false;//
		params["png"] = false;//
		params["interlace"] = false;//
		params["psd"] = false;
		params["tiff"] = false;
		params["lzw"] = false;
		params["converticc"] = false;
		params["q"] = 5;
		params["max"] = true;
		params["jpegresize"] = false;
		params["jpegw"] = "";
		params["jpegh"] = "";
		params["pngresize"] = false;//
		params["pngw"] = "";//
		params["pngh"] = "";//
		params["psdresize"] = false;
		params["psdw"] = "";
		params["psdh"] = "";
		params["tiffresize"] = false;
		params["tiffw"] = "";
		params["tiffh"] = "";
		params["runaction"] = false;
		params["actionset"] = "";
		params["action"] = "";
		params["info"] = "";
		params["icc"] = true;
		params["keepstructure"] = false;
		return params;
	}

	// transfer from the default settings or settings I read off disk to the dialog widgets
	this.InitDialog = function() {

		var d = this.dlgMain;
		var p = this.params;
		
		this.dlgMain.ip = this;
		d.loadFromDisk = true;
		
		if ( ! this.runningFromBridge ) {

			if ( app.documents.length > 0 ) {
				d.rbUseOpen.value = p["useopen"];
			} else {
				d.rbUseOpen.enabled = false;
				d.rbUseOpen.value = false;
			}
			
			d.cbIncludeSubFolders.value = p["includesub"];
			
			d.cbKeepStructure.value = p["keepstructure"];

			d.rbUseFolder.value = ! d.rbUseOpen.value;

			d.stSource.text = p["source"];
			if ( d.stSource.text == "" ) {
				d.stSource.text = strNoImagesSelected;
			}
		}
		d.sourceLongText = p["source"];

		d.rbSaveInSame.value = p["saveinsame"];
		d.rbSaveInNew.value = ! d.rbSaveInSame.value;		
		d.cbOpenFirst.value = p["open"];
		d.stDest.text = p["dest"];
		if ( d.stDest.text == "" ) {
			d.stDest.text = strNoFolderSelected;
		}
		d.destLongText = p["dest"];
		d.cbJPEG.value = p["jpeg"];
		d.cbPNG.value = p["png"];//
		d.cbInterlace.vaule = p["interlace"];//
		d.cbPSD.value = p["psd"];
		d.cbTIFF.value = p["tiff"];
		d.cbTIFFLZW.value = p["lzw"];
		d.cbConvertICC.value = p["converticc"];
		d.etQuality.text = p["q"];
		d.cbMaximize.value = p["max"];
		d.cbResizeJPEG.value = p["jpegresize"];
		d.cbKeepCMYK.value = p["keepcmyk"];//
		d.etResizeJPEGH.text = p["jpegh"];
		d.etResizeJPEGW.text = p["jpegw"];
		d.cbResizePNG.value = p["pngresize"];//
		d.etResizePNGH.text = p["pngh"];//
		d.etResizePNGW.text = p["pngw"];//
		d.cbResizePSD.value = p["psdresize"];
		d.etResizePSDH.text = p["psdh"];
		d.etResizePSDW.text = p["psdw"];
		d.cbResizeTIFF.value = p["tiffresize"];
		d.etResizeTIFFH.text = p["tiffh"];
		d.etResizeTIFFW.text = p["tiffw"];
		d.cbAction.value = p["runaction"];
		d.etCopyrightInfo.text = p["info"];
		d.cbIncludeICC.value = p["icc"];
	}

	// pretend like i clicked it to get the other items to respond to the current settings
	this.ForceDialogUpdate = function() {	
		if ( ! this.runningFromBridge ) {
			this.dlgMain.rbUseOpen.onClick();
		}
		this.dlgMain.rbSaveInSame.onClick();
		this.dlgMain.cbJPEG.onClick();
		this.dlgMain.cbPNG.onClick();///
		this.dlgMain.cbPSD.onClick();
		this.dlgMain.cbTIFF.onClick();
		index = this.dlgMain.SetDropDown( this.dlgMain.ddSet, this.params["actionset"] );
		if ( this.actionInfo.length > 0 ) {
			this.dlgMain.ddSet.onChange( index );
			this.actionIndex = this.dlgMain.SetDropDown( this.dlgMain.ddAction, this.params["action"] );
		}
		this.dlgMain.cbAction.onClick();
	}

	// transfer from the dialog widgets to my internal params
	this.GetParamsFromDialog = function() {
		
		var p = this.params;
		var d = this.dlgMain;
		
		if ( ! this.runningFromBridge ) {
			p["useopen"] = d.rbUseOpen.value;
			p["source"] = d.sourceLongText;
			p["includesub"] = d.cbIncludeSubFolders.value;
			p["keepstructure"] = d.cbKeepStructure.value;
		}

		p["saveinsame"] = d.rbSaveInSame.value;
		p["dest"] = d.destLongText;
		p["open"] = d.cbOpenFirst.value;
		p["jpeg"] = d.cbJPEG.value;
		p["keepcmyk"] = d.cbKeepCMYK.value;//
		p["png"] = d.cbPNG.value;//
		p["interlace"] = d.cbInterlace.value;//
		p["psd"] = d.cbPSD.value;
		p["tiff"] = d.cbTIFF.value;
		p["lzw"] = d.cbTIFFLZW.value;
		p["converticc"] = d.cbConvertICC.value;
		p["q"] = d.etQuality.text;
		p["max"] = d.cbMaximize.value;
		p["jpegresize"] = d.cbResizeJPEG.value;
		p["jpegh"] = d.etResizeJPEGH.text;
		p["jpegw"] = d.etResizeJPEGW.text;
		p["pngresize"] = d.cbResizePNG.value;//
		p["pngh"] = d.etResizePNGH.text;//
		p["pngw"] = d.etResizePNGW.text;//
		p["psdresize"] = d.cbResizePSD.value;
		p["psdh"] = d.etResizePSDH.text;
		p["psdw"] = d.etResizePSDW.text;
		p["tiffresize"] = d.cbResizeTIFF.value;
		p["tiffh"] = d.etResizeTIFFH.text;
		p["tiffw"] = d.etResizeTIFFW.text;
		p["runaction"] = d.cbAction.value;
		p["actionset"] = d.ddSet.selection.text;
		p["action"] = d.ddAction.selection.text;
		p["info"] = d.etCopyrightInfo.text;
		p["icc"] = d.cbIncludeICC.value;
	}
	
	// routine for running the dialog and it's interactions
	this.RunDialog = function () {

		this.dlgMain.btnCancel.onClick = function() { 
			var d = FindDialog( this );
			d.close( gCancelButtonID );
		}

		// help auto layout
		this.dlgMain.onShow = function() {
			
			this.cbOpenFirst.location.x += this.marginLeft;
			this.grpLeft.grp1Info.grpRight.bounds.right += this.marginLeft;
			
			var p = this.grpFileType;

			// align the ":" and edit text boxes for the resize numbers
			if ( p.grpJPEG.grpRight.grpH.bounds.width < p.grpJPEG.grpRight.grpW.bounds.width ) {
				var mover = p.grpJPEG.grpRight.grpW.bounds.width - p.grpJPEG.grpRight.grpH.bounds.width;

				p.grpJPEG.grpRight.grpH.bounds.right += mover;
				this.stResizeJPEGH.location.x += mover;
				this.etResizeJPEGH.location.x += mover;
				this.stResizeJPEGPXH.location.x += mover;
////
				p.grpPNG.grpRight.grpH.bounds.right += mover;
				this.stResizePNGH.location.x += mover;
				this.etResizePNGH.location.x += mover;
				this.stResizePNGPXH.location.x += mover;
////
				p.grpPSD.grpRight.grpH.bounds.right += mover;
				this.stResizePSDH.location.x += mover;
				this.etResizePSDH.location.x += mover;
				this.stResizePSDPXH.location.x += mover;

				p.grpTIFF.grpRight.grpH.bounds.right += mover;
				this.stResizeTIFFH.location.x += mover;
				this.etResizeTIFFH.location.x += mover;
				this.stResizeTIFFPXH.location.x += mover;

			} else {
				var mover = p.grpJPEG.grpRight.grpH.bounds.width - p.grpJPEG.grpRight.grpW.bounds.width;

				p.grpJPEG.grpRight.grpW.bounds.right += mover;
				this.stResizeJPEGW.location.x += mover;
				this.etResizeJPEGW.location.x += mover;
				this.stResizeJPEGPXW.location.x += mover;
///
				p.grpPNG.grpRight.grpW.bounds.right += mover;
				this.stResizePNGW.location.x += mover;
				this.etResizePNGW.location.x += mover;
				this.stResizePNGPXW.location.x += mover;
///

				p.grpPSD.grpRight.grpW.bounds.right += mover;
				this.stResizePSDW.location.x += mover;
				this.etResizePSDW.location.x += mover;
				this.stResizePSDPXW.location.x += mover;

				p.grpTIFF.grpRight.grpW.bounds.right += mover;
				this.stResizeTIFFW.location.x += mover;
				this.etResizeTIFFW.location.x += mover;
				this.stResizeTIFFPXW.location.x += mover;

			}
			
			// align the resize groups
			var farRight = p.grpJPEG.grpRight.location.x;
			if ( p.grpPSD.grpRight.location.x > farRight ) {
				farRight = p.grpPSD.grpRight.location.x;
			}
//
			if ( p.grpPNG.grpRight.location.x > farRight ) {
				farRight = p.grpPNG.grpRight.location.x;
			}
//
			if ( p.grpTIFF.grpRight.location.x > farRight ) {
				farRight = p.grpTIFF.grpRight.location.x;
			}

			p.grpJPEG.grpRight.location.x = farRight;
			p.grpPNG.grpRight.location.x = farRight;//
			p.grpPSD.grpRight.location.x = farRight;
			p.grpTIFF.grpRight.location.x = farRight;	

			// make the copyright and action drop downs as large as possible
			// and align them with the third line
			var leftAdjuster = this.etCopyrightInfo.parent.bounds.left;
			leftAdjuster += this.etCopyrightInfo.parent.parent.bounds.left;
			leftAdjuster += this.etCopyrightInfo.parent.parent.parent.bounds.left;

			var mover = this.line3.bounds.right - this.etCopyrightInfo.bounds.right;
			mover -= leftAdjuster;

			this.etCopyrightInfo.bounds.right += mover;

			// make all the parents bigger to fit the new size of the copyright
			this.etCopyrightInfo.parent.bounds.right += mover;
			this.etCopyrightInfo.parent.parent.bounds.right += mover;
			this.etCopyrightInfo.parent.parent.parent.bounds.right += mover;

			// split the adjustment above into the two dropdowns
			// make sure the right edges line up by looking at the oddness
			var halfMover = mover / 2;
			var isOdd = halfMover % 2 ? true : false;

			this.ddSet.bounds.width += halfMover;
			this.ddAction.bounds.width += halfMover;
			this.ddAction.location.x += halfMover + ( isOdd ? 1 : 0 );

			// make your parents bigger so everybody looks nice
			this.ddSet.parent.bounds.right += mover;
			this.ddSet.parent.parent.bounds.right += mover;
		}
		
		if ( ! this.runningFromBridge ) {
			this.dlgMain.rbUseOpen.onClick = function() {
				var d = FindDialog( this );
				d.rbUseFolder.value = ! this.value;
				d.cbOpenFirst.enabled = ! this.value;
				d.btnSource.enabled = ! this.value;
				d.stSource.enabled = ! this.value;
				d.cbIncludeSubFolders.enabled = ! this.value;
			}

			this.dlgMain.rbUseFolder.onClick = function() {
				var d = FindDialog( this );
				d.rbUseOpen.value = ! this.value;
				d.cbOpenFirst.enabled = this.value;
				d.btnSource.enabled = this.value;
				d.stSource.enabled = this.value;
				d.cbIncludeSubFolders.enabled = this.value;
			}

			this.dlgMain.btnSource.onClick = function() { 
				var d = FindDialog( this );
				var selFolder = Folder.selectDialog( strPickSource, d.sourceLongText );
				if ( selFolder != null ) {
					d.sourceLongText = selFolder.fsName.toString()
					d.stSource.text = d.sourceLongText;
				}
				d.defaultElement.active = true;
			}

		}

		this.dlgMain.rbSaveInSame.onClick = function() {
			var d = FindDialog( this );
			d.rbSaveInNew.value = ! this.value;
			d.btnDest.enabled = ! this.value;
			d.stDest.enabled = ! this.value;
			if ( ! d.ip.runningFromBridge ) {
				d.cbKeepStructure.enabled = ! this.value;
			}
		}
		
		this.dlgMain.rbSaveInNew.onClick = function() {
			var d = FindDialog( this );
			d.rbSaveInSame.value = ! this.value;
			d.btnDest.enabled = this.value;
			d.stDest.enabled = this.value;
			if ( ! d.ip.runningFromBridge ) {
				d.cbKeepStructure.enabled = this.value;
			}
		}

		this.dlgMain.SetDropDown = function ( dd, strSet ) {
			var index = 0;
			for ( var i = 0; i < dd.items.length; i++ ) {
				if ( dd.items[ i ].toString() == strSet ) {
					index = i;
					break;
				}
			}
			if ( dd.items.length > 0 ) {
				dd.items[ index ].selected = true;
			}
			return index;
		}

		this.dlgMain.btnLoad.onClick = function() {
 
			var d = FindDialog( this );
			var loadFile = null;
			Folder.current = Folder( "~/" );
			if ( File.fs == "Windows" ) {
				loadFile = File.openDialog( strPickXML, strPickXMLWin );
			} else {
				loadFile = File.openDialog( strPickXML, MacXMLFilter );
			}
			if ( loadFile != null ) {
				d.ip.LoadParamsFromDisk( loadFile );
				d.ip.InitDialog();
				d.loadFromDisk = true;
				d.ip.ForceDialogUpdate();
			}
			d.defaultElement.active = true;
		}
		
		this.dlgMain.btnSave.onClick = function() { 
			var d = FindDialog( this );
			var saveFile = null;
			Folder.current = Folder( "~/" );
			if ( File.fs == "Windows" ) {
				saveFile = File.saveDialog( strPickXMLSave, strPickXMLWin );
			} else {
				saveFile = File.saveDialog( strPickXMLSave, MacXMLFilter );
			}
			if ( saveFile != null ) {
				d.ip.GetParamsFromDialog();
				d.ip.SaveParamsToDisk( saveFile );
			}
			d.defaultElement.active = true;
		}

		this.dlgMain.btnDest.onClick = function() { 
			var d = FindDialog( this );
			var selFolder = Folder.selectDialog( strPickDest, d.destLongText );
			if ( selFolder != null ) {
				d.destLongText = selFolder.fsName.toString()
				d.stDest.text = d.destLongText;
			}
			d.defaultElement.active = true;
		}
		
		this.dlgMain.cbPSD.onClick = function() {
			var d = FindDialog( this );
			d.cbMaximize.enabled = this.value;
			d.cbResizePSD.enabled = this.value;
			d.cbResizePSD.onClick();
		}
		
		this.dlgMain.cbTIFF.onClick = function() {
			var d = FindDialog( this );
			d.cbTIFFLZW.enabled = this.value;
			d.cbResizeTIFF.enabled = this.value;
			d.cbResizeTIFF.onClick();
		}
		
		this.dlgMain.cbJPEG.onClick = function() {
			var d = FindDialog( this );
			d.stQuality.enabled = this.value;
			d.etQuality.enabled = this.value;
			d.cbConvertICC.enabled = this.value;
			d.cbKeepCMYK.enabled = this.value;//
			d.cbResizeJPEG.enabled = this.value;
			d.cbResizeJPEG.onClick();
		}

		this.dlgMain.cbResizeJPEG.onClick = function( inValue ) {
			var d = FindDialog( this );
			var realValue = this.value;
			if ( ! d.cbJPEG.value )
				realValue = false;
			d.stResizeJPEGW.enabled = realValue;
			d.etResizeJPEGW.enabled = realValue;
			d.stResizeJPEGPXW.enabled = realValue;
			d.stResizeJPEGH.enabled = realValue;
			d.etResizeJPEGH.enabled = realValue;
			d.stResizeJPEGPXH.enabled = realValue;
		}
///
		this.dlgMain.cbPNG.onClick = function() {
			var d = FindDialog( this );
			d.cbResizePNG.enabled = this.value;
			d.cbInterlace.enabled = this.value;
			d.cbResizePNG.onClick();
		}

		this.dlgMain.cbResizePNG.onClick = function( inValue ) {
			var d = FindDialog( this );
			var realValue = this.value;
			if ( ! d.cbPNG.value )
				realValue = false;
			d.stResizePNGW.enabled = realValue;
			d.etResizePNGW.enabled = realValue;
			d.stResizePNGPXW.enabled = realValue;
			d.stResizePNGH.enabled = realValue;
			d.etResizePNGH.enabled = realValue;
			d.stResizePNGPXH.enabled = realValue;
		}
///
		this.dlgMain.cbResizePSD.onClick = function( inValue ) {
			var d = FindDialog( this );
			var realValue = this.value;
			if ( ! d.cbPSD.value )
				realValue = false;
			d.stResizePSDW.enabled = realValue;
			d.etResizePSDW.enabled = realValue;
			d.stResizePSDPXW.enabled = realValue;
			d.stResizePSDH.enabled = realValue;
			d.etResizePSDH.enabled = realValue;
			d.stResizePSDPXH.enabled = realValue;
		}
		
		this.dlgMain.cbResizeTIFF.onClick = function( inValue ) {
			var d = FindDialog( this );
			var realValue = this.value;
			if ( ! d.cbTIFF.value )
				realValue = false;
			d.stResizeTIFFW.enabled = realValue;
			d.etResizeTIFFW.enabled = realValue;
			d.stResizeTIFFPXW.enabled = realValue;
			d.stResizeTIFFH.enabled = realValue;
			d.etResizeTIFFH.enabled = realValue;
			d.stResizeTIFFPXH.enabled = realValue;
		}

		this.dlgMain.cbAction.onClick = function() {
			var d = FindDialog( this );
			d.ddSet.enabled = this.value;
			d.ddAction.enabled = this.value;
		}

		if ( this.actionInfo.length > 0 ) {
			for ( var i = 0; i < this.actionInfo.length; i++ ) {
				this.dlgMain.ddSet.add( "item", this.actionInfo[i].name );
			}
			this.dlgMain.ddSet.items[0].selected = true;
			this.dlgMain.ddSet.onChange = function( forcedSelectionIndex ) {
				var index = 0;
				var d = FindDialog( this );
				d.ddAction.removeAll();
				if ( undefined == forcedSelectionIndex ) {
					forcedSelectionIndex = this.selection.index;
					if ( undefined != d.ip.actionIndex ) {
						index = d.ip.actionIndex;
						d.ip.actionIndex = undefined;
					}
				}
				for ( var i = 0; i < d.ip.actionInfo[ forcedSelectionIndex ].children.length; i++ ) {
					d.ddAction.add( "item", d.ip.actionInfo[ forcedSelectionIndex ].children[ i ].name );
				}
				if ( d.ddAction.items.length > 0 ) {
					d.ddAction.items[ index ].selected = true;
				}
				if ( null != this.selection ) {
					this.helpTip = this.selection.text;
				}
			}
		} else {
			this.dlgMain.grpLeft.grpAction.enabled = false;
		}
	
		this.dlgMain.ddAction.onChange = function() {
			this.helpTip = this.selection.text;
		}

		// do not allow anything except for numbers 0-9
		this.dlgMain.etQuality.addEventListener ('keydown', NumericEditKeyboardHandler);

		// do not allow anything except for numbers 0-9
		this.dlgMain.etResizeJPEGW.addEventListener ('keydown', NumericEditKeyboardHandler);

		// do not allow anything except for numbers 0-9
		this.dlgMain.etResizeJPEGH.addEventListener ('keydown', NumericEditKeyboardHandler);
///
		// do not allow anything except for numbers 0-9
		this.dlgMain.etResizePNGW.addEventListener ('keydown', NumericEditKeyboardHandler);

		// do not allow anything except for numbers 0-9
		this.dlgMain.etResizePNGH.addEventListener ('keydown', NumericEditKeyboardHandler);
///
		// do not allow anything except for numbers 0-9
		this.dlgMain.etResizeTIFFW.addEventListener ('keydown', NumericEditKeyboardHandler);

		// do not allow anything except for numbers 0-9
		this.dlgMain.etResizeTIFFH.addEventListener ('keydown', NumericEditKeyboardHandler);

		// do not allow anything except for numbers 0-9
		this.dlgMain.etResizePSDW.addEventListener ('keydown', NumericEditKeyboardHandler);

		// do not allow anything except for numbers 0-9
		this.dlgMain.etResizePSDH.addEventListener ('keydown', NumericEditKeyboardHandler);

		this.dlgMain.btnRun.onClick = function () {
			var testFolder = null;
			var d = FindDialog( this );
			if ( ! this.runningFromBridge ) {
				if ( this.rbUseFolder ) {
					if ( d.sourceLongText.length > 0 && d.sourceLongText[0] != '.' ) {
						testFolder = new Folder( d.sourceLongText );
						if ( !testFolder.exists ) {
							alert( strSpecifySource );
							return;
						}
					} else {
						alert( strSpecifySource );
						return;
					}
				}
			}

			if ( d.rbSaveInNew.value ) {
				if ( d.destLongText.length > 0 && d.destLongText[0] != '.' ) {
					testFolder = new Folder( d.destLongText );
					if ( !testFolder.exists ) {
						alert( strSpecifyDest );
						return;
					}
				} else {
					alert( strSpecifyDest );
					return;
				}
			}
						
			if ( d.cbJPEG.value ) {
				var q = Number( d.etQuality.text );
				if ( q < 0 || q > 12 || isNaN( q ) ) {
					alert( strJPEGQuality );
					return;
				}

			    if ( d.cbResizeJPEG.value ) {
				    var w = Number( d.etResizeJPEGW.text );
				    var h = Number( d.etResizeJPEGH.text );
			        if ( isNaN( w ) || w < 1 || w > gMaxResize ||
			             isNaN( h ) || h < 1 || h > gMaxResize ) {
					    alert( strJPEGWandH );
					    return;
				    }
			    }
			}
///
			if ( d.cbPNG.value ) {

			    if ( d.cbResizePNG.value ) {
				    var w = Number( d.etResizePNGW.text );
				    var h = Number( d.etResizePNGH.text );
			        if ( isNaN( w ) || w < 1 || w > gMaxResize ||
			             isNaN( h ) || h < 1 || h > gMaxResize ) {
					    alert( strPNGWandH );
					    return;
				    }
			    }
			}
///

			if ( d.cbTIFF.value && d.cbResizeTIFF.value ) {
				var w = Number( d.etResizeTIFFW.text );
				var h = Number( d.etResizeTIFFH.text );
			    if ( isNaN( w ) || w < 1 || w > gMaxResizeTIFF ||
			         isNaN( h ) || h < 1 || h > gMaxResizeTIFF ) {
					alert( strTIFFWandH );
					return;
				}
			}

			if ( d.cbPSD.value && d.cbResizePSD.value ) {
				var w = Number( d.etResizePSDW.text );
				var h = Number( d.etResizePSDH.text );
			    if ( isNaN( w ) || w < 1 || w > gMaxResize ||
			         isNaN( h ) || h < 1 || h > gMaxResize ) {
					alert( strPSDWandH );
					return;
				}
			}

			// make sure they have at least one file format specified for output
			var outputCount = 0;
			if ( d.cbJPEG.value ) {
				outputCount++;
			}
///
			if ( d.cbPNG.value ) {
				outputCount++;
			}
///
			if ( d.cbPSD.value ) {
				outputCount++;
			}
			if ( d.cbTIFF.value ) {
				outputCount++;
			}

			if ( outputCount == 0 ) {
				alert( strOneType );
				return;
			}

			d.ip.GetParamsFromDialog()
			
			d.close( gRunButtonID );
		}

		this.InitDialog();

		this.ForceDialogUpdate();
		
		// in case we double clicked the file
		app.bringToFront();

		this.dlgMain.center();
		
		return this.dlgMain.show();

	}

	// if I get here then the dialog params are ok and it is time
	// to do what they want
	// the heart of the script is this routine
	// loop through all the files and save accordingly
	this.Execute = function()  {
		var cameraRawParams = new Object();
		cameraRawParams.desc = undefined;
		cameraRawParams.useDescriptor = false;
		
		var inputFiles;
		if ( this.runningFromBridge ) {
			inputFiles = this.filesFromBridge;
		} else if ( this.params["useopen"] ) {
			inputFiles = OpenDocs();
		} else if ( this.params["includesub"] ) {
			inputFiles = new Array();
			inputFiles = FindAllFiles( this.params["source"], inputFiles );
		} else {
			inputFiles = Folder ( this.params["source"] ).getFiles ();
		}

        var rememberMaximize;
        var needMaximize = this.params["max"] ? QueryStateType.ALWAYS : QueryStateType.NEVER;
        if ( this.params["psd"] && app.preferences.maximizeCompatibility != needMaximize ) {
            rememberMaximize = app.preferences.maximizeCompatibility;
            app.preferences.maximizeCompatibility = needMaximize;
        }
            
		for (var i = 0; i < inputFiles.length; i++) {

			try {
				if ( ( inputFiles[i] instanceof File && 
					! inputFiles[i].hidden ) || 
					this.params["useopen"] ) {

					cameraRawParams.fileName = inputFiles[i].fullName.toString();

					if ( IsFileOneOfThese( cameraRawParams.fileName, gFileExtensionsToRead ) ||
				 		IsFileOneOfTheseTypes( cameraRawParams.fileName, gFileTypesToRead ) ) {
						gFoundFileToProcess = true;
						if ( ! this.runningFromBridge && this.params["useopen"] ) {
							app.activeDocument = inputFiles[ i ];
							app.activeDocument.duplicate();
						} else {
							if ( ! gOpenedFirstCR && this.params["open"] && IsFileOneOfThese( cameraRawParams.fileName, gFilesForCameraRaw ) ){
								// this is the first CR file and the user elected to open it and choose settings to apply to the
								// rest of the CR files
								gOpenedFirstCR = true;
								cameraRawParams.useDescriptor = true;
								this.OpenCameraRaw( cameraRawParams, true )
							} else {
								this.OpenCameraRaw( cameraRawParams, false, DialogModes.NO );
							}
						}

						this.AdjustFile( cameraRawParams );

						if ( this.params["saveinsame"] ) {
							var destFolder = inputFiles[i].parent.toString();
							if ( ! this.runningFromBridge && this.params["useopen"] ) {
								var destFolder = inputFiles[i].fullName.parent.toString();
								cameraRawParams.fileName = app.activeDocument.name;
							}
						} else {
							var destFolder = this.params["dest"];
						}

						this.SaveFile( cameraRawParams.fileName, destFolder  );
						app.activeDocument.close( SaveOptions.DONOTSAVECHANGES );
					}
				}
			}
			// don't let one file spoil the party!
			// trying to stop on user cancel is a problem
			// during the open of a large file the error we get is no such element
			// and not the actual cancel 8007
			// it's all about timing, hit the cancel right after a document opens
			// and all is well and you get the cancel and everything stops
			catch( e ) {
				if ( e.number == 8007 ) { // stop only on cancel
					break;
				}
				this.fileErrors.push( inputFiles[i] );
			}
		}
		
		if ( rememberMaximize != undefined ) {
            app.preferences.maximizeCompatibility = rememberMaximize;
        }

        if ( ! gFoundFileToProcess )
			alert( strNoOpenableFiles );

		// crash on quit when running from bridge
		cameraRawParams.desc = null;
		$.gc();

	}
	
	// using the dialog adjust the active document
	this.AdjustFile = function ( inOutCameraRawParams ) {
		var docRef = app.activeDocument;

		if ( this.params["info"] != "" ) {
			docRef.info.copyrightNotice = this.params["info"];
			docRef.info.copyrighted = CopyrightedType.COPYRIGHTEDWORK;
		}
	}
	
	// I can save in three formats, JPEG, PSD, TIFF /// plus PNG
	this.SaveFile = function ( inFileName, inFolderLocation ) {
		var lastDot = inFileName.lastIndexOf( "." );
		if ( lastDot == -1 ) {
			lastDot = inFileName.length;
		}
		var fileNameNoPath = inFileName.substr( 0, lastDot );
		var lastSlash = fileNameNoPath.lastIndexOf( "/" );
		fileNameNoPath = fileNameNoPath.substr( lastSlash + 1, fileNameNoPath.length );
		if ( this.params["jpeg"] ) {
			if ( ! this.runningFromBridge && this.params["keepstructure"] && ! this.params["saveinsame"] ) {
				var subFolderText = activeDocument.path.fsName.toString();
				subFolderText = subFolderText.replace( this.params["source"], this.params["dest"] );
				subFolderText += "/";
			} else {
			var subFolderText = inFolderLocation + "/JPEG/";
			}
			Folder( subFolderText ).create();
			var historyState = app.activeDocument.activeHistoryState;
			app.activeDocument.flatten();
			if ( DocumentMode.RGB != app.activeDocument.mode ) {
				if( !this.params["keepcmyk"] ){//
					ConditionalModeChangeToRGB();
				}else if( DocumentMode.CMYK != app.activeDocument.mode ) {//
					ConditionalModeChangeToRGB();//
				}
			}
			app.activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
			RemoveAlphaChannels();
			if ( this.params["converticc"] && !this.params["keepcmyk"] ) {//
				ConvertTosRGBProfile();
			}
			if ( this.params["jpegresize"] ) {
				FitImage( this.params["jpegw"], this.params["jpegh"] ); 
			}
			if ( this.params["runaction"] ) {
				doAction( this.params["action"], this.params["actionset"] );
			}
			var uniqueFileName = CreateUniqueFileName( subFolderText, fileNameNoPath, ".jpg" );
			if ( ! IsFolderWritable( subFolderText ) ) {
				alert( strCannotWriteToFolder + File( subFolderText ).fsName );
			} else {
				SaveAsJPEG( uniqueFileName, this.params["q"], this.params["icc"] );
			}
			app.activeDocument.activeHistoryState = historyState;
		}
///
		if ( this.params["png"] ) {
			if ( ! this.runningFromBridge && this.params["keepstructure"] && ! this.params["saveinsame"] ) {
				var subFolderText = activeDocument.path.fsName.toString();
				subFolderText = subFolderText.replace( this.params["source"], this.params["dest"] );
				subFolderText += "/";
			} else {
			var subFolderText = inFolderLocation + "/PNG/";
			}
			Folder( subFolderText ).create();
			var historyState = app.activeDocument.activeHistoryState;
			// don't flatten saveAs copy to deal with layers while keeping transparency
			if ( DocumentMode.RGB != app.activeDocument.mode ) {
				ConditionalModeChangeToRGB();
			}
			app.activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
			RemoveAlphaChannels();

			if ( this.params["pngresize"] ) {
				FitImage( this.params["pngw"], this.params["pngh"] ); 
			}
			if ( this.params["runaction"] ) {
				doAction( this.params["action"], this.params["actionset"] );
			}
			var uniqueFileName = CreateUniqueFileName( subFolderText, fileNameNoPath, ".png" );
			if ( ! IsFolderWritable( subFolderText ) ) {
				alert( strCannotWriteToFolder + File( subFolderText ).fsName );
			} else {
				SaveAsPNG( uniqueFileName, this.params["interlace"] );
			}
			app.activeDocument.activeHistoryState = historyState;
		}
///
		if ( this.params["psd"] ) {
			if ( ! this.runningFromBridge && this.params["keepstructure"] && ! this.params["saveinsame"] ) {
				var subFolderText = activeDocument.path.fsName.toString();
				subFolderText = subFolderText.replace( this.params["source"], this.params["dest"] );
				subFolderText += "/";
			} else {
			var subFolderText = inFolderLocation + "/PSD/";
			}
			Folder( subFolderText ).create();
			var historyState = app.activeDocument.activeHistoryState;
			if ( this.params["psdresize"] ) {
				FitImage( this.params["psdw"], this.params["psdh"] ); 
			}
			if ( this.params["runaction"] ) {
				doAction( this.params["action"], this.params["actionset"] );
			}
			var uniqueFileName = CreateUniqueFileName( subFolderText, fileNameNoPath, ".psd" );
			if ( ! IsFolderWritable( subFolderText ) ) {
				alert( strCannotWriteToFolder + File( subFolderText ).fsName );
			} else {
				SaveAsPSD( uniqueFileName, this.params["icc"] );
			}
			app.activeDocument.activeHistoryState = historyState;
		}
		
		if ( this.params["tiff"] ) {
			if ( ! this.runningFromBridge && this.params["keepstructure"] && ! this.params["saveinsame"] ) {
				var subFolderText = activeDocument.path.fsName.toString();
				subFolderText = subFolderText.replace( this.params["source"], this.params["dest"] );
				subFolderText += "/";
			} else {
			var subFolderText = inFolderLocation + "/TIFF/";
			}
			Folder( subFolderText ).create();
			var historyState = app.activeDocument.activeHistoryState;
			if ( this.params["tiffresize"] ) {
				FitImage( this.params["tiffw"], this.params["tiffh"] ); 
			}
			if ( this.params["runaction"] ) {
				doAction( this.params["action"], this.params["actionset"] );
			}
			var uniqueFileName = CreateUniqueFileName( subFolderText, fileNameNoPath, ".tif" );
			if ( ! IsFolderWritable( subFolderText ) ) {
				alert( strCannotWriteToFolder + File( subFolderText ).fsName );
			} else {
				SaveAsTIFF( uniqueFileName, this.params["icc"], this.params["lzw"] );
			}
			app.activeDocument.activeHistoryState = historyState;
		}
	}
		
	// open a camera raw file returning the camera raw action desc
	this.OpenCameraRaw = function( inOutCameraRawParams, updateCRDesc, inDialogMode ) {
		var keyNull = charIDToTypeID( 'null' );
		var keyAs = charIDToTypeID( 'As  ' );
		var adobeCameraRawID = stringIDToTypeID( "Adobe Camera Raw" );
		var desc = new ActionDescriptor();
		desc.putPath( keyNull, File( inOutCameraRawParams.fileName ) );
		if ( inOutCameraRawParams.desc != undefined && inOutCameraRawParams.useDescriptor &&
		     IsFileOneOfThese( inOutCameraRawParams.fileName, gFilesForCameraRaw ) ) {
			desc.putObject( keyAs, adobeCameraRawID, inOutCameraRawParams.desc );
		}
		if ( inDialogMode == undefined ) {
			inDialogMode = DialogModes.ALL;
			
			// Suppress choose file dialog.
			var overrideOpenID = stringIDToTypeID( 'overrideOpen' );
			desc.putBoolean( overrideOpenID, true );
		}
		var returnDesc = executeAction( charIDToTypeID( 'Opn ' ), desc, inDialogMode );
		if ( returnDesc.hasKey( keyAs ) ) {
			if (updateCRDesc)
				inOutCameraRawParams.desc = returnDesc.getObjectValue( keyAs, adobeCameraRawID );
			if ( returnDesc.hasKey( keyNull ) ) {
				inOutCameraRawParams.fileName = returnDesc.getPath( keyNull ).toString();
				return true;
			}
		}
		return false;
	}
	
	// given a folder return the first valid file in that folder
	this.GetFirstFile = function ( inFolder ) {
		if ( inFolder.length > 0 && inFolder[0] != '.' ) {
			var fileList = Folder( inFolder ).getFiles();
			for ( var i = 0; i < fileList.length; i++) {
				if ( fileList[i] instanceof File && ! fileList[i].hidden &&
					(IsFileOneOfThese( fileList[i], gFileExtensionsToRead ) ||
					 IsFileOneOfTheseTypes( fileList[i], gFileTypesToRead ) ) ) {
					return fileList[i].toString();
				}
			}
		}
		return "";
	}
	
	///////////////////////////////////////////////////////////////////////////
	// Function: ConfigForBridge
	// Usage: see if the Bridge app is running this script
	// Input: gFilesFromBridge is a variable that is defined in photoshop.jsx
	// Return: runningFromBridge and filesFromBridge are initialized
	///////////////////////////////////////////////////////////////////////////
	this.ConfigForBridge = function() {
		if ( typeof( gFilesFromBridge ) != "undefined" ) {
			this.filesFromBridge = gFilesFromBridge;
			if ( this.filesFromBridge.length > 0 ) {
				this.runningFromBridge = true;
			} else {
				this.runningFromBridge = false;
			}
		} else { 
			this.runningFromBridge = false;
			this.filesFromBridge = undefined;
		}
	}

	///////////////////////////////////////////////////////////////////////////
	// Function: ReportErrors
	// Usage: pop the name of the files we had trouble with
	// Input:
	// Return:
	///////////////////////////////////////////////////////////////////////////
	this.ReportErrors = function() {
		if ( this.fileErrors.length ) {
			var message = strCouldNotProcess;
			for ( var i = 0; i < this.fileErrors.length; i++ ) {
				message += File( this.fileErrors[i] ).fsName + "\r";
			}
			alert( message );
		}
	}

	// initialize properties
	this.fileErrors = new Array();

	this.params = this.InitParams();

	this.actionInfo = GetActionSetInfo();
	
	this.ConfigForBridge();
	
}


function SaveAsJPEG( inFileName, inQuality, inEmbedICC ) {
	var jpegOptions = new JPEGSaveOptions();
	jpegOptions.quality = inQuality;
	jpegOptions.embedColorProfile = inEmbedICC;
	app.activeDocument.saveAs( File( inFileName ), jpegOptions );
}
///
function SaveAsPNG( inFileName, interlace ) {// only option for PNG is lnterlaced
	var pngOptions = new PNGSaveOptions();
	pngOptions.interlaced = interlace;
	app.activeDocument.saveAs( File( inFileName ), pngOptions, true );
}
///
function SaveAsPSD( inFileName, inEmbedICC ) {
	var psdSaveOptions = new PhotoshopSaveOptions();
    psdSaveOptions.embedColorProfile = inEmbedICC;
	app.activeDocument.saveAs( File( inFileName ), psdSaveOptions );
}
	
function SaveAsTIFF( inFileName, inEmbedICC, inLZW ) {
	var tiffSaveOptions = new TiffSaveOptions();
    tiffSaveOptions.embedColorProfile = inEmbedICC;
    if ( inLZW ) {
		tiffSaveOptions.imageCompression = TIFFEncoding.TIFFLZW;
	} else {
		tiffSaveOptions.imageCompression = TIFFEncoding.NONE;
	}	
	app.activeDocument.saveAs( File( inFileName ), tiffSaveOptions );
}

// use the fit image automation plug-in to do this work for me
function FitImage( inWidth, inHeight ) {
	if ( inWidth == undefined || inHeight == undefined ) {
		alert( strWidthAndHeight );
		return;
	}
	var desc = new ActionDescriptor();
	var unitPixels = charIDToTypeID( '#Pxl' );
	desc.putUnitDouble( charIDToTypeID( 'Wdth' ), unitPixels, inWidth );
	desc.putUnitDouble( charIDToTypeID( 'Hght' ), unitPixels, inHeight );
	var runtimeEventID = stringIDToTypeID( "3caa3434-cb67-11d1-bc43-0060b0a13dc4" );	
	executeAction( runtimeEventID, desc, DialogModes.NO );
}

// a very crude xml parser, this reads the "Tag" of the <Tag>Data</Tag>
function ReadHeader( inFile ) {
	var returnValue = "";
	if ( ! inFile.eof ) {
		var c = "";
		while ( c != "<" && ! inFile.eof ) {
			c = inFile.read( 1 );
		}
		while ( c != ">" && ! inFile.eof ) {
			c = inFile.read( 1 );
			if ( c != ">" ) {
				returnValue += c;
			}
		}
	} else {
		returnValue = "end of file";
	}
	return returnValue;
}

// very crude xml parser, this reads the "Data" of the <Tag>Data</Tag>
function ReadData( inFile ) {
	var returnValue = "";
	if ( ! inFile.eof ) {
		var c = "";
		while ( c != "<" && ! inFile.eof ) {
			c = inFile.read( 1 );
			if ( c != "<" ) {
				returnValue += c;
			}
		}
		inFile.seek( -1, 1 );
	}
	return returnValue;
}

///////////////////////////////////////////////////////////////////////////////
// Function: CheckVersion
// Usage: Check our minimum requirement for a host version
// Input: <none> Photoshop should be our target environment but i just look at the version
// Return: throws an error if we do not pass
///////////////////////////////////////////////////////////////////////////////
function CheckVersion() {
	var numberArray = version.split(".");
	if ( numberArray[0] < 9 ) {
		alert( strMustUse );
		throw( strMustUse );
	}
}

///////////////////////////////////////////////////////////////////////////
// Function: StrToIntWithDefault
// Usage: convert a string to a number, first stripping all characters
// Input: string and a default number
// Return: a number
///////////////////////////////////////////////////////////////////////////
function StrToIntWithDefault( s, n ) {
    var onlyNumbers = /[^0-9]/g;
    var t = s.replace( onlyNumbers, "" );
	t = parseInt( t );
	if ( ! isNaN( t ) ) {
        n = t;
    }
    return n;
}

///////////////////////////////////////////////////////////////////////////////
// Function: CreateUniqueFileName
// Usage: Given a folder, filename, and extension, come up with a unique file name
// using a numbering system
// Input: string for folder, fileName, and extension, extension contains the "."
// Return: string for the full path to the unique file
///////////////////////////////////////////////////////////////////////////////
function CreateUniqueFileName( inFolder, inFileName, inExtension ) {
	inFileName = inFileName.replace(/[:\/\\*\?\"\<\>\|]/g, "_");  // '/\:*?"<>|' -> '_'
	var uniqueFileName = inFolder + inFileName + inExtension;
	var fileNumber = 1;
	while ( File( uniqueFileName ).exists ) {
		uniqueFileName = inFolder + inFileName + "_" + fileNumber + inExtension;
		fileNumber++;
	}
	return uniqueFileName;
}

///////////////////////////////////////////////////////////////////////////////
// Function: IsWindowsOS
// Usage: Are we running on the Windows OS?
// Input: <none>
// Return: true if on a Windows
///////////////////////////////////////////////////////////////////////////////
function IsWindowsOS() {
	if ( $.os.search(/windows/i) != -1 ) {
		return true;
	} else {
		return false;
	}
}

///////////////////////////////////////////////////////////////////////////////
// Function: IsMacintoshOS
// Usage: Are we running on the Macintosh OS?
// Input: <none>
// Return: true if on a macintosh
///////////////////////////////////////////////////////////////////////////////
function IsMacintoshOS() {
	if ( $.os.search(/macintosh/i) != -1 ) {
		return true;
	} else {
		return false;
	}
}

///////////////////////////////////////////////////////////////////////////////
// Function: RemoveAlphaChannels
// Usage: Remove all of the extra channels from the current document
// Input: <none> (must be an active document)
// Return: <none> activeDocument now has only component channels
///////////////////////////////////////////////////////////////////////////////
function RemoveAlphaChannels() {
	var channels = app.activeDocument.channels;
	var channelCount = channels.length - 1;
	while ( channels[channelCount].kind != ChannelType.COMPONENT ) {
		channels[channelCount].remove();
		channelCount--;
	}
}

///////////////////////////////////////////////////////////////////////////////
// Function: ConvertTosRGBProfile
// Usage: Convert to sRGB profile
// Input: <none> (must be an active document)
// Return: activeDocument is now in sRGB profile
///////////////////////////////////////////////////////////////////////////////
function ConvertTosRGBProfile() {
	app.activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, true);
}


///////////////////////////////////////////////////////////////////////////////
// Function: GetScriptNameForXML
// Usage: From my file name, get the XML version
// Input: <none>
// Return: String for XML version of my script, taken from strTitle which is a global
// NOTE: you can't save certain characters in xml, strip them here
// this list is not complete
///////////////////////////////////////////////////////////////////////////////
function GetScriptNameForXML () {
	var scriptNameForXML = new String( strTitle );
	var charsToStrip = Array( " ", "'", "." );
	for (var a = 0; a < charsToStrip.length; a++ )  {
		var nameArray = scriptNameForXML.split( charsToStrip[a] );
		scriptNameForXML = "";
		for ( var b = 0; b < nameArray.length; b++ ) {
			scriptNameForXML += nameArray[b];
		}
	}
	return scriptNameForXML;
}


/////////////////////////////////////////////////////////////////////
// Function: MacXMLFilter
// Input: f, file or folder to check
// Return: true or false, true if file or folder is to be displayed
/////////////////////////////////////////////////////////////////////
function MacXMLFilter( f )
{
	var xmlExtension = ".xml";
	var lCaseName = f.name;
	lCaseName.toLowerCase();
	if ( lCaseName.indexOf( xmlExtension ) == f.name.length - xmlExtension.length )
		return true;
	else if ( f.type == 'TEXT' )
		return true;
	else if ( f instanceof Folder )
		return true;
	else
		return false;
}

///////////////////////////////////////////////////////////////////////////////
// Function: GetDefaultParamsFile
// Usage: Find my default settings, this is last ran values
// Input: <none>
// Return: File to my default settings
///////////////////////////////////////////////////////////////////////////////
function GetDefaultParamsFile() {
	return ( new File( app.preferencesFolder + "/" + strTitle + ".xml" ) );
}

///////////////////////////////////////////////////////////////////////////////
// Function: FindDialog
// Usage: From a deeply grouped dialog item go up til you find the parent dialog
// Input: Current dialog item, an actual item or a group
// Return: top parent dialog
///////////////////////////////////////////////////////////////////////////////
function FindDialog( inItem ) {
	var w = inItem;
	while ( 'dialog' != w.type ) {
		if ( undefined == w.parent ) {
			w = null;
			break;
		}
		w = w.parent;
	}
	return w;
}

///////////////////////////////////////////////////////////////////////////////
// Function: GetFilesFromBridge
// Usage: Use this to retrieve the current files from the Bridge application
// Input: <none>
// Return: arary of the current documents that have file paths
// NOTE: I don't use this routine as I run differently only when called from 
// the Bridge, see photoshop.jsx
///////////////////////////////////////////////////////////////////////////////
function GetFilesFromBridge() {
	var fileList;
	if ( BridgeTalk.isRunning( "bridge" ) ) {
		var bt = new BridgeTalk();
		bt.target = "bridge";
		bt.body = "var theFiles = photoshop.getBridgeFileListForAutomateCommand();theFiles.toSource();";
		bt.onResult = function( inBT ) { fileList = eval( inBT.body ); }
		bt.onError = function( inBT ) { fileList = new Array(); }
		bt.send();
		bt.pump();
		$.sleep( 100 );
		var timeOutAt = ( new Date() ).getTime() + 5000;
		var currentTime = ( new Date() ).getTime();
		while ( ( currentTime < timeOutAt ) && ( undefined == fileList ) ) {
			bt.pump();
			$.sleep( 100 );
			currentTime = ( new Date() ).getTime();
		}
	}
	if ( undefined == fileList ) {
		fileList = new Array();
	}
	return fileList; 
}


///////////////////////////////////////////////////////////////////////////////
// Function: GetActionSetInfo
// Usage: walk all the items in the action palette and record the action set
//        names and all the action children
// Input: <none>
// Return: the array of all the ActionData
// Note: This will throw an error during a normal execution. There is a bug
// in Photoshop that makes it impossible to get an acurate count of the number
// of action sets.
///////////////////////////////////////////////////////////////////////////////
function GetActionSetInfo() {
	var actionSetInfo = new Array();
	var setCounter = 1;
  	while ( true ) {
		var ref = new ActionReference();
		ref.putIndex( gClassActionSet, setCounter );
		var desc = undefined;
		try { desc = executeActionGet( ref ); }
		catch( e ) { break; }
		var actionData = new ActionData();
		if ( desc.hasKey( gKeyName ) ) {
			actionData.name = desc.getString( gKeyName );
		}
		var numberChildren = 0;
		if ( desc.hasKey( gKeyNumberOfChildren ) ) {
			numberChildren = desc.getInteger( gKeyNumberOfChildren );
		}
		if ( numberChildren ) {
			actionData.children = GetActionInfo( setCounter, numberChildren );
			actionSetInfo.push( actionData );
		}
		setCounter++;
	}
	return actionSetInfo;
}


///////////////////////////////////////////////////////////////////////////////
// Function: GetActionInfo
// Usage: used when walking through all the actions in the action set
// Input: action set index, number of actions in this action set
// Return: true or false, true if file or folder is to be displayed
///////////////////////////////////////////////////////////////////////////////
function GetActionInfo( setIndex, numChildren ) {
	var actionInfo = new Array();
	for ( var i = 1; i <= numChildren; i++ ) {
		var ref = new ActionReference();
		ref.putIndex( gClassAction, i );
		ref.putIndex( gClassActionSet, setIndex );
		var desc = undefined;
		desc = executeActionGet( ref );
		var actionData = new ActionData();
		if ( desc.hasKey( gKeyName ) ) {
			actionData.name = desc.getString( gKeyName );
		}
		var numberChildren = 0;
		if ( desc.hasKey( gKeyNumberOfChildren ) ) {
			numberChildren = desc.getInteger( gKeyNumberOfChildren );
		}
		actionInfo.push( actionData );
	}
	return actionInfo;
}


///////////////////////////////////////////////////////////////////////////////
// Function: ActionData
// Usage: this could be an action set or an action
// Input: <none>
// Return: a new Object of ActionData
///////////////////////////////////////////////////////////////////////////////
function ActionData() {
	this.name = "";
	this.children = undefined;
	this.toString = function () {
		var strTemp = this.name;
		if ( undefined != this.children ) {
			for ( var i = 0; i < this.children.length; i++ ) {
				strTemp += " " + this.children[i].toString();
			}
		}
		return strTemp;
	}
}

///////////////////////////////////////////////////////////////////////////////
// Function: OpenDocs
// Usage: we want the current open documents that have a path
// Input: <none>
// Return: arary of the current documents that have file paths
// NOTE: We want the current open documents that have a path
// if I do inputFiles = documents then I have a reference
// and if I add documents it also adds them to my inputFiles
// I want to copy the current state
///////////////////////////////////////////////////////////////////////////////
function OpenDocs() {
	var docs = new Array();
	var i = 0;
	var docIndex = 0;
	var alertNonSavedDocs = false;
	var nonSavedDocs = new Array();
	for ( var i = 0; i < app.documents.length; i++ ) {
		try {
			var temp = app.documents[ i ].fullName;
			docs[ docIndex ] = app.documents[ i ];
			docIndex++;
		}
		catch( e ) {
			if ( e.number == 8103 ) { // this document has not been saved
				alertNonSavedDocs = true;
				nonSavedDocs.push( app.documents[ i ].name );
			} else {
				throw e;
			}
		}
	}
	if ( alertNonSavedDocs ) {
		alert( strMustSaveOpen + "\r" + strFollowing + "\r( " + nonSavedDocs + " )" );
	}
	return docs;
}

///////////////////////////////////////////////////////////////////////////////
// Function: ConditionalModeChangeToRGB
// Usage: Convert the front document to RGB no matter what the original space is
// Input: <none>
// Return: activeDocument is now in RGB mode, this actually is another script now
///////////////////////////////////////////////////////////////////////////////
function ConditionalModeChangeToRGB() {
	var eventModeChange = stringIDToTypeID( "8cba8cd6-cb66-11d1-bc43-0060b0a13dc4" );
	var descSource = new ActionDescriptor();
	var keySourceMode = charIDToTypeID( "SrcM" );
	var list = new ActionList();
	var keyCondition = charIDToTypeID( "Cndn" );
	var keyBitmap = charIDToTypeID( "UBtm" );
	var keyGrayscale = charIDToTypeID( "UGry" );
	var keyDuotone = charIDToTypeID( "UDtn" );
	var keyIndex = charIDToTypeID( "UInd" );
	var keyRGB = charIDToTypeID( "URGB" );
	var keyCMYK = charIDToTypeID( "UCMY" );
	var keyLab = charIDToTypeID( "ULab" );
	var keyMultichannel = charIDToTypeID( "UMlt" );
	list.putEnumerated( keyCondition, keyBitmap );
	list.putEnumerated( keyCondition, keyGrayscale );
	list.putEnumerated( keyCondition, keyDuotone );
	list.putEnumerated( keyCondition, keyIndex );
	list.putEnumerated( keyCondition, keyRGB );
	list.putEnumerated( keyCondition, keyCMYK );
	list.putEnumerated( keyCondition, keyLab );
	list.putEnumerated( keyCondition, keyMultichannel );
	descSource.putList( keySourceMode, list );
	var keyDestination = charIDToTypeID( "DstM" );
	var descDest = new ActionDescriptor();
	var keyRGB = charIDToTypeID( "RGBM" );
	descSource.putObject( keyDestination, keyRGB, descDest );
	executeAction( eventModeChange, descSource, DialogModes.NO );
}

///////////////////////////////////////////////////////////////////////////////
// Function: FindAllFiles
// Usage: Find all the files in the given folder recursively
// Input: srcFolder is a string to a folder
//		  destArray is an Array of File objects
// Return: Array of File objects, same as destArray
///////////////////////////////////////////////////////////////////////////////
function FindAllFiles( srcFolderStr, destArray ) {
	var fileFolderArray = Folder( srcFolderStr ).getFiles();

	for ( var i = 0; i < fileFolderArray.length; i++ ) {
		var fileFoldObj = fileFolderArray[i];
		if ( fileFoldObj instanceof File ) {
			destArray.push( fileFoldObj );
		} else { // folder
			FindAllFiles( fileFoldObj.toString(), destArray );
		}
	}

	return destArray;
}

///////////////////////////////////////////////////////////////////////////////
// Function: NumericEditKeyboardHandler
// Usage: Do not allow anything except for numbers 0-9
// Input: ScriptUI keydown event
// Return: <nothing> key is rejected and beep is sounded if invalid
///////////////////////////////////////////////////////////////////////////////
function NumericEditKeyboardHandler (event) {
    try {
        var keyIsOK = KeyIsNumeric (event) || 
		              KeyIsDelete (event) || 
					  KeyIsLRArrow (event) ||
					  KeyIsTabEnterEscape (event);
					  
        if (! keyIsOK) {
            //    Bad input: tell ScriptUI not to accept the keydown event
            event.preventDefault();
            /*    Notify user of invalid input: make sure NOT
                to put up an alert dialog or do anything which
                requires user interaction, because that
                interferes with preventing the 'default'
                action for the keydown event */
            app.beep();
        }
    }
    catch (e) {
        ; // alert ("Ack! bug in NumericEditKeyboardHandler: " + e);
    }
}


//    key identifier functions
function KeyHasModifier (event) {
    return event.shiftKey || event.ctrlKey || event.altKey || event.metaKey;
}

function KeyIsNumeric (event) {
    return  (event.keyName >= '0') && (event.keyName <= '9') && ! KeyHasModifier (event);
}

function KeyIsDelete (event) {
    //    Shift-delete is ok
    return (event.keyName == 'Backspace') && ! (event.ctrlKey);
}

function KeyIsLRArrow (event) {
    return ((event.keyName == 'Left') || (event.keyName == 'Right')) && ! (event.altKey || event.metaKey);
}

function KeyIsTabEnterEscape (event) {
	return event.keyName == 'Tab' || event.keyName == 'Enter' || event.keyName == 'Escape';
}

// End Image Processor.jsx

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 19, 2022 Oct 19, 2022

Copy link to clipboard

Copied

LATEST

@Tom Winkelmann – Thank you! What other goodies do you have stashed away?!

 

TIP: At least for me on the Mac with Safari, it was faster to scroll by click and select from the bottom upward, rather than the top down.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 15, 2022 Oct 15, 2022

Copy link to clipboard

Copied

Another couple of options, I hacked these from another script back in 2019... Both scripts convert to sRGB. They are batch scripts that process a selected folder of PSD files. The file type can be changed as required.

 

This one uses Save As, therefore, it will retain the resolution metadata info.

 

#target photoshop

// Batch Save As sRGB PNG.jsx

displayDialogs = DialogModes.NO

// raw.githubusercontent.com/jonahvsweb/Photoshop-Automated-Resize-to-Web.jsx/master/Automated%20Resize%20To%20Web.jsx

if (BridgeTalk.appName == "photoshop") {
    app.bringToFront;

    var inputFolder = Folder.selectDialog("Select the source folder that contains the PSD files for save as PNG:");

    if (inputFolder != null) {
        var fileList = inputFolder.getFiles(/\.(psd)$/i);
        var outputFolder = inputFolder;

        for (var i = 0; i < fileList.length; i++) {
            if (fileList[i] instanceof File) {
                var document = open(fileList[i]);
                var documentName = fileList[i].name.replace(/\.[^\.]+$/, ''); // Regex remove filename extension

                while (app.documents.length) {
                    var newFile = new File(decodeURI(outputFolder) + "/" + documentName + ".png");

                    // document.flatten (); // Disable flatten image step

                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    function ConvertTosRGBProfile() {
                        app.activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
                    }
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                    var pngOptions = new PNGSaveOptions();
                    pngOptions.compression = 0
                    pngOptions.interlaced = false;
                    app.activeDocument.saveAs(newFile, pngOptions, true, Extension.LOWERCASE);
                    app.activeDocument.close();

                }
            }
            if (i == fileList.length - 1) {
                alert("All PSD files have been saved as PNG files!");
            }
        }
    }
}

 

 

While this one uses Export Save for Web (Legacy) and will not retain the resolution metadata:

 

#target photoshop

// Batch Export SfW sRGB PNG.jsx

displayDialogs = DialogModes.NO

// raw.githubusercontent.com/jonahvsweb/Photoshop-Automated-Resize-to-Web.jsx/master/Automated%20Resize%20To%20Web.jsx

if (BridgeTalk.appName == "photoshop") {
    app.bringToFront;

    var inputFolder = Folder.selectDialog("Select the source folder that contains the PSD files for PNG export:");

    if (inputFolder != null) {
        var fileList = inputFolder.getFiles(/\.(psd)$/i);
        var outputFolder = inputFolder ;

        for (var i = 0; i < fileList.length; i++) {
            if (fileList[i] instanceof File) {
                var document = open (fileList [i]);
                var documentName = fileList [i].name.replace(/\.[^\.]+$/, ''); // Regex remove filename extension

                while (app.documents.length) {
                    var newFile = new File(decodeURI(outputFolder) + "/" + documentName + ".png");

                    // document.flatten (); // Disable flatten image step

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    function ConvertTosRGBProfile() {
                            app.activeDocument.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
                        }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                    exportOptions = new ExportOptionsSaveForWeb();
                    exportOptions.format = SaveDocumentType.PNG;
                    exportOptions.PNG8 = false; // false = PNG-24
                    exportOptions.transparency = true; // true = transparent
                    exportOptions.interlaced = false; // true = interlacing on
                    exportOptions.includeProfile = true; // false = don't embedd ICC profile
                    document.exportDocument(newFile, ExportType.SAVEFORWEB, exportOptions);
                    document.close(SaveOptions.DONOTSAVECHANGES);
                }
            }
            if (i == fileList.length - 1) {
                alert("All PSD files have been saved as PNG files!");
            }
        }
    }
}

 

  

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 17, 2022 Oct 17, 2022

Copy link to clipboard

Copied

Oh WOW this is way beyond my technical boundaries for me to understand, but thank you you're amazing.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 18, 2022 Oct 18, 2022

Copy link to clipboard

Copied

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines