Copy link to clipboard
Copied
Standart function (copy(relativeObject,insertionLocation)) don't work with several objetcts, and can copy only first layer.
Copy link to clipboard
Copied
If you can't do it all at once you can loop the action to get the desired result. For this to work you need to know and store a reference to the layers that are selected. Getting the selected layers is one of the common questions here on the forum. All solutions use action manager code. Once wrapped in a function they're pretty easy to use. A solution to your question could be something like this using three functions: getSelectedLayers, selectByIndex, copySelectedAfter.
///////////////////////////////////////////////////////////////////////////////
// Function: getSelectedLayers
// Usage: creates and array of the currently selected layers
// Input: <none> Must have an open document
// Return: Array containing the Idx of the selectedLayers
///////////////////////////////////////////////////////////////////////////////
function getSelectedLayersIdx(){
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){
desc = desc.getList( stringIDToTypeID( 'targetLayers' ));
var c = desc.count
var selectedLayers = new Array();
for(var i=0;i<c;i++){
try{
activeDocument.backgroundLayer;
selectedLayers.push( desc.getReference( i ).getIndex() );
}catch(e){
selectedLayers.push( desc.getReference( i ).getIndex()+1 );
}
}
}else{
var ref = new ActionReference();
ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "ItmI" ));
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
try{
activeDocument.backgroundLayer;
selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" ))-1);
}catch(e){
selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" )));
}
var vis = app.activeDocument.activeLayer.visible;
if(vis == true) app.activeDocument.activeLayer.visible = false;
var desc9 = new ActionDescriptor();
var list9 = new ActionList();
var ref9 = new ActionReference();
ref9.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
list9.putReference( ref9 );
desc9.putList( charIDToTypeID('null'), list9 );
executeAction( charIDToTypeID('Shw '), desc9, DialogModes.NO );
if(app.activeDocument.activeLayer.visible == false) selectedLayers.shift();
app.activeDocument.activeLayer.visible = vis;
}
return selectedLayers;
}
///////////////////////////////////////////////////////////////////////////////
// Function: selectByIndex
// Description: Sets the activeLayer by AM itemIndex and returns DOM active layer
// Usage: var idx = makeActiveByIndex( 7 );
// Input: Number (single idx)
// Return: activeLayer
///////////////////////////////////////////////////////////////////////////////
function selectByIndex( idx) {
// avoid error when background layer idx is passed
if ( idx == 0 ) return;
// if an array is passed use only the first element
if (idx.length != undefined){
idx = idx[0];
}
// execute selection
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( 'Lyr ' ), idx );
desc.putReference( charIDToTypeID('null'), ref );
executeAction( charIDToTypeID( 'slct' ), desc, DialogModes.NO );
return app.activeDocument.activeLayer;
}
///////////////////////////////////////////////////////////////////////////////
// Function: copySelectedAfter
// Description: duplicate selected layers to the position after the passed reference layer (_layerReff)
// Usage: copySelectedAfter(app.activeDocument.layers[0]);
// Input: reference layer
// Return: nothing/error
///////////////////////////////////////////////////////////////////////////////
function copySelectedAfter(_layerReff){
var selectedIDX = getSelectedLayersIdx();
var numOfLayers = selectedIDX.length;
var templayer;
for(var i = 0; i < numOfLayers; i++){
tempLayer = selectByIndex(selectedIDX);
tempLayer.duplicate(_layerReff, ElementPlacement.PLACEAFTER);
}
}
// This would copy the selected layers below the top layer of the stack
//copySelectedAfter(app.activeDocument.layers[0]);
Copy link to clipboard
Copied
You see, I have 100 - 400 layers in one doc, and I need to copy them several times in a specific order.
The reason I asked the question in the first place, is that copying all layers one by one in loop is taking hell lot of time.
But thanks for answer anyway, I appreciate your help.
P.S. I'll save your example though, might be useful in a future
Copy link to clipboard
Copied
You could temporarily wrap them in a layerset/group. I think these can be moved and duplicated like a single layer and then ungrouped in the new location.
Copy link to clipboard
Copied
Have you tried Duplicate() ?
It will copy all selected layers in one go.
activeDocument.activeLayer.duplicate ( activeDocument.activeLayer, ElementPlacement.PLACEBEFORE);
Copy link to clipboard
Copied
Here's the code from AM
function copyAndMove(_x, _y) {
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
desc1.putReference(charIDToTypeID('null'), ref1);
var desc2 = new ActionDescriptor();
desc2.putUnitDouble(charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), _x);
desc2.putUnitDouble(charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), _y);
desc1.putObject(charIDToTypeID('T '), charIDToTypeID('Ofst'), desc2);
executeAction(charIDToTypeID('copy'), desc1, DialogModes.NO);
}
copyAndMove(200, 200);