8 Replies Latest reply on Dec 21, 2017 1:27 PM by r-bin

    Brush Rename Event

    tsliwkan

      Hi everyone,

       

      One of the parts of my plugin has to do with responding to brush rename events. I can subscribe to the event and get a callback when the event happens, but I'm at a loss of how to figure out *which* brush was renamed. I am working with Photoshop CC 2014.

       

      Using the script listener when I renamed a brush I get

       

      var idRnm = charIDToTypeID( "Rnm " );
          var desc3 = new ActionDescriptor();
          var idnull = charIDToTypeID( "null" );
              var ref1 = new ActionReference();
              var idBrsh = charIDToTypeID( "Brsh" );
              ref1.putIndex( idBrsh, 2 );
          desc3.putReference( idnull, ref1 );
          var idT = charIDToTypeID( "T   " );
          desc3.putString( idT, """hhjk""" );
      executeAction( idRnm, desc3, DialogModes.NO );
      
      

       

      I can subscribe to the event by running the following code

       

      var eventFile = new File(app.path + '/Presets/Scripts/Event Scripts Only/BrushRenameEventHandler.jsx');
      app.notifiers.add('Rnm ',  eventFile, 'Brsh');
      
      

       

      And I can handle the event with

       

      try {
          var renameClassID = charIDToTypeID('Rnm ');
          var brushClassID = charIDToTypeID('Brsh');
      
          var actionDescriptor = arguments[0];
          var eventClass = arguments[1];
      
          if( eventClass == renameClassID ) {
              var list = actionDescriptor.getList( charIDToTypeID('null') );
              if( list.count == 1 ) {
                  var ref = list.getReference(0);
                  if( ref.getDesiredClass() == brushClassID ) {
                      alert( 'Brush renamed' );
                      // How do we know which brush was renamed?!
                  }
              }
          }
      } catch( e ) {
          alert(e);
      }
      
      

       

      However, I don't know how to grab which brush was renamed. Looking at the script listener code I should be able to get the index of the brush (2) that was renamed along with the new name (hhjk). Is it possible to get this information from the ActionReference and/or ActionDescriptor

        • 1. Re: Brush Rename Event
          Kukurykus Adobe Community Professional

          Name it as Brush Rename Presets Notifier.jsx and copy to your Ps StartupScripts folder, so probably at end of this path:

          C:\Program Files (x86)\Common Files\Adobe\Startup Scripts CS6\Adobe Photoshop / (it's CS6 EXTENDED in my case)

           

          function rw(v1, v2, v3) {v2.open(v1), v1 < 'w' ? v3 = v2.read() : v2.write(v3), v2.close(); return v3}
          function sTT(v) {return stringIDToTypeID(v)}; fle = File('~/desktop/ScriptingListenerJS.log')
          
          if (typeof name != 'undefined') {
               function bP() {
                    arr = [], (ref = new ActionReference()).putEnumerated
                    (sTT('application'), sTT('ordinal'), sTT('targetEnum'))
                    for(lst = (executeActionGet(ref).getList(sTT('presetManager')))
                    .getObjectValue(0).getList(sTT('name')), j = 0; j < lst.count; j++) {
                         arr.push('"' + lst.getString(j) + '"')}; $.setenv('bP', arr), arr = []
               }
          
               if (!$.getenv('bP')) bP()
          
               if ((!eval(evl = "typeof arguments != 'undefined'") && notifiersEnabled)
               || (eval(evl) && (args = arguments)[1] != 1382968608)) notifiersEnabled = false
          
               if (!notifiersEnabled) {
                    for(notifiersEnabled = true, i = 0; i < notifiers.length; i++) {
                         if (rnm = app.notifiers[i].event == 'Rnm ') break
                    }
                    if (typeof rnm == 'undefined') notifiers.add('Rnm ',  File($.fileName))
               }
               else if((args[0].getReference(sTT('null')).getDesiredClass()) == sTT('brush')) {
                    vls = rw('r', fle).match(/(\d+) \);(?:.*\n){3}.*"{3}(.*)\b(.*\n){3}$/)
                    alrt = 'Name before change: \r' + eval('[' + $.getenv('bP') + ']')[vls[1] - 1]
                    + '\r\rName after change: \r' + vls[2], alert(alrt), $.setenv('bP', ''), bP()
               }
          }
          

           

          With a start of new session of Ps it takes to to memory an array of loaded Brush Presets by setenv(). When user will rename some Brush Preset an notifier register its changed name and position from a list of available Brush Presets. Then it'll use this position on previous Brush Presets list to get original name of changed Brush Preset. Both of them will be alerted each time an user performs such operation. At the end it updates a list of Brush Presets for changes made so all process starts over...

           

          There are limitation in user behaviour I didn't have time to solve however I know how. For example, someone may load new set of Brush Presets, while script wasn't wrote yet for taking to memory list of new Brush Presets. There may be situation that user will delete some Preset or append others to current ones. Again, script is not ready for these circumstances, however it's not hard to add few another notifiers to prevent all these incidents.

           

          Ps. as this script uses ScriptListener.log created on desktop and you write your plugin for other users you may instruct them that to use it with all its components they should change Administrator Priviliges for Adobe folder, so your plugin may send ScriptListener.8li to "Required" Ps subfolder in order of activating recordings they be saved in SL file on their desktops.

          • 2. Re: Brush Rename Event
            r-bin Level 5

            Use in BrushRenameEventHandler.jsx

             

            alert ("Brush with index " + actionDescriptor.getReference(charIDToTypeID('null')).getIndex() + " was renamed )");
            

             

            Is it useful?

            • 3. Re: Brush Rename Event
              Kukurykus Adobe Community Professional

              He asked for a name, not index on a list; and not a name of changed Brush Preset, but a name that existed before change.

               

              Anyway, r-bin using it:

              app.notifiers.add('Rnm ',  File(app.path + '/Presets/Scripts/Event Scripts Only/BrushRenameEventHandler.jsx'), 'Brsh')
              

               

              I activate:

              alert(arguments[0].getReference(charIDToTypeID('null')).getIndex())
              

               

              So I know index from:

              var idRnm = charIDToTypeID( "Rnm " )
                  var desc = new ActionDescriptor()
                  var idnull = charIDToTypeID( "null" )
                      var ref = new ActionReference()
                      var idBrsh = charIDToTypeID( "Brsh" )
                      ref.putIndex( idBrsh, 2 )
                  desc.putReference( idnull, ref )
                  var idT = charIDToTypeID( "T   " )
                  desc.putString( idT, """changedName""" )
              executeAction( idRnm, desc, DialogModes.NO )
              

               

              Can you answer for my silly question (as I'm a little ActionManager noob , it's why I'm using RegEx).

              How to access "changedName" from above code.

               

              For example there was ActionDescriptor ---> ActionReference ---> Index way to get the '2' value.

              What should I write to get String, (where I see there is direct ActionDescriptor ---> String way) as this doesn't work:

               

              alert(arguments[0].getString()) <--- probalby that must be changed to something else, correct version. THX in advance!

              • 4. Re: Brush Rename Event
                r-bin Level 5

                It's hard for me to translate so much text )

                 

                Do you want this?

                 

                alert ("Brush new name is: " + actionDescriptor.getString(charIDToTypeID('T   ')) + " \n:)");  
                

                 

                .

                1 person found this helpful
                • 5. Re: Brush Rename Event
                  Kukurykus Adobe Community Professional

                  Thank you very much, that was so easy, but I couldn't find it though. I tired eveyrhitng only not that 'to' string. I knew it has to do something with it but gave up before used it So here is version which doesn't use RegEx, as that was changed to pure ActionManager method and this way also ScriptListenerJS.log file part was removed from code as it's not necessary anymore to get proper values / strings:

                   

                  if (typeof name != 'undefined') {
                       function bP() {
                            arr = [], (ref = new ActionReference()).putEnumerated
                            (sTT('application'), sTT('ordinal'), sTT('targetEnum'))
                            for(lst = (executeActionGet(ref).getList(sTT('presetManager')))
                            .getObjectValue(0).getList(sTT('name')), j = 0; j < lst.count; j++) {
                                 arr.push('"' + lst.getString(j) + '"')}; $.setenv('bP', arr), arr = []
                       }
                  
                       function sTT(v) {return stringIDToTypeID(v)}; if (!$.getenv('bP')) bP()
                  
                       if ((!eval(evl = "typeof arguments != 'undefined'") && notifiersEnabled)
                       || (eval(evl) && (args = arguments)[1] != 1382968608)) notifiersEnabled = false
                  
                       if (!notifiersEnabled) {
                            for(notifiersEnabled = true, i = 0; i < notifiers.length; i++) {
                                 if (rnm = app.notifiers[i].event == 'Rnm ') break
                            }
                            if (typeof rnm == 'undefined') notifiers.add('Rnm ',  File($.fileName))
                       }
                       else if(((a0 = args[0]).getReference(sTT('null')).getDesiredClass()) == sTT('brush')) {
                            idx = a0.getReference(sTT('null')).getIndex() - 1, nme = a0.getString(sTT('to'))
                            alrt = 'Name before change: \r' + eval('[' + $.getenv('bP') + ']')[idx] +
                            '\r\rName after change: \r' + nme, alert(alrt), $.setenv('bP', ''), bP()
                       }
                  }
                  

                   

                  For those who want to use it, search for instructions few posts upper, where I pasted first version of this code.

                  • 6. Re: Brush Rename Event
                    r-bin Level 5

                    It seems to me that the environment is not rubbery. Maybe it will overflow. Probably it is better to use putCustomOptions (desc), where desc is the pure descriptor obtained by executeActionGet (). Then use getCustomOptions () and eraseCustomOptions ().

                    No? )

                    • 7. Re: Brush Rename Event
                      Kukurykus Adobe Community Professional

                      That's funny, before I asked you of help with getString() I searched for some solution on this forum and found a topic about that you say now Re: Is there any way to assign a global value to a document (object)?  I tested it a while, but never met it before. Well if you say so I give it a try... Ps. it won't be overflowed, I ussed at the end $.setenv('bP', '') to clear global var.

                      • 8. Re: Brush Rename Event
                        r-bin Level 5

                        In two word (have no time) )

                         

                        instead setenv() use

                         

                        app.putCustomOptions("_BRUSHLIST_", executeActionGet(ref).getList(sTT('presetManager')).getObjectValue(0), true);
                        

                         

                        instead of code with getenv() should use

                         

                        try { var desc = app.getCustomOptions("_BRUSHLIST_"); } catch(e) { /*do putCustomOptions first*/ }
                        var orig_name = desc.getList(sTT('name')).getString(idx);
                        

                         

                        ps. not tested

                        1 person found this helpful