• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Move unsaved SO to another doc retaining SO

Community Expert ,
Jan 17, 2019 Jan 17, 2019

Copy link to clipboard

Copied

I have looked at the JS scripting ref and other posts, however I can’t find an answer.

I have a temporary unsaved document that was created from opening up multiple saved images as a layered stack and blended with mean blending. This part has been automated and is all good.

However I would like to create a script to move this temporary unsaved SO layer into another open file, say the previous document in the list. The key being retaining the layer as a SO. I can easily do this using the move tool + shift key combo to centre the file (which is the same px width/depth, effectively pin registering), dragging from the unsaved SO doc into the previous window, which retains the SO.

The temporary SO has not been saved, so it can’t be placed. I am guessing that this is the sticking point.

I have tried recording AM code of the manual shift drag of the move tool, however I am getting an error so am doubtful that this will work unless the recorded code requires modification.

Is this simply one of those things that is easy to do via the GUI, but has no counterpart in DOM or AM code?

TOPICS
Actions and scripting

Views

1.5K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

People's Champ , Jan 18, 2019 Jan 18, 2019

Use

reference2.putIdentifier(stringIDToTypeID("document"), doc_ref.id);

instead of
  reference2.putName( s2t( "document" ), "_4232915.ORF" );  

Where doc_ref is the reference to the required document.

Votes

Translate

Translate
Adobe
People's Champ ,
Jan 17, 2019 Jan 17, 2019

Copy link to clipboard

Copied

Understood nothing.

SO == SmartObject?

What do you mean when you say: "The temporary SO has not been saved, so it can’t be placed" ?

What error pops up when you try to record the required action as an AM code?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 17, 2019 Jan 17, 2019

Copy link to clipboard

Copied

Apologies for not being clear.

The following workflow creates “Document B”:

  1. Multiple saved files on disk
  2. Loaded into a new unsaved document as smart object layer stack (multiple layers blended in mean blend mode)
  3. Single smart object layer in the unsaved file

I wish to move the unsaved document smart object layer from “Document B” to an existing “Document A” which is already open in Photoshop (in this example only 2 documents are currently open, Document A which has been saved to disk, Document B that is a newly created unsaved file).

The ScriptListener code that was recorded when using the Move tool + Shift Key was:

// =======================================================

var idtoolModalStateChanged = stringIDToTypeID( "toolModalStateChanged" );

    var desc666 = new ActionDescriptor();

    var idLvl = charIDToTypeID( "Lvl " );

    desc666.putInteger( idLvl, 0 );

    var idStte = charIDToTypeID( "Stte" );

    var idStte = charIDToTypeID( "Stte" );

    var idexit = stringIDToTypeID( "exit" );

    desc666.putEnumerated( idStte, idStte, idexit );

    var idTool = charIDToTypeID( "Tool" );

        var desc667 = new ActionDescriptor();

        var idIdnt = charIDToTypeID( "Idnt" );

        desc667.putString( idIdnt, """arwT""" );

        var idTtl = charIDToTypeID( "Ttl " );

        desc667.putString( idTtl, """Move Tool""" );

    var idTool = charIDToTypeID( "Tool" );

    desc666.putObject( idTool, idTool, desc667 );

    var idKnd = charIDToTypeID( "Knd " );

    var idKnd = charIDToTypeID( "Knd " );

    var idmouse = stringIDToTypeID( "mouse" );

    desc666.putEnumerated( idKnd, idKnd, idmouse );

    var idkcanDispatchWhileModal = stringIDToTypeID( "kcanDispatchWhileModal" );

    desc666.putBoolean( idkcanDispatchWhileModal, true );

executeAction( idtoolModalStateChanged, desc666, DialogModes.NO );

The error code:

am_error.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jan 17, 2019 Jan 17, 2019

Copy link to clipboard

Copied

Why don't you try recording the "Duplicate" command?

You can also use.

src_layer.duplucate(dst_doc.layers[0]);

P.S. I again did not understand everything correctly?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

Thank you r-bin– I tested in the GUI with Layer > Duplicate > Destination Document and the smart object is indeed preserved!

So now all I need to do is incorporate your DOM code snippet into my script or record and possibly modify AM code... as a scripting newb this may be easier said than done!

Does the following annotated screenshot help explain my goal?

goal.jpg

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

Try it.
If you fail, you will have to show the entire script in which you need to paste the code to duplicate the layer. It is hard for me to explain in words what you need to do. )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

Thank you for the reply. I am starting from scratch as the first step is to copy the smart object created by a script + action into the previously opened image.

DOM code would be cleaner and easier to maintain, however I’ll use AM code if I must choose the expedient approach...

Here is what was recorded, I then ran the Clean SL script to tidy up the output:

duplicate();

function duplicate() {

  var c2t = function (s) {

  return app.charIDToTypeID(s);

  };

  var s2t = function (s) {

  return app.stringIDToTypeID(s);

  };

  var descriptor = new ActionDescriptor();

  var list = new ActionList();

  var reference = new ActionReference();

  var reference2 = new ActionReference();

  reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));

  descriptor.putReference( c2t( "null" ), reference );

  reference2.putName( s2t( "document" ), "_4232915.ORF" );

  descriptor.putReference( s2t( "to" ), reference2 );

  descriptor.putInteger( s2t( "version" ), 5 );

  list.putInteger( 2 );

  descriptor.putList( s2t( "ID" ), list );

  executeAction( s2t( "duplicate" ), descriptor, DialogModes.NO );

}

I think that I have to change the code referring to the "_4232915.ORF” in line 18 to refer to the first open file by using the app.documents.index(0) or similar?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

Use

reference2.putIdentifier(stringIDToTypeID("document"), doc_ref.id);

instead of
  reference2.putName( s2t( "document" ), "_4232915.ORF" );  

Where doc_ref is the reference to the required document.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

Well that was “fun” trying to get the syntax correct :]

Thank you r-bin, I got there in the end!

duplicate();

function duplicate() {

  var c2t = function (s) {

  return app.charIDToTypeID(s);

  };

  var s2t = function (s) {

  return app.stringIDToTypeID(s);

  };

  var descriptor = new ActionDescriptor();

  var list = new ActionList();

  var reference = new ActionReference();

  var reference2 = new ActionReference();

  var doc_ref = app.documents[0];

  reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));

  descriptor.putReference( c2t( "null" ), reference );

  reference2.putIdentifier(stringIDToTypeID("document"), doc_ref.id);

  descriptor.putReference( s2t( "to" ), reference2 );

  descriptor.putInteger( s2t( "version" ), 5 );

  list.putInteger( 2 );

  descriptor.putList( s2t( "ID" ), list );

  executeAction( s2t( "duplicate" ), descriptor, DialogModes.NO );

}

I’m sure that it would only have taken 5-10 lines of DOM code, which would have taken me days to try to figure out!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

This code depends on the order of the documents.

The following code does not depend on the order of the documents, but assumes that only two documents are open.

Copying is make to inactive document.

duplicate(); 

function duplicate() { 

  var c2t = function (s) { 

  return app.charIDToTypeID(s); 

  }; 

 

  var s2t = function (s) { 

  return app.stringIDToTypeID(s); 

  }; 

 

  var descriptor = new ActionDescriptor(); 

  var list = new ActionList(); 

  var reference = new ActionReference(); 

  var reference2 = new ActionReference(); 

  if (app.documents.length != 2) throw("\n\nOnly two documents allowed!\n\n"); 

  var id;

  for (var i = 0; i < app.documents.length; i++)

    {

    if (app.documents != app.activeDocument)

        {

        id = app.documents.id; 

        break;

        }

    }

 

  reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" )); 

  descriptor.putReference( c2t( "null" ), reference ); 

  reference2.putIdentifier(stringIDToTypeID("document"), id); 

  descriptor.putReference( s2t( "to" ), reference2 ); 

  descriptor.putInteger( s2t( "version" ), 5 ); 

  list.putInteger( 2 ); 

  descriptor.putList( s2t( "ID" ), list ); 

  executeAction( s2t( "duplicate" ), descriptor, DialogModes.NO ); 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

Thank you r-bin, you are indeed correct, I was only presuming that the first open document was the target and that the second open document was the smart object to copy back to the target document.

I’m sure it will take me some study to work out how the new script knows which is the target and which is the source...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

I’m sure that it would only have taken 5-10 lines of DOM code, which would have taken me days to try to figure out!

Could it really be this simple? You would not believe how long these 4 lines of code took for me to get working!

displayDialogs = DialogModes.NO

var src_layer = app.activeDocument.layers[0];

var dst_doc = app.documents[0];

src_layer.duplicate(dst_doc);

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

That may be also one line (with no dialog and variables), but in both cases you must remember the order of present docs:

activeDocument.layers[0].duplicate(documents[0])

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 24, 2019 Jan 24, 2019

Copy link to clipboard

Copied

That may be also one line (with no dialog and variables), but in both cases you must remember the order of present docs:

activeDocument.layers[0].duplicate(documents[0])

So, what if one wanted to use substring of filename for a more robust method of finding a source and destination file for the layer duplication?

Unsaved Source Document = myfilename123_VariantStack

Saved Target Document = myfilename123.tif

It should be possible to use the variable text in blue, ignoring the static text in red separated by a leading underscore, in order to find a matching “pair” of files, then it would not matter how many files were open or in what order they were opened.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 24, 2019 Jan 24, 2019

Copy link to clipboard

Copied

I think you can only use exact name of document, so when you create one document, and then second, you can duplicate a layer from that second active document to the first:

activeDocument.layers[0].duplicate(documents.getByName('Untitled-1'))

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 24, 2019 Jan 24, 2019

Copy link to clipboard

Copied

That is a shame, doc filenames vary, so I was hoping for a variable as the source doc name is based off the target doc name. Something like this which obviously does not work:

var destinationDoc = app.activeDocument.name.replace(/_VariantStack/,"");

activeDocument.layers[0].duplicate(documents.destinationDoc)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 03, 2019 Feb 03, 2019

Copy link to clipboard

Copied

I’m still trying to think of a creative solution – however if I am beating a dead horse, please let me know...

Expressed another way, with a list of open files, files may have been opened or created in any order:

_4232915.psd

another file.tif

and yet another file.jpg

_4232915_VariantStack

one-more_File.png

So, what I was thinking was is there a way to create an array of the open documents, then copy from:

_4232915_VariantStack

to

_4232915.psd

Using either a regex or some other method to isolate the two “similar” files by their name or their index number based on their name?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 03, 2019 Feb 03, 2019

Copy link to clipboard

Copied

LATEST

Files will be open in the order they were opened, but you can take all of them to array and sort by name. They still will be open as they were but you can do operations on them in alphabetical order.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

Stephen_A_Marsh 

I’m sure that it would only have taken 5-10 lines of DOM code, which would have taken me days to try to figure out!

Could it really be this simple? You would not believe how long these 4 lines of code took for me to get working!

displayDialogs = DialogModes.NO var src_layer = app.activeDocument.layers[0]; var dst_doc = app.documents[0]; src_layer.duplicate(dst_doc);

According to the documentation, the first argument of the duplicate method must be of type ArtLayer or LayerSet.
However, you have it of type Document. And it works!!
You have found either a bug or an undocumented feature.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 18, 2019 Jan 18, 2019

Copy link to clipboard

Copied

That's probably side effect of bug or undocumented feature, as in 'Layers' panel when we choose 'duplicate' item we can specify where it has to go, so current or another document. To be honest I was not aware there is lack of description in reference but always used duplication this way, so either to current or other document. Too bad Adobe almost never corrects their documentation 😕

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines