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

Targeting a layer when none is selected.

Advocate ,
Sep 23, 2016 Sep 23, 2016

Copy link to clipboard

Copied

Hi,

this is probably so easy that I can't see it. Simple document:

DB 2016-09-23 at 18.27.31.png

Simple script that loops through layers and deletes the one that's hidden:

var doc = app.activeDocument;

for (var i = 0; i < doc.artLayers.length; i++) {

    if (!doc.artLayers.visible) {

        doc.artLayers.remove();

    }

}

There are better ways I know, but it works.

Now try this as a starting point (no layers actually selected):

DB 2016-09-23 at 18.31.44.png

The above script fails with error "The Command Delete is not currently available".

I've added an extra line to make it active, but it doesn't (at least Photoshop CC2015.5, OSX)

var doc = app.activeDocument;

for (var i = 0; i < doc.artLayers.length; i++) {

    if (!doc.artLayers.visible) {

        app.activeDocument.activeLayer = doc.artLayers;

        doc.artLayers.remove();

    }

}

Am I missing something here?

Thank you!

Davide

TOPICS
Actions and scripting

Views

4.2K

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
Adobe
Community Expert ,
Sep 23, 2016 Sep 23, 2016

Copy link to clipboard

Copied

I do not think so.  I have had to catch that error in some scripts  when the user used the script and had nothing targeted. Even when the script was processing all layers. I had to catch that error I thought should not have happen because I was processing all layers in a recursive loop.  I had to target the top layer the use the scipt's main function to get the recursive loop to work.  I think your loop will also miss layers in layer groups that have their visibility off.

JJMack

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 ,
Sep 23, 2016 Sep 23, 2016

Copy link to clipboard

Copied

Hi JJMack​,

the script is for demo purposes only. The question remains – how to you select / make active *any* layer if even:

app.activeDocument.activeLayer = app.activeDocument.artLayers[0];

fails? I'd like to avoid actionmanager in this case.

Thank you!

Davide

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
LEGEND ,
Sep 23, 2016 Sep 23, 2016

Copy link to clipboard

Copied

I tired second case (no layer selected) with hidden layer[1] or background and it worked, but only then. The same was when I made a loop from end to beggining, so it failed when first (not bottom / background) layer was hidden.

When I checked which layer is active when none of them was selected it always said the first one, even if before I unselected any other that was below top layer. It must be bug.

It doesn't work also with simple:

activeDocument.activeLayer = activeDocument.layers[0]

no matter top layer is (in)visible, when all are unselected

it works only for any other layer beside first one in case of all (manually) unselected layers

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 ,
Sep 23, 2016 Sep 23, 2016

Copy link to clipboard

Copied

Let's step back and forget for a moment about the delete layer, which doesn't work if a layer (any) isn't selected.

I rephrase the issue: if no layer is selected, how do you select / make active a layer (possibly w/o ActionManager)?

Thank you,

Davide

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 ,
Sep 23, 2016 Sep 23, 2016

Copy link to clipboard

Copied

I can not help w/o ActionManager code. What I used was the Action Manager code for the shortcut Alt+.  Select front visible layer.

function selectFront() {

// Alt+. shortcut select ftont visible layer

var idslct = charIDToTypeID( "slct" );

    var desc250 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref207 = new ActionReference();

        var idLyr = charIDToTypeID( "Lyr " );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idFrnt = charIDToTypeID( "Frnt" );

        ref207.putEnumerated( idLyr, idOrdn, idFrnt );

    desc250.putReference( idnull, ref207 );

    var idMkVs = charIDToTypeID( "MkVs" );

    desc250.putBoolean( idMkVs, false );

executeAction( idslct, desc250, DialogModes.NO );

}

JJMack

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
Contributor ,
Aug 30, 2017 Aug 30, 2017

Copy link to clipboard

Copied

JJMack​,

Thank you very much for the code snipped. It will help for my case.

Do you know is there any way (preferably fast to run) to find out if layer is unselected or selected any.

app.activeDocument.activeLayer seems same when it is selected and when none of layer selected.

Thank you,

Naoki

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
LEGEND ,
Sep 23, 2016 Sep 23, 2016

Copy link to clipboard

Copied

Only a trick works:

1) when there are more than one layer or background, and all layers (incl. bg) are unselected then:

select by script any other layer and then you can select layer[0]

2) when there is only one (unselected) layer in a document and it's not a background you can:

if that is set to invisible, make it visible - it won't make a layer active. Then (or if that was already visible) change this layer to background, so it automaticly will be selected. Finally you can change it to layer again. (In case of only background and no other layers there is no problem as background can't be unselected).

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
LEGEND ,
Sep 23, 2016 Sep 23, 2016

Copy link to clipboard

Copied

I JUST THOUGHT UP ANOTHER TRICK!

It's not always method to change only one layer to background, as then you may loose masks or some adjustmensts, so the best and most practical is:

- change only one layer to background

- call the history state before that change, so even if that was unselected, now it will be selected and all adjustments and masks won't be lost

if (activeDocument.layers[0].visible == 1) activeDocument.activeLayer.isBackgroundLayer = true

activeDocument.activeHistoryState = activeDocument.historyStates[activeDocument.historyStates.length - 2]

I tried with duplication but that didn't work. maybe setting to Inteligent Object could help, anyway that above solution seems to be convinient.

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 ,
Sep 23, 2016 Sep 23, 2016

Copy link to clipboard

Copied

Interesting information: the issue happens only when trying to make active the layer[0], and not layer[1] – thanks to Kukurykus​ for finding this out – thanks to JJMack​ for the AM code.

I've submitted this as a bug, because this is what it looks like.

Davide

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 ,
Sep 26, 2016 Sep 26, 2016

Copy link to clipboard

Copied

I am experiencing same issues as well when duplicating layers.

Found yet another workaround - create new layer and then remove it. This will force to auto highlight first layer in the stack.

var newLayer = app.activeDocument.artLayers.add();

newLayer.remove();

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 Beginner ,
May 24, 2018 May 24, 2018

Copy link to clipboard

Copied

I was having the same issue with the following script.

Before adding in the two noted lines the script would not function correctly unless I started with the first layer selected.

Explicitly making it the active layer by calling it by name didn't seem to matter. This seems like a real hack, but it works.

Will see what happens when I test it further in production.

Thanks for the tip,

Scott

#target photoshop

// Make Photoshop the frontmost application

app.bringToFront();

var myDoc = app.activeDocument;

//Adding these two lines fixed it

//var newLayer = myDoc.artLayers.add(); 

//newLayer.remove(); 

var numberOfLayerGroups = myDoc.layerSets.length;

alert("Number of Layer Groups:" + numberOfLayerGroups);

    for (i = 0 ; i < numberOfLayerGroups ; i++){

        var myLayerGroup = myDoc.layerSets;          

        var numberOfSubGroups = myLayerGroup.layerSets.length;

        alert("Number of SubGroups:" + numberOfSubGroups);

       

        for (j = 0 ; j < numberOfSubGroups ; j++){

           

            var theSubGroup = myLayerGroup.layerSets;

            myDoc.activeLayer = myDoc.artLayers.getByName("Signature"); //Get the signature layer

           

            var sigLay = myDoc.activeLayer;

            var sigCopy = sigLay.duplicate(theSubGroup, ElementPlacement.INSIDE);

        

            myDoc.activeLayer = sigCopy;

                      

        }         

    }

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
Contributor ,
Apr 05, 2022 Apr 05, 2022

Copy link to clipboard

Copied

I owe you a beer!

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
Participant ,
Jan 29, 2018 Jan 29, 2018

Copy link to clipboard

Copied

Hey guys.

I have an issue that might be related or not to this topic.

Having a document with 2 layers:

Layer 0 – invisibile

Layer 1 – visibile

I need to merge this all to a new layer. Because merging doesn't work when you have only one visible layer in the document, what I try to do is create a new empty layer on top and then call merging to new layer method. It results in merging going to that new layer.

Now the problem is that when Layer 0 is invisible, calling app.activeDocument.activeLayer = app.activeDocument.layers[0], for whatever reason, makes it visible. This breaks logic of my script a little.

Any tips? I didn't find anything in the docs about activeLayer being visible all the time

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
Participant ,
Jan 29, 2018 Jan 29, 2018

Copy link to clipboard

Copied

So far I have worked this around by doing

var topLayerVisibility = app.activeDocument.layers[0].visible

   app.activeDocument.activeLayer = app.activeDocument.layers[0]

   app.activeDocument.activeLayer.visible = topLayerVisibility

But that's a little funny

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
LEGEND ,
Jan 30, 2018 Jan 30, 2018

Copy link to clipboard

Copied

activeDocument.activeLayer = (lyr = activeDocument.layers)[1], lyr[0].remove()

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 ,
Aug 30, 2017 Aug 30, 2017

Copy link to clipboard

Copied

When you make a loop that deletes an element like a layer, you need to change what "i" is less than. The layers length is going to change as you delete layers. Put that into a variable then us that variable in the loop statement.

var Len = app.activeDocument.layers.length;

for (var i =0;i<Len;i++)

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
People's Champ ,
May 25, 2018 May 25, 2018

Copy link to clipboard

Copied

function reselect_active_layer()

    {

    var r = new ActionReference();  

    r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("layerID"));      

    r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));  

    var id = executeActionGet(r).getInteger(stringIDToTypeID("layerID"));

    var r = new ActionReference();

    r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));  

    var d = new ActionDescriptor();

    d.putReference(stringIDToTypeID("null"), r);

    try { executeAction(stringIDToTypeID("selectNoLayers"), d, DialogModes.NO); } catch(e) {}

    var r = new ActionReference();

    r.putIdentifier(stringIDToTypeID("layer"), id);

    var d = new ActionDescriptor();

    d.putReference(stringIDToTypeID("null"), r);

    d.putBoolean(stringIDToTypeID( "makeVisible"), activeDocument.activeLayer.visible);

    try { executeAction(stringIDToTypeID("select"), d, DialogModes.NO); } catch(e) {}

    }

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
Enthusiast ,
May 25, 2018 May 25, 2018

Copy link to clipboard

Copied

Hi Davide,

I have the same error as you on the last version of Photoshop (19.1.4).

I know you said you don't want AM code, but somehow this will delete all the hidden layers with no error on the "delete".

deleteAllHiddenLayers();

function deleteAllHiddenLayers() {

  var c2t = function (s) { return app.charIDToTypeID(s); };

  var s2t = function (s) { return app.stringIDToTypeID(s); };

  var descriptor = new ActionDescriptor();

  var reference = new ActionReference();

  reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "hidden" ));

  descriptor.putReference( c2t( "null" ), reference );

  executeAction( s2t( "delete" ), descriptor, DialogModes.NO );

}

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
New Here ,
Sep 16, 2022 Sep 16, 2022

Copy link to clipboard

Copied

LATEST

Found the same problem after all these years... Has this bug been reported?

It happens both when no layer is selected and when all layers are selected.

So far, the solutions below work (a big thank you!), but it leaves kind of unnecessary code in the script...

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