Skip to main content
Known Participant
August 19, 2013
Question

Suspend History State (Undo Once)

  • August 19, 2013
  • 1 reply
  • 2091 views

I can't seem to get the suspendhistory code to work right in my script. I have a text script that reads the info of a text layer and displays it's info in another text layer......but it seems to have many states in between. I want to just undo from the first and last state only so that it undo's everything at once. Right now, i have to undo many times.

Also, it seems to create another text info layer  that is not suppose to.

Can someone help me figure out why my script does not undo all the way?

      if (app.documents.length > 0) {
        var myDocument = app.activeDocument;
          myDocument.suspendHistory("this will show up in the history panel", "multiselectfontreader()");
        };
        //
     function multiselectfontreader() {

          app.bringToFront();
          main();

          function main() {
            if (!documents.length) return;
            var selLayers = [];
            selLayers = getSelectedLayersIdx();
            for (var a in selLayers) {
              makeActiveByIndex(selLayers, false);
              //amend to suit.
              readTextLayer()
            }
          }

          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) {
            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);
          };
        };

        // Read one or more selected fonts
        function readTextLayer() {
          if (app.documents.length > 0) {
            var myDoc = app.activeDocument;
            var myLayer = myDoc.activeLayer;
            if (myLayer.kind == LayerKind.TEXT) {
              var thisText = myLayer.textItem;
              // Renaming the Justifcation info from Justification.CENTER - > Center;
              try {
                var theJustification = String(thisText.justification)
                  .replace("Justification.", "")
              } catch (e) {
                var theJustification = "LEFT"
              };

              theJustification = theJustification[0] + theJustification.slice(1, theJustification.length)
                .toLowerCase();
            
        var fonts = getFonts(app.activeDocument.activeLayer);

              for (var i = 0; i < fonts.length; i++) {
                addTextLayer(
                  ((fonts.length > 1) ? fonts.text + ((fonts.text.length) ? "\r" : '') : '') + "Font: " + fonts.font + "\r" + "Size: " + fonts.size + "\r" + "Color: #" + fonts.color.rgb.hexValue + "\r" + ((i === 0 && fonts.leading !== '') ? "Leading: " + fonts.leading + "\r" : '') + ((i === 0) ? "Justify: " + theJustification + "\r" : ''),
                  "Font Info #" + (i + 1),
                  [myLayer.bounds[0] + i * 150, myLayer.bounds[3] + 15]
                );
              }
            }
          }
        };

        // Add's a text layer which contains the content of the read string above
        function addTextLayer(theText, theName, thePosition) {
          var aTextLayer = app.activeDocument.artLayers.add();
          aTextLayer.kind = LayerKind.TEXT;
          aTextLayer.name = theName;
          var aTextLayerRef = aTextLayer.textItem;
          aTextLayerRef.kind = TextType.POINTTEXT;
          aTextLayerRef.size = 10;
          aTextLayerRef.font = "Arial-BoldMT";
          aTextLayerRef.color = app.foregroundColor;
          aTextLayerRef.justification = Justification.LEFT;
          aTextLayerRef.position = thePosition;
          aTextLayer.blendMode = BlendMode.NORMAL;
          aTextLayer.opacity = 100;
          aTextLayer.fillOpacity = 100;
          aTextLayerRef.useAutoLeading = true;
          aTextLayerRef.leading = 0;
          aTextLayerRef.horizontalScale = 100;
          aTextLayerRef.verticalScale = 100;
          aTextLayerRef.contents = theText;
          aTextLayerRef.antiAliasMethod = AntiAlias.SHARP;


          //Move the newly created font layers into the existing "Pixel Spec" folder
          var doc = app.activeDocument;
          var srcLayer = doc.activeLayer;

          try {
            moveLayerToSet(doc, srcLayer, 'Pixel Specs');
          } catch (error) {
            false;
          }

          function moveLayerToSet(doc, srcLayer, toLayerName) {
            var destLayer = doc.layers[toLayerName];
            if (destLayer.layers) destLayer = destLayer.layers[0];
            srcLayer.move(destLayer, ElementPlacement.PLACEBEFORE);
          }



        };

        function getColorFromDescriptor(colorDesc, keyClass) {
          var colorObject = new SolidColor();
          switch (keyClass) {
          case "Grsc":
            colorObject.grey.grey = color.getDouble(charIDToTypeID('Gry '));
            break;
          case "RGBC":
            colorObject.rgb.red = colorDesc.getDouble(charIDToTypeID('Rd  '));
            colorObject.rgb.green = colorDesc.getDouble(charIDToTypeID('Grn '));
            colorObject.rgb.blue = colorDesc.getDouble(charIDToTypeID('Bl  '));
            break;
          case "CMYC":
            colorObject.cmyk.cyan = colorDesc.getDouble(charIDToTypeID('Cyn '));
            colorObject.cmyk.magenta = colorDesc.getDouble(charIDToTypeID('Mgnt'));
            colorObject.cmyk.yellow = colorDesc.getDouble(charIDToTypeID('Ylw '));
            colorObject.cmyk.black = colorDesc.getDouble(charIDToTypeID('Blck'));
            break;
          case "LbCl":
            colorObject.lab.l = colorDesc.getDouble(charIDToTypeID('Lmnc'));
            colorObject.lab.a = colorDesc.getDouble(charIDToTypeID('A   '));
            colorObject.lab.b = colorDesc.getDouble(charIDToTypeID('B   '));
            break;
          default:
            return null;
          }
          return colorObject;
        };
        // get fonts and other parameters used in type layer
        function getFonts(textLayer) {

          function markReturnedContentText(text) {
            if (font_content_detection) {
              return font_content_detection_symbols[0] + text + font_content_detection_symbols[1] + "\r";
            } else {
              return '';
            }
          }

          if (textLayer.kind == LayerKind.TEXT) {

            app.activeDocument.activeLayer = textLayer;
            var ref = new ActionReference();
            ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
            var layerDesc = executeActionGet(ref);
            var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
            var rangeList = textDesc.getList(stringIDToTypeID('textStyleRange'));

            var fonts = [];

            for (var m = 0; m < rangeList.count; m++) {
              var styleDesc = rangeList.getObjectValue(m)
                .getObjectValue(stringIDToTypeID('textStyle'));
              var aFrom = rangeList.getObjectValue(m)
                .getInteger(stringIDToTypeID('from'));
              var aTo = rangeList.getObjectValue(m)
                .getInteger(stringIDToTypeID('to'));
              if (m > 0) {
                if (rangeList.getObjectValue(m - 1)
                  .getInteger(stringIDToTypeID('from')) == aFrom && rangeList.getObjectValue(m - 1)
                  .getInteger(stringIDToTypeID('to')) == aTo) continue;
              }
              var theLetters = app.activeDocument.activeLayer.textItem.contents.substring(aFrom, aTo);

              var aFont = styleDesc.getString(stringIDToTypeID('fontPostScriptName'));

              //var aSize = styleDesc.getUnitDoubleValue(stringIDToTypeID('size')) + " " + typeIDToCharID(styleDesc.getUnitDoubleType(stringIDToTypeID('size')));
              var aSize = new UnitValue(styleDesc.getUnitDoubleValue(stringIDToTypeID('size')), "px");

              var aColor = getColorFromDescriptor(styleDesc.getObjectValue(charIDToTypeID("Clr ")), typeIDToCharID(styleDesc.getClass(charIDToTypeID("Clr "))));


              if (styleDesc.hasKey(stringIDToTypeID('leading'))) {
                var aLeading = new UnitValue(styleDesc.getUnitDoubleValue(stringIDToTypeID('leading')), "px");
              } else {
                var aLeading = "";
          
        }
              var txt = theLetters.replace(/^\s+/, '').replace(/\s+$/, '');
              var merged = false;

              if (txt.length > 0) {
                for (var x = 0; x < m; x++) {
                  try {
                    if (fonts.font === aFont && fonts.size === aSize && fonts.color.rgb.hexValue === aColor.rgb.hexValue && fonts.leading === aLeading) {
                      // It's a hack!!!
                      if (fonts.text !== txt) {
                        fonts.text += markReturnedContentText(txt);
                      }
                      merged = true;
                    }
                  } catch (e) {}
                }

                if (!merged) {
                  fonts.push({
                    text: markReturnedContentText(txt),
                    font: aFont,
                    size: aSize,
                    color: aColor,
                    leading: aLeading
                  });
                }
              }

            };

            return fonts;

          }
        };



This topic has been closed for replies.

1 reply

c.pfaffenbichler
Community Expert
Community Expert
August 20, 2013

The suspendHistory-part seems to be working, something in the rest fails for me.

So far it sems to be the function getFonts because font_content_detection is undefined.

MycortAuthor
Known Participant
August 20, 2013

My apologies for only putting a code snippet or part of this text font script here where it's missing some variable or erros, it's actually part of a very big and massive code (1k lines of code).

I dont want to put this entire code here, but here's a link to the actual code where this text layer is part of:

http://www.ps-scripts.com/bb/viewtopic.php?f=9&t=5504&sid=67917f646530d026f010a39a0676e0c3

Maybe part of the problem is that I don't really know where to put the suspend history code snippet in my bigger code. Hopefully you can help me with this.

I just want to undo from "last" to "first" state, not undoing to many inbetween states for this text creation.

The other thing it seems to do when I do add the suspend history is that it's creating another text layer info that I did not want.

c.pfaffenbichler
Community Expert
Community Expert
August 21, 2013

That code still seems to be incomplete, »color« in line 1022 is undefined when I try to run it.