10 Replies Latest reply on May 20, 2018 4:35 AM by zakariaef29492779

    Duplicate a layerSet inside another layerSet

    zakariaef29492779

      Hello beautiful people,

       

      first time here, I'm working on a jsx script to duplicate layers inside an artboard, what I want to achieve now is just to duplicate a layerSet inside another layerSet, and both are in the same artboard.

       

      I've tried the "move" method, not working, I've tried also the script from here, without artboards it's working fine, but if my layerSets are inside an artboard it doesn't move the duplicated layer, any help, please.

       

      thanks.

        • 1. Re: Duplicate a layerSet inside another layerSet
          sidpalas Level 2

          Just to clarify, are you successfully duplicating the LayerSet using LayerSet.duplicate() method first? But then you are unable to move it into the desired LayerSet?

           

          Do you have an example .psd file you can share?

          • 2. Re: Duplicate a layerSet inside another layerSet
            zakariaef29492779 Level 1

            Yes, the LayerSet.duplicate() is working, but neither LayerSet.duplicate(targetLayerSet, ElementPlacement.INSIDE) nor LayerSet.move() are working, here is a psd example, where you can find two artboards, the main idea is to duplicate one LayerSet from artboard1 to "TARGET" LayerSet.

             

            thanks

            • 3. Re: Duplicate a layerSet inside another layerSet
              sidpalas Level 2

              This seems to be a case where Adobe's note about ElementPlacement values applies...

              Screen Shot 2018-05-11 at 5.14.42 AM.png

              That being said, ElementPlacement.PLACEBEFORE is a valid value for moving a LayerSet, so there is a potential workaround by creating a temporary LayerSet within your TARGET LayerSet, and moving the duplicates in front of it. For example, using the naming from the .psd you provided:

               

              var docRef = app.activeDocument;
              var artboard1 = docRef.layerSets.getByName("Artboard 1");
              var warningLayerSet = artboard1.layerSets.getByName("WARNING");
              var targetLayerSet = docRef.layerSets.getByName("TARGET");
              
              var tempLayerSet = targetLayerSet.layerSets.add();
              tempLayerSet.name = "TEMP";
              
              var warningLayerSetDuplicate = warningLayerSet.duplicate();
              warningLayerSetDuplicate.move(tempLayerSet, ElementPlacement.PLACEBEFORE);
              
              //tempLayerSet.remove();
              

               

              This successfully duplicates the WARNING LayerSet and moves it to within the TARGET LayerSet. However, this is where things get odd...

               

              When I delete the temporary LayerSet (via the commando on line 12 or the GUI), the "Rounded Rectangle" layer jumps out of the new WARNING LayerSet and back into Artboard 1. I haven't worked with ArtBoards before and am at a loss for why this would happen this way.

               

              Thoughts?

              • 4. Re: Duplicate a layerSet inside another layerSet
                zakariaef29492779 Level 1

                Yes, I've tried the same approach, with a recursive function to copy the content of the layerSet even when it contains another layerSet (not the case in the example psd), but I had the same issue, a weird situation

                • 5. Re: Duplicate a layerSet inside another layerSet
                  sidpalas Level 2

                  It seems to be caused by the "Auto-nesting" of layers within Artboards.

                  Screen Shot 2018-05-11 at 5.37.19 AM.png

                  By selecting the option shown in the screenshot ("Prevent auto-nesting into and out of Artboards"), I was then able to delete the TEMP LayerSet without the odd behavior described in my previous response. I was even able to duplicate the LayerSet into the desired location, eliminating a line:

                   

                  var docRef = app.activeDocument;
                  var artboard1 = docRef.layerSets.getByName("Artboard 1");
                  var warningLayerSet = artboard1.layerSets.getByName("WARNING");
                  var targetLayerSet = docRef.layerSets.getByName("TARGET");
                  
                  var tempLayerSet = targetLayerSet.layerSets.add();
                  tempLayerSet.name = "TEMP";
                  
                  var warningLayerSetDuplicate = warningLayerSet.duplicate(tempLayerSet, ElementPlacement.PLACEBEFORE);
                  
                  tempLayerSet.remove();
                  

                   

                  If toggling this feature doesn't mess up your workflow, perhaps that will do the trick!

                  • 6. Re: Duplicate a layerSet inside another layerSet
                    zakariaef29492779 Level 1

                    Thanks mate, I'll try this approach, it will be great to toggle this feature programmatically.

                     

                    Edit:

                    I just test it and as expected, it's perfectly working, I tried with a nested layerSet (inside Warning layerSet) and tried to apply the action on it and it did the same behavior, so I think that the idea is to disable the auth-nesting temporary for the parent when doing the duplication/moving, but I can't find how to do it :/

                    • 7. Re: Duplicate a layerSet inside another layerSet
                      SuperMerlin Level 5
                      protectArtboardAutonest(activeDocument.activeLayer.id,true);
                      //Layer ID, true/false
                      function protectArtboardAutonest(ID,Bool){
                      try{
                      var d=new ActionDescriptor();
                      var r=new ActionReference();
                      r.putIdentifier(stringIDToTypeID("layer"), ID );
                      d.putReference(stringIDToTypeID("null"), r);
                      var d1=new ActionDescriptor();
                      d1.putBoolean(stringIDToTypeID("protectArtboardAutonest"), Bool);
                      d.putObject(stringIDToTypeID("layerLocking"), stringIDToTypeID("layerLocking"), d1);
                      executeAction(stringIDToTypeID("applyLocking"), d, DialogModes.NO);
                      }catch(e){}
                      };
                      
                      

                      Is this what you need?

                      • 8. Re: Duplicate a layerSet inside another layerSet
                        zakariaef29492779 Level 1

                        thanks, yes something like that, by the way, how you get this kind of code ? (talking about the actions part)

                        • 9. Re: Duplicate a layerSet inside another layerSet
                          sidpalas Level 2

                          I can't speak for SuperMerlin, but usually when you see code using ActionDescriptors being utilized with executeAction(), it is the result of using the ScriptingListener plugin (see here).

                           

                          The plugin records actions taken within photoshop as ExtendScript code in a log file. This allows you to manually execute a particular sequence and then view the resulting code. While incredibly useful, the code it produces is not the cleanest and if the desired functionality is available via the ExtendScript API it is preferable to use those functions. The ScriptingListener code can then be used directly, used as an example but modified by hand to acheive the desired result, or processed programmatically to clean it up (using an approach such asClean SL).

                           

                          Additional Adobe documentation on Action Manager can be found in the Photoshop CC Scripting Guide starting on page 73.

                           

                          Hopefully this helps!

                          • 10. Re: Duplicate a layerSet inside another layerSet
                            zakariaef29492779 Level 1

                            thanks all that I needed as information.