Below is an example demonstrating how you can create a custom action and add it to a menu, via script.
// Define an anonymous function; // serves as our main loop, // limits the scope of variables (function(){ /*********************************************************************/ // Boolean : Function for testing if a file exists on disk function fileExists( sFilePath ) { // Create a file info object var oFileInfo = new DzFileInfo( sFilePath ); // Get whether or not the file exists var bExists = oFileInfo.exists(); // Do not leak memory oFileInfo.deleteLater(); // Return the answer return bExists; }; /*********************************************************************/ // String : Function for creating a custom action function createCustomAction( sActionText, sActionDesc, sActionFilePath, sActionIconPath, bUpdate ) { // Get the action manager var oActionMgr = MainWindow.getActionMgr(); // Declare working variables var sName, sText, sDesc, sFile, sIcon; // Initialize var bFound = false; // Iterate over all custom actions for( var i = 0, nActions = oActionMgr.getNumCustomActions(); i < nActions; i += 1 ){ // Get 'current' custom action information sName = oActionMgr.getCustomActionName( i ); sText = oActionMgr.getCustomActionText( i ); sDesc = oActionMgr.getCustomActionDesc( i ); sFile = oActionMgr.getCustomActionFile( i ); sIcon = oActionMgr.getCustomActionIcon( i ); // If the file is the one we are looking for if( sFile == sActionFilePath ){ // Update our flag bFound = true; // If we are updating if( bUpdate ){ // If the text is not what we are looking for if( sText != sActionText ){ // Update it oActionMgr.setCustomActionText( i, sActionText ); } // If the description is not what we are looking for if( sDesc != sActionDesc ){ // Update it oActionMgr.setCustomActionDesc( i, sActionDesc ); } // If an icon path is passed in if( !sActionIconPath.isEmpty() && sIcon != sActionIconPath ){ // If the file exists if( fileExists( sActionIconPath ) ){ // Update it oActionMgr.setCustomActionIcon( i, sActionIconPath ); } } } // Return the name of the action return sName; } } // If the custom action was not found if( !bFound ){ // If the file exists if( fileExists( sActionFilePath ) ){ // If a icon path is passed in if( !sActionIconPath.isEmpty() ){ // If the file does not exist if( !fileExists( sActionIconPath ) ){ // Update it sActionIconPath = ""; } } // Add the custom action and return the name return oActionMgr.addCustomAction( sActionText, sActionDesc, sActionFilePath, true, "", sActionIconPath ); } } // Return an empty string return ""; }; /*********************************************************************/ // DzActionMenu : Function for getting/creating a menu path function getActionMenu( sPath ) { // Get the action manager var oActionMgr = MainWindow.getActionMgr(); // Initialize var oMenu = oActionMgr.getMenu(); var sName = ""; var nIdx = -1; var sSubPath = sPath; // While the remaining path is not empty while( !sSubPath.isEmpty() ){ // Get the index of the first slash nIdx = sSubPath.indexOf( "/" ); // If a slash was not found if( nIdx < 0 ){ // The menu name is the path sName = sSubPath; // Break the loop on the next evaluation sSubPath = ""; // If a slash was found } else { // The menu name is before the slash sName = sSubPath.left( nIdx ); // Get the remaining path sSubPath = sSubPath.right( sSubPath.length - nIdx - 1 ); } // Get the sub menu oMenu = oMenu.getSubMenu( sName ); } // Return the menu return oMenu; }; /*********************************************************************/ // Boolean : Function for determining if a menu has an action function menuHasAction( oMenu, sAction, bCustom ) { // Initialize var bStatus = false; // Declare working variable var oItem; // Get the items in the menu var aItems = oMenu.getItemList(); // Iterate over the items for( var i = 0; i < aItems.length; i += 1 ){ // Get the 'current' item oItem = aItems[ i ]; // If the item is not an action or a custom action if( (!bCustom && oItem.type != DzActionMenuItem.Action) || (bCustom && oItem.type != DzActionMenuItem.CustomAction) ){ // Next!! continue; } // If the action is the one we are looking for if( oItem.action == sAction ){ // Update our flag bStatus = true; // We are done... break; } } // Return whether the action was found return bStatus; }; /*********************************************************************/ // Boolean : Function for adding an action to a menu function addActionToMenu( sMenuPath, sAction, bCustom, nIndex ) { // Initialize var bStatus = false; // Get the action manager var oActionMgr = MainWindow.getActionMgr(); // Declare working variables var oMenu; // Find the action; // a custom action will yeild an index // an action will yeild a DzAction var vAction = (bCustom ? oActionMgr.findCustomAction( sAction ) : oActionMgr.findAction( sAction )); // If the action was found if( bCustom ? vAction > -1 : vAction ){ // Get the index of the pane delimiter var nIdx = sMenuPath.indexOf( "::" ); // If the menu path contains the pane delimiter if( nIdx > -1 ){ // Get the pane manager var oPaneMgr = MainWindow.getPaneMgr(); // Get the pane class var sPaneClass = sMenuPath.substring( 0, nIdx ); // Find the pane var oPane = oPaneMgr.findPane( sPaneClass ); // If we have the pane if( oPane ){ // Get the pane option menu oMenu = oPane.getOptionsMenu(); // Get/Create the sub menu oMenu = oMenu.getSubMenu( sMenuPath.substring( nIdx + 2 ) ); } // If the menu path does not contain the pane delimiter } else { // Get/Create the sub menu oMenu = getActionMenu( sMenuPath ); } } // If we have a menu and it does not have the action if( oMenu && !menuHasAction( oMenu, sAction, bCustom ) ){ // If we have a custom action if( bCustom ){ // Insert the custom action in the menu oMenu.insertCustomAction( sAction, nIndex ); // If we have an action } else { // Insert the action in the menu oMenu.insertAction( sAction, nIndex ); } // Update our flag bStatus = true; } // Return whether the action was added return bStatus; }; /*********************************************************************/ // DzToolBar : Function for getting/creating a toolbar function getToolBar( sToolBar ) { // Get the pane manager var oPaneMgr = MainWindow.getPaneMgr(); // Find the toolbar var oToolBar = oPaneMgr.findToolBar( sToolBar ); // If the toolbar was not found if( !oToolBar ){ // Create the toolbar oToolBar = oPaneMgr.createToolBar( sToolBar ); } // Return the toolbar return oToolBar; }; /*********************************************************************/ // Boolean : Function for determining if a toolbar has an action function toolBarHasAction( oToolBar, sAction, bCustom ) { // Initialize var bStatus = false; // Declare working variable var oItem; // Get the items in the toolbar var aItems = oToolBar.getItemList(); // Iterate over the items for( var i = 0; i < aItems.length; i += 1 ){ // Get the 'current' item oItem = aItems[ i ]; // If the item is not an action or a custom action if( (!bCustom && oItem.type != DzToolBarItem.Action) || (bCustom && oItem.type != DzToolBarItem.CustomAction) ){ // Next!! continue; } // If the action is the one we are looking for if( oItem.action == sAction ){ // Update our flag bStatus = true; // We are done... break; } } // Return whether the action was found return bStatus; }; /*********************************************************************/ // Boolean : Function for adding an action to a toolbar function addActionToToolBar( sToolBar, sAction, bCustom, nIndex ) { // Initialize var bStatus = false; // Get the toolbar var oToolBar = getToolBar( sToolBar ); // If we have a toolbar if( oToolBar ){ // If we did not find the action if( !toolBarHasAction( oToolBar, sAction, bCustom ) ){ // If we have a custom action if( bCustom ){ // Insert the custom action in the toolbar oToolBar.insertCustomAction( sAction, nIndex ); // If we have an action } else { // Insert the action in the toolbar oToolBar.insertAction( sAction, nIndex ); } // Update our flag bStatus = true; } } // Return whether the action was added return bStatus; }; /*********************************************************************/ // Let the user know we are busy setBusyCursor(); // Define the custom action components var sActionMenu = "&Scripts/Testing"; var sActionToolbar = "Testing"; var sActionText = "Custom - Content Directory Manager"; var sActionDesc = "dzContentDirectoryManager"; var sActionFilePath = String("%1/support/DAZ/dzContentDirectoryManager.dse").arg( App.getScriptsPath() ); var sActionIconPath = String("%1/images/icons/whatsthissmallicon.png").arg( App.getResourcesPath() ); var sActionName = createCustomAction( sActionText, sActionDesc, sActionFilePath, sActionIconPath, true ); addActionToMenu( sActionMenu, sActionName, true, -1 ); addActionToToolBar( sActionToolbar, sActionName, true, -1 ); // Let the user know we are done clearBusyCursor(); // Finalize the function and invoke })();