Constructor of arrays

Hello everybody
I've recently created a new class called Patient. I've now created a second class called Statistic.
In the second class I've decided to declare, as a data member an array of type Patient.
Because there will be only one array, so I have chosen to declare the data member static (the methods in the Statistics class will also be static).
I was simply wondering when I create the array I will write:
Patient [ ] patientTable=new Patient [100];
After this is done do I absolutely need a constructor because I've learned that if there is no constructor, default values are assigned; or is it better programming practice to have a constructor? Does the creation of the array have to be done in the constructor and then initialised with a for loop, for example. Shou;d the constructor have any parameters of type Patient for example. I'm not really sure how to create and initialise my array in the Statistic class.
There will be a third class eventually (main class) where the data will be inputted, Patient instances created and then called one after the other to fill the array, where calculations will be performed and then sent back to the main application.
Thank you for your time

Hello everybody
I've recently created a new class called Patient. I've
now created a second class called Statistic.Excellent!
>
In the second class I've decided to declare, as a data
member an array of type Patient.So a Statistic has many Patients? I would think it more likely that a Patient would have many Statistics.
Because there will be only one array, so I have chosen
to declare the data member static (the methods in the
Statistics class will also be static).Array of what? This isn't clear.
What is the Statistics class doing? Providing functions to calculate mean, standard deviation, etc., a la java.lang.Math and its sine and consine functions?
>
I was simply wondering when I create the array I will
write:
Patient [ ] patientTable=new Patient [100];Yes, this will create an array of 100 references to Patient, and every single one of them will be set equal to null until you call a Patient constructor to point them to a valid Patient instance.
After this is done do I absolutely need a constructor
because I've learned that if there is no constructor,The compiler will write a no-argument default constructor for you. It allocates memory for your object and assigns initial values for every data member. Primitives are given their default values, and object references are set to null.
If this default behavior isn't acceptable (and having null data member references usually isn't), you'll have to write a sensible constructor or two of your own. The instant you supply even one constructor the compiler will no long write the default constructor for you.
default values are assigned; or is it better
programming practice to have a constructor? Does the
creation of the array have to be done in the
constructor and then initialised with a for loop, for
example. Yes, absolutely:
int maxPatients = 100;
Patient [] patients = new Patient[maxPatients];
for (int i = 0; i < maxPatients; ++i)
    patients[i] = new Patient(name, rank, serialNumber);
Shou;d the constructor have any parameters of
type Patient for example. I'm not really sure how to
create and initialise my array in the Statistic class.
There will be a third class eventually (main class)
where the data will be inputted, Patient instances
created and then called one after the other to fill
the array, where calculations will be performed and
then sent back to the main application.Hard to answer this bit without knowing more about your problem. It sounds like the Patient object will use the Statistic class to perform calculations on some data that you haven't described.
Why a fixed-length array of Patients? Why not a java.util.List of Patients that can accomodate an arbitrary number of Patients?
This design can get complicated fast. A Patient might have many measurements taken during a typical hospital stay (e.g., weight, height, blood pressure, heart rate, etc.) You might want a Quantity class that will combine the value with the type of measurement and the units used (weight can be lbf in the USA or kg in Europe). When you calculate Statistics you'll want to make sure that you add Quantities of the same type and units. LOTS of complications here. Martin Fowler's "Analysis Patterns" has a lot of info on this and other problems if you're interested.

Similar Messages

  • Multiple Constructors and Arrays

    Hi. I have a default contructor that takes in a an array of doubles like so,
    public Foo (double [] numbers)
    }What I want to do is have another constructor use this first one but with a different parameter list.
    public Foo (double x, double y)
         this( { x, y} );
    }Basically, I am trying to dynamically create an array of the doubles with the given doubles and pass them to the other constructor (all in the first line of the constructor because of the way this is used.
    I get an "illegal start of statement error", so I am a bit confused with what I should do. Is it possible to do what I'm trying to do or should i simply create a brand new constructor?
    Thanks in advance

    Try this( new double[] { x, y} );

  • Best way to perform the same task wih arrays of different Objects

    Hello all.
    This isn't an XPath question, it's a much lower-level Java Object question, but it involves XPath. I hope that doesn't distract from the question, or confuse anything.
    I have 4-5 different types of Objects (call them A, B, C, etc.) that each contain an array of other Objects (call them a[], b[], c[], etc.)
    a, b, c, etc., each have an Xpath object and and XPathExpression. When I create each XPath object I assign it a NamespaceContext object which contains the namespaces needed for that XPath.
    When I create, for example, an A object, I pass is constructor an array of a and an array of Namespaces. With each a object I need to:
    1. create a NamespaceContext object
    2. go through all the Namespace objects and if its route matches,
    (if Namespace.route == a.getRoute() )
    3. add that Namespace to the NamespaceContext Object,
    4. assign the NamespaceContext to the XPath object, and finally
    5. create the a object, passing it the XPath object
    My problem / question is: I also have to do the same thing with B and b[], C and c[], etc. It's not that long of a process, not that much code, but all the same, I was wondering what the best way to write this code once would be, and have it work for all the different types of Objects.
    In other words, I'd like to write a mehod, call it assignNamespaces(), that accepts an array of Objects(a[], b[], c[], etc.) and an array of Namespaces, creates the XPath Object for each a, b, c, etc., and that creates and returns an array of a[],b[],c[], etc., sending the XPath Object as a parameter.
    That way when I create for example an A Object, I call:
    class A
    ObjectsWithXpath[] objectsWithXPath;
    this..objectsWithXPath = assignNamespaces(objectsWithXPath,namespaces);
    Should the assgnNamespaces() method simply use Class.forName() to see what type of Object it is and do a cast accordingly, or is there some other, more elegant way of doing this?
    I hope I've explained myself, and haven't bored you ...
    Thanks in advance,
    Bob

    Thanks for your reply!
    I poked around a bit looking into Factory classes. I've used them a million times but never actually made one. At any rate, they seem like a good idea when you have a bunch of different classes that are similar but not equal.
    In my case my classes ONLY have the XPathExpression in common. Which means that I'd have to make a base abstract class with a bunch of methods of which only a percentage are defined by any class that extends it. In other words, if I had 3 classes -- a, b and c -- that extend the base abstract class, and each had 5 getters and setters, the base abstract class would have 15 methods, 5 only used by a, 5 only used by b and 5 only used by c.
    It seemed a bit ugly to me. Besides, I only have 3 classes. I decided to factor out the inner loop, which is about 70% of the code, stick it in a utility class, and call it from there. I am repeating some code still, but it isn't that bad, and it saves me having to define an interface, an abstract class, a Factory class, etc.
    It ain't perfect, but then nothing ever is.
    Thanks for all the help! Viva the Java community!
    Bob

  • Problem with layer sets opening

    Hi,
    I have a problem open layer sets. In my script I get layers index and then iterate throught this layers.
    Here is the script:
    function getAllLayersByIndex(){
           function getNumberLayers(){
           var ref = new ActionReference();
           ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID("NmbL") )
           ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
           return executeActionGet(ref).getInteger(charIDToTypeID("NmbL"));
           function hasBackground() {
               var ref = new ActionReference();
               ref.putProperty( charIDToTypeID("Prpr"), charIDToTypeID( "Bckg" ));
               ref.putEnumerated(charIDToTypeID( "Lyr " ),charIDToTypeID( "Ordn" ),charIDToTypeID( "Back" ))//bottom Layer/background
               var desc =  executeActionGet(ref);
               var res = desc.getBoolean(charIDToTypeID( "Bckg" ));
               return res  
           function getLayerType(idx,prop) {      
               var ref = new ActionReference();
               ref.putIndex(charIDToTypeID( "Lyr " ), idx);
               var desc =  executeActionGet(ref);
               var type = desc.getEnumerationValue(prop);
               var res = typeIDToStringID(type);
               return res  
           function getLayerVisibilityByIndex( idx ) {
               var ref = new ActionReference();
               ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "Vsbl" ));
               ref.putIndex( charIDToTypeID( "Lyr " ), idx );
               return executeActionGet(ref).getBoolean(charIDToTypeID( "Vsbl" ));;
           var cnt = getNumberLayers()+1;
           var res = new Array();
           if(hasBackground()){
        var i = 0;
              }else{
        var i = 1;
           var prop =  stringIDToTypeID("layerSection");
           for(i;i<cnt;i++){
              var temp = getLayerType(i,prop);
              if(temp != "layerSectionEnds") res.push(i);
           return res;
           function getLayerVisibilityByIndex( idx ) {
               var ref = new ActionReference();
               ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "Vsbl" ));
               ref.putIndex( charIDToTypeID( "Lyr " ), idx );
               return executeActionGet(ref).getBoolean(charIDToTypeID( "Vsbl" ));
    function makeActiveByIndex( idx, visible ){
        var desc = new ActionDescriptor();
          var ref = new ActionReference();
          ref.putIndex(charIDToTypeID( "Lyr " ), idx)
          desc.putReference( charIDToTypeID( "null" ), ref );     
          desc.putBoolean( charIDToTypeID( "MkVs" ), visible );
       executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
    var groups = getAllLayersByIndex();
        for(var i = groups.length-1; i >= 0 ; i--) {
          makeActiveByIndex( groups[i], true );
          ....working with layers....
    I think, my problem is in function makeActiveByIndex, because it doesn't make active a folder and doesn't open it.
    You can see it on this picture. Active layer set is "Skupina 1" and it is in layer set "hlavicka". But "hlavicka" is not open. WHY??
    Can you help me fix this problem??
    Thank you Domaneni

    Hi, for the past days I've worked on a script to toogle opening and closing layeSets, I've taken the code that TeddyBear posted here: http://ps-scripts.com/bb/viewtopic.php?p=14773 and adjusted it a little bit, and that's what I came up with, I hope it will help you:
    <javascriptresource>
      <name>BCM> ToogleOpen_CloseGroup...</name>
      <category>BCM</category>
    </javascriptresource>
    //For code readability
    // http://ps-scripts.com/bb/viewtopic.php?f=9&t=3235
    function getActiveLayerIndex() {
        var ref = new ActionReference();
        ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "ItmI" ));
        ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
        return executeActionGet(ref).getInteger(charIDToTypeID( "ItmI" ));
    function cTID(s){return charIDToTypeID(s)}
    function sTID(s){return stringIDToTypeID(s)}
    // =============================
    // The main function
    function closeGroup(layerSet) {
       var m_Name = layerSet.name;
       var m_Opacity = layerSet.opacity;
       var m_BlendMode = layerSet.blendMode;
       var m_LinkedLayers = layerSet.linkedLayers;
      var currINDEX = getActiveLayerIndex();
       var m_bHasMask = hasLayerMask();
       if(m_bHasMask) loadSelectionOfMask();
       if(layerSet.layers.length <= 1) {
          addTempLayerSetIn(currSetIDX-1);
          makeActiveByIndex(currSetIDX+2, false);
          ungroup();
          groupSelected(m_Name);
          deleteTempLayerSetbyIdx(currSetIDX+1);
       } else {
           makeActiveByIndex(currSetIDX, false);
          ungroup();
          groupSelected(m_Name);
       var m_Closed = activeDocument.activeLayer;
       m_Closed.opacity = m_Opacity;
       m_Closed.blendMode = m_BlendMode;
       for(x in m_LinkedLayers) {
          if(m_LinkedLayers[x].typename == "LayerSet")
             activeDocument.activeLayer.link(m_LinkedLayers[x]);
       if(m_bHasMask) maskFromSelection();
       return m_Closed;
    // =============================
    // Below are all necessary subroutines for the main function to work
    function ungroup() {
       var m_Dsc01 = new ActionDescriptor();
       var m_Ref01 = new ActionReference();
       m_Ref01.putEnumerated( cTID( "Lyr " ), cTID( "Ordn" ), cTID( "Trgt" ) );
       m_Dsc01.putReference( cTID( "null" ), m_Ref01 );
       try {
          executeAction( sTID( "ungroupLayersEvent" ), m_Dsc01, DialogModes.NO );
       } catch(e) {}
    function addLayer() {
       var m_ActiveLayer          =    activeDocument.activeLayer;
       var m_NewLayer             =    activeDocument.layerSets.add();
       m_NewLayer.move(m_ActiveLayer, ElementPlacement.PLACEBEFORE);
       return m_NewLayer;
    function hasLayerMask() {
       var m_Ref01 = new ActionReference();
       m_Ref01.putEnumerated( sTID( "layer" ), cTID( "Ordn" ), cTID( "Trgt" ));
       var m_Dsc01= executeActionGet( m_Ref01 );
       return m_Dsc01.hasKey(cTID('Usrs'));
    function activateLayerMask() {
       var m_Dsc01 = new ActionDescriptor();
       var m_Ref01 = new ActionReference();
       m_Ref01.putEnumerated( cTID( "Chnl" ), cTID( "Chnl" ), cTID( "Msk " ) );
       m_Dsc01.putReference( cTID( "null" ), m_Ref01 );
       try {
          executeAction( cTID( "slct" ), m_Dsc01, DialogModes.NO );
       } catch(e) {
          var m_TmpAlpha = new TemporaryAlpha();
          maskFromSelection();
          activateLayerMask();
          m_TmpAlpha.consume();
    function deleteMask(makeSelection) {
       if(makeSelection) {
          loadSelectionOfMask();
       var m_Dsc01 = new ActionDescriptor();
       var m_Ref01 = new ActionReference();
       m_Ref01.putEnumerated( cTID( "Chnl" ), cTID( "Ordn" ), cTID( "Trgt" ) );
       m_Dsc01.putReference( cTID( "null" ), m_Ref01 );
       try {
          executeAction( cTID( "Dlt " ), m_Dsc01, DialogModes.NO );
       } catch(e) {}
    function selectLayerMask() {
       var m_Dsc01 = new ActionDescriptor();
       var m_Ref01 = new ActionReference();
       m_Ref01.putEnumerated(cTID("Chnl"), cTID("Chnl"), cTID("Msk "));
       m_Dsc01.putReference(cTID("null"), m_Ref01);
       m_Dsc01.putBoolean(cTID("MkVs"), false );
       try {
          executeAction(cTID("slct"), m_Dsc01, DialogModes.NO );
       } catch(e) {}
    function loadSelectionOfMask() {
       selectLayerMask();
       var m_Dsc01 = new ActionDescriptor();
       var m_Ref01 = new ActionReference();
       m_Ref01.putProperty( cTID( "Chnl" ), cTID( "fsel" ) );
       m_Dsc01.putReference( cTID( "null" ), m_Ref01 );
       var m_Ref02 = new ActionReference();
       m_Ref02.putEnumerated( cTID( "Chnl" ), cTID( "Ordn" ), cTID( "Trgt" ) );
       m_Dsc01.putReference( cTID( "T   " ), m_Ref02 );
       try {
          executeAction( cTID( "setd" ), m_Dsc01, DialogModes.NO );
       } catch(e) {}
    function maskFromSelection() {
       if(!hasLayerMask()) {
          var m_Dsc01 = new ActionDescriptor();
          m_Dsc01.putClass( cTID( "Nw  " ), cTID( "Chnl" ) );
          var m_Ref01 = new ActionReference();
          m_Ref01.putEnumerated( cTID( "Chnl" ), cTID( "Chnl" ), cTID( "Msk " ) );
          m_Dsc01.putReference( cTID( "At  " ), m_Ref01 );
          m_Dsc01.putEnumerated( cTID( "Usng" ), cTID( "UsrM" ), cTID( "RvlS" ) );
          try {
             executeAction( cTID( "Mk  " ), m_Dsc01, DialogModes.NO );
          } catch(e) {
             activeDocument.selection.selectAll();
             maskFromSelection();
       } else {
          if(confirm("Delete existing mask?", true, "Warning")) {
             activateLayerMask();
             deleteMask();
    function groupSelected(name) {
       var m_Dsc01 = new ActionDescriptor();
       var m_Ref01 = new ActionReference();
       m_Ref01.putClass( sTID( "layerSection" ) );
       m_Dsc01.putReference(  cTID( "null" ), m_Ref01 );
       var m_Ref02 = new ActionReference();
       m_Ref02.putEnumerated( cTID( "Lyr " ), cTID( "Ordn" ), cTID( "Trgt" ) );
       m_Dsc01.putReference( cTID( "From" ), m_Ref02 );
       var m_Dsc02 = new ActionDescriptor();
       m_Dsc02.putString( cTID( "Nm  " ), name);
       m_Dsc01.putObject( cTID( "Usng" ), sTID( "layerSection" ), m_Dsc02 );
       executeAction( cTID( "Mk  " ), m_Dsc01, DialogModes.NO );
       return activeDocument.activeLayer;
    function addToSelection(layerName) {
       var m_Dsc01 = new ActionDescriptor();
       var m_Ref01 = new ActionReference();
       m_Ref01.putName( cTID( "Lyr " ), layerName );
       m_Dsc01.putReference( cTID( "null" ), m_Ref01 );
       m_Dsc01.putEnumerated( sTID( "selectionModifier" ), sTID( "selectionModifierType" ), sTID( "addToSelection" ) );
       m_Dsc01.putBoolean( cTID( "MkVs" ), false );
       try {
          executeAction( cTID( "slct" ), m_Dsc01, DialogModes.NO );
       } catch(e) {}
    function TemporaryAlpha() {
       activeDocument.selection.store((this.alpha = activeDocument.channels.add()));
       activeDocument.selection.deselect();
       this.consume = function() {
          activeDocument.selection.load(this.alpha);
          this.alpha.remove();
    function makeActiveByIndex( idx, visible ){
         if( idx.constructor != Array ) idx = [ idx ];
         for( var i = 0; i < idx.length; i++ ){
              var desc = new ActionDescriptor();
              var ref = new ActionReference();
              ref.putIndex(charIDToTypeID( 'Lyr ' ), idx[i])
              desc.putReference( charIDToTypeID( 'null' ), ref );
              if( i > 0 ) {
                   var idselectionModifier = stringIDToTypeID( 'selectionModifier' );
                   var idselectionModifierType = stringIDToTypeID( 'selectionModifierType' );
                   var idaddToSelection = stringIDToTypeID( 'addToSelection' );
                   desc.putEnumerated( idselectionModifier, idselectionModifierType, idaddToSelection );
              desc.putBoolean( charIDToTypeID( 'MkVs' ), visible );
              executeAction( charIDToTypeID( 'slct' ), desc, DialogModes.NO );
    function deleteActiveLayer(){
       // =======================================================
       var idDlt = charIDToTypeID( "Dlt " );
           var desc752 = new ActionDescriptor();
           var idnull = charIDToTypeID( "null" );
               var ref529 = new ActionReference();
               var idLyr = charIDToTypeID( "Lyr " );
               var idOrdn = charIDToTypeID( "Ordn" );
               var idTrgt = charIDToTypeID( "Trgt" );
               ref529.putEnumerated( idLyr, idOrdn, idTrgt );
           desc752.putReference( idnull, ref529 );
       executeAction( idDlt, desc752, DialogModes.NO );
    function isLayerSet( idx ) {
         var propName = stringIDToTypeID( 'layerSection' );
         var ref = new ActionReference();
         ref.putProperty( charIDToTypeID( "Prpr" ) , propName);
         ref.putIndex( charIDToTypeID ( "Lyr " ), idx );
         var desc =  executeActionGet( ref );
         var type = desc.getEnumerationValue( propName );
         var res = typeIDToStringID( type );
         // alert(res);
         return res == 'layerSectionStart' ? true:false;
    function openGroup1(theGroup) {
       currSetIDX= getActiveLayerIndex();
       if(isLayerSet( currSetIDX ))
        getNamesPlusIDsOfLayerSet();
      makeActiveByIndex(currSetIDX, false);
    function getNamesPlusIDsOfLayerSet(){
       var ref = new ActionReference();
       ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
       var count = executeActionGet(ref).getInteger(charIDToTypeID('Cnt '));
      var parId = executeActionGet(ref).getInteger(stringIDToTypeID( 'layerID' ));
       var Names=[];
       var x = 0;
       var y = 0;
       var r = 0;
       currINDEX = getActiveLayerIndex();
        var i = currINDEX;
       for(i; i > 0 ; i--){
            ref = new ActionReference();
            ref.putIndex( charIDToTypeID( 'Lyr ' ), i );
            var desc = executeActionGet(ref);
            var layerName = desc.getString(charIDToTypeID( 'Nm  ' ));
            var Id = desc.getInteger(stringIDToTypeID( 'layerID' ));
            var ls = desc.getEnumerationValue(stringIDToTypeID("layerSection"));
            ls = typeIDToStringID(ls);
            // alert(layerName+": _ :"+ls);
            if(ls == "layerSectionStart"){x++};
            if(layerName.match(/^<\/Layer group/) )
              y ++;
              r = x - y;
              if(r == 0 && ls == "layerSectionEnd"){break};
              continue
            if(ls == "layerSectionContent"){makeActiveByIndex(i,false);break};
            var layerType = typeIDToStringID(desc.getEnumerationValue( stringIDToTypeID( 'layerSection' )));
            var isLayerSet =( layerType == 'layerSectionContent') ? false:true;
    Names.push([[Id],[layerName],[isLayerSet]]);
    return Names;
    function getLayersNb()//function to find out if the number of layers in the document
        var ref = new ActionReference();
        ref.putProperty( charIDToTypeID( 'Prpr' ), stringIDToTypeID('numberOfLayers') );
        ref.putEnumerated( charIDToTypeID( "Dcmn" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
        var desc = executeActionGet(ref);
        var numberOfLayers = desc.getInteger(stringIDToTypeID('numberOfLayers'));
        return numberOfLayers;
    function toogleOpenCloseSet(){
      myALayerIDX = getActiveLayerIndex();
      myGroupP = app.activeDocument.activeLayer;
      if(!isLayerSet(myALayerIDX)){
          myGroupP = app.activeDocument.activeLayer.parent;
          if(myGroupP.typename != "Document"){
            if(isSetOpened1(myGroupP)){closeGroup(myGroupP)}else{openGroup1(myGroupP)};
      }else{
        if(isSetOpened1(myGroupP)){closeGroup(myGroupP)}else{openGroup1(myGroupP)};
    function getFristLayerSetChildVisible(){
      xx = false;
       var ref = new ActionReference();
       ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
       var count = executeActionGet(ref).getInteger(charIDToTypeID('Cnt '));
      var parId = executeActionGet(ref).getInteger(stringIDToTypeID( 'layerID' ));
       var Names=[];
        var x = 0;
        var y = 0;
        var r = 0;
       currINDEX = getActiveLayerIndex();
        var i = currINDEX;
       for(i; i > 0 ; i--){
            ref = new ActionReference();
            ref.putIndex( charIDToTypeID( 'Lyr ' ), i );
            var desc = executeActionGet(ref);
            var layerName = desc.getString(charIDToTypeID( 'Nm  ' ));
            var Id = desc.getInteger(stringIDToTypeID( 'layerID' ));
            var ls = desc.getEnumerationValue(stringIDToTypeID("layerSection"));
            ls = typeIDToStringID(ls);
            var vis = desc.getInteger(stringIDToTypeID( 'visible' ));
            // alert(layerName+": _ :"+vis);
    /*        if(desc.hasKey(stringIDToTypeID("visible")))
              alert(desc.getType(stringIDToTypeID("visible")));
            if(ls == "layerSectionStart"){x++};
            if(vis == 1 && Id!=parId && r!=0){
              var theOBj = {id:Id, lname:layerName, idx:i};
              xx =true;
              Names.push(theOBj);
              break;
            if(layerName.match(/^<\/Layer group/) )
              y ++;
              r = x - y;
              if(r == 0 && ls == "layerSectionEnd"){break};
              continue
        return Names;
    function getLastChildIdx(){
      xx = false;
       var ref = new ActionReference();
       ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
       var count = executeActionGet(ref).getInteger(charIDToTypeID('Cnt '));
      var parId = executeActionGet(ref).getInteger(stringIDToTypeID( 'layerID' ));
       currINDEX = getActiveLayerIndex();
        var i = currINDEX;
        var x = 0;
        var y = 0;
        var r = 0;
        var lastChIdx = 0;
       for(i; i > 0 ; i--){
            ref = new ActionReference();
            ref.putIndex( charIDToTypeID( 'Lyr ' ), i );
            var desc = executeActionGet(ref);
            var layerName = desc.getString(charIDToTypeID( 'Nm  ' ));
            var Id = desc.getInteger(stringIDToTypeID( 'layerID' ));
            var ls = desc.getEnumerationValue(stringIDToTypeID("layerSection"));
            ls = typeIDToStringID(ls);
            var vis = desc.getInteger(stringIDToTypeID( 'visible' ));
            if(ls == "layerSectionStart"){x++};
            if(layerName.match(/^<\/Layer group/) )
              y ++;
              r = x - y;
              if(r == 0 && ls == "layerSectionEnd")
                lastChIdx = i;
                break;
            // alert(x+" _ "+y+" _ "+r+" _ "+layerName);
        return lastChIdx;
    function getNbOfChilds(){
      xx = false;
       var ref = new ActionReference();
       ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
       var count = executeActionGet(ref).getInteger(charIDToTypeID('Cnt '));
      var parId = executeActionGet(ref).getInteger(stringIDToTypeID( 'layerID' ));
       currINDEX = getActiveLayerIndex();
        var i = currINDEX;
        var nb = 0;
        var x = 0;
        var y = 0;
        var r = 0;
       for(i; i > 0 ; i--){
            ref = new ActionReference();
            ref.putIndex( charIDToTypeID( 'Lyr ' ), i );
            var desc = executeActionGet(ref);
            var layerName = desc.getString(charIDToTypeID( 'Nm  ' ));
            var Id = desc.getInteger(stringIDToTypeID( 'layerID' ));
            var ls = desc.getEnumerationValue(stringIDToTypeID("layerSection"));
            ls = typeIDToStringID(ls);
            var vis = desc.getInteger(stringIDToTypeID( 'visible' ));
            if(ls == "layerSectionStart"){x++};
            if(layerName.match(/^<\/Layer group/) )
              y ++;
              r = x - y;
              if(r == 0 && ls == "layerSectionEnd")
                break
              continue
            nb++;
        return nb;
    function isSetOpened1( group ){
      app.activeDocument.activeLayer = group;
      xx = true;
      currSetIDX = getActiveLayerIndex();
      addTempLayerSetIn(currSetIDX-1);
      var fIdx = getActiveLayerIndex();
      makeActiveByIndex(currSetIDX+2, false);
      if(fIdx == getActiveLayerIndex())
        xx = false;
      deleteTempLayerSetbyIdx(currSetIDX+1);
      return xx;
    function addTempLayerSetIn(idxx){
        // =======================================================
        var idMk = charIDToTypeID( "Mk  " );
            var desc58 = new ActionDescriptor();
            var idnull = charIDToTypeID( "null" );
                var ref63 = new ActionReference();
                var idlayerSection = stringIDToTypeID( "layerSection" );
                ref63.putClass( idlayerSection );
            desc58.putReference( idnull, ref63 );
        executeAction( idMk, desc58, DialogModes.NO );
        // =======================================================rename
        var idsetd = charIDToTypeID( "setd" );
            var desc202 = new ActionDescriptor();
            var idnull = charIDToTypeID( "null" );
                var ref209 = new ActionReference();
                var idLyr = charIDToTypeID( "Lyr " );
                var idOrdn = charIDToTypeID( "Ordn" );
                var idTrgt = charIDToTypeID( "Trgt" );
                ref209.putEnumerated( idLyr, idOrdn, idTrgt );
            desc202.putReference( idnull, ref209 );
            var idT = charIDToTypeID( "T   " );
                var desc203 = new ActionDescriptor();
                var idNm = charIDToTypeID( "Nm  " );
                desc203.putString( idNm, "mb-dummy tempTestLayerSetOpen_Closed" );
            var idLyr = charIDToTypeID( "Lyr " );
            desc202.putObject( idT, idLyr, desc203 );
        executeAction( idsetd, desc202, DialogModes.NO );
        // =======================================================move
        var idmove = charIDToTypeID( "move" );
            var desc59 = new ActionDescriptor();
            var idnull = charIDToTypeID( "null" );
                var ref64 = new ActionReference();
                var idLyr = charIDToTypeID( "Lyr " );
                var idOrdn = charIDToTypeID( "Ordn" );
                var idTrgt = charIDToTypeID( "Trgt" );
                ref64.putEnumerated( idLyr, idOrdn, idTrgt );
            desc59.putReference( idnull, ref64 );
            var idT = charIDToTypeID( "T   " );
                var ref65 = new ActionReference();
                var idLyr = charIDToTypeID( "Lyr " );
                ref65.putIndex( idLyr, idxx );
            desc59.putReference( idT, ref65 );
            var idAdjs = charIDToTypeID( "Adjs" );
            desc59.putBoolean( idAdjs, false );
            var idVrsn = charIDToTypeID( "Vrsn" );
            desc59.putInteger( idVrsn, 5 );
        executeAction( idmove, desc59, DialogModes.NO );
    function deleteTempLayerSetbyIdx(idxx){
      // =======================================================
      var idDlt = charIDToTypeID( "Dlt " );
          var desc = new ActionDescriptor();
              var ref = new ActionReference();
              ref.putIndex(charIDToTypeID( 'Lyr ' ), idxx);
              // ref.putIdentifier(charIDToTypeID( 'Lyr ' ), idxx);
              desc.putReference( charIDToTypeID( 'null' ), ref );
      executeAction( idDlt, desc, DialogModes.NO );
    toogleOpenCloseSet();

  • Export multiple images with random layers

    I have this texture file that has many different variations to it. (3 different kinds of pants, different hairpieces, some optional items, etc...)
    What i want to do, is export it with random layers selected. (there are also folders inside, it's fine if i have to merge the folder into a single layer, but it would be better if it could treat the folders as a layer)
    There are 2 layers that must always be on,
    then there are 6 other layers that can be mixed and matched completely at random.
    Finally: there are 3 layers that only one of them can be active at one time (if one is active, the other 2 cannot be). Those last 3 layers I wouldn't mind if i had to go through manually and remove the combinations that couldn't work, but it would be much better to have it automatic.
    Is there any way to script this so that it exports all of these textures as *filename*_*variation#*.png

    -the first 8 lines just make sure there is a valid document open, and if there is, find out the file path and everything
    Correct.
    But I cut corners, if I were more diligent I would also check for the existence of more than one layer and that the file has been saved at all (otherwise it has no path and an error occurs) etc.
    -line 14 just makes sure it outputs no more than 20 images (which i find odd. the texture files are extremely small ~6.82 kb each, so loading them won't be a problem. it would be good if it got stuck in an infinite loop)
    Feel free to change it to a higher number.
    To create 100 files change to
    for (var p = 1; p < 101; p++) {
    Why is thearray2 put in thearray, but then never used separately?
    The function RandomShow checks if the elements in the Array are Arrays themselves
    if (theObject.constructor != Array) {
    and just assumes it is a Layer if it is not an Array.
    But when it is an Array the function RandomShow is run with that Arrays elements as arguments.
    This is intended to enable the various rules – for example if you have two or more Layers of which only one may be visible you could put them in such an Array with minimal and maximal set to 1, which should only make one visible.
    But – and again I should have included checks for this – you should not put a Layer in more than one Array.
    In the example changing theArray2 to
    var theArray2 = [[theLayers[0], theLayers[1], theLayers[2]], 1, 1, "no"];
    would mean that 7, 8 and 9 would only be visible individually.
    But as theArray2 is itself part of theArray it may be visible or not unless it is set as the baseLayer.
    Or rather it would if I had not forget to check the baseLayer item for being an Array itself …
    So please change the affected if-clause (should be about line 34) to
    // show the baselayer;
    if (baseLayer.constructor == Number) {
              var theObject = theArray[baseLayer];
    // show baselayer if layer;
              if (theObject.constructor != Array) {
                        theObject.visible = true;
    // run function if baselayer is an array;
              else {
                        RandomShow (theObject[0], theObject[1], theObject[2], theObject[3])
              maximal--
    -baselayer is defined (but i can't find out where to input what it is, do i put it in place of the "no" on line 15?)
    The function takes four arguments,
    • the Array
    • the minimum number of visible elements
    • the maximum number of visible elements
    • a layer that should always be visible identified by its place in the Array
    So when invoking the function RandomShow and wanting the first layer in the Array to be visible it would be:
    RandomShow (theArray, 1, 5, 0);
    -for the layer array do I put in the actual layer names?
    If you want to address a layer with teh name »Layer 1« by name (top level layers that is, layers in Groups are filial to the Group) you can use
    myDocument.layers.getByName("Layer 1")
    -If I currently have layers hidden, how would i tel it to not add those to be randomly shuffled and made visible (it was randomizing the texturemap and the other layer that is there for future reference into the compiled pngs)
    Whether a Layer is visible or not is irrelevant in the curren tform of the Script, the Layers are addressed in the Array.
    Introducing a check for visibility would be possible, but make the function a bit more convoluted as this would also affect the maximum number for example.
    I don’t think I answered all questions, but maybe you’ve made progress on your own already and you can always post again if matters are still unclear.
    Maybe the function is more complicated than it would need to be or maybe it will not be able to accomodate all your needs currently, but one could for example extend the baseLayer argument to an Array itself to have more than one element (either Layer or another Array) that will always be visible … there are still possibilities but the issue might be a bit complicated.

  • Splitting layer into RGB layers in a group - newbie

    I'm a newbie trying to split a selected layer into multiple layers, each with only one channel enabled. What I mean into the script below, I’d like to do that same thing I do manually by going into Layer Style, in Advanced blending where it has the Channels R checkbox, G checkbox, B checkbox, for my R layer uncheck the G & B.
    I've got a start on grouping, copying the layers, renaming them as I'd like, but I don't know how to do the equivalent of what I described above.
    What I have so far...
    var doc = app.activeDocument,
          currentLayer = doc.activeLayer;
    var group = doc.layerSets.add();
          group.name = currentLayer.name;
    var bLayer = currentLayer.duplicate(); // duplicate layer in target doc
          bLayer.name = 'Blue:' + currentLayer.name;
             currentLayer.visible =false;
    //somehow here  I’d like to do that same thing I do manually in
    //Layer Style, in Advanced blending it has
    //Channels R checkbox, G checkbox, B checkbox
    //for my R layer uncheck the G & B
          bLayer.move( group, ElementPlacement.PLACEATEND ); // move it
          doc.activeLayer = bLayer;
    var gLayer = bLayer.duplicate();
          gLayer.name = 'Green:' + currentLayer.name;
          gLayer.blendMode = BlendMode.NORMAL;
    //somehow here  I’d like to do that same thing I do manually in
    //Layer Style, in Advanced blending it has
    //Channels R checkbox, G checkbox, B checkbox
    //for my G layer uncheck the R & B
          gLayer.opacity = 100.0;
          doc.activeLayer = gLayer;
    var rLayer = gLayer.duplicate();
          rLayer.name = 'Red:' + currentLayer.name;
          rLayer.blendMode = BlendMode.NORMAL;
    //somehow here  I’d like to do that same thing I do manually in
    //Layer Style, in Advanced blending it has
    //Channels R checkbox, G checkbox, B checkbox
    //for my R layer uncheck the G & B
          rLayer.opacity = 100.0;
          doc.activeLayer = rLayer;

    I looked around and finally did this by creating actions and then calling the actions.  I then added a loop that loops around all selected layers, using what I found at:
    https://forums.adobe.com/thread/1536677
    So with more research I answered my question.  Below is my script if others find it useful...
    #target photoshop
    alert("copying each layer in group with R, G, B layers");
    runMulti();
    // run();   
    function runMulti(){
        var selLay = getSelectedLayersIdx();
        if( selLay.constructor != Array ) selLay = [ selLay ];
        for( var i=0; i<selLay.length; i++){
            multiSelectByIDx(selLay[i]);
            run();
    function run (){
    var doc = app.activeDocument,
            currentLayer = doc.activeLayer;
    // test script: what I really want loop around all of the layers in the doc, not just the active one
    // so I want to create a group for each of the original layers
    var group = doc.layerSets.add();
            group.name = currentLayer.name;
    var bLayer = currentLayer.duplicate(); // duplicate layer in target doc
            bLayer.name = 'Blue:' + currentLayer.name;
             currentLayer.visible =false;
            bLayer.move( group, ElementPlacement.PLACEATEND ); // move it
            doc.activeLayer = bLayer;
    //what the action "blue" does is in
    //Layer Style, in Advanced blending it has
    //Channels R checkbox, G checkbox, B checkbox
    //for my B layer uncheck the R & G
              app.doAction("blue", "Default Actions");
    var gLayer = bLayer.duplicate();
            gLayer.name = 'Green:' + currentLayer.name;
            gLayer.blendMode = BlendMode.NORMAL;
            gLayer.opacity = 100.0;
            doc.activeLayer = gLayer;
    //what the action green does is in
    //Layer Style, in Advanced blending it has
    //Channels R checkbox, G checkbox, B checkbox
    //for my G layer uncheck the R & B     
             app.doAction("green", "Default Actions");
    var rLayer = gLayer.duplicate();
            rLayer.name = 'Red:' + currentLayer.name;       
            rLayer.blendMode = BlendMode.NORMAL;
            rLayer.opacity = 100.0;
            doc.activeLayer = rLayer;
    //what the action red does is in
    //Layer Style, in Advanced blending it has
    //Channels R checkbox, G checkbox, B checkbox
    //for my R layer uncheck the G & B  
              app.doAction("red", "Default Actions");
    function hasBackground(){// function to check if there is a background layer
        var res = undefined;
        try{
            var ref = new ActionReference();
            ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID("Nm  "));
            ref.putIndex( charIDToTypeID("Lyr "), 0 );
            executeActionGet(ref).getString(charIDToTypeID("Nm  ") );
            res = true;
        }catch(e){ res = false}
        return res;
    function getSelectedLayersIdx(){// get the selected layers index( positon in layer editor)
         var selectedLayers = new Array;
         var ref = new ActionReference();
         ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
         var desc = executeActionGet(ref);
         var add = 1;
         if(hasBackground()){add = 0}
         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++){
                   selectedLayers.push(  (desc.getReference( i ).getIndex()) + add);
         }else{
              var ref = new ActionReference();
              ref.putProperty( charIDToTypeID('Prpr') , charIDToTypeID( 'ItmI' ));
              ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
              srs = hasBackground()?executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ))-1:executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ));
              selectedLayers.push( srs);
         return selectedLayers;
    function multiSelectByIDx(idx) {
      if( idx.constructor != Array ) idx = [ idx ];
        var layers = new Array();
        var id54 = charIDToTypeID( "slct" );
        var desc12 = new ActionDescriptor();
        var id55 = charIDToTypeID( "null" );
        var ref9 = new ActionReference();
        for (var i = 0; i < idx.length; i++) {
              layers[i] = charIDToTypeID( "Lyr " );
              ref9.putIndex(layers[i], idx[i]);
        desc12.putReference( id55, ref9 );
        var id58 = charIDToTypeID( "MkVs" );
        desc12.putBoolean( id58, false );
        executeAction( id54, desc12, DialogModes.NO );

  • Object is undefined : why?

    Hi all.
    I'm working on a script to facilitate the creation and editing of books in InDesign. I'm not a programmer, and besides a few lines of code written by me, the script consists of code found and adapted to the purpose.
    I have a problem related to two objects (left_box and right_box) : they appear to be undefined, therefore I can not operate on the elements that populate the listboxes that are contained in the objects themselves.
    I have reviewed the code many times but I do not understand where I'm wrong.
    Thanks in advance for any help.
    This is the complete code :
    #target indesign
    #targetengine Main
    // ============================== V A R I A B L E S =================================//
    var theName, theFolder;
    var right_arr = [];
    var left_arr = [];
    main_win();
    // ============================== M A I N ===========================================//
    // -------------------- Creation of main window -------------------------------------//
    function main_win() {
    var dialog_win = new Window ("palette", "Book creator / Book modificator");
        dialog_win.alignChildren = ["fill", "fill"];
        var group_width =  450;
        var group_length = 100;
        var char_length = 45;
        var pm_width = 200; // placemark
        var pm_length = 300 // placemark
        var group_group_1 = dialog_win.add("group");
            group_group_1.alignChildren = ["fill", "fill"];
            var step_group_1 = group_group_1.add("panel");
                step_group_1.preferredSize = [Math.round(group_width / 2), group_length];
                step_group_1.alignChildren = "fill";
                var info_text_1 = step_group_1.add("statictext", undefined, "STEP 1\rSelect the option you are interested in, in order to activate its controls.\rWith no choice, only QUIT button is working.\r\r", {multiline: true});
                    info_text_1.alignment = "fill";
                    info_text_1.characters = Math.round(group_width / 20);
                var radio_group = step_group_1.add("group");
                    radio_group.orientation = "column";
                    radio_group.alignChildren = "fill";
                    var radio1 = radio_group.add("radiobutton", undefined, " Create a new book");
                    var radio2 = radio_group.add("radiobutton", undefined, " Open a book to edit");
            var step_group_2 = group_group_1.add("panel");
                step_group_2.alignChildren = "left";
                var info_text_2 = step_group_2.add("statictext", undefined, "STEP 2\r• Create a new book : first of all choose the destination folder, then type the desired name (max " + (char_length - 10) + " characters) without extension.\r• Open a book to edit : I think you don't need special instructions, right?.\r\r", {multiline: true});
                    info_text_2.alignment = "fill";
                    info_text_2.characters = Math.round(group_width / 8);
                var button_group = step_group_2.add("group");
                    button_group.alignment = "center";
                    button_group.alignChildren = "fill";
                    var new_button = button_group.add("button", undefined, "Destination folder...");
                    var old_button = button_group.add("button", undefined, "Open a book...");
                        new_button.enabled = false;
                        old_button.enabled = false;
                var dir_group = step_group_2.add("group");
                    dir_group.add('statictext {text: "Book folder :", justify: "right"}');
                    dir_group.alignChildren = "right";
                    var book_dir = dir_group.add("statictext", undefined, theFolder);
                        book_dir.characters = char_length;
                var name_group = step_group_2.add("group");
                    name_group.add('statictext {text: "Book name :", justify: "right"}');
                    dir_group.alignChildren = "right";
                    var book_name = name_group.add("edittext", undefined, theName);
                        book_name.characters = char_length - 10;
                        book_name.enabled = false;
        var group_group_2 = dialog_win.add("group");
            group_group_2.alignChildren = ["fill", "fill"];
            var step_group_3 = group_group_2.add("panel");
                step_group_3.preferredSize = [group_width, group_length * 4];
                var group_a = step_group_3.add("group");
                    group_a.orientation = "row";
                    var info_text_3 = group_a.add("statictext", undefined, "STEP 3\r• The left side shows the contents of the book to which you can add or remove documents, and / or order them as you like.\r• The right side shows the documents that are available in the selected folder (if checkbox is selected, the search is also done in the subfolders). Any documents already in the book are not listed. This list is sorted alphabetically by default.\r\r", {multiline: true});
                        info_text_3.alignment = ["left", "top"];
                        info_text_3.characters = Math.round(group_width / 7);
                    var sub_group_a = group_a.add("group");
                        sub_group_a.orientation = "column";
                        sub_group_a.alignChildren = ["fill", "fill"];
                        var list_button = sub_group_a.add("button", undefined, "Files to add...");
                            list_button.enabled = false;
                        var check_sub = sub_group_a.add("checkbox", undefined, "Search in sub-folders");
                            check_sub.enabled = false;
                            check_sub.value = false;
                var group_b = step_group_3.add("group");
                    var button_group_LS = group_b.add("group");
                        var move_group_LS = button_group_LS.add("group");
                            move_group_LS.orientation = "column";
                            move_group_LS.alignChildren = ["fill", "fill"];
                            var move_up = move_group_LS.add("button", undefined, "Move up");
                            var move_down = move_group_LS.add("button", undefined, "Move down");
                            button_group_LS.children[0].enabled = false;
                    var list_group_LS = group_b.add("group");
                        var left_box = add_left (list_group_LS, left_arr);
                            left_box.preferredSize = [pm_width, pm_length];
                            function add_left (left_case, left_arr) {
                                var left_data = left_case.add("listbox", undefined, left_arr, {multiselect: true, showHeaders: true, columnTitles: [" > BOOK CONTENTS"]});
                                return left_data;
                            list_group_LS.children[0].enabled = false;
                    var list_group_RS = group_b.add("group");
                        var right_box = add_right (list_group_RS, right_arr);
                            right_box.preferredSize = [pm_width, pm_length]
                            function add_right (right_case, right_arr) {
                                var right_data = right_case.add("listbox", undefined, right_arr, {multiselect: true, showHeaders: true, columnTitles: [" > AVAILABLE DOCUMENTS "]});
                                return right_data;
                            list_group_RS.children[0].enabled = false;
                    var button_group_RS = group_b.add("group");
                        var move_group_RS = button_group_RS.add("group");
                            move_group_RS.orientation = "column";
                            move_group_RS.alignChildren = ["fill", "fill"];
                            var add_doc = move_group_RS.add("button", undefined, "Add to book");
                            var remove_doc = move_group_RS.add("button", undefined, "Remove from book");
                            button_group_RS.children[0].enabled = false;
        var button_dialog = dialog_win.add("group");
            button_dialog.alignment = "right";
            var quit_button = button_dialog.add("button", undefined, "QUIT");
            var doit_button = button_dialog.add("button", undefined, "DO IT");
                doit_button.enabled = false;
    // -------------------- Evaluate choices --------------------------------------------//
        // --- STEP 1 ---//
        radio1.onClick = function() {
            check_open();
            new_button.enabled = true;
            old_button.enabled = false;
            new_button.active = true;
        radio2.onClick = function() {
            check_open();
            new_button.enabled = false;
            old_button.enabled = true;
            old_button.active = true;
        // --- STEP 2 ---//
        new_button.onClick = function() {
            book_name.text = "";
            new_book = Folder.selectDialog ("Choose the destination folder for the new book...");
            if (left_box.items.length > 0) {
                left_arr = [];
                upd_left(left_box);
            if (new_book != null) {
                book_dir.text = path_trim(new_book.fsName);
            book_name.enabled = true;
            book_name.active = true;
            list_button.enabled = true;
            check_sub.enabled = true;
        book_name.onChanging = function() {
            max_char = book_name.text;
            if (max_char.length > book_name.characters) {
                book_name.text = "";
                book_name.textselection = max_char.slice(0, book_name.characters);
        old_button.onClick = function() {
            old_book = File.openDialog ("Select the book file to open...", let_me_see, true);
            if (left_box.items.length > 0) {
                left_arr = [];
                upd_left(left_box);
            if (old_book != null) {
                book_dir.text = path_trim(old_book);
                book_split(book_dir.text);
                book_dir.text = the_folder;
                book_name.text = the_name;
            get_Docs(old_book);
            clean(left_arr);
            list_group_LS.remove(list_group_LS.children[0]);
            left_box = add_left (list_group_LS, left_arr);
            left_box.preferredSize = [pm_width, pm_length];
            book_name.enabled = false;
            list_button.enabled = true;
            list_button.active = true;
            check_sub.enabled = true;
            dialog_win.layout.layout(true);
        // --- STEP 3 ---//
        list_button.onClick = function() {
            var myFolder = Folder.selectDialog("Select a folder in which to search for documents...");
            if (right_box.items.length > 0) {
                right_arr = [];
                upd_right(right_box);
            check_folder(myFolder, check_sub.value);
            right_arr.sort();                   // sorting the values of the array
            right_arr = decodeURI(right_arr);   // replacing %20 with space
            right_arr = right_arr.split(',');   // converting into array
            var the_right_arr = right_arr.slice();
                right_arr = [];
                getFileName(the_right_arr);
            list_group_RS.remove(list_group_RS.children[0]);
            right_box = add_right (list_group_RS, right_arr);
            right_box.preferredSize = [pm_width, pm_length];
            list_group_LS.children[0].enabled = true;
            list_group_RS.children[0].enabled = true;
            button_group_LS.children[0].enabled = true;
            button_group_RS.children[0].enabled = true;
            doit_button.enabled = true;
            dialog_win.layout.layout(true);
        move_up.onClick = function () {
            var n = left_box.selection.index;
            if(n > 0) {
                swap (left_box.items[n - 1], left_box.items[n]);
                left_box.selection = n - 1;
        move_down.onClick = function () {
            var n = left_box.selection.index;
            if (n < left_box.items.length - 1) {
                swap (left_box.items[n], left_box.items[n + 1]);
                left_box.selection = n + 1;
        add_doc.onClick = function() {
            // something ...
        remove_doc.onClick = function() {
            left_arr.splice(left_box.selection.index, 1);
            upd_left(left_box);
        // --- LAST STEP ---//
        quit_button.onClick = function() {
            dialog_win.close();
        doit_button.onClick = function() {
            if (book_name.text != "") {
                check_book(new_book, book_name);
            else {
                alert("The book name is missing.");
        check_open();
        dialog_win.show ();
    // ============================== F U N C T I O N S =================================//
    // --- BEGINNIG ---//
        // -------------------- Check for open book files -----------------------------------//
        function check_open() {
            if (app.books.length != 0) {
                var q = confirm("All book files must be closed before proceeding. If you press YES I will close them for you, otherwise press NO and close them manually.");
                if (q == true) {
                    for (var x1 = 0; x1 < app.books.length; x1++) {
                        var open = app.books[x1];
                        open.close();
                        radio1.checked = false;
                        radio2.checked = false;
                } else {
                    exit(0);
    // --- STEP 2 NEW BOOK / OLD BOOK ---//
        // -------------------- Adapt directory text to max length of the static text ---//
        function path_trim(path) {
            var theFile = new File(path);
            var pathTrim = ".../" + theFile.fsName.split("/").splice(0).join("/");
            if ((pathTrim.length - 50) < 50) {
                pathTrim = ".../" + theFile.fsName.split("/").splice(-3).join("/");
            else if ((pathTrim.length - 50) > 50) {
                pathTrim = ".../" + theFile.fsName.split("/").splice(-2).join("/");
            return pathTrim;
    // --- STEP 2 OLD - LEFT SIDE ---//
        // -------------------- Selection of what can be shown in dialog window ---------//
        function let_me_see(bookPath){
            if (bookPath.constructor.name == "Folder") {return true}
            if (bookPath.name.slice(-5) == ".indb") {return true}
                return false;
        // -------------------- Extraction of the book name and its path ----------------//
        function book_split(split_it) {
            var the_path = new File(split_it);
            var book_path = decodeURI(String(the_path));
            //  the_name.text = book_path.pop(); // file name with extension
                the_name = (book_path.split('/').pop().split('.'))[0];
                the_folder = book_path.split("/").slice(0, -1).join("/");
                while (the_folder.charAt(0)=='/') the_folder = the_folder.substring(1,the_folder.length);
                return [the_name, the_folder];
        // -------------------- Left list update ----------------------------------------//
        function upd_left(left_data) {
            left_data.removeAll();
            var x2 = 0;
            while (left_data.items.length < left_arr.length) {
                left_data.add(left_arr[x2]);
                x2++;
        // -------------------- Extract document name from book -------------------------//
        function get_Docs(doc) {
            app.open(doc);
            var book_ref = app.activeBook;
            for (var x3 = 0; x3 < book_ref.bookContents.length; x3++){
                left_arr += book_ref.bookContents[x3].name;
            book_ref.close();
            left_arr = left_arr.split('.indd'); // converting into array
            return doc;
    // --- STEP 3 RIGHT SIDE ---//
        // -------------------- Right list update ---------------------------------------//
        function upd_right(right_data) {
            right_data.removeAll();
            var x5 = 0;
            while (right_data.items.length < right_arr.length) {
                right_data.add(right_arr[x5]);
                x5++;
        // -------------------- Files search through folders ----------------------------//
        function check_folder(folder, sub_dir) {
            var myFilesList = folder.getFiles();
            for (var x6 = 0; x6 < myFilesList.length; x6++) {
                var myList = myFilesList[x6];
                if (myList instanceof File && myList.name.match(/\.indd$/i)) {
                    right_arr.push(myList);
                else if (myList instanceof Folder) {
                    if (sub_dir == true) {
                        check_folder(myList);
            return folder;
        // -------------------- Extract document name from folders list -----------------//
        function getFileName(value) {
            for (var x7 = 0; x7 < value.length; x7++){
                var theFile = (value[x7].split('/').pop().split('.indd'))[0];
                    right_arr.push(theFile);
            right_arr.sort();
            return value;
        // -------------------- Swap for move up and move down --------------------------//
        function swap (x, y) {
            var temp = x.text; x.text = y.text; y.text = temp;
    // --- LAST STEP ---//
        // -------------------- Check existance -----------------------------------------//
        function check_book(check_dir, check_name) {
            var check_path = check_dir + "/" + check_name.text + ".indb";
            if (File(check_path).exists == true) {
                alert("A book with the same name already exists, please change the name.");
            } else {
            // something
                alert("ALL DONE");
    // ========== UTILIY ==========//
        // -------------------- Remove empty records ------------------------------------//
        function clean(what) {
            for(var i = what.length - 1; i >= 0; i--) {
                if(what[i] == "") {
                   what.splice(i, 1);
    // ========== THE END =========//

    You can't really expect anyone to read that much code, without a sample to run the script against and see what happens. But by chance I noticed these lines:
    right_arr.sort();                  // sorting the values of the array 
    right_arr = decodeURI(right_arr);  // replacing %20 with space 
    right_arr = right_arr.split(',');
    which are probably the source of the problem. decodeURI() is a string function, not an array function. Unfortunately, instead of throwing an error, it converts an array to a string:
    a = ['a%20b'];
    $.writeln (a.constructor.name);  // Array
    s = decodeURI(a);
    $.writeln (s.constructor.name);  // String
    You need to change %20 to a space in each individual array element. If this doesn't solve the problem you'll have to find the person who wrote the code and ask them to fix it.
    Peter

  • PS3 script to batch rename layers

    Sometimes, I make copies of layers (for example: copy little diamonds to align into a shape of the letter M). Each time I "alt+drag" the content in that layer (to make a copy of it), PS makes a copy and then appends the name of the layer to something like "diamond copy 3". After making a ton of copies (and because I'm anal about having actual names for each layer), I want each layer to read "diamond". Instead of manually renaming all these layers, is there a way to highlight the affected layers and choose to rename all layers according to what you want?

    Try this. Just select the layers you want 'copy' removed from and run this script.
    if( app.documents.length > 0 ){
    app.activeDocument.suspendHistory('Rename selected layers','removeCopyFromSelectedLayersNames()');
    function removeCopyFromLayerName(){
         if( getSelectedLayersIdx().length > 1 ){
              var selectedLayers = getSelectedLayersIdx();
              makeActiveByIndex( selectedLayers[0], false );
       var startLoop = Number( !hasBackground() );
       var endLoop = getNumberOfLayer() + 1;
       for( var l = startLoop;l < endLoop; l++){
            while( !isValidActiveLayer( l ) ) {
                l++;
              var oldName =  getLayerNameByIndex( l );
              var newName = oldName.replace(/\scopy\s?\d*$/i,'');
              putLayerNameByIndex( l, newName )
         if( selectedLayers != undefined ) makeActiveByIndex( selectedLayers, false );
    function removeCopyFromSelectedLayersNames(){
         var selectedLayers = getSelectedLayersIdx();
         for( var l = 0;l < selectedLayers.length; l++){
              var oldName =  getLayerNameByIndex( selectedLayers[ l ] );
              var newName = oldName.replace(/\scopy.*$/i,'');
              makeActiveByIndex( selectedLayers[ l ], false );
              putLayerNameByIndex( selectedLayers[ l ], newName )
         makeActiveByIndex( selectedLayers, false );
    function getNumberOfLayer(){
    var ref = new ActionReference();
    ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
    var desc = executeActionGet(ref);
    var numberOfLayer = desc.getInteger(charIDToTypeID('NmbL'));
    return numberOfLayer;
    function getLayerNameByIndex( idx ) {
        var ref = new ActionReference();
        ref.putProperty( charIDToTypeID('Prpr') , charIDToTypeID( 'Nm  ' ));
        ref.putIndex( charIDToTypeID( 'Lyr ' ), idx );
        return executeActionGet(ref).getString(charIDToTypeID( 'Nm  ' ));;
    function putLayerNameByIndex( idx, name ) {
         if( idx == 0 ) return;
        var desc = new ActionDescriptor();
            var ref = new ActionReference();
            ref.putIndex( charIDToTypeID( 'Lyr ' ), idx );
        desc.putReference( charIDToTypeID('null'), ref );
            var nameDesc = new ActionDescriptor();
            nameDesc.putString( charIDToTypeID('Nm  '), name );
        desc.putObject( charIDToTypeID('T   '), charIDToTypeID('Lyr '), nameDesc );
        executeAction( charIDToTypeID('setd'), desc, DialogModes.NO );
    function getActiveLayerIndex() {
         var ref = new ActionReference();
         ref.putProperty( 1349677170 , 1232366921 );
         ref.putEnumerated( 1283027488, 1332896878, 1416783732 );
         var res = executeActionGet(ref).getInteger( 1232366921 )
                                                           - Number( hasBackground() );
         return res;  
    function isValidActiveLayer( idx ) {
         var propName = stringIDToTypeID( 'layerSection' );
         var ref = new ActionReference();
         ref.putProperty( 1349677170 , propName);
         ref.putIndex( 1283027488, idx );
         var desc =  executeActionGet( ref );
         var type = desc.getEnumerationValue( propName );
         var res = typeIDToStringID( type );
         return res == 'layerSectionEnd' ? false:true;
    function hasBackground(){
        var res = undefined;
        try{
            var ref = new ActionReference();
            ref.putProperty( 1349677170 , 1315774496);
            ref.putIndex( 1283027488, 0 );
            executeActionGet(ref).getString(1315774496 );;
            res = true;
        }catch(e){ res = false}
        return res;
    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++){
                   selectedLayers.push(  desc.getReference( i ).getIndex());
         }else{
              var ref = new ActionReference();
              ref.putProperty( charIDToTypeID('Prpr') , charIDToTypeID( 'ItmI' ));
              ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
              selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' )));
         return selectedLayers;
    function makeActiveByIndex( idx, visible ){
         if( idx.constructor != Array ) idx = [ idx ];
         for( var i = 0; i < idx.length; i++ ){
              var desc = new ActionDescriptor();
              var ref = new ActionReference();
              ref.putIndex(charIDToTypeID( 'Lyr ' ), idx[i])
              desc.putReference( charIDToTypeID( 'null' ), ref );
              if( i > 0 ) {
                   var idselectionModifier = stringIDToTypeID( 'selectionModifier' );
                   var idselectionModifierType = stringIDToTypeID( 'selectionModifierType' );
                   var idaddToSelection = stringIDToTypeID( 'addToSelection' );
                   desc.putEnumerated( idselectionModifier, idselectionModifierType, idaddToSelection );
              desc.putBoolean( charIDToTypeID( 'MkVs' ), visible );
              executeAction( charIDToTypeID( 'slct' ), desc, DialogModes.NO );

  • Creating my first Photoshop plugin

    Hi all,
    I am a programmer, I program in PHP, and Obj-C, I know C++ quite fair. I also Design web templates & code them. I need a plugin for photoshop, I searched it but I couldn't find it. So I thought I will try creating it for mysel & if it was nice I will share it too. But unfortunately I don't much help online for creating a very basic photoshop plugin.
    By the way, here are my requirments for that plugin:
    Most when I create my templates, I group layers e.g Button, Banner, CommentBox etc etc. Now all the related layers are gouped, but if I sometime want to move 2 layers from Buttons, 3 layers from Banner, & 1 layer from CommentBox group, so I select all those layers (Searching for them in my Layer palette ) & move all together. Now I want to move them again I will search for all these layers again across those groups, so I want to save layer selections. e.g I select a few layers across different groups, & save the selection as 'LeftObjects' & similarly select some more layers and save this layer selection as 'RightObjects'. Now whenever I need to select all those left layers together I click the 'LeftObjects' selection & select all the layers for me saving me from searching for those layers.
    I would really appreciate if someone could help, or suggest me  a step by step guide to a basic Photoshop plugin. I am a pretty good learner, so I would do it, but I just need a start.
    Thank you all
    Cheers.

    Actually you can do that with java script and a flex panel, but I don't see why because you can just use the link layers already in Photoshop, the only downside of linking is that you can't define any name for the link layer set.
    Anyway if you still want to develop that you can do it with javascript and flex or html5 for CC.
    For the Flash panels (Cs4,Cs5,Cs6) you can find the documentation here: Adobe Photoshop Panel Developer's Guide, as for the html5 panels for CC there are some great tutorials here: http://www.davidebarranca.com/.
    Also here are some java script functions to get the selected layers id's and select an array of id's.
    function getSelectedLayersIds(){// get the selected layers identifiers
      //( these id's are unique and they will not change if the layer name is changed or it's position in the layers editor will change)
      var idxs = getSelectedLayersIdx();// first get the indexes
      var selectedLayersIds = [];
      //for each index get the layer id
      for( var i=0;i<idxs.length;i++){
      selectedLayersIds.push(getIdfromIdx(idxs[i]));
      return selectedLayersIds;
    function hasBackground(){// function to check if there is a background layer
        var res = undefined;
        try{
            var ref = new ActionReference();
            ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID("Nm  "));
            ref.putIndex( charIDToTypeID("Lyr "), 0 );
            executeActionGet(ref).getString(charIDToTypeID("Nm  ") );
            res = true;
        }catch(e){ res = false}
        return res;
    function getIdfromIdx( idx ){// get the id from index
      var ref = new ActionReference();
      ref.putIndex(charIDToTypeID('Lyr '), idx);
        var desc = executeActionGet(ref);
        desc = desc.getInteger(charIDToTypeID("LyrI"));
        return desc;
    function getSelectedLayersIdx(){// get the selected layers index( positon in layer editor)
         var selectedLayers = new Array;
         var ref = new ActionReference();
         ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
         var desc = executeActionGet(ref);
         var add = 1;
         if(hasBackground()){alert('hBck');add = 0}
         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++){
                   selectedLayers.push(  (desc.getReference( i ).getIndex()) + add);
         }else{
              var ref = new ActionReference();
              ref.putProperty( charIDToTypeID('Prpr') , charIDToTypeID( 'ItmI' ));
              ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
              srs = hasBackground()?executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ))-1:executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ));
              selectedLayers.push( srs);
         return selectedLayers;
    function doesIdExists( id ){// function to check if the id exists
      var res = true;
      var ref = new ActionReference();
      ref.putIdentifier(charIDToTypeID('Lyr '), id);
        try{var desc = executeActionGet(ref)}catch(err){res = false};
        return res;
    function multiSelectByIDs(ids) {
      if( ids.constructor != Array ) ids = [ ids ];
        var layers = new Array();
        var id54 = charIDToTypeID( "slct" );
        var desc12 = new ActionDescriptor();
        var id55 = charIDToTypeID( "null" );
        var ref9 = new ActionReference();
        for (var i = 0; i < ids.length; i++) {
        if(doesIdExists(ids[i]) == true){// a check to see if the id stil exists
             layers[i] = charIDToTypeID( "Lyr " );
             ref9.putIdentifier(layers[i], ids[i]);
        desc12.putReference( id55, ref9 );
        var id58 = charIDToTypeID( "MkVs" );
        desc12.putBoolean( id58, false );
        executeAction( id54, desc12, DialogModes.NO );
    The way I see the panel will be like this:
    first get the selected id's with the "getSelectedLayersIds()"  command , and create a metadata with the name of the set and the array of id's, also add in the panel one button with the name of the new set. I am thinking of the metadata because you can save it with the document and every time you will open the document you can read that data to populate your panel with the already saved sets.
    When you want to select back the layers from one set, just click on the button set from the panel, and from the metadata of the document search the name of the set and get the corresponding array of id's, than just use the "multiSelectByIDs( the array)" to select the layers.
    That's it I hope I was clear enough.

  • [JS] Found text is not a text?

    Hi,
    Could you help me to find a reason of 'undefined is not an object' error, pls?
    app.findTextPreferences = NothingEnum.nothing;
    app.findTextPreferences.appliedParagraphStyle = myParaStyle;
    mFound = myStory.findText();
    if (myFound.length > 0)
         mStart = myFound[0].insertionPoints[0];     // here is error 'undefined is not an object'
    this is a part of preety long code and I wouldn't paste it here, but:
    I checked some variables properties:
    mFound.length  = = 1 so InD found some text, I guess;
    mFound[0].constructor.name = = "Array";
    mFound[0].length = = 0;
    so what is found by ID (which .appliedParagraphStyle = = myParaStyle) and why this is not a text?
    If I run this part of code manually, starting from point where script ends ==> mFound.length = = 0.
    I know that I made mistake(s) somewhere, but I have not idea what should I look for...
    Has 0-element Array some property to check and discover, where it came from?
    Help me pls.
    Thx

    Now to your question:
    1) Usually, myArea.findText() will return an Array of zero, one or more Text objects. In other words, provided that myFound.length > 0, each myFound[i] should be a Text specifier. This is what happens if myArea is the Application, a Document, a Story, or any singular Text specifier.
    2) BUT, if for some reason myArea is a plural specifier—such as myStory.paragraphs.everyItem()—then myArea.findText() will return an Array of Array(s) of Text(s). The outer array reflects the plural behavior of the specifier, while the inner arrays reflect the return type of the findText() method. In that case you may have empty arrays within the outer array. Indeed:
       myStory.paragraphs.everyItem().findText()
    will send the findText() command to every paragraph, so any paragraph that does not match the query will produce an empty array.
    Maybe your script leads to something similar. We'd need to see more code to figure it out.
    @+
    Marc

  • How do I get the Photoshop layer tags in JavaScript?

    I asked this question at graphic design stack exchange but they pointed me here:
    http://graphicdesign.stackexchange.com/questions/35374/how-do-i-get-the-photoshop-layer-ta gs-in-javascript?noredirect=1#comment48962_35374
    I want to do actions based on the tagged layer color (these thing 1) in Photoshop. I can't find a property inside the JavaScript documentation or the ExtendScript Toolkit that might contain the value.
    I'd prefer not to abuse the name for that, the layer tags look like a very clean solution to my problem. If only I could fetch them.
    Any Ideas?
    Kind Regards,
    Mii

    Hi, these functions will select all your layers with the specified color:
    use the command: selectAllByColor("red");
    function getIDXwithsameColor(TheColor){// search and return a list of indexes for the layers with the specified color
        var ref = new ActionReference();
        var toRet = [];
        try{activeDocument.backgroundLayer;var a=0 }catch(e){ var a = 1; };
        while(true){
          ref = new ActionReference();
          ref.putIndex( charIDToTypeID( 'Lyr ' ), a );
          try{var desc = executeActionGet(ref);}catch(err){break;}
            var cl = desc.getEnumerationValue(charIDToTypeID("Clr "));
            cl = typeIDToStringID(cl);
            var ls = desc.getEnumerationValue(stringIDToTypeID("layerSection"));
            ls = typeIDToStringID(ls);
            if(ls != 'layerSectionEnd'){
              if(cl == TheColor){
                toRet.push(a);
          a++;
        return toRet;
    function multiSelectByIDX(idx) {// selection function
      if( idx.constructor != Array ) idx = [ idx ];
        var layers = new Array();
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        for (var i = 0; i < idx.length; i++) {
              layers[i] = charIDToTypeID( "Lyr " );
              ref.putIndex(layers[i], idx[i]);
        desc.putReference( charIDToTypeID( "null" ), ref );
        executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
    function selectAllByColor(TheColor){// main function
      theSameClIDX = getIDXwithsameColor(TheColor);
      multiSelectByIDX(theSameClIDX);
    //...example::
    // selectAllByColor("none");
    //selectAllByColor("red");
    // selectAllByColor("orange");
    // selectAllByColor("yellowColor");
    // selectAllByColor("grain");
    // selectAllByColor("blue");
    // selectAllByColor("violet");
    // selectAllByColor("gray");

  • How to set layer color property via script?

    I'm looking for a way to set a layer's UI color property via script (see attached). Any help would be greatly appreciated!

    jrapczak2 wrote:
    Uhm.. wow. That's crazy complicated
    It is even more complicated to work with multi-selected layers.
    if( app.documents.length > 0 && versionCheck()  ){
         app.activeDocument.suspendHistory("Set Layer's Color", 'changeLayersColor()');
    function versionCheck()  { return app.version.match(/1[1|2]./) >= 11; };
    function changeLayersColor(){
         function setActiveLayerColor( color ) {
              var desc = new ActionDescriptor();
                   var ref = new ActionReference();
                   ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
              desc.putReference( charIDToTypeID('null'), ref );
                   var colorEnumDesc = new ActionDescriptor();
                   colorEnumDesc.putEnumerated( charIDToTypeID('Clr '), charIDToTypeID('Clr '), color );
              desc.putObject( charIDToTypeID('T   '), charIDToTypeID('Lyr '), colorEnumDesc );
              executeAction( charIDToTypeID('setd'), desc, DialogModes.NO );
         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" )));
                   return selectedLayers;
         function makeActiveByIndex( idx, visible ){
              if( idx.constructor != Array ) idx = [ idx ];
              for( var i = 0; i < idx.length; i++ ){
                   var desc = new ActionDescriptor();
                   var ref = new ActionReference();
                   ref.putIndex(charIDToTypeID( "Lyr " ), idx[i] );
                   desc.putReference( charIDToTypeID( "null" ), ref );
                   if( i > 0 ) {
                        var idselectionModifier = stringIDToTypeID( "selectionModifier" );
                        var idselectionModifierType = stringIDToTypeID( "selectionModifierType" );
                        var idaddToSelection = stringIDToTypeID( "addToSelection" );
                        desc.putEnumerated( idselectionModifier, idselectionModifierType, idaddToSelection );
                   desc.putBoolean( charIDToTypeID( "MkVs" ), visible );
                   executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
         var colors = ['None','Red','Orange','Yellow','Green','Blue','Violet','Grey'];
         var colorIDs = [charIDToTypeID('None'),
                                  charIDToTypeID( "Rd  " ),
                                  charIDToTypeID( "Orng" ),
                                  charIDToTypeID( "Ylw " ),
                                  charIDToTypeID( "Grn " ),
                                  charIDToTypeID( "Bl  " ),
                                  charIDToTypeID( "Vlt " ),
                                  charIDToTypeID( "Gry " )];
         var dlg = new Window( 'dialog', 'Change Layer Color' );
         dlg.ddColors= dlg.add("dropdownlist", undefined,  colors);
         dlg.ddColors.preferredSize.width = 100;
         dlg.ddColors.items[0].selected = true;
         dlg.ok = dlg.add('button',undefined,'Ok');
         dlg.cancel = dlg.add('button',undefined,'Cancel');
         var results = dlg.show();
         if( results == 1 ){
              var selectedLayers =  getSelectedLayersIdx();
              for( var l=0;l<selectedLayers.length;l++ ){
                   makeActiveByIndex( selectedLayers[l], false );
                   setActiveLayerColor( colorIDs[dlg.ddColors.selection.index] );
              makeActiveByIndex( selectedLayers,false );

  • [JS] Problem in findKeyString and menuAction

    Hi,
    I read the scripting guide and try to apply that snippet :
    var myString = "";
    var myMenuAction = app.menuActions.item("Convert to Note");
    var myKeyStrings = app.findKeyStrings(myMenuAction.name);
    if(myKeyStrings.constructor.name == "Array"){
    for(var myCounter = 0; myCounter < myKeyStrings.length; myCounter ++){
    myString += myKeyStrings[myCounter] + "\r";
    else{
    myString = myKeyStrings;
    alert(myString);
    I want to get the independant locale string for my french "Document..." command (New Document basically). But if I replace "Convert to Note" by "Document...", the script just prints an empty string.
    I am not sure at all but all my attempts to findKeyString with strings containing ellipsis just fail.
    Furtherly I want to add a eventListener on that menu but I think this post from Kasyan will be instructive enough.
    The problem is start, at the very beginning, I can't get acces to the native $ID/xxx string for the New Document command :-S
    http://forums.adobe.com/message/1107494#1107494
    Any hint ?
    Thanks for all of you guys helping me through years.
    Loic

    Oh, this is fascinating. It appears to, most of the time, return an & but only if you give it an & as input.
    So, for instance:
    function check(s) {
         $.writeln("for "+s+"\n"+
         "no-&\t" + app.findKeyStrings(s).join("\n\t")+"\n"+
         "&\t" + app.findKeyStrings("&"+s).join("\n\t")+
         "\n");    
    check("Document");
    check("New");
    check("File");
    check("Layout");
    check("Edit");
    check("Open...");
    Produces:
    for Document
    no-&    $ID/TV Document
            $ID/DE_Document
            $ID/Document
            $ID/kDocument
            $ID/kPMDocumentTextKey
            $ID/kPMWOpenDocumentWidgetTextLineIIKey
            $ID/kPMWNewDocumentWidgetTextLineIIKey
    for New
    no-&    $ID/kPMWNewDocumentWidgetTextLineIKey
            $ID/Structure_NewFlyout
    &       $ID/&New
    for File
    no-&
    &       $ID/&File
    for Layout
    no-&    $ID/0x58900kS_LayoutStr [NT]
            $ID/LayoutTabName
            $ID/0x58900kS_LayoutKey
            $ID/FS Layout
            $ID/Layout
    &       $ID/&Layout
    for Edit
    no-&    $ID/Structure_Edit
            $ID/Edit
    &       $ID/&Edit
            $ID/#DIALOG_HyperlinkEdit
    for Open...
    no-&    $ID/kPMOpenDocTextKey
    &       $ID/Open...
            $ID/&Open...
    So, in many cases, findKeyStrings() with an & and without an & both return their respective & and &-less versions of $ID/foo and $ID/&foo. But in some cases, without an & returns wrong unhelpful keystrings that seem to substring match foo. And in other cases, & seems required.
    I don't find any support here for the idea that using & is better than not. Obviously in some cases you are required to use it (File) and in other cases you are required not to use it (Document), and this seems like it must be a bug because who the heck would figure it out,..

  • How does columnSpan work? [JS][CC2014]

    Some background info:
    I'm using InDesign CC 2014 latest version
    I have a simple table set up: 6 columns by 5 rows
    I want to check if the first cell in the first row is merged, and if it isn't merged, merge the first 4 columns of the first row. So I wrote this javascript:
    myDoc = app.activeDocument,
    myPage = myDoc.pages[0],
    myTable = myDoc.stories.everyItem().tables[0];
    var checkMerged = myTable.rows[0].cells[0].columnSpan;
    alert(checkMerged);
    //merge the cells if not already merged
    if (checkMerged === 1){
       myTable.rows[0].cells[0].merge(myTable.rows[0].cells[3]);
        } else {
            alert("Merged");
    When the cell is not merged, the alert returns "1,1,1", when it is merged, it returns "4,1,1".
    on this page: Adobe InDesign CS6 (8.0) Object Model JS: Cell it says that columnSpan is a readonly number, but it looks like an array.
    Please help. I feel like I'm taking crazy pills.
    Thanks

    @Laubender Thanks for pointing me in the right direction.
    When I ran your tests, the console outputs:
    $.writeln(myTable);  //[object Table]
    $.writeln(myTable.constructor.name);  //Table
    $.writeln(myTable.getElements().constructor.name);    //Array
    $.writeln(myTable.getElements().length); //1
    I'm not sure I fully grasped all the concepts on my first read of those articles, though. My understanding is that  everyitem() is returning an array, but the array is not something that can be used because it's only a path to the item and not the actual item (Not 100% sure that's right - need to re-read those articles again).
    I changed my code to:
    var myDoc = app.activeDocument,
    myPage = myDoc.pages[0],
    myTable = myDoc.stories[0].tables[0];
    var checkMerged = myTable.rows[0].cells[0].columnSpan;
    alert(checkMerged);
    //merge the cells if not already merged
    if (checkMerged === 1){
      myTable.rows[0].cells[0].merge(myTable.rows[0].cells[3]);
        } else {
            alert("Merged");
    And now it works
    Thanks again!

  • Draw a pen path, then a script to select/copy and close activeDocument

    Is this possible?
    I do this step 90 times every day:
    Select a image area drawing a pen path zone, and copying it to the clipboard.
    Then close without save.
    Then I use the selection on clipboard to paste it on the previous opened image.
    P.S. I use paths because I need to have a more accurate and precise curves.

    Does this help?
    // get active path, close document without saving, create path;
    // 2011, use it at your own risk;
    #target photoshop
    if (app.documents.length > 1) {
    // identify path;
    var thePath = selectedPath();
    if (thePath != undefined) {
    var myDocument = app.activeDocument;
    // set to pixels;
    var originalRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;
    // collect info;
    var thePathInfo = collectPathInfoFromDesc(myDocument, thePath);
    // close withpout saving;
    myDocument.close(SaveOptions.DONOTSAVECHANGES);
    // create path;
    createPath(thePathInfo, dateString());
    // reset;
    app.preferences.rulerUnits = originalRulerUnits;
    else {alert ("no path selected")}
    ////// determine selected path //////
    function selectedPath () {
    try {
    var ref = new ActionReference();
    ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
    var desc = executeActionGet(ref);
    var theName = desc.getString(charIDToTypeID("PthN"));
    return app.activeDocument.pathItems.getByName(theName)
    catch (e) {
    return undefined
    ////// collect path infor from actiondescriptor //////
    function collectPathInfoFromDesc (myDocument, thePath) {
    //var myDocument = app.activeDocument;
    var originalRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.POINTS;
    // based of functions from xbytor’s stdlib;
    var ref = new ActionReference();
    for (var l = 0; l < myDocument.pathItems.length; l++) {
         var thisPath = myDocument.pathItems[l];
         if (thisPath == thePath && thisPath.name == "Work Path") {
              ref.putProperty(cTID("Path"), cTID("WrPt"));
         if (thisPath == thePath && thisPath.name != "Work Path" && thisPath.kind != PathKind.VECTORMASK) {
              ref.putIndex(cTID("Path"), l + 1);
         if (thisPath == thePath && thisPath.kind == PathKind.VECTORMASK) {
            var idPath = charIDToTypeID( "Path" );
            var idPath = charIDToTypeID( "Path" );
            var idvectorMask = stringIDToTypeID( "vectorMask" );
            ref.putEnumerated( idPath, idPath, idvectorMask );
    var desc = app.executeActionGet(ref);
    var pname = desc.getString(cTID('PthN'));
    // create new array;
    var theArray = new Array;
    var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
    // for subpathitems;
    for (var m = 0; m < pathComponents.count; m++) {
         var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
         var operation = thePath.subPathItems[m].operation;
    // for subpathitem’s count;
         for (var n = 0; n < listKey.count; n++) {
              theArray.push(new Array);
              var points = listKey.getObjectValue(n).getList(sTID('points'));
              try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}
              catch (e) {var closed = false};
    // for subpathitem’s segment’s number of points;
              for (var o = 0; o < points.count; o++) {
                   var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));
                   var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
                   var thisPoint = [anchor];
                   try {
                        var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));
                        var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];
                        thisPoint.push(leftDirection)
                   catch (e) {
                        thisPoint.push(anchor)
                   try {
                        var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));
                        var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))]
                        thisPoint.push(rightDirection)
                   catch (e) {
                        thisPoint.push(anchor)
                   theArray[theArray.length - 1].push(thisPoint);
              theArray[theArray.length - 1].push(closed);
              theArray[theArray.length - 1].push(operation);
    // by xbytor, thanks to him;
    function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
    function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
    // reset;
    app.preferences.rulerUnits = originalRulerUnits;
    return theArray;
    ////// function to create path from array with one array per point that holds anchor, leftdirection, etc, 2010 //////
    function createPath (theArray, thePathsName) {
    var originalRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.POINTS;
    lineSubPathArray = new Array ();
    if (theArray[theArray.length - 1].constructor != Array) {var numberOfSubPathItems = theArray.length - 1}
    else {var numberOfSubPathItems = theArray.length};
    for (var b = 0; b < numberOfSubPathItems; b++) {
         var lineArray = new Array ();
         for (c = 0; c < (theArray[b].length - 2); c++) {
              lineArray[c] = new PathPointInfo;
              if (!theArray[b][c][3]) {lineArray[c].kind = PointKind.CORNERPOINT}
              else {lineArray[c].kind = theArray[b][c][3]};
              lineArray[c].anchor = theArray[b][c][0];
              if (!theArray[b][c][1]) {lineArray[c].leftDirection = theArray[b][c][0]}
              else {lineArray[c].leftDirection = theArray[b][c][1]};
              if (!theArray[b][c][2]) {lineArray[c].rightDirection = theArray[b][c][0]}
              else {lineArray[c].rightDirection = theArray[b][c][2]};     
         lineSubPathArray[b] = new SubPathInfo();
         lineSubPathArray[b].closed = theArray[b][theArray[b].length - 2];
         lineSubPathArray[b].operation = theArray[b][theArray[b].length - 1];
         lineSubPathArray[b].entireSubPath = lineArray;
    var myPathItem = app.activeDocument.pathItems.add(thePathsName, lineSubPathArray);
    app.preferences.rulerUnits = originalRulerUnits;
    return myPathItem
    ////// function to get the date //////
    function dateString () {
         var now = new Date();
         var day = now.getDate();
         day = bufferNumberWithZeros(day, 2);
         var month = now.getMonth();
         month++;
         month = bufferNumberWithZeros(month, 2);
         var year = now.getFullYear();
         var hour = now.getHours();
         hour = bufferNumberWithZeros(hour, 2);
         var minutes = now.getMinutes();
         minutes = bufferNumberWithZeros(minutes, 2);
         var seconds = now.getSeconds();
         seconds = bufferNumberWithZeros(seconds, 2);
         var myDateText = year+"-"+month+"-"+day+"_"+hour+"-"+minutes+"-"+seconds;
         return myDateText
    ////// buffer number with zeros //////
    function bufferNumberWithZeros (number, places) {
         var theNumberString = String(number);
         for (var o = 0; o < (places - String(number).length); o++) {
              theNumberString = String("0" + theNumberString)
         return theNumberString

Maybe you are looking for

  • Why won't Adobe X search for hyphens?

    I'm using Adobe X with Windows 7 to proof fiction for a publishing firm.  I would like to be able to search for words at the end of the lines where there is a word break but Adobe X will not let me search for those. For example, I found in the text I

  • My macbook can detect my line in, but no input is given. The bar below does not move. What has happened?

    For more information, my macbook 2009 is running lion. I have tested the mic on another pc, to confirm that the mic works. I have tested my mic through skype on my mac. Here is a screenshot for more information.

  • ISE and NAC wireless guest networks

    I have a wireless network that is NAC controlled and use lobby ambassador for guest wireless. What is the best way to migrate to ISE for guest. Are there problems running NAC and ISE on the same controller? Sent from Cisco Technical Support iPad App

  • VLV & Server Side Sort Query with ODSEE 11g

    Hi We are trying to integrate Microsoft FIM with ODSEE.. When FIM does a Full Import it with VLVControl and SortControl ON it gets the following error 1100 objects were returned on import, exceeding the configured page size in the Run Profile of 500.

  • PR generation of Alternate item of BOM

    Dear Gurus, I have a BOM with alternate item group maintenance among 2 item material. Those item group has maintained with proper priority and usage. Now I have a requirement of header item and the priority 2 material has some stock. Therefore, I wou