I cobbled together quite a large script for Photoshop, but have run into a problem with part of it. Part of the script moves the selected layer in Photoshop to a specified folder/group. The part I’m having difficulty with is if the selected layer is within a folder, or a few nested folders.
If I know how many folders the selected layer is in (and their names) then I can adjust the script accordingly, but I’d like it to work when nested in any amount of folders so I don’t have to keep changing the script
Here’s the part of the script:
tell application id "com.adobe.Photoshop"
tell current document
set selectedLayer to name of current layer
set layerContainer to name of container of current layer
set rootContainer to name of container of container of current layer
move layer selectedLayer of layer set layerContainer of layer set rootContainer to layer set "mask" of layer set "colour fill" of layer set "Artwork"
end tell
end tell
So the part at the bottom is fine where it moves the selected layer to ‘Artwork’ folder > ‘colour fill’ folder > ‘mask’ folder.
I guess I’d just need a script to count the number of folders the selected layer is in (and set each nested folder as variables?) so that I could move the selected layer no matter how many folders it’s nested in (it seems you have to specify the folders that the selected layer is nested in, in order to be able to move the layer to another folder).
I’d bypass all the “figuring out how deep the nesting goes” thing by getting the Photoshop Index Number for the selected layer, convert the index to a reference, then move it by reference.
So it would just need a minor modification, as below.
As it stands now, it would move any set of selected layers to the destination - you could do more than one at a time if you wanted.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
global foundLayer -- recursive function to drill down arbitrary layer nesting, setting global to exit function regardless of how deep the calls go
set selectedLayerIndexes to get_selected_layer_indexes() -- get the index numbers for all selected layers
set selectedLayerReferences to {}
tell application "Adobe Photoshop CC 2018" to tell the current document to set allLayers to the layers
-- convert each layer index to a layer reference
repeat with aLayerIndex in selectedLayerIndexes
set foundLayer to false
copy recurse_layer_sets(allLayers, aLayerIndex) to end of selectedLayerReferences
end repeat
-- move each layer
tell application "Adobe Photoshop CC 2018"
set currentDoc to the current document
tell currentDoc
set repeatCount to 0
repeat with i from (count of selectedLayerReferences) to 1 by -1
set aLayer to item i of selectedLayerReferences
move aLayer to layer set "mask" of layer set "colour fill" of layer set "Artwork"
end repeat
end tell
end tell
-- drills through all layer sets to look up layers by itemindex and return an Applescript reference to the layer
on recurse_layer_sets(layerList, theItemIndex)
set theItemIndex to theItemIndex as number -- it's already an integer; not sure why this is necessary
if foundLayer is not false then return foundLayer
tell application "Adobe Photoshop CC 2018"
set currentDoc to the current document
tell currentDoc
set layerGroupCount to the count of layerList
repeat with i from 1 to layerGroupCount
set aLayer to item i of layerList
if the (itemindex of aLayer) as number is theItemIndex then
set foundLayer to aLayer
exit repeat
else
if the class of aLayer is layer set then my recurse_layer_sets((layers of aLayer), theItemIndex)
end if
end repeat
end tell
end tell
return foundLayer
end recurse_layer_sets
-- AM code to get the indexes of all selected layers
on get_selected_layer_indexes()
tell application "Adobe Photoshop CC 2018"
set selectedLayers to do javascript "
getSelectedLayersIdx()
function getSelectedLayersIdx() {
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID(\"Dcmn\"), charIDToTypeID(\"Ordn\"), charIDToTypeID(\"Trgt\"));
var desc = executeActionGet(ref);
if (desc.hasKey(stringIDToTypeID(\"targetLayers\"))) {
desc = desc.getList(stringIDToTypeID(\"targetLayers\"));
var c = desc.count
var selectedLayers = new Array();
for (var i = 0; i < c; i++) {
try {
docRef.backgroundLayer;
selectedLayers.push(desc.getReference(i).getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i).getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(charIDToTypeID(\"Prpr\"), charIDToTypeID(\"ItmI\"));
ref.putEnumerated(charIDToTypeID(\"Lyr \"), charIDToTypeID(\"Ordn\"), charIDToTypeID(\"Trgt\"));
try {
docRef.backgroundLayer;
selectedLayers.push(executeActionGet(ref).getInteger(charIDToTypeID(\"ItmI\")) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref).getInteger(charIDToTypeID(\"ItmI\")));
}
}
return selectedLayers;
} "
end tell
set selectedLayersListText to text_to_list(selectedLayers, ",") -- Javascript spits out comma delimited list
-- Javascript also spits out numbers as strings; switch to integers
set selectedLayersList to {}
repeat with anItem in selectedLayersListText
set selectedLayersList to selectedLayersList & (anItem as number)
end repeat
return selectedLayersList
end get_selected_layer_indexes
-- converts text delimited strings to AS lists
on text_to_list(someText, aSeparator)
set {delimitHolder, AppleScript's text item delimiters} to {AppleScript's text item delimiters, aSeparator}
set outputList to the text items of someText
set AppleScript's text item delimiters to delimitHolder
return outputList
end text_to_list
If I select a single layer it works perfectly. But if I select multiple layers then it doesn’t quite work right, it moves some of the layers but not all of them and shows an error.
For example, here I select 4 layers
Then run script and one of the selected layers doesn’t get moved (green), and a layer that wasn’t selected gets moved (orange).
When running the script it highlights this line
move aLayer to layer set "mask" of layer set "colour fill" of layer set "Artwork"
And the error message in Script Editor says:
error “Adobe Photoshop CC 2018 got an error: Can’t get art layer 4 of layer set 2 of layer set 1 of document "Test_Document.psd".” number -1728 from art layer 4 of layer set 2 of layer set 1 of document “Test_Document.psd”
Hi. If I understand the original question, the problem appears to be that the selection is being purposefully deconstructed and reconstructed when the object reference is fine as-is.
tell application "Adobe Photoshop CS3"'s document 1 to move current layer to layer set "mask" of layer set "colour fill" of layer set "Artwork"
Ah, yes, I see the problem here. The AppleScript references are not absolute references to the layers - they are relative references. Once you start moving things, an Applescript reference like:
won’t still refer to the same layer if other layers have moved around.
So it’ll always move a single selected layer correctly, but after that, all bets are off because that first move starts changing what (if anything) the remaining references refer to.
I haven’t experimented yet, but I don’t think Marc’s solution is going to solve this situation with multiple layers, because Applescript’s “current layer” only refers to the active layer, not the other selected layers when there is a multiple-layer selection.
This is certainly fixable. But I need to check and see what layer identifier remains static as the layers are moved, and use that to identify them to perform the move.
I don’t have time for that at the moment, but maybe in the next few days.
I’m posting my whole script below so you can see what’s going on. The script creates the Artwork, colour fill, and mask folders, and in the process loses focus of the selected layer. So in my existing script it has to specify the path to the previously selected layer in order to move it.
But if there’s a better/simpler way then please let me know
Sure, no hurry. I appreciate the help, so whenever’s good for you
Here’s the whole of my script:
set colourFromClipboard to (get the clipboard)
tell application id "com.adobe.Photoshop"
activate
tell current document
set selectedLayer to current layer
set layerName to name of current layer
set layerContainer to name of container of current layer
(* Make sure current layer/group as visible *)
set visible of selectedLayer to true
end tell
(* Fill selected vector shape with black *)
tell current document
do javascript "var c = new SolidColor();
c.rgb.hexValue = '000000'
set_fill_color(c);
//set_stroke_color(c);
function set_stroke_color(c)
{
try {
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID('contentLayer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
d.putReference(stringIDToTypeID('null'), r);
var d1 = new ActionDescriptor();
var d2 = new ActionDescriptor();
var d3 = new ActionDescriptor();
var d4 = new ActionDescriptor();
d4.putDouble(stringIDToTypeID('red'), c.rgb.red);
d4.putDouble(stringIDToTypeID('green'), c.rgb.green);
d4.putDouble(stringIDToTypeID('blue'), c.rgb.blue);
d3.putObject(stringIDToTypeID('color'), stringIDToTypeID('RGBColor'), d4);
d2.putObject(stringIDToTypeID('strokeStyleContent'), stringIDToTypeID('solidColorLayer'), d3);
d2.putBoolean(stringIDToTypeID('strokeEnabled'), true);
d1.putObject(stringIDToTypeID('strokeStyle'), stringIDToTypeID('strokeStyle'), d2);
d.putObject(stringIDToTypeID('to'), stringIDToTypeID('shapeStyle'), d1);
executeAction(stringIDToTypeID('set'), d, DialogModes.NO);
}
catch (e) { throw(e); }
}
function set_fill_color(c)
{
try {
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID('contentLayer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
d.putReference(stringIDToTypeID('null'), r);
var d1 = new ActionDescriptor();
var d2 = new ActionDescriptor();
var d3 = new ActionDescriptor();
d3.putDouble(stringIDToTypeID('red'), c.rgb.red);
d3.putDouble(stringIDToTypeID('green'), c.rgb.green);
d3.putDouble(stringIDToTypeID('blue'), c.rgb.blue);
d2.putObject(stringIDToTypeID('color'), stringIDToTypeID('RGBColor'), d3);
d1.putObject(stringIDToTypeID('fillContents'), stringIDToTypeID('solidColorLayer'), d2);
var d4 = new ActionDescriptor();
d4.putBoolean(stringIDToTypeID('fillEnabled'), true);
d1.putObject(stringIDToTypeID('strokeStyle'), stringIDToTypeID('strokeStyle'), d4);
d.putObject(stringIDToTypeID('to'), stringIDToTypeID('shapeStyle'), d1);
executeAction(stringIDToTypeID('set'), d, DialogModes.NO);
}
catch (e) { throw(e); }
}" show debugger on runtime error
end tell
(* Create Folders *)
tell current document
set artworkFolder to "Artwork"
if exists layer set named artworkFolder then
(* Do nothing *)
else
make new layer set at beginning with properties {name:artworkFolder}
end if
set colourFillFolder to "colour fill"
if exists layer set named colourFillFolder in layer set artworkFolder then
(* Do nothing *)
else
make new layer set in layer set artworkFolder with properties {name:colourFillFolder}
end if
set blendingMaskFolder to "mask"
if exists layer set named blendingMaskFolder in layer set colourFillFolder in layer set artworkFolder then
(* Do nothing *)
else
make new layer set in layer set colourFillFolder in layer set artworkFolder ¬
with properties {name:blendingMaskFolder}
end if
end tell
(* Set blending mode for mask folder *)
tell current document
do javascript "
blend_if(0,0, 255,255, 0,0, 0,255, 'k');
function blend_if(db0,db1, dw0,dw1, sb0,sb1, sw0,sw1, ch)
{
try {
if (db0 == undefined) db0 = 0;
if (db1 == undefined) db1 = db0;
if (dw0 == undefined) dw0 = 255;
if (dw1 == undefined) dw1 = dw0;
if (sb0 == undefined) sb0 = 0;
if (sb1 == undefined) sb1 = sb0;
if (sw0 == undefined) sw0 = 255;
if (sw1 == undefined) sw1 = sw0;
if (ch == undefined) ch = 'krgb';
var use_r = false;
var use_g = false;
var use_b = false;
var use_k = false;
if (ch.indexOf('r') >= 0) use_r = true;
if (ch.indexOf('g') >= 0) use_g = true;
if (ch.indexOf('b') >= 0) use_b = true;
if (ch.indexOf('k') >= 0) use_k = true;
var desc3 = new ActionDescriptor();
var desc4 = new ActionDescriptor();
var ref1 = new ActionReference();
var list1 = new ActionList();
ref1.putEnumerated( charIDToTypeID( 'Lyr ' ), charIDToTypeID( 'Ordn' ), charIDToTypeID( 'Trgt' ) );
desc3.putReference( charIDToTypeID( 'null' ), ref1 );
for (var i = 0; i < 4; i++)
{
var desc5 = new ActionDescriptor();
var ref2 = new ActionReference();
use_cont = false;
switch ( i )
{
case 0: if (!use_k) { use_cont = true; break; } ref2.putEnumerated( charIDToTypeID( 'Chnl' ), charIDToTypeID( 'Chnl' ), charIDToTypeID( 'Gry ' ) ); break;
case 1: if (!use_r) { use_cont = true; break; } ref2.putEnumerated( charIDToTypeID( 'Chnl' ), charIDToTypeID( 'Chnl' ), charIDToTypeID( 'Rd ' ) ); break;
case 2: if (!use_g) { use_cont = true; break; } ref2.putEnumerated( charIDToTypeID( 'Chnl' ), charIDToTypeID( 'Chnl' ), charIDToTypeID( 'Grn ' ) ); break;
case 3: if (!use_b) { use_cont = true; break; } ref2.putEnumerated( charIDToTypeID( 'Chnl' ), charIDToTypeID( 'Chnl' ), charIDToTypeID( 'Bl ' ) ); break;
}
if (use_cont) continue;
desc5.putReference( charIDToTypeID( 'Chnl' ), ref2 );
desc5.putInteger( charIDToTypeID( 'SrcB' ), sb0 );
desc5.putInteger( charIDToTypeID( 'Srcl' ), sb1 );
desc5.putInteger( charIDToTypeID( 'SrcW' ), sw0 );
desc5.putInteger( charIDToTypeID( 'Srcm' ), sw1 );
desc5.putInteger( charIDToTypeID( 'DstB' ), db0 );
desc5.putInteger( charIDToTypeID( 'Dstl' ), db1 );
desc5.putInteger( charIDToTypeID( 'DstW' ), dw0 );
desc5.putInteger( charIDToTypeID( 'Dstt' ), dw1 );
list1.putObject( charIDToTypeID( 'Blnd' ), desc5 );
}
desc4.putList( charIDToTypeID( 'Blnd' ), list1 );
desc3.putObject( charIDToTypeID( 'T ' ), charIDToTypeID( 'Lyr ' ), desc4 );
executeAction( charIDToTypeID( 'setd' ), desc3, DialogModes.NO );
}
catch (e) { alert(e); }
}" show debugger on runtime error
end tell
(* Move selected layer to 'mask' folder *)
tell current document
move layer layerName of layer set layerContainer to layer set blendingMaskFolder of layer set colourFillFolder of layer set artworkFolder
(* Select 'colour fill' folder *)
set current layer to layer set colourFillFolder of layer set artworkFolder
end tell
end tell
(* Show dialog & ask to choose colour *)
activate me
set colourList to {"Clipboard (#" & colourFromClipboard & ")", "Black", "White"}
set chosenColour to (choose from list colourList with prompt "Fill Colour?" without multiple selections allowed) as text
if chosenColour is "Clipboard (#" & colourFromClipboard & ")" then
set theColour to colourFromClipboard
else if chosenColour is "Black" then
set theColour to "000000"
else if chosenColour is "White" then
set theColour to "FFFFFF"
end if
(* Add chosen colour to folder as colour overlay style *)
tell application id "com.adobe.Photoshop"
tell current document
do javascript "var c = new SolidColor();
c.rgb.hexValue = " & quoted form of theColour & "
app.activeDocument.suspendHistory('TMP', 'aaa()');
executeAction( charIDToTypeID( 'undo' ), undefined, DialogModes.NO );
executeAction( charIDToTypeID( 'PaFX' ), undefined, DialogModes.NO );
function aaa()
{
app.activeDocument.artLayers.add();
var idsetd = charIDToTypeID( 'setd' );
var desc9 = new ActionDescriptor();
var idnull = charIDToTypeID( 'null' );
var ref1 = new ActionReference();
var idPrpr = charIDToTypeID( 'Prpr' );
var idLefx = charIDToTypeID( 'Lefx' );
ref1.putProperty( idPrpr, idLefx );
var idLyr = charIDToTypeID( 'Lyr ' );
var idOrdn = charIDToTypeID( 'Ordn' );
var idTrgt = charIDToTypeID( 'Trgt' );
ref1.putEnumerated( idLyr, idOrdn, idTrgt );
desc9.putReference( idnull, ref1 );
var idT = charIDToTypeID( 'T ' );
var desc10 = new ActionDescriptor();
var idScl = charIDToTypeID( 'Scl ' );
var idPrc = charIDToTypeID( '#Prc' );
desc10.putUnitDouble( idScl, idPrc, 100.000000 );
var idSoFi = charIDToTypeID( 'SoFi' );
var desc11 = new ActionDescriptor();
var idenab = charIDToTypeID( 'enab' );
desc11.putBoolean( idenab, true );
var idpresent = stringIDToTypeID( 'present' );
desc11.putBoolean( idpresent, true );
var idshowInDialog = stringIDToTypeID( 'showInDialog' );
desc11.putBoolean( idshowInDialog, true );
var idMd = charIDToTypeID( 'Md ' );
var idBlnM = charIDToTypeID( 'BlnM' );
var idNrml = charIDToTypeID( 'Nrml' );
desc11.putEnumerated( idMd, idBlnM, idNrml );
var idClr = charIDToTypeID( 'Clr ' );
var desc12 = new ActionDescriptor();
var idRd = charIDToTypeID( 'Rd ' );
desc12.putDouble( idRd, c.rgb.red ); // RED
var idGrn = charIDToTypeID( 'Grn ' );
desc12.putDouble( idGrn, c.rgb.green ); // GREEN
var idBl = charIDToTypeID( 'Bl ' );
desc12.putDouble( idBl, c.rgb.blue ); // BLUE
var idRGBC = charIDToTypeID( 'RGBC' );
desc11.putObject( idClr, idRGBC, desc12 );
var idOpct = charIDToTypeID( 'Opct' );
var idPrc = charIDToTypeID( '#Prc' );
desc11.putUnitDouble( idOpct, idPrc, 100.000000 );
var idSoFi = charIDToTypeID( 'SoFi' );
desc10.putObject( idSoFi, idSoFi, desc11 );
var idLefx = charIDToTypeID( 'Lefx' );
desc9.putObject( idT, idLefx, desc10 );
executeAction( idsetd, desc9, DialogModes.NO );
executeAction( charIDToTypeID( 'CpFX' ), undefined, DialogModes.NO );
}" show debugger on runtime error
end tell
end tell
(* Select previously selected layer *)
tell application id "com.adobe.Photoshop"
activate
tell current document
set current layer to layer layerName of layer set blendingMaskFolder ¬
of layer set colourFillFolder of layer set artworkFolder
end tell
end tell
Current layer is problematic, as there can be only one and the references are relative, as noted by t.spoon. The best option may be to abandon your desired multi-selection method, which become even more troublesome with nested items. Your best alternative to that option may be to move the selecting into the script, excepting the first instance.
tell application "Adobe Photoshop CS3"'s document 1
set isTarget to current layer
if exists layer set "art"'s layer set "fill"'s layer set "mask" then
set nextTarget to layer set "art"'s layer set "fill"'s layer set "mask"
else
set nextTarget to make layer set with properties {name:"mask"} at make layer set with properties {name:"fill"} at make layer set with properties {name:"art"}
end if
if isTarget's container's class = document then
try --prevent action on immovable objects
repeat with focus in my (choose from list (get art layers's name) with multiple selections allowed)
move layer (focus's contents) to nextTarget
end repeat
end try
else
try --ditto
repeat with focus in my (choose from list (get isTarget's container's art layers's name) with multiple selections allowed)
move current layer's container's layer (focus's contents) to nextTarget
end repeat
end try
end if
end tell
What are you initially selecting? It’s fine to select a layer within a layer set, but I haven’t accounted for the eventuality that the initial item actually is a layer set. Try a couple different choices and post more detail if it continues to fail.
I’m sure this could be much, much simpler if I knew more Javascript AM code.
But in some testing I did, it seems to be working.
Photoshop’s “layer index” that the javascript function returns is the same as the Applescript references in that it’s relative - move one layer, and the rest of the references change what they refer to.
There’s “layer ID,” which stays static with moves.
I couldn’t find code to return the layer ID’s though.
So I’m still getting the indexes of the selected layers, then converting them to a list of Layer ID’s. Then I one by one convert the layer ID’s to references and move them. Let me know if this works for you.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
tell application "Adobe Photoshop CC 2018"
tell the current document
set allLayers to the layers
set moveToLayerSet to layer set "Move To Folder" -- set the location you want the files moved to here
end tell
end tell
global foundLayerID -- recursive function to drill down arbitrary layer nesting, setting global to exit function regardless of how deep the calls go
global foundLayerReference
set selectedLayerIndexes to get_selected_layer_indexes() -- get the index numbers for all selected layers
set selectedLayerIDs to {}
-- convert each layer index to a layer reference
repeat with aLayerIndex in selectedLayerIndexes
set foundLayerID to false
copy get_layer_ID_from_layer_index(allLayers, aLayerIndex) to end of selectedLayerIDs
end repeat
move_layers_by_layer_ID(moveToLayerSet, allLayers, selectedLayerIDs)
on move_layers_by_layer_ID(moveLocation, layerList, moveLayerIDs)
set moveLayerCount to the count of moveLayerIDs
repeat with i from 1 to moveLayerCount
set aLayerID to item i of moveLayerIDs
set foundLayerReference to false
set layerRef to my get_layer_reference_from_layerID(layerList, aLayerID)
tell application "Adobe Photoshop CC 2018" to tell the current document to move layerRef to moveLocation
end repeat
end move_layers_by_layer_ID
on get_layer_reference_from_layerID(layerList, layerID)
set layerID to layerID as number
if foundLayerReference is not false then return foundLayerReference
tell application "Adobe Photoshop CC 2018"
tell the current document
set layerGroupCount to the count of layerList
repeat with i from 1 to layerGroupCount
set aLayer to item i of layerList
if the (id of aLayer) as number is layerID then
set foundLayerReference to aLayer
exit repeat
else
if the class of aLayer is layer set then my get_layer_reference_from_layerID((layers of aLayer), layerID)
end if
end repeat
end tell
end tell
return foundLayerReference
end get_layer_reference_from_layerID
on get_layer_ID_from_layer_index(layerList, theItemIndex)
set theItemIndex to theItemIndex as number -- it's already an integer; not sure why this is necessary
if foundLayerID is not false then return foundLayerID
tell application "Adobe Photoshop CC 2018"
tell the current document
set layerGroupCount to the count of layerList
repeat with i from 1 to layerGroupCount
set aLayer to item i of layerList
if the (itemindex of aLayer) as number is theItemIndex then
set foundLayerID to the id of aLayer
exit repeat
else
if the class of aLayer is layer set then my get_layer_ID_from_layer_index((layers of aLayer), theItemIndex)
end if
end repeat
end tell
end tell
return foundLayerID
end get_layer_ID_from_layer_index
-- AM code to get the indexes of all selected layers
on get_selected_layer_indexes()
tell application "Adobe Photoshop CC 2018"
set selectedLayers to do javascript "
getSelectedLayersIdx()
function getSelectedLayersIdx() {
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID(\"Dcmn\"), charIDToTypeID(\"Ordn\"), charIDToTypeID(\"Trgt\"));
var desc = executeActionGet(ref);
if (desc.hasKey(stringIDToTypeID(\"targetLayers\"))) {
desc = desc.getList(stringIDToTypeID(\"targetLayers\"));
var c = desc.count
var selectedLayers = new Array();
for (var i = 0; i < c; i++) {
try {
docRef.backgroundLayer;
selectedLayers.push(desc.getReference(i).getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i).getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(charIDToTypeID(\"Prpr\"), charIDToTypeID(\"ItmI\"));
ref.putEnumerated(charIDToTypeID(\"Lyr \"), charIDToTypeID(\"Ordn\"), charIDToTypeID(\"Trgt\"));
try {
docRef.backgroundLayer;
selectedLayers.push(executeActionGet(ref).getInteger(charIDToTypeID(\"ItmI\")) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref).getInteger(charIDToTypeID(\"ItmI\")));
}
}
return selectedLayers;
} "
end tell
set selectedLayersListText to text_to_list(selectedLayers, ",") -- Javascript spits out comma delimited list
-- Javascript also spits out numbers as strings; switch to integers
set selectedLayersList to {}
repeat with anItem in selectedLayersListText
set selectedLayersList to selectedLayersList & (anItem as number)
end repeat
return selectedLayersList
end get_selected_layer_indexes
-- converts text delimited strings to AS lists
on text_to_list(someText, aSeparator)
set {delimitHolder, AppleScript's text item delimiters} to {AppleScript's text item delimiters, aSeparator}
set outputList to the text items of someText
set AppleScript's text item delimiters to delimitHolder
return outputList
end text_to_list
One inside a single folder, and one not in a folder. When it shows the error message in Script Editor it also highlights ‘document’ in this line of the script:
if isTarget's «class ctnr»'s class = document then
Hmm. t.spoon’s code appears to not be backwards compatible, as it states a requested property is unavailable, and I don’t understand enough JavaScript to attempt to modify the method for my use.
I suspect that you edited my code to reflect the application ID as the tell object, as in your other posts; my dictionary loses the connection when telling “com.adobe…” and returns the same raw events and subsequent error you reported. For my reference, if you restart PS and plug in your literal version into the code in post #7, does it work? If it still errors, please post the event log from this:
tell application "Adobe Photoshop CS3" --change to your version... Adobe Photoshop CC?
activate (launch)
tell (make document) to {its class, current layer's class, current layer's container, current layer's container's class}
end tell
I tried your original script again, but only changed ‘tell application “Adobe Photoshop CS3”’ to ‘tell application "Adobe Photoshop CC 2018’.
After playing around with it I have managed to get it to work… sort of.
When I run it for the first time I get the same error as always (but can see that the ‘art’, ‘fill’ and ‘mask’ folders were successfully created). If I select the layer I want to move again, and then run the script again (after the folders have been created when the script ran for the first time) then it works fine.
Could it be that after the script has run the part that creates the folders (and the ‘mask’ folder is selected in the layers list in Ps) it loses focus/reference to the original selected layer?
And so it works the second time around because focus is on the selected layer, and it doesn’t need to create the folders again?
Here’s the result of the last script you posted:
tell application "Adobe Photoshop CC 2018"
launch
activate
make new document
--> document "Untitled-1"
get class of document "Untitled-1"
--> document
get class of current layer of document "Untitled-1"
--> art layer
get container of current layer of document "Untitled-1"
--> document "Untitled-1"
get class of container of current layer of document "Untitled-1"
--> document
end tell
Result:
{document, art layer, document "Untitled-1" of application "Adobe Photoshop CC 2018", document}
So I’m trying to integrate this with my original script, but have run into a problem.
The first part of my script creates folders/layer sets (code below), but means the previously selected layers become unselected before this part of the script is run (so your script doesn’t know which layers were selected in order to move them). And if I don’t create the folders then your script won’t work because it can’t find the target folders
Any ideas on the best way to make this work properly, and how the rest of my code (in my previous post) should fit in with it?
(* Create Folders *)
tell current document
set artworkFolder to "Artwork"
if exists layer set named artworkFolder then
(* Do nothing *)
else
make new layer set at beginning with properties {name:artworkFolder}
end if
set colourFillFolder to "colour fill"
if exists layer set named colourFillFolder in layer set artworkFolder then
(* Do nothing *)
else
make new layer set in layer set artworkFolder with properties {name:colourFillFolder}
end if
set blendingMaskFolder to "mask"
if exists layer set named blendingMaskFolder in layer set colourFillFolder in layer set artworkFolder then
(* Do nothing *)
else
make new layer set in layer set colourFillFolder in layer set artworkFolder ¬
with properties {name:blendingMaskFolder}
end if
end tell
Yes, you’ll want to start by running the parts of my script up through the repeat loop that builds the list of selectedLayerIDs.
The layer ID’s will not change as you create new layers, so this will be a list of what layers were selected before you do anything else and lose the selection.
Then go ahead and modify the document any way you need to - make the new folders, set the variable for moveToLayerSet to the new folder you made.