Copy link to clipboard
Copied
I've been able to sucessfully add items to the InDesign menu thanks in part to Marijan Tompa's (tomaxxi) blog post http://indisnip.wordpress.com/2010/08/08/create-customized-menu/
My test code (below) creates a new menu, and sucessfully adds two menu items plus a submenu. The submenu is causing me problems. When you first launch InDesign it's created in the proper place (in the middle of the menu). But when you relaunch InDesign, the submenu moves to the top of the menu and never goes back to it's proper position farther down in the menu where it was the first time InDesign was launched.
I've searched high and low in this forum, the web and InDesign's documentation and can't figure out how to keep it from moving (I want the menu to be farther down the menu, not at the top). I hope one of you kind souls will help me to control the position of the submenu (and have it stay there across launches).
Thanks in advance!
Dan
Here's the code I'm working with. This is saved as testMenu.jsx in the Scripts > startup scripts folder.
P.S. I'm testing this in CS5.5 currently, but ideally this solution should work in CS3 and later.
#targetengine "myTestMenu"
var myFolder = Folder(app.activeScript.path);
myFolder = myFolder.parent + '/Scripts Panel/';
var menuItem1Handler = function( /*onInvoke*/ ){
app.doScript(File(myFolder + 'MyTest1.jsx'));
};
var menuItem2Handler = function( /*onInvoke*/ ){
app.doScript(File(myFolder + 'MyTest2.jsx'));
};
menuInstaller()
function menuInstaller() {
var menuItem1T = "My Menu Item 1",
menuItem2T = "My Menu Item 2",
menuT = "MyTestMenu",
subT = "Sub Menu",
subs = app.menus.item("$ID/Main").submenus, sma, mnu;
var refItem = app.menus.item("$ID/Main").submenus.item("$ID/&Layout");
subMenu1 = app.scriptMenuActions.item(menuItem1T);
if( subMenu1 == null ) {
subMenu2 = app.scriptMenuActions.add(menuItem1T);
}
subMenu2 = app.scriptMenuActions.item(menuItem2T);
if( subMenu2 == null ) {
subMenu2 = app.scriptMenuActions.add(menuItem2T);
}
subMenu2.eventListeners.add("onInvoke", menuItem2Handler);
mnu = subs.item(menuT);
if( mnu == null ) {
mnu = subs.add(menuT, LocationOptions.after, refItem);
}
mnu.menuItems.add(subMenu1);
mnu.menuSeparators.add();
subsSubs = app.menus.item( '$ID/Main' ).submenus.item( menuT ).submenus;
mnuSubMenu = subsSubs.item( subT );
if( mnuSubMenu == null ) {
mnuSubMenu = subsSubs.add( subT);
}
mnu.menuItems.add(subMenu2);
};
Thank you all so much for your replies, and thank you Harbs for making it finally work!
Just to make sure this can serve as a resource for others in the future, below is a final (working) menu based on Harb's code. I also added 2 submenu items just to be complete.
Thanks again everyone. I'm so glad you could help get this working!
Dan
...#targetengine "HarbsTestMenu"
menuInstaller();
function menuInstaller() {
// SET THE FILES THAT ARE TRIGGERED BY MENU ITEMS
menuItem1Handler = function( /*onInvo
Copy link to clipboard
Copied
Great.
Copy link to clipboard
Copied
Hi Dan,
There would be much to say about your code (variable scope, etc.) but the two most important, I think, are:
— Custom menus and submenus are application-persistent while script menu actions are (usually) session-persistent
— In the specific case where an action directly relies on a script file, you don't need to deal w/ session-persistence and you can directly address the script file (no need of app.doScript() stuff and so on).
Here is a possible approach (provided that the featured script files are located in the parent folder of the Startup scripts folder):
#targetengine "DanRodneyMenu"
// =====================================
// This script is a 'startup script', it runs each time ID starts
// and shouldn't be rerun during the session. We don't really need
// it to be session-persistent. However we use a #targetengine to
// save a 'done' flag which prevents the script from being rerun.
// =====================================
(function(/*obj|undefined*/HOST)
// -------------------------------------
// Install and/or update the menu/submenu
// and connect the menu actions
{
// ---
// HOST can be your framework container, if needed (default: $.global)
// ---
HOST || (HOST=$.global);
// ---
// Prevent the current (startup) script from being uselessly rerun
// ---
if( HOST[$.engineName] )
{
alert( "This script is automatically executed at startup. You shouldn't run it manually." );
return;
}
// ---
HOST[$.engineName] = true;
// ---
// Settings and constants
// ---
var MENU_NAME = "My Test Menu",
FEATURES = [
{ caption: "My Menu Item 1", fileName: 'File-One.jsx', subName: "" },
{ caption: "My Menu Item 2", fileName: 'File-Two.jsx', subName: "My Sub Menu" }
],
LO_END = LocationOptions.atEnd,
INDESIGN_ROOT_MENU = app.menus.item( '$ID/Main' ),
FEATURE_LOCATION_PATH = (function()
{
var f;
try{ f=app.activeScript; }
catch(_){ f=File(_.fileName); }
return f.parent.parent + '/';
})();
// ---
// (Re)set the actions
// Note: checks also whether script files are available
// ---
var t, f, i = FEATURES.length;
while( i-- )
{
t = FEATURES;
if( (f=File(FEATURE_LOCATION_PATH + t.fileName)).exists )
{
// The script file exists => create the corresponding action
// and directly attach the event listener to the file
// (no need to use app.doScript(...) here)
// ---
(t.action = app.scriptMenuActions.add( t.caption )).
addEventListener('onInvoke', f);
}
else
{
// The script file does not exist => remove that feature
// ---
FEATURES.splice(i,1);
}
}
// ---
// Create/reset the custom menu container *if necessary*
// Note: menus/submenus are application-persistent
// ---
var mnu = INDESIGN_ROOT_MENU.submenus.itemByName( MENU_NAME );
if( !mnu.isValid )
{
// Our custom menu hasn't been created yet
// ---
if( !FEATURES.length ) return;
mnu = INDESIGN_ROOT_MENU.submenus.add(
MENU_NAME,
LocationOptions.after,
INDESIGN_ROOT_MENU.submenus.item( '$ID/&Window' )
);
}
else
{
// Our custom menu already exists, but we must clear
// any sub element in order to rebuild a fresh structure
// ---
mnu.menuElements.everyItem().remove();
// If FEATURES is empty, remove the menu itself
// ---
if( !FEATURES.length ){ mnu.remove(); return; }
}
// ---
// Now, let's fill mnu with respect to FEATURES' order
// (Possible submenus are specified in .subName and created on the fly)
// ---
var s,
n = FEATURES.length,
subs = {},
sub = null;
for( i=0 ; i < n ; ++i )
{
t = FEATURES;
// Target the desired submenu
// ---
sub = (s=t.subName) ?
( subs
|| (subs=mnu.submenus.add( s, LO_END )) ) :mnu;
// Connect the related action
// ---
sub.menuItems.add( t.action );
}
})();
@+
Marc
Copy link to clipboard
Copied
That's odd. John's post seems to exist, but doesn't show up...
Copy link to clipboard
Copied
That seemed to do it... Weird...
Copy link to clipboard
Copied
That's odd. John's post seems to exist, but doesn't show up...
It's worse than that. Cache corruption.
Viewing from adobe-vm-wa06.sgvm2hosted.jiveland.com
I see my post but not your replies. Dumping cookies and reloading
fixes it, because I get another server.
I'll start a thread in Forum Comments.