// =========================================================================== // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // =========================================================================== // // // Creation Date: September 2006 // // // // // // pluginResourceUtil(string $pluginName, string $outputFile) // // // // // This utility script extracts localizable resources for a // plugin to an output file. // //

// The procedure will produce a script file containing the default // resource values for all resources registered with the plugin. // This includes all MStringResource values registered in the plugin // source code, the localizable node and attribute strings for // each node registered with the plugin and all plugin resources // registered in mel scripts (using registerPluginResource) // The extracted resources can then be localized and the resulting file /// will be suitable for use with the loadPluginLanguageResources command. // //

// Note that the script only runs if the UI language is // set to the English default (it will not produce the desired default // values when running in a localized setting). // // // string $pluginName Unique Plugin name (as passed to loadPlugin) // string $filename file name for redirection of output (or "") // // // // Extract localizable resources for the plugin "myPlugin" // // and store them in the file "myPlugin.pres.mel" // // // pluginResourceUtil("myPlugin", "myPlugin.pres.mel") // // // Show all localizable resources for the plugin "myPlugin" // // but do not redirect the output to a file. // // // pluginResourceUtil("myPlugin", "") // // // proc printToFile(string $outStr) { global int $gPluginResUtilFileId; if ($gPluginResUtilFileId > 0) { fprint $gPluginResUtilFileId $outStr; } else { print $outStr; } } proc debugMsg(string $msg) { global int $gPluginResUtilDebugMode; if ($gPluginResUtilDebugMode) { print ("DEBUG: " + $msg); } } proc printComment(string $comment) { // Put comment markers and end of line around the text string $output = "// " + $comment + "\n"; printToFile ($output); } proc printPluginStringCall(string $pluginName, string $id, string $value) { string $fmt = "setPluginResource( \"^1s\", \"^2s\", \"^3s\");\n"; string $output = `format -stringArg $pluginName -stringArg $id -stringArg $value $fmt`; printToFile ($output); } proc printNodeNiceNameCall(string $nodeType, string $value) { string $fmt = "setNodeNiceNameResource( \"^1s\", \"^2s\" );\n"; string $output = `format -stringArg $nodeType -stringArg $value $fmt`; printToFile ($output); } proc printAttrNiceNameCall(string $nodeType, string $attrShortName, string $value) { string $fmt = "setAttrNiceNameResource( \"^1s\", \"^2s\", \"^3s\" );\n"; string $output = `format -stringArg $nodeType -stringArg $attrShortName -stringArg $value $fmt`; printToFile ($output); } proc printAttrEnumCall(string $nodeType, string $attrShortName, string $enumIndex, string $value) { string $fmt = "setAttrEnumResource( \"^1s\", \"^2s\", ^3s, \"^4s\" );\n"; string $output = `format -stringArg $nodeType -stringArg $attrShortName -stringArg $enumIndex -stringArg $value $fmt`; printToFile ($output); } proc string[] getAttrsForNodeType(string $nodeType) { string $attrs[]; if (catch($attrs = `attributeInfo -all -type $nodeType`)) { debugMsg("skipping " + $nodeType + "\n"); } return $attrs; } // genNodeRes: // Internal routine to generate all resources associated with a // single node type. proc genNodeRes(string $nodeType) { // Create a node of this type to use for queries if (catch ($nodeInstance = `createNode -skipSelect $nodeType`)) { string $fmt = (uiRes("m_pluginResourceUtil.kCantMakeNode")); string $msg = `format -stringArg $nodeType $fmt`; warning $msg; return; } // Heading comment printComment ( "" ); printComment ("Node: " + $nodeType); printComment ( "" ); // Generate Node niceName resource $resValue = `nodeTypeNiceName $nodeType`; printNodeNiceNameCall($nodeType, $resValue); if (!`objExists $nodeInstance`) { // Catch-all for nodes that are ignored by most other commands, such as 'objExists' and 'ls'. // For instance, Manip nodes. // Manipulator nodes do get created and stick around, but most other commands, // such as 'ls', are set up to ignore them since they are normally temporary // nodes and not part of the scene. If you really wanted to look at their // attributes you could do so through the API. // For the purposes of localization, having their names unlocalized seems like the // easiest choice, as its clear that knowing about them or using them directly is // not an expected workflow from the user point of view. string $fmt = (uiRes("m_pluginResourceUtil.kSkippingAttributesForNodeOfType")); string $msg = `format -stringArg $nodeType $fmt`; warning $msg; return; } // Get a list of all node attributes string $nAttrs[] = getAttrsForNodeType($nodeType); // Get a list of enum attributes string $eAttrs[] = `attributeInfo -enumerated on $nodeInstance`; // Build a list of all attributes to prune // Start with standard attributes on all nodes string $pruneAttrs[] = { "message", "caching", "isHistoricallyInteresting", "nodeState", "binMembership" }; // Add to prune list all attributes that are inherited from a parent node string $pNodeTypes[] = `nodeType -inherited $nodeInstance`; for ($pNodeType in $pNodeTypes) { // Skip self if ($pNodeType == $nodeType) { continue; } // Skip placeholder "THxxxx" nodes that show up for plugins else if (`gmatch $pNodeType "TH*"`) { continue; } else { // Look up all the attributes of this parent node type // and add it to the exclusion list string $pAttrs[]; $pAttrs = getAttrsForNodeType($pNodeType); $pruneAttrs = stringArrayCatenate($pruneAttrs, $pAttrs); } } // Prune the attribute lists to those we want to generate // resources for $nAttrs = stringArrayRemove($pruneAttrs, $nAttrs); $eAttrs = stringArrayRemove($pruneAttrs, $eAttrs); // Remove the duplicated attribute name if any. // This is very rare but happens for Arnold related nodes (mtoa plugin). $nAttrs = stringArrayRemoveDuplicates($nAttrs); $eAttrs = stringArrayRemoveDuplicates($eAttrs); // Generate Calls for Attribute niceName resources for ($nAttr in $nAttrs) { $sName = `attributeQuery -shortName -n $nodeInstance $nAttr`; $resValue = `attributeQuery -niceName -n $nodeInstance $nAttr`; printAttrNiceNameCall($nodeType, $sName, $resValue); } // Generate Attribute enum resources for ($eAttr in $eAttrs) { $sName = `attributeQuery -shortName -n $nodeInstance $eAttr`; // Query enum values and split into an array string $eValueStr[] = `attributeQuery -node $nodeInstance -listEnum $eAttr`; string $eValueArray[] = stringToStringArray($eValueStr[0], ":"); int $numEnums = size($eValueArray); int $i; int $currentBaseIndex = 0; int $currentBiasToTheBaseIndex = 0; for ($i=0; $i < $numEnums; $i++) { // Enum values are either "value" or "value=index" // Tokenize to find out, and use index if its specified. string $tokens[]; string $str1 = $eValueArray[$i]; int $numTokens = tokenize($str1, "=", $tokens); string $enumStr = $tokens[0]; // If there is an index for this enum value, // it means the following indices will be calculated // based on this index. // E.g.: // "Grid=1 Tree Delaunary Fine" means: // "Grid=1 Tree=2 Delaunary=3 Fine=4" // // Here is a more general case, just make sure // the code will handle this case. // E.g.: // "Grid=1 Tree Delaunary=4 Fine" means: // "Grid=1 Tree=2 Delaunary=4 Fine=5" // // E.g.: // "BSP:Large BSP=3:BSP2" means: // "BSP=0 Large BSP=3 BSP2 = 4" // if ($numTokens > 1) { $currentBaseIndex = $tokens[1]; $currentBiasToTheBaseIndex = 0; } string $enumIndex = $currentBaseIndex + $currentBiasToTheBaseIndex; // Print out the resource printAttrEnumCall($nodeType, $sName, $enumIndex, $enumStr); $currentBiasToTheBaseIndex += 1; } } // Cleanup the temporary node we made delete $nodeInstance; } proc int checkEnvironment() { // These checks help ensure the utility is being run with // relatively clean data and that results should be // okay: // This utility should only be run in the default language // or it will give incorrect results. if (`about -uiLanguageIsLocalized`) { string $msg = (uiRes("m_pluginResourceUtil.kLangNotDefault")); // I18N_TODO: bug 261860 // This is an error - if you are running in a localized environment, // the strings may already be translated, you are not going to // get the defaults. error $msg; return 1; } // Make sure pseudotranslation is off string $psMode = `getenv("MAYA_PSEUDOTRANS_MODE")`; if (size($psMode) > 0) { int $psModeInt = $psMode; if ($psModeInt > 0) { string $msg = "Cannot run with pseudo translation enabled - utility will produce incorrect results"; error $msg; return 1; } } return 0; } // genNodeRes: // Internal routine to generate all resources associated with the // plugin name (i.e. registered by MStrings or mel). proc genPluginStringRes(string $pluginName) { // Locate all strings registered with the plugin i.e. matching // on the plugin's name string $matchPattern = "p_" + $pluginName + "."; string $matches[] = `displayString -query -keys $matchPattern`; string $key; // Heading comment printComment ("----------------------------"); printComment ("Registered string resources:"); printComment ("----------------------------"); if (size($matches) <= 0) { printComment ( "" ); printComment ( " (Plugin has no registered string resources)" ); printComment ( "" ); } for ($key in $matches) { // Look up the string value $resValue = `displayString -query -value $key`; // Split the id into subparts to get the unique string part $idPart = stringRemovePrefix($key, $matchPattern); // Encode escape characters in the resource value string $resValueEncoded = `encodeString $resValue`; // Format and generate the correct initialization string printPluginStringCall($pluginName, $idPart, $resValueEncoded); } } global proc pluginResourceUtil( string $pluginName, string $outputFile ) { // Write resources for plug-in $pluginName to file $outputFile. global int $gPluginResUtilFileId; // Perform environment checks to ensure utility is being run in // suitable environment: if (checkEnvironment() != 0) { return; } // Find out if this plugin is loaded, if not try to load it. int $isLoaded = `pluginInfo -query -loaded $pluginName`; if ($isLoaded == 0) { if (catch (`loadPlugin $pluginName`)) { $fmt = (uiRes("m_pluginResourceUtil.kPluginInvalid")); $msg = `format -stringArg $pluginName $fmt`; error $msg; return; } // In some cases the load silently fails if it is known but unavailable. // So check that it really did load. $isLoaded = `pluginInfo -query -loaded $pluginName`; if ($isLoaded == 0) { $fmt = (uiRes("m_pluginResourceUtil.kPluginLoadError")); $msg = `format -stringArg $pluginName $fmt`; error $msg; return; } } // Query the plugin's path from its name, needed for // subsequent queries using pluginInfo string $ppath; if ( catch ($ppath = `pluginInfo -query -path $pluginName`) ) { $fmt = (uiRes("m_pluginResourceUtil.kPluginNotFound")); $msg = `format -stringArg $pluginName $fmt`; error $msg; return; } // Are we directing output to a file? If so, open the file and set // file handle variable. $gPluginResUtilFileId = 0; if (size($outputFile) > 0) { $gPluginResUtilFileId = `fopen $outputFile "w"`; if ($gPluginResUtilFileId == 0) { $msg = (uiRes("m_pluginResourceUtil.kCantWriteFile")); error $msg; return; } } printComment ( "Resources for Plug-in: " + $pluginName ); printComment ( "" ); // // Generate a list of all resources associated with the plugin // via MStringResource or mel string registrations. // genPluginStringRes($pluginName); // // Get a list of all dependency nodes generated by the plugin // and generate associated resources for each. // printComment ( "" ); printComment ("--------------------------"); printComment ("Registered node resources:"); printComment ("--------------------------"); string $pnodes[] = `pluginInfo -query -dependNode $ppath`; if ( size( $pnodes ) > 0 ) { for ( $node in $pnodes ) { genNodeRes($node); } } else { printComment ( "" ); printComment ( " (Plugin has no registered nodes)" ); printComment ( "" ); } if ($gPluginResUtilFileId > 0) { fclose $gPluginResUtilFileId; } }