Changing selected text layers language with photoshop script
虽然我设法将一个功能性脚本一起更改所选图层的字典语言,但这还不是我所需要的。
我目前正在检索我选择的图层的索引,使用它们来获取图层名称——这是有问题的部分——然后根据我显示的自定义对话框中选择的选项使用魔法来更改它们的语言。
图层名称的使用是一个非常不成熟的解决方案,我需要精确,我需要能够根据图层 ID 或索引更改语言。不仅我的脚本容易出现名称冲突,而且我不知道这些选定的图层将在哪里,如果在文档的根目录上或在 5 个组堆栈内。
这是我当前的代码:
主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function main() { // Create window with language selection and retrieve selected value var lang = createWindow(); // Retrieve selected layers var selectedLayers = getSelectedLayersIdx(); // Look at each entry and change language when possible for(var a in selectedLayers){ try { setLangByIndex(Number( selectedLayers[a]), lang ); } catch(err) { } } } |
(createWindow 返回一个 lang 值,跳过它)
迈克得到身份证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | function getSelectedLayersIdx(){ var selectedLayers = new Array; var ref = new ActionReference(); ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); var desc = executeActionGet(ref); if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ) { desc = desc.getList( stringIDToTypeID( 'targetLayers' )); var c = desc.count var selectedLayers = new Array(); for(var i=0;i<c;i++) { try{ activeDocument.backgroundLayer; selectedLayers.push( desc.getReference( i ).getIndex() ); } catch(e) { selectedLayers.push( desc.getReference( i ).getIndex()+1 ); } } } else { var ref = new ActionReference(); ref.putProperty( charIDToTypeID('Prpr') , charIDToTypeID( 'ItmI' )); ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); try { activeDocument.backgroundLayer; selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ))-1); } catch(e) { selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ))); } } return selectedLayers; } |
设置语言的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function setLangByIndex(idx, lang){ ref = new ActionReference(); ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID("Nm " )); ref.putIndex( charIDToTypeID("Lyr" ), idx ); var name = executeActionGet(ref).getString(charIDToTypeID("Nm " )); var el = activeDocument.layers.getByName( name ); // Temp quick block; MUST UPDATE IN CASE OF NEW LANGUAGES if (lang == 'pt_br' ) el.textItem.language = Language.BRAZILLIANPORTUGUESE; else if (lang == 'en_us' ) el.textItem.language = Language.ENGLISHUSA; else el.textItem.language = Language.ENGLISHUK; } |
我尝试低效的解决方法:
-
使用 Adob??e 的脚本侦听器通过 executeAction 更改语言,
但无法使其工作。语言部分在?4堆叠内
描述符(和一个列表!)。我迷路了,不断收到错误 8800。 -
弄清楚如何使用 idx 获取对象 ref。失败的
悲惨地。
在我注意到与段落样式相关的一些烦人的故障(您可以将其定义为 PS 上文本的默认设置,而不是 JS 对象)之后,我放弃了固执并停止避免通过索引数组执行新循环完成后重新选择图层。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | /* * Based in Mike Hale's"getSelectedLayersIdx" script and Adobe's Scripting Listener dump. Based the panel on Davide Barranca's code: http://www.davidebarranca.com/2012/10/scriptui-window-in-photoshop-palette-vs-dialog/ Useful Resources: Photoshop char list: http://www.pcpix.com/Photoshop/char.htm ActionDescriptor methods: http://jongware.mit.edu/pscs5js_html/psjscs5/pc_ActionDescriptor.html TextItem methods: http://jongware.mit.edu/pscs5js_html/psjscs5/pc_TextItem.html You can fish for language codes here: http://wingp.googlecode.com/svn/photogp/photoshopapi/photoshop/PIStringTerminology.h */ /* ______________________________ SCRIPT ______________________________ */ var scriptAlert ="Language Change says"; // MUST UPDATE IF YOU WANT TO CHANGE THE AVAILABLE LANGUAGES // The available languages, as { text displayed on dialog window : codename }. See notes above for more language codes var langs = {}; langs['Português (Brasil)'] = 'brazilianPortugueseLanguage'; langs['English (UK)'] = 'ukenglishLanguage'; langs['English (USA)'] = 'englishLanguage'; if(app.documents.length>0){ // the script will be executed only if an active document exists. var imgName = activeDocument.name; var extreme= imgName.substr(imgName.length - 5, 5); var dot = extreme.lastIndexOf("."); if(dot == -1) { // Checks if the active document was saved or not. alert("Please, save your document!", scriptAlert, false); } else { main(); // if the active document was saved, go ahead! } } function createWindow() { // Creates a panel asking for input var isDone, win, windowResource, radio_group, cancel, rb, i; //sentinel variable isDone = false; cancel = false; // Build dialog radio buttons i = 0; for( var k in langs ) { if( i==0 ) rb ="rb"+i+": RadioButton { text: '"+k+"', value: 1 }, "; else rb +="rb"+i+": RadioButton { text: '"+k+"' }, "; i++; } windowResource ="palette { \\ orientation: 'column', \\ alignChildren: ['fill', 'top'], \\ preferredSize:[300, 130], \\ text: 'Change Spell Check Language', \\ margins:15, \\ \\ optPanel: Panel { \\ orientation: 'row', \\ alignChildren: 'left', \\ margins:15, \\ text: ' Select the desired dictionary language for the select text ', "+ rb +" \\ } \\ \\ bottomGroup: Group{ \\ cancelButton: Button { text: 'Cancel', properties:{name:'cancel'}, size: [120,24], alignment:['right', 'center'] }, \\ applyButton: Button { text: 'Ok', properties:{name:'ok'}, size: [120,24], alignment:['right', 'center'], active: true }, \\ }\\ }"; win = new Window(windowResource); radio_group = win.optPanel; // set group // Match options with language function selected_rbutton (rbuttons) { for (var i = 0; i < rbuttons.children.length; i++) if (rbuttons.children[i].value == true) return langs[rbuttons.children[i].text]; } win.bottomGroup.cancelButton.onClick = function() { win.close(); return cancel = true; }; // Button listeners win.bottomGroup.applyButton.onClick = function() { return isDone = true; }; // don't forget this one! win.onClose = function() { return cancel = true; }; win.addEventListener("keydown", function (k) { if (k.keyName == 'Enter') return isDone = true; }); win.show(); while (isDone === false) { try { app.refresh(); } catch(err) { // Esc cancels without errors return false; } } return cancel ? false : selected_rbutton (radio_group); // return value, or false if cancelled } function getSelectedLayersIdx(){ // Gets array of indexes of selected layers var selectedLayers = new Array; var ref = new ActionReference(); ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); var desc = executeActionGet(ref); if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ) { desc = desc.getList( stringIDToTypeID( 'targetLayers' )); var c = desc.count var selectedLayers = new Array(); for(var i=0;i<c;i++) { try{ activeDocument.backgroundLayer; selectedLayers.push( desc.getReference( i ).getIndex() ); } catch(e) { selectedLayers.push( desc.getReference( i ).getIndex()+1 ); } } } else { var ref = new ActionReference(); ref.putProperty( charIDToTypeID('Prpr') , charIDToTypeID( 'ItmI' )); ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') ); try { activeDocument.backgroundLayer; selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ))-1); } catch(e) { selectedLayers.push( executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ))); } } return selectedLayers; } function selectLayerByIndex( selectedLayers, add ){ // Selects layers by index. If fed an array + true add, selects them, otherwise provide a single value so it selects a single layer if (typeof(add)==='undefined') add = false; if ( add ) // If Add it's an array for(var a in selectedLayers){ var desc = new ActionDescriptor(); var ref = new ActionReference(); ref.putIndex( charIDToTypeID("Lyr" ), Number(selectedLayers[a]) ); desc.putReference( charIDToTypeID("null" ), ref ); desc.putEnumerated( stringIDToTypeID("selectionModifier" ), stringIDToTypeID("selectionModifierType" ), stringIDToTypeID("addToSelection" ) ); var idMkVs = charIDToTypeID("MkVs" ); desc.putBoolean( charIDToTypeID("MkVs" ), false ); executeAction( charIDToTypeID("slct" ), desc, DialogModes.NO ); } else // Else I just need to make this layer active, it's a number { var desc = new ActionDescriptor(); var ref = new ActionReference(); var idLyr = charIDToTypeID("Lyr" ); ref.putIndex( charIDToTypeID("Lyr" ), selectedLayers ); desc.putReference( charIDToTypeID("null" ), ref ); desc.putBoolean( charIDToTypeID("MkVs" ), false ); executeAction( charIDToTypeID("slct" ), desc, DialogModes.NO ); } } function setLangByIndex( idx, lang ){ // Sets the dictionary language for a text layer based on its index // Make layer active selectLayerByIndex( idx ); // And do tiny override var textObj = new ActionDescriptor(); var target = new ActionReference(); target.putProperty( charIDToTypeID("Prpr" ), charIDToTypeID("TxtS" ) ); // desired property: text style target.putEnumerated( charIDToTypeID("TxLr" ), charIDToTypeID("Ordn" ), charIDToTypeID("Trgt" ) ); // the active layer textObj.putReference( charIDToTypeID("null" ), target ); var textStyle = new ActionDescriptor(); textStyle.putInteger( stringIDToTypeID("textOverrideFeatureName" ), 808466225 ); textStyle.putInteger( stringIDToTypeID("typeStyleOperationType" ), 3 ); textStyle.putEnumerated( stringIDToTypeID("textLanguage" ), stringIDToTypeID("textLanguage" ), stringIDToTypeID( lang ) ); textObj.putObject( charIDToTypeID("T " ), charIDToTypeID("TxtS" ), textStyle ); // to (end); text style, desc. executeAction( charIDToTypeID("setd" ), textObj, DialogModes.NO ); // execute } //////////////////////////////////// // Main function function main() { // Create window with language selection and retrieve selected value var lang = createWindow(); if ( !lang ) // If cancelled please stop return; // Retrieve selected layers var selectedLayers = getSelectedLayersIdx(); // Look at each entry and change language when possible; otherwise skip to next item for(var k in selectedLayers){ try { setLangByIndex(Number(selectedLayers[k]), lang); } catch(err) { continue; } } selectLayerByIndex( selectedLayers, true ); } |