actionExists function

Photoshop Script Snippets - Note: Full Scripts go in the Photoshop Scripts Forum

Moderators: Tom, Kukurykus

xbytor

actionExists function

Post by xbytor »

I've been meaning to write and post this for awhile. Here's a quick little function to check to see if an action has already been loaded. It's based on the ActionLister script in XToolkit.

Code: Select allcTID = function(s) { return app.charIDToTypeID(s); };

actionExists = function(atn, atnSet) {
  var asetDesc;
  var rc = false;
  var i = 1;
 
  while (true) {
    var ref = new ActionReference();
    ref.putIndex(cTID("ASet"), i);
    var desc;
    try {
      desc = executeActionGet(ref);
    } catch (e) {
      break;    // all done
    }
    if (desc.hasKey(cTID("Nm  ")) &&
        desc.getString(cTID("Nm  ")) == atnSet) {
      asetDesc = desc;
      break;
    }
    i++;
  }

  var asetIndex = i;
  if (asetDesc) {
    max = asetDesc.count;
    for (var i = 1; i <= max; i++) {
      var ref = new ActionReference();
      ref.putIndex(cTID("Actn"), i);           // Action index
      ref.putIndex(cTID("ASet"), asetIndex);   // ActionSet index

      var desc = executeActionGet(ref);
      if (desc.hasKey(cTID("Nm  ")) &&
          desc.getString(cTID("Nm  ")) == atn) {
        rc = true;
        break;
      }
    }
  }

  return rc;
};
Mike Hale

actionExists function

Post by Mike Hale »

Thanks, X

I had a function that put a doAction in a try/catch block to do something similar, but yours is much better.

It may be that there is something wrong with my system, but this seems to fail if the first step in the action was created with insert menu item. At least that is the only difference I see between the action that does exist but it returns false and the other actions.
xbytor

actionExists function

Post by xbytor »

I can't replicate this. Can you post/send a copy of the action that fails?
Mike Hale

actionExists function

Post by Mike Hale »

Like I said it may be my system. I emailed you the action set. Both "ah test" and "run vb" return false. Also in one test I used "vb run" instead and there was an untraped error on line 33.

But when I copied them into a new set to send to you they returned true. It could be there is something wrong with this set

Mike
xbytor

actionExists function

Post by xbytor »

The ActionDescriptor.count property is not always accurate, apparently. I don't know if it was the action file or something else.

Here's the 'better' way of handling the problem.

Code: Select allactionExists= function(atn, atnSet) {
  var asetDesc;
  var rc = false;
  var i = 1;
 
  while (true) {
    var ref = new ActionReference();
    ref.putIndex(cTID("ASet"), i);
    var desc;
    try {
      desc = executeActionGet(ref);
    } catch (e) {
      break;    // all done
    }
    if (desc.hasKey(cTID("Nm  ")) &&
        desc.getString(cTID("Nm  ")) == atnSet) {
      asetDesc = desc;
      break;
    }
    i++;
  }

  var asetIndex = i;
  if (!asetDesc) {
    return false;
  }

  if (!asetDesc.hasKey(cTID("NmbC"))) {
    return false;
  }
  var max = desc.getInteger(cTID("NmbC"));
  for (i = 1; i <= max; i++) {
    var ref = new ActionReference();
    ref.putIndex(cTID("Actn"), i);           // Action index
    ref.putIndex(cTID("ASet"), asetIndex);   // ActionSet index
       
    var desc;
    try {
      desc = executeActionGet(ref);
    } catch (e) {
      break;   // all done
    }
    if (desc.hasKey(cTID("Nm  ")) &&
        desc.getString(cTID("Nm  ")) == atn) {
      rc = true;
      break;
    }
  }
  return rc;
};
Mike Hale

actionExists function

Post by Mike Hale »

If I had to guess, I would say it's the action set. It's a 'junk' set that I edit a lot so it could have gotten corrupted along the way.
Mike Hale

actionExists function

Post by Mike Hale »

I remembered late last night that those two action where loaded while an action was playing. One with JS and one with VB. Maybe that is why the count if off.
xbytor

actionExists function

Post by xbytor »

Nope. It was just bad code on my part. The Action descriptors are not a part of the ActionSet descriptor. You can't iterate going from 1..count because that will just get you attributes of the ActionSet. In order to get the descriptors of the Actions you need that last 'executeAction.get' call. The reason it appeared to work correctly before was because ActionSet descriptors _always_ have 4 properties. So, as long as the Action you are looking for is one of the first 4 in the ActionSet, you'll get the descriptor for the Action back. It's a classic case of coincidental correctness.

I haven't done much Action Manager coding in the past couple of months so it took a bit for me to figure out what was going on.

-X