7 Replies Latest reply on Feb 12, 2017 9:24 AM by Chuck Uebele

    Is there any simply (probably key-value) storage in ExtendScript, i.e. "localStorage", "prefs", "settings"?

    kg93420415 Level 1

      I have an ExtendScript with dialog window with edittext. Value of edittext empties when I closing window and run script again.

      How to store it in HDD between script launches?

        • 1. Re: Is there any simply (probably key-value) storage in ExtendScript, i.e. "localStorage", "prefs", "settings"?
          maxwyss Level 4

          When everything fails you could write the data into a file, at a specific location, an when you run the script again, you load the file and interpret its content.

          • 2. Re: Is there any simply (probably key-value) storage in ExtendScript, i.e. "localStorage", "prefs", "settings"?
            kg93420415 Level 1

            Thanks, but Is there any simply (probably key-value) sIs there any simply (probably key-value) sIs there any simply (probably key-value) sIs there any simply (probably key-value) s

            • 3. Re: Is there any simply (probably key-value) storage in ExtendScript, i.e. "localStorage", "prefs", "settings"?
              JJMack Most Valuable Participant

              I have written  scripts I call run twice scripts for use in Actions   For example save and restore scripts.  Like save a documents resolution the first run and restore the document to that resolution the second run.   The script test to see if the save data exist and it not it knows its the first run and save the date into the document metadata field instruction.  If the data exists it is retrieved removed from the metadata and the document is restored.    However Adobe broke Photoshop scripting in CC 2015.5 so my scripts no longer work in CC 2015.5 and CC 2017.  Adobe states they are working on the problem.  The problem is when I remove the data from the metadata to make it empty again. Photoshop script no longer does  the save date is not removed the script can no longer be use with that document for its always a second run for the data was not removed because of Adobe new scripting bug.  I still use CC 2014.

               

              When thing work correctly  the metadata is not written to disk unlelle the action the uses the script saved the document before the second run where the data is removed.

               

              Also use that for toggle for document where a script custom option would be used as a global  option metadata is document oprianteded.

              /* ======================================================================================
              // 2015  John J. McAssey (JJMack)  http://www.mouseprints.net/
              //  
              // This script is supplied as is. It is provided as freeware. 
              // The author accepts no liability for any problems arising from its use.
              //
              // This script is designed to Toggle centering guides.
              //      assign a shortcut I use this in an action assigned to F12. 
              //
              // ===================================================================================== */
              
              
              /*
              <javascriptresource>
              <about>$$$/JavaScripts/AddRemoveCenterGuides/About=JJMack's AddRemoveCenterGuides.^r^rCopyright 2009 Mouseprints.^r^rRun twice script utility for action.^r^rFirst Run Set Guides on camvas bounds and center.^rSecond Run clears the set guides.</about>
              <category>JJMack's Action Run Twice Utility</category>
              </javascriptresource>
              */
              
              
              if (app.documents.length > 0) app.activeDocument.suspendHistory('ToggleCenterGuides','main()' );
              else alert("You must have at least one open document to run this script!"); 
              /////////////////////////////////////////////////////////////////////////////////////////// 
              function main() {
                if (app.activeDocument.info.instructions.indexOf("<CenterGuides>") == -1 ){ // no footprint fisrt useage 
                var orig_ruler_units = app.preferences.rulerUnits;
                app.preferences.rulerUnits = Units.PIXELS; // Set the ruler units to PIXELS
                try { 
                activeDocument.guides.add(Direction.VERTICAL, 0);
                activeDocument.guides.add(Direction.VERTICAL, activeDocument.width/4);
                activeDocument.guides.add(Direction.VERTICAL, activeDocument.width/2);
                activeDocument.guides.add(Direction.VERTICAL, activeDocument.width*3/4);
                activeDocument.guides.add(Direction.VERTICAL, activeDocument.width);
                activeDocument.guides.add(Direction.HORIZONTAL, 0);
                activeDocument.guides.add(Direction.HORIZONTAL, activeDocument.height/4);
                activeDocument.guides.add(Direction.HORIZONTAL, activeDocument.height/2);
                activeDocument.guides.add(Direction.HORIZONTAL, activeDocument.height*3/4);
                activeDocument.guides.add(Direction.HORIZONTAL, activeDocument.height);
                }
                // display error message if something goes wrong
                catch(e) { alert(e + ': on line ' + e.line, 'Script Error', true); }
                app.preferences.rulerUnits = orig_ruler_units; // Reset units to original settings
                // put footprint in metadata info instructions
                app.activeDocument.info.instructions = app.activeDocument.info.instructions + "<CenterGuides>" + " Show" + "</CenterGuides>"; 
                } 
                else { 
                clearGuides();
                // Remove footprint from metadata info instructions
                before = app.activeDocument.info.instructions.substr(0,app.activeDocument.info.instructions.indexOf("<CenterGuides>"));
                afterOffset = app.activeDocument.info.instructions.indexOf("</CenterGuides>") + "</CenterGuides>".length;
                after = app.activeDocument.info.instructions.substr(afterOffset, app.activeDocument.info.instructions.length - afterOffset);
                //alert ("before = " + before + " after = " + after);
                app.activeDocument.info.instructions = before + after;
                //alert("app.activeDocument.info.instructions = " + app.activeDocument.info.instructions);  
                } 
                } 
              //////////////////////////////////////////// Action Manager Code to Clear all Guides ///////////////////////////////////
              function clearGuides() { 
                 var id556 = charIDToTypeID( "Dlt " ); 
                     var desc102 = new ActionDescriptor(); 
                     var id557 = charIDToTypeID( "null" ); 
                         var ref70 = new ActionReference(); 
                         var id558 = charIDToTypeID( "Gd  " ); 
                         var id559 = charIDToTypeID( "Ordn" ); 
                         var id560 = charIDToTypeID( "Al  " ); 
                         ref70.putEnumerated( id558, id559, id560 ); 
                     desc102.putReference( id557, ref70 ); 
                 executeAction( id556, desc102, DialogModes.NO ); 
                };
              

               

              The above script will not work in CC 2015.5 and CC 2017 unless to add data to the document metadata field instructions.  If the is data in the field the script will be able to remove its data. It is onel when the field is empty the the script bug bites. Empty is however the normal case.

              • 4. Re: Is there any simply (probably key-value) storage in ExtendScript, i.e. "localStorage", "prefs", "settings"?
                JJMack Most Valuable Participant

                Thanks, but Is there any simply (probably key-value) sIs there any simply (probably key-value) sIs there any simply (probably key-value) sIs there any simply (probably key-value) s

                 

                ???????????????

                • 5. Re: Is there any simply (probably key-value) storage in ExtendScript, i.e. "localStorage", "prefs", "settings"?
                  maxwyss Level 4

                  Sounds to me as if the OP is looking for something like the Persistent Global Variables, we have in Acrobat JavaScript.

                   

                  But, as far as I have seen so far, there is no such concept in Extendscript (but I may be wrong on that).

                  • 6. Re: Is there any simply (probably key-value) storage in ExtendScript, i.e. "localStorage", "prefs", "settings"?
                    JJMack Most Valuable Participant

                    Sounds to me as if the OP is looking for something like the Persistent Global Variables, we have in Acrobat JavaScript.

                     

                    But, as far as I have seen so far, there is no such concept in Extendscript (but I may be wrong on that).

                    Actually that what custom script options are they are global across all document.  You can have them be persistent for just the Photoshop session or all Photoshop sessions.  The following script uses a custom script option that last just during a Photoshop session.  For cycling thought sets of tool presets sets. Each tools preset set would have its own custom option and script.  The Script is designed to actually in two parts the function designed to be included into the cycling scripts that set the parameters up for the function the uses the included function. Each script would relate to a tool preset set for a tool like the brush tool.  The function included has all the code and creates the custom script option. Which is an index used to address the presets array.

                     

                    /* ======================================================================================
                                  Cycling Forward and Backward through Sets of Tool Presets 
                    =========================================================================================
                    2017  John J. McAssey (JJMack)
                    =========================================================================================
                    Naming Your Script so that it identify the tool and Presets Set will be helpful.
                        Copy this script to a new Name for each set of presets you want to cycle through.
                      Run that script via shortcut keys. Set two Shortcuts keys 
                      F(n) Forward  Modifier+F(n) Backward
                      There are three required parameters for the cycling function:
                      1.) Correct Photoshop Tools Name 
                      2.) Presets Set file name the * part of the *.tpl file
                      The *.tpl file must reside in the scripts folder
                      3.) Array of preset names in your desired cycling order
                    =========================================================================================
                    Note: This script only deals with Tool Preset files .tpl for tools preset are easily 
                      reset back to Adobe's defaults using the Preset manager. Tool presets may require
                      other Photoshop add-ons like brush .abr, patterns .pat, swatch .aco, etc files to
                      also be loaded this script will not load them this script will only load .tpl 
                      files if there is a need too. You must add what your presets require to Photoshop
                    ======================================================================================== */
                    #target photoshop;
                    app.bringToFront();
                    // Required three parameters  tool,Set,list
                    var tool = 'paintbrushTool';                     // Photoshop Tool name your Presets set is for. Only one tool's presets
                    // This sample script presets were downloaded from DeviantArt brushes "The Sketch Arsenal" "the_sketch_arsenal_by_thatld.tpl"
                    // http://thatld.deviantart.com/art/The-Sketch-Arsenal-161678023 Download link on Top Right of the Page not the one on the bottom
                    var presetSet  = 'the_sketch_arsenal_by_thatld'; // Presets set name *.tpl file need to be same folder as this Photoshop script.
                    var presetNames = [                              // Preset names list start. Presets you want to cycle through. Set can have more. 
                      'Color Brush - Flat',
                      'Color Brush - Magic Edge',
                      'Color Pencil - Hard',
                      'Color Pencil - Soft',
                      'Drawing Pencil - B Lead',
                      'Drawing Pencil - Blue Line',
                      'Drawing Pencil - H Lead',
                      'Linework Pen - Fine',
                      'Marker - Lower the Flow to Dry',
                      'Shading Brush - Pressure Hold',
                      'Shading Brush - Soft Texture',
                      'Shading Pencil - General',
                      'Shading Pencil - Hard',
                      'Shading Pencil - Soft',
                      'Sketch Pencil - H Lead',
                      'Sketch Pencil - The Ultimate!',
                      'Watercolor Brush - General'
                      ];                                          // Presets names list end. Order the way you want to cycle through them
                    // End Required Parameters
                    cycle(tool,presetSet,presetNames);                  // Cycle Forward and Backward through tool presets set names
                    // End of Script
                    // =================================================== Main function ======================================================== //
                    function cycle(toolName,toolPresetSet,toolPresetNames){
                      if (currentToolName()!=toolName) { // if user is switching tools try to else switch tool preset
                      try {selectTool(toolName);} // Insure the tool is select so preset can be selected
                      catch(e) {alert("Unable to Select the Tool "+toolName); return;} // Tool name wrong or unavailable 
                      //if (app.toolSupportsBrushes(app.currentTool)) app.runMenuItem(charIDToTypeID(('TglB'))); //Toggle Brush Palette
                      return; // Just switch to the tools current setting 
                      }
                      var desc = new ActionDescriptor(); // Set up Photoshop to remember variables
                      try {var desc = app.getCustomOptions('Cycle'+toolPresetSet);} // Try to get CustomOption for cycling this tool presets set
                      catch(e){ // Each Photoshop session this should fail first time reset
                      try {selectToolPreset(toolPresetNames[0]);} // Insure Tool Presets Set has been loaded 
                      catch(e) { // Will fail if tools presets set is not loaded
                      if (loadToolPresetSet(toolPresetSet)) { // Load Tool presets set
                      try {selectToolPreset(toolPresetNames[0]);} // Load sets first preset
                      catch(e) {alert("Was unable to Select the Tools Preset "+toolPresetNames[0]); return;} // Failed to select preset
                      }
                      else {alert("Was unable to load Tools Presets Set "+toolPresetSet); return;} // Failed to load tools presets set
                      }
                      desc.putInteger(0,0); // This line save the variable while Photoshop is open,
                      app.putCustomOptions('Cycle'+toolPresetSet,desc,false );// Initialize presets set CustomOption for cycling
                      desc = app.getCustomOptions('Cycle'+toolPresetSet); // Get CustomOption Cycle starting point
                            }
                      var presetNumber = desc.getInteger(0); // Get the preset index
                      if (ScriptUI.environment.keyboardState.ctrlKey||ScriptUI.environment.keyboardState.altKey||
                      ScriptUI.environment.keyboardState.shiftKey) { // Previous preset if Ctrl or Alt or Shift key is down
                      presetNumber = presetNumber-2; // Back up two preset for it will be bumped one
                      if (presetNumber<0){presetNumber=toolPresetNames.length-1;} // Set preset index to the end of the list
                      }
                      if (presetNumber<toolPresetNames.length){desc.putInteger(0,presetNumber+1);} // Update preset index number
                      else {presetNumber=0; desc.putInteger(0,1);} // Reset preset index pointer to the begging of the list
                      app.putCustomOptions('Cycle'+toolPresetSet,desc,false); // Put Update the Custom option
                      try {selectToolPreset(toolPresetNames[presetNumber]);} // Set tool with preset
                      catch(e) {
                      if (loadToolPresetSet(toolPresetSet)) { // Load Tool presets set Tool presets may have reset
                      try {selectToolPreset(toolPresetNames[presetNumber]);} // Set tool with preset
                      catch(e) {alert("Was unable to Select the Tools Preset "+toolPresetNames[presetNumber]); return;} // Failed to select
                      }
                      else {alert("Was unable to load Tools Presets Set "+toolPresetSet); return;} // Failed to load tools presets set
                      }
                    };
                    // =================================================== Helper functions ===================================================== //
                    function selectTool(tool) {
                        var desc9 = new ActionDescriptor();
                            var ref7 = new ActionReference();
                            ref7.putClass( app.stringIDToTypeID(tool) );
                        desc9.putReference( app.charIDToTypeID('null'), ref7 );
                        executeAction( app.charIDToTypeID('slct'), desc9, DialogModes.NO );
                    };
                    function selectToolPreset(PresetName) {
                      var desc = new ActionDescriptor();
                      var ref = new ActionReference();
                      ref.putName( stringIDToTypeID( "toolPreset" ), PresetName );
                      desc.putReference( charIDToTypeID( "null" ), ref );
                      executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
                    }
                    function loadToolPresetSet(SetName) {
                      returncode = true;
                      var scriptLocation = String(findScript());
                      var path = scriptLocation.substr(0, scriptLocation.lastIndexOf("/") + 1 ) ;
                      var SetFile = new File(path + SetName + ".tpl");   // Requited to be in the script's folder
                      if (!SetFile.exists) { returncode = false; }
                      else {
                      var desc = new ActionDescriptor();
                      var ref = new ActionReference();
                      ref.putProperty( charIDToTypeID( "Prpr" ), stringIDToTypeID( "toolPreset"  ));
                      ref.putEnumerated( charIDToTypeID( "capp" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt"  ) );
                      desc.putReference( charIDToTypeID( "null" ), ref );
                      desc.putPath( charIDToTypeID( "T   " ), new File( SetFile ) );
                      desc.putBoolean( charIDToTypeID( "Appe" ), true );
                      try {executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );}
                      catch(e) { returncode = false; }
                      }
                      return returncode ;
                    }
                    function findScript() {// Find the location where this script resides
                      var where = "";
                      try { FORCEERROR = FORCERRROR;}
                      catch(err) { where = File(err.fileName);}
                      return where ;
                    }
                    function currentToolName() {
                      var ref = new ActionReference();
                      ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("tool"));
                      ref.putEnumerated( charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
                      var applicationDesc = executeActionGet(ref);
                      //alert(typeIDToStringID(applicationDesc.getEnumerationType(stringIDToTypeID("tool"))));
                      return(typeIDToStringID(applicationDesc.getEnumerationType(stringIDToTypeID("tool"))));
                    }
                    /* Photoshop tool names
                    'moveTool'                     'cloneStampTool'            'typeCreateOrEditTool'
                    'marqueeRectTool'              'patternStampTool'          'typeVerticalCreateOrEditTool'
                    'marqueeEllipTool'             'historyBrushTool'          'typeCreateMaskTool'
                    'marqueeSingleRowTool'         'artBrushTool'              'typeVerticalCreateMaskTool'
                    'marqueeSingleColumnTool'      'eraserTool'                'pathComponentSelectTool'
                    'lassoTool'                    'backgroundEraserTool'      'directSelectTool'
                    'polySelTool'                  'magicEraserTool'           'rectangleTool'
                    'magneticLassoTool'            'gradientTool'              'roundedRectangleTool'
                    'quickSelectTool'              'bucketTool'                'ellipseTool'
                    'magicWandTool'                'blurTool'                  'polygonTool'
                    'cropTool'                     'sharpenTool'               'lineTool'
                    'sliceTool'                    'smudgeTool'                'customShapeTool'
                    'sliceSelectTool'              'dodgeTool'                 'textAnnotTool'
                    'spotHealingBrushTool'         'burnInTool'                'soundAnnotTool'
                    'magicStampTool'               'saturationTool'            'eyedropperTool'
                    'patchSelection'               'penTool'                   'colorSamplerTool'
                    'redEyeTool'                   'freeformPenTool'           'rulerTool'
                    'paintbrushTool'               'addKnotTool'               'handTool'
                    'pencilTool'                   'deleteKnotTool'            'zoomTool'
                    'colorReplacementBrushTool'    'convertKnotTool'           'wetBrushTool'
                    
                    • 7. Re: Is there any simply (probably key-value) storage in ExtendScript, i.e. "localStorage", "prefs", "settings"?
                      Chuck Uebele Adobe Community Professional & MVP

                      I use a recursive function that saves all values in a UI to an xml file. By giving each control a variable name rather than the object name and assigning that name to the control, I can loop through any UI, and make changes to the structure of the ui, without having to modify my script.