Skip to main content
Jarda Bereza
Inspiring
July 22, 2017
Answered

PS Scripting - check if layer link is temporary disabled

  • July 22, 2017
  • 4 replies
  • 4139 views

Hard question for experts.

I can get list of linked layers, but how can I know if link is temporary disabled? (red cross)

This topic has been closed for replies.
Correct answer r-bin

it's cool!

It remains only to find out where you took the code for the command?

AM version:

var r = new ActionReference();     

r.putEnumerated(charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); 

var d = new ActionDescriptor();

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

d.putString (stringIDToTypeID("command"), "getCommandEnabled"); 

d.putDouble(stringIDToTypeID("commandID"), 2960 ); 

var ret = executeAction(stringIDToTypeID("uiInfo"), d, DialogModes.NO).getObjectValue(stringIDToTypeID("result")).getBoolean(stringIDToTypeID("enabled"));

alert(ret);

4 replies

Jarda Bereza
Inspiring
February 22, 2018

I would use this instead:

#include Humanizer.jsx

// github.com/jardicc/ActionManagerHumanizer

// I don't have time rewrite it into pure Action manager code.

var $test = Humanizer.playObject("uiInfo", {

        "null": {

"_enum": "ordinal",

"_ref": "application",

"_value": "targetEnum"

},

        "command": "getCommandEnabled",

        "commandID": 2960

    });

alert($test.result.enabled);

In pure AM this should be faster because asking for whole menu structure is costly. There is huge amount of data.

ID should be static and it's localization independent and also no matter where it is located in menu.

Note: if you have already selected all linked layers then this command is disabled

r-binCorrect answer
Legend
February 22, 2018

it's cool!

It remains only to find out where you took the code for the command?

AM version:

var r = new ActionReference();     

r.putEnumerated(charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); 

var d = new ActionDescriptor();

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

d.putString (stringIDToTypeID("command"), "getCommandEnabled"); 

d.putDouble(stringIDToTypeID("commandID"), 2960 ); 

var ret = executeAction(stringIDToTypeID("uiInfo"), d, DialogModes.NO).getObjectValue(stringIDToTypeID("result")).getBoolean(stringIDToTypeID("enabled"));

alert(ret);

Jarda Bereza
Inspiring
February 22, 2018

Command ID is inside menubar Descriptor.

Note: beware of commandIDs with negative value. They are not static but they are dynamic e.g. plugins, scripts ect.

2018-02-22_152030.jpg

Kukurykus
Legend
February 22, 2018

Works fast. I tried it with 300 layer(Set)s of different kinds with different combinations. Of course that is no answer, because when you have big dimension then saving pixels of each layer to disk my take 1-2 secs for whole document. So it's probably good up to some layers limit (depending of its dimension). Possibly faltting before saving could help? Maybe later I'll try it...

with(psd = new PhotoshopSaveOptions()) {

     layers = !(alphaChannels = embedColorProfile = annotations = spotColors = false)

}

activeDocument.saveAs(fle = File('~/desktop/.psd'), psd, true);

(function() {

     fle.encoding = 'binary', fle.open('r'); var r = fle.read()

     index = r.indexOf('8BIM\x040'), fle.seek(index + 10)

     function bin(v) {return v * fle.readch().charCodeAt()}

     var d = fle.read(L = l = bin(256) + bin(1)), re = /\x00/g

     a = []; while(re.exec(d)) (a.push(re.lastIndex)), b = []

     var r = r.slice(fle.tell(), r.length), re = /8BIMluni/g

     while(a.length && re.exec(r)) {

          if (a[0] + --l == L)  {

               b.push(re.lastIndex - 1), a.shift()

          }

     }

     while(b.length) {

          f = b.shift() + 9, w = ''

          while(!r) w += r[++f], ++f

          a.push(w)

     }

     fle.close(), fle.remove(), alert(a)

})()

I forgot to make case for not disabled layers so make sure you disabled at least one linked layer before you run this script

Jarda Bereza
Inspiring
February 22, 2018

I am seeing you are improving in binary work. Anyway I think reading file binary should be last option when everything else fails :-)

Kukurykus
Legend
May 20, 2018

There's very small mistake in my script causing a crash when none of any Linked Layers was Disabled.

But it's easy to fix. At the end of line number 12 replace comma (,) to semicolon (;) right before b = []

Jarda Bereza
Inspiring
July 23, 2017

This workaround looks a bit better. In previous code you know that link group contains disabled link but you didn't know which one.

This uses availability of "select linked" menu item. I suggest modify this code to remember selected linked layers if code will have success. So you can skip all next layers in linked group.

isLinkDisabled();

function isLinkDisabled(){

    try{

        var idslct = charIDToTypeID( "slct" );

            var desc135 = new ActionDescriptor();

            var idnull = charIDToTypeID( "null" );

                var ref63 = new ActionReference();

                var idMn = charIDToTypeID( "Mn  " );

                var idMnIt = charIDToTypeID( "MnIt" );

                var idplacedLayerEditContents = stringIDToTypeID( "selectLinkedLayers" );

                ref63.putEnumerated( idMn, idMnIt, idplacedLayerEditContents );

            desc135.putReference( idnull, ref63 );

        executeAction( idslct, desc135, DialogModes.NO );

        return true;

    }catch(e){

        if(e.number == -25920){ // menu item not available

            return false;

        }

        throw e;

    }

}

oliverIntergrafika
Inspiring
July 23, 2017

Jarda, thubs up!

This is not coding, this is the art of PS workaroundcomposing. Using layer menus plus a try/catch to watch if PS throws from the low level code snipplet.

Maybe this is THE way, PS supposed to be programmed.

Thanks!

Oliver

oliverIntergrafika
Inspiring
July 23, 2017

I had the same dead end a few months ago:

Determining if the layer link is turned on or off

 

No answer, no solution.

 

PS is clearly not designed to be scripted.

Jarda Bereza
Inspiring
July 23, 2017

I found workaround which could work

var idselectLinkedLayers = stringIDToTypeID( "selectLinkedLayers" );

    var desc80 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref35 = new ActionReference();

        var idLyr = charIDToTypeID( "Lyr " );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref35.putEnumerated( idLyr, idOrdn, idTrgt );

    desc80.putReference( idnull, ref35 );

executeAction( idselectLinkedLayers, desc80, DialogModes.NO );

1) read layers IDs of linked layers

2) run command selectedLinkedLayers

3) read IDs of selected layer

4) if list of IDs doesn't match it means that this layer or other layers link(s) is disabled