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

Disable a panel conditionnaly in window->extensions menu

Explorer ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

Hi there,

Does anyone know how to disable a panel conditionnaly thanks to scripts in window->extensions menu ?

My extension is made with 5 panels. With some conditions, I'd like users not to access to a panel.
I've got a menu inside my extensions and I can disabled panel access here ; but if users go to window->extensions, there are enabled.

Thanks

Views

2.2K

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 1 Correct answer

Guru , Apr 12, 2018 Apr 12, 2018

The following code I think is pretty clear.

//////////////////////////////////////////////////////////////////

// MenuDemo.jsx By Trevor http://creative-scripts.com 12 Apr 18 //

// Demonstrates how to control menu items on InDesign           //

//////////////////////////////////////////////////////////////////

#targetengine foo

// If using CSTK best to comment out the targetengine line

// Look at the bottom of the "Layout" menu

var installMenuItem;

/**

* [installMenuItem description]                Helper

...

Votes

Translate

Translate
Engaged ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

Remove the <Menu> Tag in the manifest.xml

Thomas

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
Explorer ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

Thanks for your reply.

That's ok but I've to do that before constructing the zxp.

What I want is to do it programmatically and dynamically by javascript or other.
For example, if opened document contains a type of data then this extension panel is enabled.
If there isn't that data, the extension panel is disabled.

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
Engaged ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

I don't think this is possible. The user will always get the notification "extension is not correctly signed ..." if you change the manifest file after signing. (Unless the user sets the debug flag)

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
Engaged ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

I'm not sure it can be done "conditionally" (without restarting the host app), but rather permanently.

Davide Barranca - PS developer and author
www.ps-scripting.com

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
Enthusiast ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

Manifest changes usually require Photoshop restart.

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
Guru ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

I would have thought that manifest changes always need? Do you know of any exceptions?

On InDesign I think it would be quite easy to do. For which app(s) is it?

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
Explorer ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

It's for Indesign.

For example in panel menu I do this :

csInterface.updatePanelMenuItem(SUBSTITUTION_TEXT_LABEL, isEnabled, false);

Where "isEnabed" is a boolean calculated.

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
Guru ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

From jsx engine

app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Window').submenus.itemByName('$ID/Extensions'). menuItems.itemByName('My Super Duper Extension').remove()

So just do an evalScript

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
Guru ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

P.s.

localization of menu items is a real pain in the neck.

You might want to use

app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Window').submenus.itemByName('$ID/Exte&nsions');

The only safe way to deal with localization is to try out what ever you need on each one.

Fortunately  there's only about 25

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
Guru ,
Apr 09, 2018 Apr 09, 2018

Copy link to clipboard

Copied

To disable the item (and not remove it) you need to target the target.

Very pseudo code.

menuAction = app.scriptMenuActions.add({ title: title, name: name });

var isLicenced = function(ev) {

ev.target.enabled = !trialExpired;

};

var isLicenced = function(ev) {

ev.target.enabled = !trialExpired;

};

menuAction.eventListeners.add('beforeDisplay', isLicenced);

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
Explorer ,
Apr 10, 2018 Apr 10, 2018

Copy link to clipboard

Copied

Thanks Trevor for all your replies.

Could you explain me your last reply's code please ?

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
Guru ,
Apr 10, 2018 Apr 10, 2018

Copy link to clipboard

Copied

I'm sorry I can't spend too much time on in now but here's a 1 minute round up.

The InDesign jsx engine unlike Ai or Ps allows you to add / remove / change menu items.

See Indiscripts :: How to Create your Own InDesign Menus  for some basics on this.

The indesign scripting forum has numerous examples.

A menu item comprises of 2 parts.

1) The bit you see.

2) The action it performs.

Mess around with the following code until you understand it.

The speech is quite useful for understanding it.

Keep on clicking the menu items until you understand why the menu items are doing what they do.

HTH

Trevor

#targetengine foo

// Look at the bottom of the Layout menu

var installMenuItem;

/**

* [installMenuItem description]

* @param  {String}              title          The words you want displayed

* @param  {DOM Menu / Sub-menu} parentMenu     The menu / sub-menu on which the item should appear

* @param  {Function}            beforeDisplay  like function(ev){ev.target.enabled = !!app.properties.activeDocument}

* @param  {Function}            onInvoke       like

*                                              function(ev){

*                                                  ev.target.title =

*                                                      (app.properties.activeDocument && app.properties.activeDocument.name) || 'Nope';

*                                              }

* @param  {DOM Constant}        position       LocationOptions.BEFORE, LocationOptions.AFTER, LocationOptions.AT_END,

*                                              LocationOptions.AT_BEGINNING, or LocationOptions.UNKNOWN

*                                              [Optional] default LocationOptions.AT_END

* @param  {DOM Menu / Sub-menu / Menu Item} reference     [description]

*                                              [Optional] only needed if position is set to LocationOptions.BEFORE or LocationOptions.AFTER

* @return {DOM menuAction}                     The created or existing menu Item

*/

installMenuItem = function(title, parentMenu, beforeDisplay, onInvoke, name, position, reference) {

    var menuAction;

    if (typeof title === 'object') {

        parentMenu = title.parentMenu;

        beforeDisplay = title.beforeDisplay;

        onInvoke = title.onInvoke;

        position = title.position;

        reference = title.reference;

        name = title.name || title.title;

        title = title.title || title.name;

    }

    position = position || LocationOptions.AT_END;

    parentMenu = parentMenu || app.menus.item("$ID/Main");

    menuAction = app.scriptMenuActions.add({ title: title, name: name });

    if (beforeDisplay) {

        menuAction.eventListeners.add('beforeDisplay', beforeDisplay);

    }

    if (onInvoke) {

        menuAction.eventListeners.add('onInvoke', onInvoke);

    }

    return parentMenu.menuItems.add(menuAction, position, reference);

};

/*

____   __   _  _  ____  __    ____    _  _  ____   __    ___  ____

/ ___) / _\ ( \/ )(  _ \(  )  (  __)  / )( \/ ___) / _\  / __)(  __)

\___ \/    \/ \/ \ ) __// (_/\ ) _)   ) \/ (\___ \/    \( (_ \ ) _)

(____/\_/\_/\_)(_/(__)  \____/(____)  \____/(____/\_/\_/ \___/(____)

*/

var foo;

foo = (function() {

    var toggle1, toggle2, toggleEnabled, toggleText, pow, say;

    toggle1 = toggle2 = false;

    say = function(message) {

        var isMac, script;

        isMac = $.os[0] === 'M';

        script = isMac ? 'Say "' + message + '"' : 'CreateObject("sapi.spvoice").Speak "' + message + '"';

        app.doScript(script, ScriptLanguage[isMac ? 'APPLESCRIPT_LANGUAGE' : 'VISUAL_BASIC']);

    };

    pow = function(ev) {

        say(ev.target.name);

    };

    toggleText = function(ev) {

        say(ev.target.name);

        ev.target.title = ev.target.name = toggle1 ? 'Do my script' : 'Don\'t do my script'; // ;-);

        toggle1 = !toggle1;

    };

    toggleEnabled = function(ev) {

        // ev.target.enabled = toggle1;

        ev.target.title = ev.target.name = (toggle2 ? 'Yep' : 'Nope');

        toggle2 = !toggle2;

        say(ev.target.name);

    };

    var fooMenu = app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Layout').submenus.itemByName('FabScript');

    if (fooMenu === null) {

        fooMenu = app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Layout').submenus.add('FabScript', LocationOptions.AT_END);

    }

    if (fooMenu.menuItems.itemByName('Yep') === null) {

        installMenuItem({

            title: 'Yep',

            name: 'Yep',

            parentMenu: fooMenu,

            onInvoke: pow,

            beforeDisplay: toggleEnabled

        });

    }

    if (fooMenu.menuItems.itemByName('Do my script') === null) {

        installMenuItem({

            title: 'Do my script',

            name: 'Do my script',

            parentMenu: fooMenu,

            onInvoke: toggleText

        });

    }

    return fooMenu;

})();

/*

To remove the menu

foo.remove();

*/

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
Guru ,
Apr 12, 2018 Apr 12, 2018

Copy link to clipboard

Copied

The following code I think is pretty clear.

//////////////////////////////////////////////////////////////////

// MenuDemo.jsx By Trevor http://creative-scripts.com 12 Apr 18 //

// Demonstrates how to control menu items on InDesign           //

//////////////////////////////////////////////////////////////////

#targetengine foo

// If using CSTK best to comment out the targetengine line

// Look at the bottom of the "Layout" menu

var installMenuItem;

/**

* [installMenuItem description]                Helper function for adding InDesign menu items by Trevor http://creative-scripts.com

* @param  {String}              title          The words you want displayed

* @param  {DOM Menu / Sub-menu} parentMenu     The menu / sub-menu on which the item should appear

* @param  {Function}            beforeDisplay  like function(ev){ev.target.enabled = !!app.properties.activeDocument}

* @param  {Function}            onInvoke       like

*                                              function(ev){

*                                                  ev.target.title =

*                                                      (app.properties.activeDocument && app.properties.activeDocument.name) || 'Nope';

*                                              }

* @param  {DOM Constant}        position       LocationOptions.BEFORE, LocationOptions.AFTER, LocationOptions.AT_END,

*                                              LocationOptions.AT_BEGINNING, or LocationOptions.UNKNOWN

*                                              [Optional] default LocationOptions.AT_END

* @param  {DOM Menu / Sub-menu / Menu Item} reference     [description]

*                                              [Optional] only needed if position is set to LocationOptions.BEFORE or LocationOptions.AFTER

* @return {DOM menuAction}                     The created or existing menu Item

*/

installMenuItem = function(title, parentMenu, beforeDisplay, onInvoke, name, position, reference) {

    var menuAction;

    if (typeof title === 'object') {

        parentMenu = title.parentMenu;

        beforeDisplay = title.beforeDisplay;

        onInvoke = title.onInvoke;

        position = title.position;

        reference = title.reference;

        name = title.name || title.title;

        title = title.title || title.name;

    }

    position = position || LocationOptions.AT_END;

    parentMenu = parentMenu || app.menus.item("$ID/Main");

    menuAction = app.scriptMenuActions.add({ title: title, name: name });

    if (beforeDisplay) {

        menuAction.eventListeners.add('beforeDisplay', beforeDisplay);

    }

    if (onInvoke) {

        menuAction.eventListeners.add('onInvoke', onInvoke);

    }

    return parentMenu.menuItems.add(menuAction, position, reference);

};

/*

____   __   _  _  ____  __    ____    _  _  ____   __    ___  ____

/ ___) / _\ ( \/ )(  _ \(  )  (  __)  / )( \/ ___) / _\  / __)(  __)

\___ \/    \/ \/ \ ) __// (_/\ ) _)   ) \/ (\___ \/    \( (_ \ ) _)

(____/\_/\_/\_)(_/(__)  \____/(____)  \____/(____/\_/\_/ \___/(____)

*/

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// This should add a "FabScript" submenu to the bottom of the "Layout" menu                                       //

// It contains to menu items                                                                                      //

// Demonstrates how to change properties of the menu items like their text and enabled status                     //

// Keep playing with the menu until you understand how it's actions fit in with the code.                         //

// To remove the menu use either foo.remove() from the correct scriptEngine or use from any engine                //

// app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Layout').submenus.itemByName('FabScript').remove(); //

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var foo;

foo = (function() {

    var toggleScriptEnable, toggleYepNopeTitle, yepNopeBeforeDisplay, enableMyScriptOnInvoke, yepNopeOnInvoke, wl, say, count;

    count = 0;

    toggleScriptEnable = toggleYepNopeTitle = false;

    /*

         _  _     _                 ___             _   _

        | || |___| |_ __  ___ _ _  | __|  _ _ _  __| |_(_)___ _ _  ___

        | __ / -_) | '_ \/ -_) '_| | _| || | ' \/ _|  _| / _ \ ' \(_-<

        |_||_\___|_| .__/\___|_|   |_| \_,_|_||_\__|\__|_\___/_||_/__/

                   |_|

    */

    /**

     * [wl description]         Shortcut to output to either ESTK or CSTK console, applying / filtering the css

     * @param  {String} message

     * @param  {String} css     [Optional] css to be applied to the message if sent to the CSTK console

     * @return {String}         The message without the css

     */

    wl = function(message, css) {

        if ($.engineName === 'CSTK') {

            $.writeln(message, css);

        } else {

            $.writeln(message);

        }

        return message;

    };

    /**

     * [say description]        Speaks the message out and passes the message out so it can be forwarded to a log etc.

     * @param  {String} message the message to say

     * @return {String}         The message

     */

    say = function(message) {

        const DONTSAY = false; // Change to true to shut the computers mouth

        if (DONTSAY) { return message; }

        var isMac, script;

        isMac = $.os[0] === 'M';

        script = (isMac ? 'Say "' : 'CreateObject("sapi.spvoice").Speak "')  + message + '"';

        app.doScript(script, ScriptLanguage[isMac ? 'APPLESCRIPT_LANGUAGE' : 'VISUAL_BASIC']);

        return message;

    };

    /*

     __  __                                _   _    _    _

    |  \/  |___ _ _ _  _   _____ _____ _ _| |_| |  (_)__| |_ ___ _ _  ___ _ _ ___

    | |\/| / -_) ' \ || | / -_) V / -_) ' \  _| |__| (_-<  _/ -_) ' \/ -_) '_(_-<

    |_|  |_\___|_||_\_,_| \___|\_/\___|_||_\__|____|_/__/\__\___|_||_\___|_| /__/

    */

    enableMyScriptOnInvoke = function(ev) {

        wl(say('On Invoke ' + ev.target.name), 'color: blue;background:yellow;');

        ev.target.title = ev.target.name = toggleScriptEnable ? 'Enable my script' : 'Dis-enable my script'; // ;-);

        toggleScriptEnable = !toggleScriptEnable;

    };

    yepNopeBeforeDisplay = function(ev) {

        count++;

        ev.target.enabled = toggleScriptEnable; // toggleScriptEnable

        ev.target.name = count + // increments on beforeDisplay events

            (toggleYepNopeTitle ? ' Yep script' : ' Nope script') + // toggles on beforeDisplay events

            (toggleScriptEnable ? ' is enabled' : ' is not enabled'); // changes on the enableMyScriptOnInvoke event

        ////////////////////////////////////////////////////////////////////

        // NOTE: The Yep and Nope are not connected to the enabled status //

        // take note of when they swap and when the count changes         //

        ////////////////////////////////////////////////////////////////////

        toggleYepNopeTitle = !toggleYepNopeTitle;

        wl(say('Before display ' + ev.target.name), 'color: orange');

        // NOTE: The before display is triggered when the menu item is invoked and before the parent menu is displayed

        // In this example the parent menu is the "Layout" menu

    };

    yepNopeOnInvoke = function(ev) {

        wl(say('On Invoke ' + ev.target.name), 'color: red;background:yellow;');

        ///////////////////////////////////////////////////////////////////////////////////////////////////////

        // NOTE: before the onInvoke fires the beforeDisplay will fire                                       //

        // This is in addition to the beforeDisplay that fired on displaying the menu                        //

        // In our case this will cause that it looks like the Yep Nope are not being toggled                 //

        // To circumvent that one could place in the on Invoke `toggleYepNopeTitle = !toggleYepNopeTitle;`   //

        // Take note that the count changes with the onInvoke because of it's associated beforeDisplay event //

        ///////////////////////////////////////////////////////////////////////////////////////////////////////

    };

    /*

       _      _    _   __  __

      /_\  __| |__| | |  \/  |___ _ _ _  _ ___

     / _ \/ _` / _` | | |\/| / -_) ' \ || (_-<

    /_/ \_\__,_\__,_| |_|  |_\___|_||_\_,_/__/

    */

    var fooMenu = app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Layout').submenus.itemByName('FabScript');

    // For convenience we shall remove the menu if it already exists.

    if (fooMenu !== null) fooMenu.remove();

    // Add the FabScript submenu

    fooMenu = app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Layout').submenus.add('FabScript', LocationOptions.AT_END);

    // Add the menu items with the event listeners

    installMenuItem({

        name: 'YepNope',

        parentMenu: fooMenu,

        onInvoke: yepNopeOnInvoke,

        beforeDisplay: yepNopeBeforeDisplay

    });

    installMenuItem({

        name: 'Enable my script',

        parentMenu: fooMenu,

        onInvoke: enableMyScriptOnInvoke

    });

    return fooMenu;

})();

/*

To remove the menu

foo.remove();

or

app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Layout').submenus.itemByName('FabScript').remove();

*/

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
Explorer ,
Apr 20, 2018 Apr 20, 2018

Copy link to clipboard

Copied

Thanks Trevor, I will try it.

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
Explorer ,
Apr 24, 2018 Apr 24, 2018

Copy link to clipboard

Copied

LATEST

Can't make it work in my case because my menu items already exist and I cannot create them again.

I could remove all of them and run your script to add them again but I don't know if it's a good way to do that..

I also tried this to modified action associated with my existing menu item :

var mnu = app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Window').submenus.itemByName('Extensions').menuItems.itemByName('MyMenu');

var action = mnu.associatedMenuAction;

action.addEventListener(

  /*event type*/   'onInvoke',

    /*event handler*/ function(){

        alert('Hello World!');

        }

    );

I also tried to add eventListener

var t1 = app.scriptMenuActions;

  for (var i = 0; i < t1.length; i++) {

      var x = t1.item(i);

      if (x.isValid && x.name == "MyMenu") {

          var test =  app.menus.itemByName('$ID/Main').submenus.itemByName('$ID/&Window').submenus.itemByName('Extensions').menuItems.itemByName('MyMenu');

            x.eventListeners.add('beforeDisplay', function(ev) {

                wl(say('beforeDisplay 2 ' + ev.target.name));

            });

    

        //test.add(x);

          test.eventListeners.add('beforeDisplay', function(ev) {

                wl(say('beforeDisplay 4' + ev.target.name));

            });

      }

But this seems to add a new submenuItem with "MyMenu" name and not updating existing menuItem.

My last code seems to work if my MenuItem does nothing at all. If it runs an extension, it does nothing like if no event is fired (or no event listener recorded)

I'm really lost in all of that !


Edit : My bad !!! It works ! "beforeDisplay" isn't available on my menuItem, but using beforeInvoke it's Ok.
I will post the final code soon.

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