8 Replies Latest reply on Mar 18, 2012 2:27 PM by dserodio

    Layers getByName() issue?

    jugenjury Level 2

      I'm using CS4 and I'm curious about a particular issue I'm having when I use getByName() to return a layer. It works fine unless the named layer is in a group. Using the following simple code it runs fine until I choose a layer that is within a group. Then it returns an error: No such element.

       

      #target photoshop

      n=app.activeDocument.activeLayer.name;

      alert(n);

      lay=app.activeDocument.artLayers.getByName(n);

      alert(lay.name);

       

      Am I doing something wrong? Is there another way other than coding a step-through function to do this so it will return the layer whether it's in a group or not without an error?

        • 1. Re: Layers getByName() issue?
          Muppet Mark-QAl63s Level 4

          Using the DOM then I would expect you need to step thru with a recursive function… I would also expect that there is a much faster action manager method have you looked at x's toolkit…?

          • 2. Re: Layers getByName() issue?
            jugenjury Level 2

            I'm afraid you're correct, Mark. The trouble is, the script I'm actually using it in is part of an Events Script and is very time critical. I've spent a lot of effort shaving off even milliseconds in the run time. Now that I've added some grouped layers to my workflow, it's giving me a bit of a problem.

             

            I do have Xbytor's toolkit but have not looked through it as of yet. I was hoping there would be a simple solution using the DOM that would work for any layer so I'm not adding run time to the execution of the script.

            • 3. Re: Layers getByName() issue?
              xbytor2 Level 4
              function makeLayerActiveByName(nm) {
                function cTID(s) { return app.charIDToTypeID(s); };
              
                try {
                  var desc5 = new ActionDescriptor();
                      var ref4 = new ActionReference();
                      ref4.putName( cTID('Lyr '),  nm);
                  desc5.putReference( cTID('null'), ref4 );
                  desc5.putBoolean( cTID('MkVs'), false );
                  executeAction( cTID('slct'), desc5, DialogModes.NO );
                  return true;
              
               } catch (e) {
                 return false;
               } 
              };
              
              // usage:
              // makeLayerActiveByName("some name");
              

               

              This shold work. It returns true if a layer with that name exists, false if not. If you have more than one layer with the same name, one of them is selected.

              • 4. Re: Layers getByName() issue?
                jugenjury Level 2

                I apologize, X. I guess I'll have to back up a bit and explain more. The script is part of an Events Script that runs when I select a layer so all the Event passes to the script is a string containing the layer's name. I use this to automatically select a specific tool for certain layers. The trouble starts when the script takes too long to process. Then, for some reason, my keyboard shortcuts for some tools acts strangely and it turns into more of a hindrance than help.

                 

                Here is the actual script I'm using. Again, I apologize for the misinformation.

                 

                cTID = function(s) { return app.charIDToTypeID(s); };
                sTID = function(s) { return app.stringIDToTypeID(s); };

                try {
                    if (arguments.length >= 2) {
                        var desc = arguments[0];
                        var event = arguments[1];
                        if (event == cTID('slct')) {
                            var ref = desc.getReference(cTID('null'));
                            var cls = ref.getDesiredClass();
                            var nam=ref.getName();
                //            alert(ref.getDesiredClass());
                            if (nam=="P2P Copyright") {
                                lay.visible=true;
                                selectTool('moveTool');
                            }
                            if (nam && ref.getDesiredClass() == 1283027488 && lay=app.activeDocument.layers.getByName(nam)) {
                                function selectTool(tool) {
                                    var desc9 = new ActionDescriptor();
                                    var ref7 = new ActionReference();
                                    ref7.putClass( app.stringIDToTypeID(tool) );
                                    desc9.putReference( app.charIDToTypeID('null'), ref7 );
                                    executeAction( app.charIDToTypeID('slct'), desc9, DialogModes.NO );
                                };
                                if (lay.kind == LayerKind.SMARTOBJECT);
                                else if (cls == cTID('Chnl') || lay.kind != LayerKind.NORMAL) {
                                    selectTool('paintbrushTool');
                                    doAction('Reset Swatch','Tools');
                                }
                                else if (cls == cTID('Lyr ')) {
                                    doAction('RGB Color Select','Tools');
                                    switch (nam) {
                                        case "Details":
                                            selectTool('magicStampTool');
                                            break;
                                        case "Dodge/Burn":
                                            selectTool('paintbrushTool');
                                            doAction('Dodge/Burn','Tools');
                                            doAction('Reset Swatch','Tools');
                                            doAction('Reverse Swatch','Tools');
                                            break;
                                        case "Touchup":
                                        case "Color Correct":
                                        case "Tone Correct":
                                            selectTool('paintbrushTool');
                                            doAction('Touchup','Tools');
                                            break;
                                        case "Spot Sharpen":
                                            selectTool('paintbrushTool');
                                        case "Cloning":
                                            selectTool('cloneStampTool');
                                            break;
                                        case "P2P Copyright":
                                            lay.visible=true;
                                            selectTool('moveTool');
                                    }
                                }
                            }
                        }
                    }
                }

                catch (e) {
                    if (!e.line.indexOf("element")) alert( "Error: " + e + ":" + e.line );
                }

                As you can see in the "catch" section, I'm bypassing the error for this to get around it. The layer that is in a group is the "P2P Copyright" layer and as you can see, I had to add an extra if-then check just for that layer as it doesn't work in the switch section and throws an error.

                • 5. Re: Layers getByName() issue?
                  xbytor2 Level 4

                  Add my function to the top of your script and try this:

                   

                  Replace

                              if (nam && ref.getDesiredClass() == 1283027488 && lay=app.activeDocument.layers.getByName(nam)) {

                   

                  with this:

                              if (nam && ref.getDesiredClass() == cTID("Lyr ") ) {
                                  var old = app.activeDocument.activeLayer;
                                  if (old.name != nam) {
                                    makeLayerActiveByName(nam);
                                    lay = app.activeDocument.activeLayer;
                                    app.activeDocument.activeLayer = old;
                                  }
                  
                  • 6. Re: Layers getByName() issue?
                    jugenjury Level 2

                    The "activeLayer" property is undefined in the Events Script. I get an error "Error: ReferenceError: lay is undefined: 43" no matter which layer I select now.

                     

                    I do remember trying this script first by using the activeLayer property but it kept returning undefined.

                     

                    I'm starting to think I'll have to take a completely different approach or simply keep the bypass in place and manually do what I need done for these grouped layers.

                     

                    Thanks

                    • 7. Re: Layers getByName() issue?
                      xbytor2 Level 4

                      My bad. For got a line of code:

                       

                                  if (nam && ref.getDesiredClass() == cTID("Lyr ") ) {
                                      var old = app.activeDocument.activeLayer;
                                      if (old.name != nam) {
                                        makeLayerActiveByName(nam);
                                        lay = app.activeDocument.activeLayer;
                                        app.activeDocument.activeLayer = old;
                                      } else {
                                        lay = old;
                                      }
                      • 8. Re: Layers getByName() issue?
                        dserodio Level 1

                        document.artLayers contains only the "top-level" layers (ie, the ones not inside layer groups). Try using the document.layers container instead, it contains both Art Layers and LayerSets (aka Layer Groups)