• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Brush Rename Event

New Here ,
May 31, 2015 May 31, 2015

Copy link to clipboard

Copied

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

TOPICS
Actions and scripting

Views

1.4K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 2 Correct answers

LEGEND , Dec 20, 2017 Dec 20, 2017

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 
...

Votes

Translate

Translate
LEGEND , Dec 21, 2017 Dec 21, 2017

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(
...

Votes

Translate

Translate
Adobe
LEGEND ,
Dec 20, 2017 Dec 20, 2017

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Dec 21, 2017 Dec 21, 2017

Copy link to clipboard

Copied

Use in BrushRenameEventHandler.jsx

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

Is it useful?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 21, 2017 Dec 21, 2017

Copy link to clipboard

Copied

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!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Dec 21, 2017 Dec 21, 2017

Copy link to clipboard

Copied

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

Do you want this?

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

.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 21, 2017 Dec 21, 2017

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Dec 21, 2017 Dec 21, 2017

Copy link to clipboard

Copied

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? )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 21, 2017 Dec 21, 2017

Copy link to clipboard

Copied

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 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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Dec 21, 2017 Dec 21, 2017

Copy link to clipboard

Copied

LATEST

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines