16 Replies Latest reply on May 20, 2018 7:14 PM by Kukurykus

    PS Scripting - check if layer link is temporary disabled

    Jarda Bereza Level 4

      Hard question for experts.

       

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

       

        • 1. Re: PS Scripting - check if layer link is temporary disabled
          oliverIntergrafika Level 2

          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.

          • 2. Re: PS Scripting - check if layer link is temporary disabled
            Jarda Bereza Level 4

            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

            • 3. Re: PS Scripting - check if layer link is temporary disabled
              Jarda Bereza Level 4

              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;
                  }
              }
              
              
              
              1 person found this helpful
              • 4. Re: PS Scripting - check if layer link is temporary disabled
                oliverIntergrafika Level 2

                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

                • 5. Re: PS Scripting - check if layer link is temporary disabled
                  Kukurykus Adobe Community Professional

                  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[f]) 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

                  • 6. Re: PS Scripting - check if layer link is temporary disabled
                    Jarda Bereza Level 4

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

                    • 7. Re: PS Scripting - check if layer link is temporary disabled
                      r-bin Level 4

                      Well then, here's a more practical function if you use PS CC ))

                       

                      alert(get_select_linked_eanbled())
                      
                      function get_select_linked_eanbled()
                          {
                          try
                              {
                              var r = new ActionReference();    
                              r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("menuBarInfo"));    
                              r.putEnumerated(charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
                      
                              var lst = executeActionGet(r).getObjectValue(stringIDToTypeID("menuBarInfo")).getList((stringIDToTypeID("submenu")))
                      
                              for (var i = 0; i < lst.count; i++)
                                  {
                                  var obj = lst.getObjectValue(i);    
                      
                                  if (obj.getString(stringIDToTypeID("title")) == "&Layer")
                                      {
                                      lst = obj.getList(stringIDToTypeID("submenu"));
                      
                                      for (var i = 0; i < lst.count; i++)
                                          {
                                          obj = lst.getObjectValue(i);    
                      
                                          if (obj.getString(stringIDToTypeID("title")) == "&Select Linked Layers")
                                              {
                                              return obj.getBoolean(stringIDToTypeID("enabled"))
                                              }
                                          }
                          
                                      break;
                                      }    
                                  }
                              }
                          catch (e) { alert(e); }
                          }
                      
                      • 8. Re: PS Scripting - check if layer link is temporary disabled
                        Kukurykus Adobe Community Professional

                        I just waited you come with something like it

                        • 9. Re: PS Scripting - check if layer link is temporary disabled
                          Jarda Bereza Level 4

                          r-bin: this will fail if user don't have photoshop in English. You should compare it according localized string. There should be way how to get this string localized in user language.

                          • 10. Re: PS Scripting - check if layer link is temporary disabled
                            Jarda Bereza Level 4

                            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

                            • 11. Re: PS Scripting - check if layer link is temporary disabled
                              r-bin Level 4

                              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);
                              
                              • 12. Re: PS Scripting - check if layer link is temporary disabled
                                Jarda Bereza Level 4

                                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

                                • 13. Re: PS Scripting - check if layer link is temporary disabled
                                  r-bin Level 4

                                  Well, then still have to go over the "menuBarInfo"?

                                  An interesting experience. Thank you!

                                  P.S. In my code, it's better to replace putDouble with putInteger. So it is more correct.

                                  • 14. Re: PS Scripting - check if layer link is temporary disabled
                                    Jarda Bereza Level 4

                                    Once you get this number I think you can hardcode it inside the code. It should be constant if a value is not negative.

                                    The menubar is one option but you can get this number from script listener code. If you click on command in menu there will be 2 blocks of code. One of them looks like garbage and here is a number you want.

                                     

                                    // =======================================================
                                    var idinvokeCommand = stringIDToTypeID( "invokeCommand" );
                                        var desc55 = new ActionDescriptor();
                                        var idcommandID = stringIDToTypeID( "commandID" );
                                        desc55.putInteger( idcommandID, 2960 ); // here is our ID
                                        var idkcanDispatchWhileModal = stringIDToTypeID( "kcanDispatchWhileModal" );
                                        desc55.putBoolean( idkcanDispatchWhileModal, true );
                                    executeAction( idinvokeCommand, desc55, DialogModes.NO );
                                    
                                    
                                    // =======================================================
                                    var idselectLinkedLayers = stringIDToTypeID( "selectLinkedLayers" );
                                        var desc56 = new ActionDescriptor();
                                        var idnull = charIDToTypeID( "null" );
                                            var ref17 = new ActionReference();
                                            var idLyr = charIDToTypeID( "Lyr " );
                                            var idOrdn = charIDToTypeID( "Ordn" );
                                            var idTrgt = charIDToTypeID( "Trgt" );
                                            ref17.putEnumerated( idLyr, idOrdn, idTrgt );
                                        desc56.putReference( idnull, ref17 );
                                    executeAction( idselectLinkedLayers, desc56, DialogModes.NO );
                                    
                                    1 person found this helpful
                                    • 15. Re: PS Scripting - check if layer link is temporary disabled
                                      Kukurykus Adobe Community Professional

                                      Few months ago when I needed to edit shortcuts in preferences (profiles you set in Photoshop) I found that is not possible by script, but I found other scriptable method. When opening a desired profile (that is a file with no extension) from for ex. C:\Users\User\AppData\Roaming\Adobe\Adobe Photoshop CS6\Adobe Photoshop CS6 Settings\WorkSpaces with XML by ExtendScript ToolKit, you'll get access to all id's and names plus shortcuts of commands. If you didn't use some shortcut in Ps then command won't be there displayed untill you save it in some profile, however build-in Photoshop commands have always the same (static) id's. I used this way of writing scripts in Adobe Bridge (however by static names for menu bars as it's all well described in Adobe Bridge JavaScript Reference) but I didn't suppose you have'll the same in Photoshop CC

                                      • 16. Re: PS Scripting - check if layer link is temporary disabled
                                        Kukurykus Adobe Community Professional

                                        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 = []