Script - is there way how to get filtered layers like from layers panel filter?

  • 1
  • Question
  • Updated 1 year ago
I want get list of filtered layers. PS has nice layers filter. Is there some way how to use these functions for filtering?

I noticed this:
function deleteHiddenLayers(){
        var idDlt = charIDToTypeID( "Dlt " ); // <- ordinary delete
            var desc213 = new ActionDescriptor();
            var idnull = charIDToTypeID( "null" );
                var ref110 = new ActionReference();
                var idLyr = charIDToTypeID( "Lyr " );
                var idOrdn = charIDToTypeID( "Ordn" );
                var idhidden = stringIDToTypeID( "hidden" ); // <- there was usually "Trgt" for selected layers, but now there is "hidden" is this some magic word for filtering?
                ref110.putEnumerated( idLyr, idOrdn, idhidden );
            desc213.putReference( idnull, ref110 );
        executeAction( idDlt, desc213, DialogModes.NO );
    }
Photo of Jaroslav Bereza

Jaroslav Bereza

  • 779 Posts
  • 166 Reply Likes

Posted 2 years ago

  • 1
Photo of christoph pfaffenbichler

christoph pfaffenbichler, Champion

  • 1224 Posts
  • 172 Reply Likes
What do you want to filter for exactly? 
When one »collects the Layers« via Action Manager code the usually is very fast and one can assess any Layer parameter in the same go. 
Photo of Jaroslav Bereza

Jaroslav Bereza

  • 779 Posts
  • 166 Reply Likes
eg. what is the fastest way how could I filter all smart objects with a broken link? In the case of many many layers.
Photo of christoph pfaffenbichler

christoph pfaffenbichler, Champion

  • 1224 Posts
  • 172 Reply Likes
Maybe there are faster ways but please give this a try – it should get you a list of the names and identifiers of SOs with broken links. 

// look for smart objects with broken link;
// 2016, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
app.activeDocument.suspendHistory("replace", "main ()");
};
////////////////////////////////////
function main () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
// if smart objects;
if (layerDesc.hasKey(stringIDToTypeID("smartObject")) == true) {
var theSO = layerDesc.getObjectValue(stringIDToTypeID("smartObject"));
if (theSO.hasKey(stringIDToTypeID("linkMissing"))) {
if (theSO.getBoolean(stringIDToTypeID("linkMissing")) == true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
theLayers.push([theName, theID])
}
};
};
};
}
catch (e) {};
};
alert ("\n"+theLayers.join("\n"));
////////////////////////////////////
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){ 
add = undefined ? add = false:add 
var ref = new ActionReference();
    ref.putIdentifier(charIDToTypeID("Lyr "), id);
    var desc = new ActionDescriptor();
    desc.putReference(charIDToTypeID("null"), ref );
       if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
      desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
   try{
    executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message); 
}
};
Photo of Jaroslav Bereza

Jaroslav Bereza

  • 779 Posts
  • 166 Reply Likes
Ok, this go through all layers in document. As you can see, this code doesn't looks nice/short. But it works and I can solve it similar.

If you look into the filter in layers panel, so there is a direct button to find broken links. So I wonder if it would not use something that is already programmed.

But I just do not know how to call it with script.

In my code above is used magic word "hidden" instead going through all layers and checking layers types and their visibilities in for cycle ect... Instead word hidden is usually used "Trgt" which return array of selected layers indexes. It's also short code without "for loops", ect. :-)
Photo of christoph pfaffenbichler

christoph pfaffenbichler, Champion

  • 1224 Posts
  • 172 Reply Likes
As you can see, this code doesn't looks nice/short. 
You think so?

But I guess I fail to see your point in principle – the Layers Panel Filter determines what is being displayed in that Panel, so from a Scripting standpoint it is no real use when trying to edit actual Layers. 
Whereas having a list with the Identifiers of all Layers in a document that fit a certain requirement makes it possible to process/remove/... them fairly easily/speedily. 
Photo of Jaroslav Bereza

Jaroslav Bereza

  • 779 Posts
  • 166 Reply Likes
Partly I found what I was looking for
Looks like this can find descriptor only for text layer from different selected layers. which has highest itemIndex in selected layers and layer must be text.
        var ref9 = new ActionReference();
        var idTxLr = charIDToTypeID( "TxLr" ); //textLayer
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref9.putEnumerated( idTxLr, idOrdn, idTrgt );
And this contains only is for adjustment layer
        var ref9 = new ActionReference();
        var idTxLr = charIDToTypeID( "AdjL" ); //adjusmentLayer
        var idOrdn = charIDToTypeID( "Ordn" );
        var idTrgt = charIDToTypeID( "Trgt" );
        ref9.putEnumerated( idTxLr, idOrdn, idTrgt );
And then I can read more data about this layer.
        var myDescriptor = executeActionGet(ref9)
And from descriptor I can dig layerID, itemIndex, name, ect. Anyway now I am able read only one matching layer, but I need list of layers. There also should more filter keys. And this should be pretty fast.
(Edited)