cg@3594: "{ Encoding: utf8 }" cg@3594: cg@2015: "{ Package: 'stx:libtool2' }" cg@2015: cg@2015: "{ NameSpace: Tools }" cg@2015: cg@2015: ApplicationModel subclass:#InternationalLanguageTranslationEditor cg@2015: instanceVariableNames:'languagesList keyStringsToLanguageMappings languageTextHolder cg@2015: originalTextHolder modified shownLanguages selectedKeyRow cg@2015: showMissingTranslationsOnly cg@2015: keyStringAndLanguageSelectionTableColumnDescriptionHolder cg@2015: languageShownHolders dataSetView lastExtractedClass cg@2015: lastExtractedApplicationClass stopApplicationIconVisibleHolder cg@2015: monitoredApplication originalTextModifiedHolder cg@2048: languageTextModifiedHolder languageTextAcceptHolder cg@2048: inSingleFileMode lastExtractedProject lastLanguage fm@2050: lastSelectedKey autoAcceptHolder languageEditor fm@2050: selectedColIndexHolder exampleLanguageSelectionHolder fm@2051: exampleLanguageTextHolder pastePreviousTranslationEnableHolder fm@2163: searchForSimilarTranslationEnableHolder alwaysWriteUTF8Holder fm@2327: lastNameSpace pasteOriginalEnableHolder ignoreCaseHolder fm@2327: closeSearchBar searchTextModifiedHolder searchNextText fm@2327: searchBarImageInfoLabelHolder searchPreviousText searchBoxVisible fm@2327: searchBarInfoLabelHolder searchTextHolder searchTextView cg@3286: searchBoxView translationsPanel lastPackage methodsUsingKey' cg@2032: classVariableNames:'LastExtractedClass LastExtractedApplicationClass cg@2410: LastExtractedProject LastProject' cg@2015: poolDictionaries:'' cg@2015: category:'Interface-UIPainter' cg@2015: ! cg@2015: cg@2015: Object subclass:#AccessCollectingPseudoResourcePack cg@3286: instanceVariableNames:'collectedKeys realResourcePack watchingTranslationEditor' cg@2015: classVariableNames:'' cg@2015: poolDictionaries:'' cg@2015: privateIn:InternationalLanguageTranslationEditor cg@2015: ! cg@2015: cg@2015: Collection subclass:#KeyStringsToLanguageMappings cg@2032: instanceVariableNames:'keys keyInfo perLanguageInfo perLanguageMappings languageMappings fm@2049: languages rowPerKey' cg@2015: classVariableNames:'' cg@2015: poolDictionaries:'' cg@2015: privateIn:InternationalLanguageTranslationEditor cg@2015: ! cg@2015: cg@2015: Object subclass:#LanguageMappingRow cg@2015: instanceVariableNames:'key mappings' cg@2015: classVariableNames:'' cg@2015: poolDictionaries:'' cg@2015: privateIn:InternationalLanguageTranslationEditor cg@2015: ! cg@2015: cg@2015: Visitor subclass:#UISpecVisitor cg@2015: instanceVariableNames:'translatedLabels' cg@2015: classVariableNames:'' cg@2015: poolDictionaries:'' cg@2015: privateIn:InternationalLanguageTranslationEditor cg@2015: ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor class methodsFor:'documentation'! cg@2015: cg@2015: documentation cg@2015: " cg@2015: documentation to be added. cg@2015: cg@2015: [author:] cg@2434: cg (cg@FUSI) cg@2015: cg@2015: [instance variables:] cg@2015: cg@2015: [class variables:] cg@2015: cg@2015: [see also:] cg@2015: cg@2015: " cg@2015: ! cg@2015: cg@2015: examples cg@2015: " cg@2015: Starting the application: cg@2434: [exBegin] cg@2015: InternationalLanguageTranslationEditor open cg@2015: cg@2434: [exEnd] cg@2015: cg@2015: more examples to be added: cg@2434: [exBegin] cg@2434: ... add code fragment for cg@2015: ... executable example here ... cg@2434: [exEnd] cg@2015: " cg@2015: ! cg@2015: cg@2015: history cg@2015: "Created: / 04-03-2006 / 09:07:19 / cg" cg@2015: ! ! cg@2015: cg@3286: !InternationalLanguageTranslationEditor class methodsFor:'help spec'! cg@3286: cg@3522: helpSpec cg@3286: cg@3286: cg@3522: ^ super helpSpec addPairsFrom:#( cg@3286: cg@3286: #searchBox cg@3286: 'Show a search box at the bottom to search for substrings in the string keys' cg@3286: cg@3286: #browseReferringMethods cg@3286: 'Browse methods which refer to this string' cg@3286: cg@3286: ) cg@3286: ! ! cg@3286: fm@2327: !InternationalLanguageTranslationEditor class methodsFor:'image specs'! fm@2327: fm@2327: closeSearchBarIcon fm@2327: "This resource specification was automatically generated fm@2327: by the ImageEditor of ST/X." fm@2327: fm@2327: "Do not manually edit this!! If it is corrupted, fm@2327: the ImageEditor may not be able to read the specification." fm@2327: fm@2327: " fm@2327: self closeSearchBar inspect fm@2327: ImageEditor openOnClass:self andSelector:#closeSearchBar fm@2327: Icon flushCachedIcons fm@2327: " fm@2327: fm@2327: fm@2327: fm@2327: ^Icon cg@2434: constantNamed:#'Psiware::SystemManagement class closeSearchBar' cg@2434: ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:' fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@GQ\SD1LSD1LSD1LSD1LWGP@@@@@@ fm@2327: @ATGA@HA@PDA@PDA@PHDA1T@@@@@@@@TAENG!!(VB XA?_''57QPPT@@@@@@@@E NJ^V)&X%)UTT5IV7 KE @@@@@@@A A"7Q,#&9VS%^MQ$ER$9JR$9ION''(PF0@@@@@@@A fm@2327: fm@2327: ^Icon cg@2434: constantNamed:#'Psiware::SystemManagement class restartSearchBarIcon' cg@2434: ifAbsentPut:[(Depth24Image new) width: 20; height: 20; photometric:(#rgb); bitsPerSample:(#[8 8 8]); samplesPerPixel:(3); bits:(ByteArray fromPackedString:' fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@?>SX?>''V?>;)?>O!!?>G]?>WY@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?=3\:[>''5;JF/Y-.+XY),(U. fm@2327: 6JZK?=J1?>V<>.+I@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?>?'':+:!!19]U6*-Q?]Y/?>RC?>*!!?>F_>+=939UL2Y!!L>MJT??W[@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@??[-=\^&1IEP=1/?=5$?=52?>NT?=^Q?>BP?>FG>;1]6JEO8;^H?]3I@@@@@@@@@@@@@@@@@@@@?\*95Y-)<+!!$??.F?>)17+-U8,E40Y-.09I) fm@2327: :Z1-?=I??=)8?<1.>K597;NL??K,@@@@@@@@@@@@?=#M6I>B>+:@?>2U=,]]5[IN7,^C5LB[;Y[??FP?=>O1YEW8,"%8Z:A?>N#?>._5KA$9-JW7=+FX6M+V%U3"''*T0Y>V4ZA7595T=;1"?=&D?=&L,W(93IU\:KE9=LBG9[Q9;K17?=?/? fm@2327: >^_''3*.M0YAUZO?=>G?+U(69YI3:IG?=Z@?>NU5:=19,6%@@@@@@@@OU5*2.+7;O??5-KF2;JS?=*&?>&"?=.E?>2R?=&F?>"X8I-N5)ED fm@2327: 29$&?>M:?=*F3:E&>]/A@@@@@@@@O5=.7O??5^/(?O++0I-/;LNE??2)?=&B?>^%,W)A8:14?=FX3)TR?>U/?=Q:3IAZ?=?T@@@@@@@@P5Y68_#?7.70 fm@2327: ??[1??C_:,F%6;A=>MJA?>6":,6+&G91?>+^?>+]79<$?<1\?=:C5IM[?<;F@@@@@@@@Q$1>6N_?3*??S(=,.(2Z!!#=-:^+9>P4,[P<>''46=O^ fm@2327: =+MX;Z)O?>^Q:Z]*;+Z''@@@@@@@@TD:O9^/?;/C??>???>/:?>71?>7Z;]^%0+JA7=CI8]O"0+[D8=#&?<&V79="?=2L?\E88[BG@@@@@@@@VU&M=_3?9N''? fm@2327: >/C???K??NK/??[1???#9M?B??3;(IV#/[WD;^_5@@@@;KR]<[10?=Q68[9,8,>W@@@@TU9&;/??9__9:.;/?_#?[==?79>_?=<_S9T5M[0,WN7^G* fm@2327: @@@@@@@@1Y= >=!!>9,]-3[],6]B''TEH=;O_''=O?6>O77>O''=>//?=_+?:O_?:_''?>O??SEM[/<[P6.O,@@@@@@@@8-F%1*%/9[>@?>R(7+VG_%,;\E]CW$=H fm@2327: U5AWV5%.U5);R5M:Q5M;S%-=TE]*[GI>):696M;*@@@@@@@@@@@@6\F[2Y914)9.;[VF?L"!!8[^_3J>''0KB:0;?V0,_''-3))5/II9+9FF+9> 0;7I5-#-7NO?7^#?8^/?:/G?7NK07>W3@@@@@@@@@@@@@@@@@@@@@@@@?>N;?>N;?=:9?>7T?>#X fm@2327: >^_%=N?6O???O?????_??>_??>_??>_??>_??>_??>_??__??O???O???G???A??/A? O') ; yourself); yourself] fm@2327: ! fm@2327: fm@2327: searchNextIcon fm@2327: "This resource specification was automatically generated fm@2327: by the ImageEditor of ST/X." fm@2327: fm@2327: "Do not manually edit this!! If it is corrupted, fm@2327: the ImageEditor may not be able to read the specification." fm@2327: fm@2327: " fm@2327: self searchNextIcon inspect fm@2327: ImageEditor openOnClass:self andSelector:#searchNextIcon fm@2327: Icon flushCachedIcons fm@2327: " fm@2327: fm@2327: fm@2327: fm@2327: ^Icon cg@2434: constantNamed:#'Psiware::SystemManagement class searchNextIcon' cg@2434: ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:' fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ZE)ZZ@@@@@@@@@@@@@@@ fm@2327: @@@@@@AFF XA@PXUQ @@@@@@@@@@@@@@@@@*@Q5G^WX6E0D*@@@@@@@@@@@@@@@,AVQ?\&1#W&X8@20@@@@@@@@@@@A[@U==\F-"VUQOUSLAV0@@@@@@@@@@ fm@2327: G19-D N2 H# @@@@@@@@@''GG)*Y2$9NRIDO4DQHP@@@@@@@@@@!!@EP[6U]I"UIQTL.@XP@@@@@@@@@@@ALAD-.XE]VS$(/@$0@@@@@@@@@@@@@@EDA fm@2327: FSQ!!VC@T@UD@@@@@@@@@@@@@@@@@#R,I@PDIJ84@@@@@@@@@@@@@@@@@@@@@%)^W% @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 48 54 77 55 63 87 56 64 89 57 67 90 59 67 90 64 69 89 71 74 92 72 76 96 76 81 100 80 89 118 82 90 119 83 91 120 84 92 122 86 94 123 87 96 124 89 97 126 92 104 132 97 106 136 97 110 138 97 112 138 100 102 112 101 107 130 104 118 144 105 113 135 105 124 146 107 109 118 107 116 144 110 127 148 112 126 148 113 129 148 117 119 129 118 130 156 119 123 133 125 140 174 127 131 146 127 132 148 127 146 178 130 151 181 131 132 143 133 149 185 133 152 182 134 134 138 137 140 150 138 138 142 139 156 191 141 160 195 143 164 199 143 169 198 144 157 197 144 158 197 152 173 208 153 184 209 155 167 210 156 180 208 157 179 215 157 180 211 160 162 171 160 173 216 160 174 216 160 182 214 161 173 217 161 174 217 161 176 219 161 179 220 161 180 220 163 182 222 163 184 222 164 182 222 164 184 223 166 164 161 166 189 212 166 194 211 167 190 228 167 194 229 167 200 221 169 170 174 169 195 212 169 196 232 170 181 228 170 203 221 171 171 176 171 173 182 171 193 220 173 182 232 173 192 232 173 200 234 175 206 239 175 210 240 176 188 237 178 175 168 178 175 173 178 202 234 178 206 240 179 195 238 180 205 223 180 214 243 180 216 244 181 193 242 181 195 239 181 204 223 181 212 243 182 206 242 182 209 243 184 180 173 184 211 244 184 215 245 185 198 246 185 200 244 188 215 233 188 225 249 189 226 249 190 206 250 190 219 248 191 209 249 191 217 248 191 222 248 192 188 181 192 221 249 194 190 184 195 191 184 196 226 251 196 232 251 199 196 189 202 198 191 202 226 253 203 199 193 203 229 253 203 237 252 203 237 253 204 202 196 206 202 195 206 205 204 207 203 196 208 204 197 208 205 201 212 208 200 212 208 201 212 208 202 212 209 205 213 210 202 213 212 213 214 211 206 215 212 207 216 213 206 218 215 210 220 221 223 221 219 214 222 219 215 222 220 215 230 228 225 236 235 232 243 243 244 255 255 255]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@C@@@C@@@C@G C@_8C@?CC??CC??CG??#G??#G??#G??#C??CC??CA?>C@? fm@2327: fm@2327: ^Icon cg@2434: constantNamed:#'Psiware::SystemManagement class searchPreviousIcon' cg@2434: ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:' fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%)^W% @@@@@@@@@@@@@@ fm@2327: @@@@@@BMJ0$A@P$+#P@@@@@@@@@@@@@@@@AQ@Q$4XU 0E@EQ@@@@@@@@@@@@@@ALAD-.XE]VS$(/@$0@@@@@@@@@@@BD@UA/YU4&IT%EP28A!!@@@@@@@@@@@ fm@2327: I11:Z&\)NS$"QC=ADRD@@@@@@@@@# !!H]F$N2 H# @@@@@@@H,A GE\FI"Y&Y VMS)@@X,@@@@@@@BG@XE3HIJY&Y&Y$!!,=P FG@@@@@@@@ ]M fm@2327: T5JY&Y&Y&Y%RLR4G @@@@@@@@@_G&4RC08MC@,JDC\SG0@@@@@@@@@@V0E__WA+X%%TS5T3@U,@@@@@@@@@@@@,AVQ?\&1#W&X8@20@@@@@@@@@@@@@@B(A fm@2327: GT]9]#XW@R(@@@@@@@@@@@@@@@@@Q!!(F@PDFETX@@@@@@@@@@@@@@@@@@@@@ZE)ZZ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 48 54 77 55 63 87 56 64 89 57 67 90 59 67 90 64 69 89 71 74 92 72 76 96 76 81 100 80 89 118 82 90 119 83 91 120 84 92 122 86 94 123 87 96 124 89 97 126 92 104 132 97 106 136 97 110 138 97 112 138 100 102 112 101 107 130 104 118 144 105 113 135 105 124 146 107 109 118 107 116 144 110 127 148 112 126 148 113 129 148 117 119 129 118 130 156 119 123 133 125 140 174 127 131 146 127 132 148 127 146 178 130 151 181 131 132 143 133 149 185 133 152 182 134 134 138 137 140 150 138 138 142 139 156 191 141 160 195 143 164 199 143 169 198 144 157 197 144 158 197 152 173 208 153 184 209 155 167 210 156 180 208 157 179 215 157 180 211 160 162 171 160 173 216 160 174 216 160 182 214 161 173 217 161 174 217 161 176 219 161 179 220 161 180 220 163 182 222 163 184 222 164 182 222 164 184 223 166 164 161 166 189 212 166 194 211 167 190 228 167 194 229 167 200 221 169 170 174 169 195 212 169 196 232 170 181 228 170 203 221 171 171 176 171 173 182 171 193 220 173 182 232 173 192 232 173 200 234 175 206 239 175 210 240 176 188 237 178 175 168 178 175 173 178 202 234 178 206 240 179 195 238 180 205 223 180 214 243 180 216 244 181 193 242 181 195 239 181 204 223 181 212 243 182 206 242 182 209 243 184 180 173 184 211 244 184 215 245 185 198 246 185 200 244 188 215 233 188 225 249 189 226 249 190 206 250 190 219 248 191 209 249 191 217 248 191 222 248 192 188 181 192 221 249 194 190 184 195 191 184 196 226 251 196 232 251 199 196 189 202 198 191 202 226 253 203 199 193 203 229 253 203 237 252 203 237 253 204 202 196 206 202 195 206 205 204 207 203 196 208 204 197 208 205 201 212 208 200 212 208 201 212 208 202 212 209 205 213 210 202 213 212 213 214 211 206 215 212 207 216 213 206 218 215 210 220 221 223 221 219 214 222 219 215 222 220 215 230 228 225 236 235 232 243 243 244 255 255 255]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@C@@@C@@@C@G C@_8C@?CC??CC??CG??#G??#G??#G??#C??CC??CA?>C@? fm@2327: fm@2327: ^Icon cg@2434: constantNamed:#'Psiware::SystemManagement class searchToolBarIcon' cg@2434: ifAbsentPut:[(Depth24Image new) width: 22; height: 22; photometric:(#rgb); bitsPerSample:(#[8 8 8]); samplesPerPixel:(3); bits:(ByteArray fromPackedString:' fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4][>4][>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@;>#8/L#+!!:KS!!:KS/,'',;>''9@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2];>^)WH fm@2327: NE:+KU*:J5&9NE6*_I#K4^S>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4][>RV3DLER"SWR6$K#0#;[.SGJ4L5"''UG_N4][>@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*K''\JT*,U6Z7:^S?>/C*;.3,6>C>RFF(KEZ"3-_-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@&Z''HFTF &Z7">N#:7NK?7NK?6=W>!!Y''YH4N -+3T@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%I>;FDV)#ZWU??''57NK? fm@2327: 7NK?:>_?\8WKFCN".K#T@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@1L;.A#V[O5")3=W;=/[4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7NK?-;#%ND&KC">BYV.*4=;>7.+>-==O;8@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@7NK? (J9GB1SZV>W:M3?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@5MS&++3H6M/#@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7NK?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@') ; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@C@@@C@@@C@A C@G8C@OC@_>C@_>C@_>C@_>C@?>CA? fm@2327: fm@2327: ^Icon cg@2434: constantNamed:#'Psiware::SystemManagement class warningSearchBarIcon' cg@2434: ifAbsentPut:[(Depth24Image new) width: 22; height: 19; photometric:(#rgb); bitsPerSample:(#[8 8 8]); samplesPerPixel:(3); bits:(ByteArray fromPackedString:' fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?:.+_;?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@?]SZ)5]X.6!! -HM2??''*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?>39-7*B4H&G>[N+%%MJ>\#A@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<+R?*U1&?=CN?>W^4HJ@+FY$?>+"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@?>G_)U!!^>Z^->,B><+"4?*^-%C8?;;Z+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??#1-(E;.65+?<#H fm@2327: ?=_T?=GP?::65W-=(EQF?>WQ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?\#D*VAY?;61<;"0;,C@6J^+;*"0>ZN$&CX)6(-:@@@@@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?>#+/7Q148E6?<"4K^>(M=1S8;)$ID8Y6^@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@;HNR4U%%<)&S?<^9??_(??;3REEN@P,J2<[C??K/?:R!!/C8?&R(0(T-N?>GZ@@@@ fm@2327: @@@@@@@@@@@@@@@@@@@@?<;H,31B3T9U2'')1?L3@?>3&=^7*XWE0@@=WL??_:<>33[G:@D2T%;^/,??#8??K19Y6^&R(0!!QPX#S8:;K22@@@@@@@@@@@@@@@@<*RZ+5I@*$D+*T48<[N&?>C_7,+U??3?7N''/(J.-?/+;??W5 fm@2327: ;.O!!?>G_3&]+ 0(O#B8.(U9X@@@@@@@@@@@@?W"?:*+*3@3$R\)^R ''2)^T@@@@ fm@2327: ?>K2;(ZO2DQ@-SP!!,5H/?7:)72EUBT+<,GD?>?,]GO?<#J8VM& P4P_A0^ C(:?>+''?:"+34%H13L/02("13T(13\,5$H>3S<= fm@2327: 1TMC0DQD/$IB/D@>.S4;-S,8,C(:,C 9-3X:(A4""@4R_1DT RH&/6%*?82D/S8503873C<85C<923H,23@+/RP\-"HX,"HW+"DX*"@V)10U)1(S)!!XU)AXU fm@2327: (Q0_$1XZ#1X["A(]^QPX&34>?;&).&-Z/6]Y06MU1&AR/5UG15-N0EYF1&EO0&EN/&EP.6AN.%5N.5-M.5%P/UYQ.$)I.4)L0UQW/U-\+5YX5XFA') ; mask:((Depth1Image new) width: 22; height: 19; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@C G@G0C@O0C@O8C@_8C@?CC??CC??CC??#G??#O??3O??3_??;????????????????') ; yourself); yourself] fm@2327: ! ! fm@2327: cg@2015: !InternationalLanguageTranslationEditor class methodsFor:'interface specs'! cg@2015: cg@2015: windowSpec cg@2015: "This resource specification was automatically generated cg@2015: by the UIPainter of ST/X." cg@2015: cg@2015: "Do not manually edit this!! If it is corrupted, cg@2015: the UIPainter may not be able to read the specification." cg@2015: cg@2015: " cg@2048: UIPainter new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#windowSpec cg@2048: Tools::InternationalLanguageTranslationEditor new openInterface:#windowSpec cg@2048: Tools::InternationalLanguageTranslationEditor open cg@2015: " cg@2015: cg@2015: cg@2015: cg@3594: ^ sv@3245: #(FullSpec sv@3245: name: windowSpec cg@3594: uuid: '37d7f37a-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: window: sv@3245: (WindowSpec cg@3594: label: 'InternationalLanguageTranslationEditor' cg@3594: name: 'InternationalLanguageTranslationEditor' cg@3594: uuid: '37d7f60e-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: min: (Point 10 10) cg@3594: bounds: (Rectangle 0 0 774 610) cg@3594: menu: mainMenu sv@3245: ) cg@3594: component: sv@3245: (SpecCollection cg@3594: collection: ( cg@3594: (MenuPanelSpec cg@3594: name: 'ToolBar' cg@3594: layout: (LayoutFrame 0 0 0 0 0 1 30 0) cg@3594: uuid: '37d7f820-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: menu: menuToolBar cg@3594: textDefault: true cg@3594: ) cg@3594: (VariableVerticalPanelSpec cg@3594: name: 'TranslationsVariableVerticalPanel' cg@3594: layout: (LayoutFrame 0 0 30 0 0 1 -32 1) cg@3594: uuid: '37d7f9ce-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: component: cg@3594: (SpecCollection cg@3594: collection: ( cg@3594: (DataSetSpec cg@3594: name: 'KeyStringAndLanguageSelectionTable' cg@3594: uuid: '37d7fb2c-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: model: selectedKeyRow cg@3594: menu: keyStringAndLanguageSelectionTableMenu cg@3594: hasHorizontalScrollBar: true cg@3594: hasVerticalScrollBar: true cg@3594: dataList: keyStringAndLanguageSelectionTable cg@3594: columnHolder: keyStringAndLanguageSelectionTableColumnDescriptionHolder cg@3594: beDependentOfRows: true cg@3594: columnAdaptor: yourself cg@3594: postBuildCallback: postBuildDataSet: cg@3594: ) cg@3594: (VariableVerticalPanelSpec cg@3594: name: 'VariableVerticalPanel1' cg@3594: uuid: '37d7fd48-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: component: cg@3594: (SpecCollection cg@3594: collection: ( cg@3594: (ViewSpec cg@3594: name: 'Box1' cg@3594: uuid: '37d7fe24-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: component: cg@3594: (SpecCollection cg@3594: collection: ( cg@3594: (LabelSpec cg@3594: label: 'Original String (Key):' cg@3594: name: 'Label2' cg@3594: layout: (LayoutFrame 0 0 -2 0 0 1 28 0) cg@3594: uuid: '37d7fee2-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: translateLabel: true cg@3594: adjust: left cg@3594: ) cg@3594: (TextEditorSpec cg@3594: name: 'OriginalText' cg@3594: layout: (LayoutFrame 0 0 27 0 0 1 -2 1) cg@3594: uuid: '37d8002c-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: model: originalTextHolder cg@3594: hasHorizontalScrollBar: true cg@3594: hasVerticalScrollBar: true cg@3594: modifiedChannel: originalTextModifiedHolder cg@3594: acceptCallBack: languageTextAccepted cg@3594: hasKeyboardFocusInitially: false cg@3594: ) cg@3594: ) cg@3594: cg@3594: ) cg@3594: ) cg@3594: (ViewSpec cg@3594: name: 'Box3' cg@3594: uuid: '37d801bc-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: component: cg@3594: (SpecCollection cg@3594: collection: ( cg@3594: (LabelSpec cg@3594: label: 'Select Another Language as example:' cg@3594: name: 'Label3' cg@3594: layout: (LayoutFrame 0 0 -6 0 0 1 24 0) cg@3594: uuid: '37d80270-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: translateLabel: true cg@3594: adjust: left cg@3594: ) cg@3594: (ComboBoxSpec cg@3594: name: 'ComboBox1' cg@3594: layout: (LayoutFrame 281 0 -2 0 406 0 18 0) cg@3594: uuid: '37d80360-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: model: exampleLanguageSelectionHolder cg@3594: immediateAccept: false cg@3594: acceptOnLeave: true cg@3594: acceptOnLostFocus: true cg@3594: acceptOnPointerLeave: false cg@3594: comboList: shownLanguages cg@3594: useIndex: false cg@3594: ) cg@3594: (TextEditorSpec cg@3594: name: 'ExampleLanguageText' cg@3594: layout: (LayoutFrame 0 0 30 0 0 1 0 1) cg@3594: uuid: '37d805cc-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: model: exampleLanguageTextHolder cg@3594: hasHorizontalScrollBar: true cg@3594: hasVerticalScrollBar: true cg@3594: isReadOnly: true cg@3594: hasKeyboardFocusInitially: false cg@3594: ) cg@3594: ) cg@3594: cg@3594: ) cg@3594: ) cg@3594: (ViewSpec cg@3594: name: 'Box2' cg@3594: uuid: '37d8070c-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: component: cg@3594: (SpecCollection cg@3594: collection: ( cg@3594: (LabelSpec cg@3594: label: 'Translated String:' cg@3594: name: 'Label1' cg@3594: layout: (LayoutFrame 0 0 0 0 0 1 30 0) cg@3594: uuid: '37d807ca-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: translateLabel: true cg@3594: adjust: left cg@3594: ) cg@3594: (TextEditorSpec cg@3594: name: 'LanguageText' cg@3594: layout: (LayoutFrame 0 0 30 0 0 1 0 1) cg@3594: uuid: '37d808ba-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: model: languageTextHolder cg@3594: hasHorizontalScrollBar: true cg@3594: hasVerticalScrollBar: true cg@3594: acceptChannel: languageTextAcceptHolder cg@3594: modifiedChannel: languageTextModifiedHolder cg@3594: acceptCallBack: languageTextAccepted cg@3594: hasKeyboardFocusInitially: false cg@3594: postBuildCallback: languageEditorBuilt: cg@3594: ) cg@3594: (ActionButtonSpec cg@3594: label: 'Paste Original' cg@3594: name: 'Button1' cg@3594: layout: (LayoutFrame -186 0.83085250338295003 0 0 -64 0.83085250338295003 27 0) cg@3594: uuid: '37d809fa-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: translateLabel: true cg@3594: model: pasteOriginalInLanguageText cg@3594: enableChannel: pasteOriginalEnableHolder cg@3594: disabledLogo: 'Paste Original' cg@3594: ) cg@3594: (ActionButtonSpec cg@3594: label: 'Paste Previous' cg@3594: name: 'pastePreviousTranslation' cg@3594: layout: (LayoutFrame -42 0.83085250338295003 0 0 118 0.83085250338295003 27 0) cg@3594: uuid: '37d80b80-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: translateLabel: true cg@3594: model: pastePreviousTranslationInLanguageText cg@3594: enableChannel: pastePreviousTranslationEnableHolder cg@3594: disabledLogo: 'Paste Previous' cg@3594: ) cg@3594: ) cg@3594: cg@3594: ) cg@3594: ) cg@3594: ) cg@3594: cg@3594: ) cg@3594: handles: (Any 0.33000000000000002 0.67000000000000004 1.0) cg@3594: ) cg@3594: ) cg@3594: cg@3594: ) cg@3594: handles: (Any 0.5 1.0) cg@3594: postBuildCallback: postBuildTranslationsPanel: cg@3594: ) cg@3594: (ViewSpec cg@3594: name: 'SearchBox' cg@3594: layout: (LayoutFrame 0 0 -32 1 0 1 0 1) cg@3594: uuid: '37d80cf2-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: level: -1 cg@3594: visibilityChannel: searchBoxVisible cg@3594: component: cg@3594: (SpecCollection cg@3594: collection: ( cg@3594: (ActionButtonSpec cg@3594: label: 'closeSearchBarIcon' cg@3594: name: 'closeSearchBarButton' cg@3594: layout: (LayoutFrame 4 0 5 0 25 0 26 0) cg@3594: uuid: '37d80dc4-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: hasCharacterOrientedLabel: false cg@3594: translateLabel: true cg@3594: model: closeSearchBar cg@3594: ) cg@3594: (LabelSpec cg@3594: label: 'Search:' cg@3594: name: 'SearchLabel' cg@3594: layout: (LayoutFrame 30 0 5 0 100 0 27 0) cg@3594: uuid: '37d80ef0-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: translateLabel: true cg@3594: adjust: right cg@3594: ) cg@3594: (InputFieldSpec cg@3594: name: 'SearchEntryField' cg@3594: layout: (LayoutFrame 100 0 5 0 257 0 27 0) cg@3594: uuid: '37d80fd6-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: model: searchTextHolder cg@3594: immediateAccept: true cg@3594: acceptOnReturn: true cg@3594: acceptOnTab: true cg@3594: acceptOnLostFocus: true cg@3594: modifiedChannel: searchTextModifiedHolder cg@3594: acceptOnPointerLeave: false cg@3594: postBuildCallback: postBuildSearchTextView: cg@3594: ) cg@3594: (ActionButtonSpec cg@3594: label: 'searchNextIcon' cg@3594: name: 'SearchNextButton' cg@3594: layout: (LayoutFrame 264 0 5 0 285 0 26 0) cg@3594: uuid: '37d8117a-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: hasCharacterOrientedLabel: false cg@3594: translateLabel: true cg@3594: model: searchNextText cg@3594: ) cg@3594: (ActionButtonSpec cg@3594: label: 'searchPreviousIcon' cg@3594: name: 'searchPreviousButton' cg@3594: layout: (LayoutFrame 292 0 5 0 313 0 26 0) cg@3594: uuid: '37d812b0-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: hasCharacterOrientedLabel: false cg@3594: translateLabel: true cg@3594: model: searchPreviousText cg@3594: ) cg@3594: (CheckBoxSpec cg@3594: label: 'Ignore case' cg@3594: name: 'IgnoreCaseCheckBox' cg@3594: layout: (LayoutFrame 322 0 5 0 518 0 27 0) cg@3594: uuid: '37d813d2-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: model: ignoreCaseHolder cg@3594: translateLabel: true cg@3594: ) cg@3594: (LabelSpec cg@3594: label: 'SearchBarImageInfoLabel' cg@3594: name: 'SearchBarImageInfoLabel' cg@3594: layout: (LayoutFrame 524 0 5 0 548 0 27 0) cg@3594: uuid: '37d81512-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: hasCharacterOrientedLabel: false cg@3594: translateLabel: true cg@3594: labelChannel: searchBarImageInfoLabelHolder cg@3594: ) cg@3594: (LabelSpec cg@3594: label: 'SearchBarInfoLabel' cg@3594: name: 'SearchBarInfoLabel' cg@3594: layout: (LayoutFrame 551 0 5 0 829 0 27 0) cg@3594: uuid: '37d8160c-b8d0-11e8-aeef-b8f6b1108e05' cg@3594: translateLabel: true cg@3594: labelChannel: searchBarInfoLabelHolder cg@3594: adjust: left cg@3594: ) cg@3594: ) cg@3594: cg@3594: ) cg@3594: postBuildCallback: postBuildSearchBoxView: cg@3594: ) cg@3594: ) cg@3594: sv@3245: ) sv@3245: ) cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor class methodsFor:'menu specs'! cg@2015: fm@2163: keyStringAndLanguageSelectionTableMenu fm@2163: "This resource specification was automatically generated fm@2163: by the MenuEditor of ST/X." fm@2163: fm@2163: "Do not manually edit this!! If it is corrupted, fm@2163: the MenuEditor may not be able to read the specification." fm@2163: mawalch@3448: fm@2163: " fm@2163: MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#keyStringAndLanguageSelectionTableMenu fm@2163: (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor keyStringAndLanguageSelectionTableMenu)) startUp fm@2163: " fm@2163: fm@2163: fm@2163: cg@3522: ^ fm@2163: #(Menu cg@3522: ( cg@3522: (MenuItem cg@3522: label: 'Browse Methods Containing this String' cg@3522: itemValue: browseReferringMethods cg@3522: ) cg@3522: (MenuItem cg@3522: label: '-' cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Set Current NameSpace...' cg@3522: itemValue: changeLastNameSpace cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Search String in Current NameSpace' cg@3522: itemValue: searchStringInLastNameSpace cg@3522: ) cg@3522: (MenuItem cg@3522: label: '-' cg@3522: isVisible: false cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Set Current Package...' cg@3522: itemValue: changeLastPackage cg@3522: isVisible: false cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Search String in Current Package' cg@3522: itemValue: searchStringInLastPackage cg@3522: isVisible: false cg@3522: ) cg@3522: ) cg@3522: nil cg@3522: nil fm@2163: ) fm@2163: ! fm@2163: cg@2015: mainMenu cg@2015: "This resource specification was automatically generated cg@2015: by the MenuEditor of ST/X." cg@2015: cg@2015: "Do not manually edit this!! If it is corrupted, cg@2015: the MenuEditor may not be able to read the specification." cg@2015: jan@3189: cg@2015: " fm@2050: MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#mainMenu fm@2050: (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor mainMenu)) startUp cg@2015: " cg@2015: cg@2015: cg@2015: cg@3599: ^ cg@2015: #(Menu cg@3599: ( cg@3599: (MenuItem cg@3599: label: 'File' cg@3599: submenu: cg@3599: (Menu cg@3599: ( cg@3599: (MenuItem cg@3599: label: 'New' cg@3599: itemValue: menuNew cg@3599: ) cg@3599: (MenuItem cg@3599: label: '-' cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Open Resources for Package or Project...' cg@3599: itemValue: menuOpenByPackage cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Open Resource File...' cg@3599: itemValue: menuOpen cg@3599: ) cg@3599: (MenuItem cg@3599: label: '-' cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Save All Resource Files' cg@3599: itemValue: menuSaveAll cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Save Resource File' cg@3599: itemValue: menuSave cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Save Resource File As...' cg@3599: itemValue: menuSaveAs cg@3599: ) cg@3599: (MenuItem cg@3599: label: '-' cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Import existing translations from file...' cg@3599: itemValue: importExistingTranslationsFromFile cg@3599: ) cg@3599: (MenuItem cg@3599: label: '-' cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Set Current NameSpace' cg@3599: itemValue: changeLastNameSpace cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Set Current Package' cg@3599: itemValue: changeLastPackage cg@3599: isVisible: false cg@3599: ) cg@3599: (MenuItem cg@3599: label: '-' cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Exit' cg@3599: itemValue: closeRequest cg@3599: ) cg@3599: ) cg@3599: nil cg@3599: nil cg@3599: ) cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'View' cg@3599: submenu: cg@3599: (Menu cg@3599: ( cg@3599: (MenuItem cg@3599: label: 'Show Missing Translations Only' cg@3599: indication: showMissingTranslationsOnly cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Show Search Box' cg@3599: indication: searchBoxVisible cg@3599: ) cg@3599: (MenuItem cg@3599: label: '-' cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Shown Languages' cg@3599: submenuChannel: shownLanguagesMenu cg@3599: ) cg@3599: ) cg@3599: nil cg@3599: nil cg@3599: ) cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Languages' cg@3599: submenu: cg@3599: (Menu cg@3599: ( cg@3599: (MenuItem cg@3599: label: 'Add Language...' cg@3599: itemValue: addLanguage cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Remove Language...' cg@3599: itemValue: removeLanguage cg@3599: ) cg@3599: (MenuItem cg@3599: label: '-' cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Merge...' cg@3599: itemValue: mergeLanguages cg@3599: ) cg@3599: ) cg@3599: nil cg@3599: nil cg@3599: ) cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Translations' cg@3599: submenuChannel: translationsMenuSpec cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Preferences' cg@3599: submenu: cg@3599: (Menu cg@3599: ( cg@3599: (MenuItem cg@3599: label: 'Auto Accept Changes' cg@3599: indication: autoAcceptHolder cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Search For Similar Translations' cg@3599: indication: searchForSimilarTranslationEnableHolder cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Always Write UTF8' cg@3599: indication: alwaysWriteUTF8Holder cg@3599: ) cg@3599: ) cg@3599: nil cg@3599: nil cg@3599: ) cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'Help' cg@3599: startGroup: right cg@3599: submenu: cg@3599: (Menu cg@3599: ( cg@3599: (MenuItem cg@3599: label: 'Documentation' cg@3599: itemValue: openDocumentation cg@3599: ) cg@3599: (MenuItem cg@3599: label: '-' cg@3599: ) cg@3599: (MenuItem cg@3599: label: 'About this Application...' cg@3599: itemValue: openAboutThisApplication cg@3599: ) cg@3599: ) cg@3599: nil cg@3599: nil cg@3599: ) cg@3599: ) cg@3599: ) cg@3599: nil cg@3599: nil cg@2015: ) cg@2015: ! cg@2015: fm@2051: menuItemsEditLanguage fm@2051: "This resource specification was automatically generated fm@2051: by the MenuEditor of ST/X." fm@2051: fm@2051: "Do not manually edit this!! If it is corrupted, fm@2051: the MenuEditor may not be able to read the specification." fm@2051: fm@2051: " fm@2051: MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#menu fm@2051: (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor menu)) startUp fm@2051: " fm@2051: fm@2051: fm@2051: cg@2434: ^ fm@2051: #(Menu cg@2434: ( cg@2434: (MenuItem cg@2434: enabled: pastePreviousTranslationEnableHolder cg@2434: label: 'Paste Previous Translation' cg@2434: itemValue: pastePreviousTranslationInLanguageText cg@2434: nameKey: pastePreviousTranslationInLanguageText cg@2434: translateLabel: true cg@2434: ) cg@2434: ) cg@2434: nil cg@2434: nil fm@2051: ) fm@2051: ! fm@2051: cg@2015: menuToolBar cg@2015: "This resource specification was automatically generated cg@2015: by the MenuEditor of ST/X." cg@2015: cg@2015: "Do not manually edit this!! If it is corrupted, cg@2015: the MenuEditor may not be able to read the specification." cg@2015: cg@2880: cg@2015: " fm@2051: MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#menuToolBar fm@2051: (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor menuToolBar)) startUp cg@2015: " cg@2015: cg@2015: cg@2015: cg@3522: ^ cg@2015: #(Menu cg@3522: ( cg@3522: (MenuItem cg@3522: label: 'Save' cg@3522: itemValue: menuSave cg@3522: isButton: true cg@3522: labelImage: (ResourceRetriever XPToolbarIconLibrary saveImageIcon) cg@3522: ) cg@3522: (MenuItem cg@3522: label: '-' cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Add Translation' cg@3522: itemValue: addTranslation cg@3522: isButton: true cg@3522: labelImage: (ResourceRetriever XPToolbarIconLibrary newRowIcon) cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Remove Translation' cg@3522: itemValue: removeTranslation cg@3522: isButton: true cg@3522: labelImage: (ResourceRetriever XPToolbarIconLibrary removeRowIcon) cg@3522: ) cg@3522: (MenuItem cg@3522: label: '-' cg@3522: ) cg@3522: (MenuItem cg@3522: activeHelpKey: browseReferringMethods cg@3522: label: 'Browse' cg@3522: itemValue: browseReferringMethods cg@3522: labelImage: (ResourceRetriever ToolbarIconLibrary systemBrowserIcon) cg@3522: ) cg@3522: (MenuItem cg@3522: label: '' cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Stop Application' cg@3522: itemValue: stopApplication cg@3522: isButton: true cg@3522: isVisible: stopApplicationIconVisibleHolder cg@3522: labelImage: (ResourceRetriever XPToolbarIconLibrary stop16x16Icon) cg@3522: ) cg@3522: (MenuItem cg@3522: activeHelpKey: searchBox cg@3522: label: 'Search' cg@3522: isButton: true cg@3522: startGroup: right cg@3522: hideMenuOnActivated: false cg@3522: indication: searchBoxVisible cg@3522: shortcutKey: Ctrlf cg@3522: labelImage: (ResourceRetriever #'Tools::InternationalLanguageTranslationEditor' searchToolBarIcon) cg@3522: ) cg@3522: ) cg@3522: nil cg@3522: nil cg@2015: ) jan@3189: ! jan@3189: jan@3189: translationsMenuSpec jan@3189: "This resource specification was automatically generated jan@3189: by the MenuEditor of ST/X." jan@3189: jan@3189: "Do not manually edit this!! If it is corrupted, jan@3189: the MenuEditor may not be able to read the specification." jan@3189: jan@3189: jan@3189: " jan@3189: MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#translationsMenuSpec jan@3189: (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor translationsMenuSpec)) startUp jan@3189: " jan@3189: jan@3189: jan@3189: cg@3522: ^ jan@3189: #(Menu cg@3522: ( cg@3522: (MenuItem cg@3522: label: 'Add Translation...' cg@3522: itemValue: addTranslation cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Remove Translation...' cg@3522: itemValue: removeTranslation cg@3522: ) cg@3522: (MenuItem cg@3522: label: '-' cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Extract from Package...' cg@3522: itemValue: extractTranslationsFromProject cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Extract from Class...' cg@3522: itemValue: extractTranslationsFromClass cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Extract from NameSpace...' cg@3522: itemValue: extractTranslationsFromNameSpace cg@3522: ) cg@3522: (MenuItem cg@3522: label: '-' cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Run Application and Collect Translations...' cg@3522: itemValue: runApplicationAndCollectTranslations cg@3522: ) cg@3522: (MenuItem cg@3522: label: '-' cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Generate Missing Translations' cg@3522: itemValue: generateMissingTranslations cg@3522: ) cg@3522: (MenuItem cg@3522: label: 'Generate Missing Translations Slice' cg@3522: submenuChannel: menuSliceTranslateGenerate cg@3522: isMenuSlice: true cg@3522: ) cg@3522: ) cg@3522: nil cg@3522: nil jan@3189: ) cg@2015: ! ! cg@2015: cg@2433: !InternationalLanguageTranslationEditor class methodsFor:'startup'! cg@2433: cg@2433: openOnFile:aFilename cg@2433: |fn| cg@2433: cg@2433: fn := aFilename asFilename. cg@2433: cg@3077: ^ self new cg@3522: allButOpen; cg@3522: readResourceFile:fn asLanguage:fn withoutSuffix baseName; cg@3522: openWindow; cg@3522: yourself. cg@3077: ! cg@3077: cg@3077: openOnPackage:aPackageId cg@3077: ^ self new cg@3522: allButOpen; cg@3522: readResourceFileForPackage:aPackageId; cg@3522: openWindow; cg@3522: yourself. cg@2433: ! ! cg@2433: cg@2047: !InternationalLanguageTranslationEditor class methodsFor:'tableColumns specs'! cg@2047: cg@2047: keyTableColumn cg@2047: "This resource specification was automatically generated cg@2047: by the DataSetBuilder of ST/X." cg@2047: cg@2047: "Do not manually edit this!! If it is corrupted, cg@2047: the DataSetBuilder may not be able to read the specification." cg@2047: cg@2047: " cg@2047: DataSetBuilder new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#keyTableColumn cg@2047: " cg@2047: cg@2047: cg@2047: cg@2047: ^#( cg@2047: (DataSetColumnSpec cg@2434: label: 'Key' cg@2434: labelButtonType: Button cg@2434: minWidth: 50 cg@2434: model: keyStringInRow: cg@2047: ) cg@2047: ) cg@2047: ! cg@2047: cg@2047: languageTableColumn cg@2047: "This resource specification was automatically generated cg@2047: by the DataSetBuilder of ST/X." cg@2047: cg@2047: "Do not manually edit this!! If it is corrupted, cg@2047: the DataSetBuilder may not be able to read the specification." cg@2047: cg@2047: " fm@2049: DataSetBuilder new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#languageTableColumn cg@2047: " cg@2047: cg@2047: cg@2047: cg@2047: ^#( fm@2049: (DataSetColumnSpec cg@2434: label: lang cg@2434: labelButtonType: Button cg@2434: minWidth: 50 cg@2434: editorType: None cg@2434: model: columnInRow:at: cg@2434: backgroundSelector: getBackgroundForRow:rowNr:col: fm@2049: ) fm@2049: ) fm@2049: ! ! fm@2049: fm@2049: !InternationalLanguageTranslationEditor methodsFor:'accessing'! cg@2047: cg@2434: currentSelectionIndex fm@2327: fm@2327: ^ self selectedKeyRow value fm@2327: fm@2327: "Created: / 16-06-2007 / 09:04:11 / Administrador" fm@2327: "Modified: / 19-06-2007 / 17:28:38 / Administrador" fm@2327: ! fm@2327: fm@2327: exists: anObject fm@2327: fm@2327: ^self objectsList includes: anObject fm@2327: fm@2327: "Created: / 19-06-2007 / 16:42:22 / Administrador" fm@2327: ! fm@2327: fm@2327: indexOf: anObject fm@2327: fm@2327: ^self objectsList indexOf: anObject fm@2327: fm@2327: "Created: / 19-06-2007 / 16:39:44 / Administrador" fm@2327: ! fm@2327: fm@2049: newLanguageText fm@2049: "/ languageEditor accept sv@3245: ^self languageTextHolder value isEmptyOrNil cg@3522: ifTrue:[''] cg@3522: ifFalse:[self languageTextHolder value asCollectionOfLines first.] fm@2050: ! fm@2050: fm@2327: objectsList fm@2327: cg@2434: ^ keyStringsToLanguageMappings fm@2327: ! fm@2327: fm@2327: selectListIndex: rowIndex fm@2327: "/ |selection list| fm@2327: "/ list := self objectsList. fm@2327: "/ list isEmpty ifTrue:[^self]. fm@2327: "/ selection := list at:rowIndex ifAbsent:nil. fm@2327: self selectedKeyRow value: rowIndex. fm@2327: fm@2327: "Created: / 16-06-2007 / 09:06:46 / Administrador" fm@2327: "Modified: / 22-06-2007 / 13:45:54 / Administrador" fm@2327: ! fm@2327: cg@2434: selectedKey fm@2050: "Returns the current selected key if there is one row seleted. Otherwise, returns nil" fm@2050: |rowSelectionIndex | fm@2050: fm@2163: keyStringsToLanguageMappings isNil ifTrue:[^nil]. fm@2163: self selectedKeyRow value isNil ifTrue:[^nil]. fm@2050: rowSelectionIndex := self selectedKeyRow value. fm@2050: rowSelectionIndex == 0 ifTrue:[^nil]. fm@2050: ^ keyStringsToLanguageMappings keyAt:rowSelectionIndex. fm@2327: ! fm@2327: fm@2327: tableView fm@2327: fm@2327: ^dataSetView scrolledView fm@2327: fm@2327: "Created: / 15-06-2007 / 18:59:51 / Administrador" cg@2047: ! ! cg@2047: cg@3599: !InternationalLanguageTranslationEditor methodsFor:'additionalFunctionalities'! fm@2051: fm@2051: searchForSimilarTranslation fm@2163: "Looks for a quite similar translation for the key and display a dialog with available options" fm@2327: |similarTranslationsAssociations selectedTranslation key| fm@2051: cg@2434: self shouldSearchForSimilarTranslation ifFalse:[^self]. fm@2051: fm@2327: key := self selectedKey. fm@2327: key isNil ifTrue:[^ self.]. fm@2327: similarTranslationsAssociations := keyStringsToLanguageMappings searchForSimilarTranslation: key in: self currentLanguage. cg@2434: similarTranslationsAssociations isEmpty ifTrue:[^self]. fm@2051: fm@2163: similarTranslationsAssociations := similarTranslationsAssociations associations inject: OrderedCollection new into:[:collection :association | cg@2434: collection detect:[:selectedAssociation | cg@2434: selectedAssociation value sameAs: association value] ifNone:[collection add: association]. cg@2434: collection]. cg@2434: selectedTranslation := Dialog cg@3594: choose:'Choose one if you consider it´s usefull to translate: cg@2434: ', cg@2434: '<', key, '> ', (self currentExampleLanguageText ifNil:['']) cg@2434: fromList: (similarTranslationsAssociations collect:[:each | '<', each key, '> ', each value]) cg@2434: values: (similarTranslationsAssociations collect:[:each | each value]) cg@2434: lines:10 cg@2434: cancel: nil. cg@2434: cg@2434: selectedTranslation notNil ifTrue:[self languageTextHolderValue: selectedTranslation]. fm@2051: ! ! fm@2051: cg@2015: !InternationalLanguageTranslationEditor methodsFor:'aspects'! cg@2015: fm@2053: alwaysWriteUTF8Holder cg@2434: alwaysWriteUTF8Holder isNil ifTrue:[alwaysWriteUTF8Holder := true asValue]. fm@2053: ^ alwaysWriteUTF8Holder fm@2053: ! fm@2053: fm@2050: autoAcceptHolder cg@2434: autoAcceptHolder isNil ifTrue:[autoAcceptHolder := true asValue]. fm@2050: ^ autoAcceptHolder fm@2050: ! fm@2050: fm@2050: exampleLanguageSelectionHolder fm@2050: exampleLanguageSelectionHolder isNil ifTrue:[ cg@2434: exampleLanguageSelectionHolder := self exampleLanguageByDefault asValue. cg@2434: exampleLanguageSelectionHolder addDependent:self. cg@2434: ]. fm@2050: ^ exampleLanguageSelectionHolder fm@2050: ! fm@2050: fm@2050: exampleLanguageTextHolder fm@2050: exampleLanguageTextHolder isNil ifTrue:[ cg@2434: exampleLanguageTextHolder := '' asValue. fm@2050: ]. fm@2050: ^ exampleLanguageTextHolder. fm@2050: ! fm@2050: fm@2327: ignoreCaseHolder fm@2327: fm@2327: ignoreCaseHolder isNil ifTrue:[ cg@2434: ignoreCaseHolder := false asValue. fm@2327: "/ if your app needs to be notified of changes, uncomment one of the lines below: fm@2327: "/ ignoreCaseHolder addDependent:self. cg@2434: ignoreCaseHolder onChangeSend:#ignoreCaseHolderChanged to:self. fm@2327: fm@2327: ]. fm@2327: ^ ignoreCaseHolder. fm@2327: fm@2327: "Created: / 16-06-2007 / 06:45:04 / Administrador" fm@2327: "Modified: / 16-06-2007 / 19:32:15 / Administrador" fm@2327: ! fm@2327: cg@2015: keyStringAndLanguageSelectionTable cg@2015: keyStringsToLanguageMappings isNil ifTrue:[ cg@2434: keyStringsToLanguageMappings := KeyStringsToLanguageMappings new. cg@2015: ]. cg@2015: ^ keyStringsToLanguageMappings. cg@2015: ! cg@2015: cg@2015: keyStringAndLanguageSelectionTableColumnDescriptionHolder cg@2015: keyStringAndLanguageSelectionTableColumnDescriptionHolder isNil ifTrue:[ cg@2434: keyStringAndLanguageSelectionTableColumnDescriptionHolder := ValueHolder new. cg@2434: keyStringAndLanguageSelectionTableColumnDescriptionHolder value:(self keyStringAndLanguageSelectionTableColumnDescription). cg@2015: ]. cg@2015: ^ keyStringAndLanguageSelectionTableColumnDescriptionHolder. cg@2015: ! cg@2015: cg@2015: languageAtCol:colNr cg@2015: ^ shownLanguages at:colNr-1. cg@2015: ! cg@2015: cg@2015: languageShownHolderFor:lang cg@2015: |holder| cg@2015: cg@2015: languageShownHolders isNil ifTrue:[ cg@2434: languageShownHolders := Dictionary new cg@2015: ]. cg@2434: holder := languageShownHolders cg@2434: at:lang cg@2434: ifAbsentPut:[ cg@2434: |h| cg@2434: cg@2434: h := true asValue. cg@2434: h onChangeEvaluate:[ cg@2434: h value ifTrue:[ cg@2434: self enableLanguageDisplayFor:lang cg@2434: ] ifFalse:[ cg@2434: self disableLanguageDisplayFor:lang cg@2434: ]. cg@2434: ]. cg@2434: h cg@2434: ]. cg@2015: ^ holder. cg@2015: ! cg@2015: cg@2048: languageTextAcceptHolder cg@2048: languageTextAcceptHolder isNil ifTrue:[ cg@2434: languageTextAcceptHolder := false asValue. cg@2048: ]. cg@2048: ^ languageTextAcceptHolder. cg@2048: ! cg@2048: cg@2015: languageTextHolder cg@2015: languageTextHolder isNil ifTrue:[ cg@2434: languageTextHolder := '' asValue. cg@2015: ]. cg@2015: ^ languageTextHolder. cg@2015: ! cg@2015: cg@2015: languageTextModifiedHolder cg@2015: languageTextModifiedHolder isNil ifTrue:[ cg@2434: languageTextModifiedHolder := false asValue. cg@2015: ]. cg@2015: ^ languageTextModifiedHolder. cg@2015: ! cg@2015: cg@2015: languagesList cg@2015: languagesList isNil ifTrue:[ cg@2434: languagesList := List withAll:(self keyStringAndLanguageSelectionTable languages). cg@2015: ]. cg@2015: ^ languagesList. cg@2015: ! cg@2015: cg@2015: originalTextHolder cg@2015: originalTextHolder isNil ifTrue:[ cg@2434: originalTextHolder := '' asValue. cg@2015: ]. cg@2015: ^ originalTextHolder. cg@2015: ! cg@2015: cg@2015: originalTextModifiedHolder cg@2015: originalTextModifiedHolder isNil ifTrue:[ cg@2434: originalTextModifiedHolder := false asValue. cg@2015: ]. cg@2015: ^ originalTextModifiedHolder. cg@2015: ! cg@2015: fm@2323: pasteOriginalEnableHolder cg@2434: pasteOriginalEnableHolder isNil ifTrue:[pasteOriginalEnableHolder := false asValue]. fm@2323: ^ pasteOriginalEnableHolder fm@2323: ! fm@2323: fm@2051: pastePreviousTranslationEnableHolder cg@2434: pastePreviousTranslationEnableHolder isNil ifTrue:[pastePreviousTranslationEnableHolder := false asValue]. fm@2051: ^ pastePreviousTranslationEnableHolder fm@2051: ! fm@2051: fm@2327: searchBarImageInfoLabelHolder fm@2327: fm@2327: searchBarImageInfoLabelHolder isNil ifTrue:[ cg@2434: searchBarImageInfoLabelHolder := nil asValue . fm@2327: ]. fm@2327: ^ searchBarImageInfoLabelHolder. fm@2327: fm@2327: "Created: / 16-06-2007 / 10:06:28 / Administrador" fm@2327: ! fm@2327: fm@2327: searchBarInfoLabelHolder fm@2327: fm@2327: searchBarInfoLabelHolder isNil ifTrue:[ cg@2434: searchBarInfoLabelHolder := '' asValue . fm@2327: ]. fm@2327: ^ searchBarInfoLabelHolder. fm@2327: fm@2327: "Created: / 16-06-2007 / 06:20:49 / Administrador" fm@2327: ! fm@2327: fm@2327: searchBoxVisible fm@2327: fm@2327: searchBoxVisible isNil ifTrue:[ cg@3522: searchBoxVisible := false asValue. cg@3522: searchBoxVisible cg@3522: onChangeEvaluate:[ cg@3522: self updateToolVisibility. cg@3522: searchBoxVisible value ifTrue:[ cg@3522: searchTextView takeFocus. cg@3522: ]. cg@3522: ]. fm@2327: ]. fm@2327: ^ searchBoxVisible. fm@2327: fm@2327: "Created: / 15-06-2007 / 18:15:52 / Administrador" fm@2327: ! fm@2327: fm@2051: searchForSimilarTranslationEnableHolder cg@2434: searchForSimilarTranslationEnableHolder isNil cg@2434: ifTrue:[searchForSimilarTranslationEnableHolder := true asValue]. fm@2051: ^ searchForSimilarTranslationEnableHolder fm@2051: ! fm@2051: fm@2327: searchTextHolder fm@2327: fm@2327: searchTextHolder isNil ifTrue:[ cg@2434: searchTextHolder := ValueHolder new. fm@2327: "/ if your app needs to be notified of changes, uncomment one of the lines below: fm@2327: "/ userSelectedHolder addDependent:self. fm@2327: "/ userSelectedHolder onChangeSend:#searchTextHolderChanged to:self. fm@2327: ]. fm@2327: ^ searchTextHolder. fm@2327: fm@2327: "Created: / 15-06-2007 / 18:06:08 / Administrador" fm@2327: ! fm@2327: fm@2327: searchTextModifiedHolder fm@2327: fm@2327: searchTextModifiedHolder isNil ifTrue:[ cg@2434: searchTextModifiedHolder := false asValue . fm@2327: "/ if your app needs to be notified of changes, uncomment one of the lines below: fm@2327: "/ searchTextModifiedHolder addDependent:self. fm@2327: searchTextModifiedHolder onChangeSend:#searchTextModifiedHolderChanged to:self. fm@2327: ]. fm@2327: ^ searchTextModifiedHolder. fm@2327: fm@2327: "Created: / 15-06-2007 / 18:07:19 / Administrador" fm@2327: ! fm@2327: cg@2015: selectedKeyRow cg@2015: selectedKeyRow isNil ifTrue:[ cg@2434: selectedKeyRow := ValueHolder new. cg@2434: selectedKeyRow onChangeSend:#selectionChanged to:self. cg@2015: ]. cg@2015: ^ selectedKeyRow. cg@2015: ! cg@2015: cg@2015: showMissingTranslationsOnly cg@2015: showMissingTranslationsOnly isNil ifTrue:[ cg@2434: showMissingTranslationsOnly := false asValue. cg@2434: showMissingTranslationsOnly onChangeSend:#showMissingTranslationsOnlyChanged to:self. cg@2015: ]. cg@2015: ^ showMissingTranslationsOnly. cg@2015: ! cg@2015: cg@2015: shownLanguages cg@2015: shownLanguages isNil ifTrue:[ cg@2434: shownLanguages := List new. cg@2434: shownLanguages addAll:(self languagesList). cg@2434: shownLanguages onChangeSend:#shownLanguagesChanged to:self. cg@2015: ]. cg@2015: ^ shownLanguages. cg@2015: ! cg@2015: cg@2015: stopApplicationIconVisibleHolder cg@2015: stopApplicationIconVisibleHolder isNil ifTrue:[ cg@2434: stopApplicationIconVisibleHolder := false asValue. cg@2015: ]. cg@2015: ^ stopApplicationIconVisibleHolder. cg@2015: ! ! cg@2015: cg@2048: !InternationalLanguageTranslationEditor methodsFor:'change & update'! cg@2048: fm@2051: languageTextHolderValue: aString fm@2051: fm@2163: self languageTextHolder value: aString. fm@2163: self languageTextModifiedHolder value:true. fm@2051: ! fm@2051: cg@2048: update:something with:aParameter from:changedObject cg@3594: languageEditor modified ifTrue:[ cg@3594: languageEditor accept cg@3594: ]. cg@2048: changedObject == shownLanguages ifTrue:[ cg@3594: self shownLanguagesChanged. cg@3594: ^ self. cg@2048: ]. fm@2049: changedObject == languageTextAcceptHolder ifTrue:[ cg@3594: self updateLanguageTextModification. cg@3594: ^ self. fm@2049: ]. fm@2050: changedObject == exampleLanguageSelectionHolder ifTrue:[ cg@3594: self updateExampleLanguageText. cg@3594: ^ self. cg@2434: ]. fm@2051: changedObject == showMissingTranslationsOnly ifTrue:[ cg@3594: self showMissingTranslationsOnlyChanged. cg@3594: ^ self. cg@2434: ]. cg@3594: cg@3594: "Modified: / 15-09-2018 / 12:17:07 / Claus Gittinger" fm@2051: ! fm@2051: fm@2051: updateCopyPreviousTranslationButtonEnabled fm@2051: fm@2163: self pastePreviousTranslationEnableHolder value: self shouldCopyPreviousTranslationButtonBeEnabled fm@2050: ! fm@2050: fm@2050: updateExampleLanguageText fm@2050: fm@2050: self selectedKeyRow value isNil ifTrue:[^ self]. fm@2050: self exampleLanguageTextHolder value:self currentExampleLanguageText fm@2049: ! fm@2049: cg@2434: updateKeyStringsToLanguageMappings cg@2434: cg@2434: keyStringsToLanguageMappings cg@2434: at:lastSelectedKey cg@2434: language:lastLanguage cg@2434: put: self newLanguageText. fm@2049: ! fm@2049: fm@2050: updateLanguageAndKeySelection fm@2050: fm@2050: self originalTextHolder value: self selectedKey. fm@2051: self languageTextHolder value: (self languageTextFromSelectedKeyFor: self currentLanguage). fm@2051: lastLanguage := self currentLanguage. cg@2434: lastSelectedKey := self selectedKey. fm@2050: ! fm@2050: cg@2434: updateLanguageTextModification cg@2434: self languageTextModifiedHolder value ifTrue:[ cg@2434: (self autoAccept or:[Dialog confirm:'Accept changed translation ?']) ifTrue:[ cg@2434: self languageTextModifiedHolder value:false. cg@2434: self languageTextHolder value:languageEditor contents. cg@2434: lastLanguage notNil ifTrue:[self updateKeyStringsToLanguageMappings.] cg@2434: ] fm@2049: ]. fm@2049: ! fm@2049: fm@2049: updateOriginalTextModification fm@2049: fm@2163: |answer| fm@2049: cg@3522: self originalTextModifiedHolder value ifTrue:[ cg@3522: answer := OptionBox cg@3522: request:'Accept changed original text (key) ?' cg@3522: label:'Original text (key) changed' cg@3522: image:(WarningBox iconBitmap) cg@3522: buttonLabels:#('Cancel' 'Accept' 'Accept As New') cg@3522: values:#(nil #accept #acceptAsNew) cg@3522: default:#acceptAsNew. cg@3522: cg@3522: answer isNil ifTrue:[^ self originalTextModifiedHolder value:false. ]. cg@3522: answer == #accept ifTrue:[ sv@3245: self shouldImplement. ]. cg@3522: answer == #acceptAsNew ifTrue:[ sv@3245: self shouldImplement. ]. cg@3522: ]. fm@2323: ! fm@2323: fm@2323: updatePasteOriginalButtonEnabled fm@2323: fm@2323: self pasteOriginalEnableHolder value: self shouldPasteOriginalButtonBeEnabled cg@2048: ! ! cg@2048: fm@2050: !InternationalLanguageTranslationEditor methodsFor:'dialogs'! fm@2050: fm@2051: requestEncoderDialog fm@2051: fm@2051: |box val characterCollection| fm@2050: fm@2051: val := '' asValue. fm@2051: box := Dialog new. fm@2051: (box addTextLabel:'Select or write the encoder') adjust:#left. fm@2051: box addVerticalSpace. cg@2434: characterCollection := CharacterEncoder supportedExternalEncodings cg@2434: inject: OrderedCollection new cg@2434: into:[:collection :each | cg@2434: collection add: each first; cg@2434: yourself]. fm@2051: (box addComboBoxOn:val) list: characterCollection. fm@2051: box addOkButton. fm@2051: box open. fm@2051: ^val value fm@2051: ! fm@2051: fm@2051: requestEncoderStringFor: lang fm@2051: "Returns an encoder string and updates the language's info" fm@2051: |encoderString encoder| fm@2051: encoderString := self requestEncoderDialog. fm@2051: encoderString notEmpty ifTrue:[ cg@2434: encoder := CharacterEncoder encoderFor: encoderString ifAbsent:nil. cg@2434: encoder notNil ifTrue:[keyStringsToLanguageMappings atLanguage: lang putEncoder: encoder.]. fm@2051: ]. fm@2051: ^encoderString fm@2050: ! fm@2050: cg@2434: requestFilename fm@2050: fm@2050: |aFilename| fm@2050: cg@2434: aFilename := Dialog cg@2434: requestFileName:(resources string:'Name of resource file:') cg@2434: default:nil cg@2434: pattern:'*.rs'. fm@2050: fm@2050: aFilename isEmptyOrNil ifTrue:[^ nil ]. fm@2050: ^aFilename asFilename fm@2050: ! fm@2050: cg@2434: requestFilenameFor: lang cg@3594: "Returns a filename to save the language resource and updates the language's info" cg@3594: fm@2051: |aFilename| fm@2051: cg@2434: aFilename := Dialog cg@3594: requestFileName:(resources string:'Name of resource file to save %1:' with:lang asString) cg@3594: default:nil cg@3594: pattern:'*.rs'. fm@2051: fm@2051: aFilename isEmptyOrNil ifTrue:[^ nil ]. fm@2051: keyStringsToLanguageMappings atLanguage: lang putFilename: aFilename. fm@2051: ^aFilename asFilename cg@3594: cg@3594: "Modified (format): / 15-09-2018 / 12:28:28 / Claus Gittinger" fm@2051: ! fm@2051: fm@2050: requestLanguage cg@2434: ^ Dialog cg@2434: choose:(resources string:'For which language ?') cg@2434: fromList:languagesList cg@2434: lines:10. fm@2327: ! fm@2327: fm@2327: requestLanguageToSave cg@3594: |question filename| cg@3594: cg@3594: question := resources string:'Which language do you want to save?'. cg@3594: cg@3594: lastLanguage notNil ifTrue:[ cg@3594: filename := keyStringsToLanguageMappings filenameAt:lastLanguage. cg@3594: filename notNil ifTrue:[ cg@3594: question := question , Character cr , cg@3594: (resources string:'(Last was "%1" in "%2")' cg@3594: with:lastLanguage cg@3594: with:(filename asFilename pathName)). cg@3594: ]. cg@3594: ]. cg@3594: cg@2434: ^ Dialog cg@3594: choose:question cg@3594: fromList:languagesList cg@3594: lines:10 cg@3594: cg@3594: "Modified: / 15-09-2018 / 12:39:30 / Claus Gittinger" cg@2410: ! cg@2410: cg@2410: requestPackage cg@2419: |package allProjects projectsWithResources| cg@2419: matilk@3264: allProjects := Smalltalk allPackageIDs. cg@2419: projectsWithResources := allProjects cg@3522: select:[:pID | cg@3522: |dir| cg@3522: dir := Smalltalk projectDirectoryForPackage:pID. cg@3522: dir notNil and:[ cg@3522: (dir asFilename construct:'resources') exists] cg@3522: ]. cg@2410: cg@2410: package := Dialog cg@3522: requestProject:(resources string:'Name of Package:') cg@3522: from:projectsWithResources cg@3522: initialAnswer:LastProject cg@3522: suggestions:nil. cg@2410: cg@2410: package isEmptyOrNil ifTrue:[^ nil ]. cg@2410: LastProject := package. cg@2410: ^ package fm@2050: ! ! fm@2050: fm@2327: !InternationalLanguageTranslationEditor methodsFor:'images'! fm@2327: fm@2327: restartSearchBarIcon fm@2327: fm@2327: ^ self class restartSearchBarIcon fm@2327: ! fm@2327: fm@2327: warningSearchBarIcon fm@2327: fm@2327: ^ self class warningSearchBarIcon fm@2327: ! ! fm@2327: cg@2015: !InternationalLanguageTranslationEditor methodsFor:'initialization & release'! cg@2015: cg@2015: closeRequest cg@2015: "asks for permission before closing" cg@2015: cg@2015: self hasUnsavedChanges ifTrue:[ cg@2434: (Dialog cg@2434: confirm:(resources string:'Close without saving ?') cg@2434: default:false) ifFalse:[ cg@2434: ^ self cg@2434: ] cg@2015: ]. cg@2015: cg@2015: super closeRequest cg@2015: ! cg@2015: cg@2015: initialize cg@2015: modified := false. cg@2031: inSingleFileMode := false. cg@3286: methodsUsingKey := Dictionary new. cg@2015: super initialize cg@2015: ! cg@2015: fm@2049: languageEditorBuilt:aView fm@2049: languageEditor := aView. cg@3594: cg@3594: "Modified: / 15-09-2018 / 12:16:22 / Claus Gittinger" fm@2049: ! fm@2049: cg@2015: postBuildDataSet:aView fm@2049: dataSetView := aView. fm@2049: aView selectedColIndexHolder onChangeSend:#selectionChanged to:self. cg@2015: ! ! cg@2015: fm@2327: !InternationalLanguageTranslationEditor methodsFor:'initialize'! fm@2327: fm@2327: postBuildSearchBoxView: aBoxView fm@2327: fm@2327: searchBoxView := aBoxView fm@2327: fm@2327: "Created: / 15-06-2007 / 18:02:38 / Administrador" fm@2327: ! fm@2327: fm@2327: postBuildSearchTextView: anEditFieldView fm@2327: fm@2327: searchTextView := anEditFieldView fm@2327: fm@2327: "Created: / 15-06-2007 / 18:17:15 / Administrador" fm@2327: ! fm@2327: fm@2327: postBuildTranslationsPanel: aPanel fm@2327: fm@2327: translationsPanel := aPanel fm@2327: ! fm@2327: fm@2327: postBuildWith:aBuilder fm@2327: fm@2327: super postBuildWith:aBuilder. fm@2327: self updateToolVisibility. fm@2327: ! ! fm@2327: cg@2015: !InternationalLanguageTranslationEditor methodsFor:'menu actions'! cg@2015: cg@2015: addLanguage cg@2015: |lang| cg@2015: cg@2410: lang := Dialog request:(resources string:'New language (ISO symbol):'). cg@2015: lang isEmptyOrNil ifTrue:[^ self]. cg@2410: self addLanguage:lang cg@2410: ! cg@2410: cg@2410: addLanguage:langArg cg@2410: |lang| cg@2410: cg@2410: lang := langArg asSymbol. cg@2015: (keyStringsToLanguageMappings includesLanguage:lang) ifTrue:[^ self ]. cg@2015: cg@2015: keyStringsToLanguageMappings addLanguage:lang. cg@2015: self languagesList add:lang. cg@2015: self shownLanguages add:lang. cg@2015: modified := true. cg@2015: ! cg@2015: cg@2015: addTranslation cg@2015: |key index| cg@2015: cg@2015: key := Dialog request:'New Key:'. fm@2051: key isEmpty ifTrue:[^self]. cg@3599: fm@2163: (self includesKey:key) ifFalse:[ cg@3599: keyStringsToLanguageMappings addKey:key. cg@3599: modified := true. cg@2015: ]. fm@2051: index := keyStringsToLanguageMappings indexOfKey:key. fm@2051: self selectedKeyRow value:index cg@2015: ! cg@2015: cg@3286: browseReferringMethods cg@3286: |selectedKey methods browser| cg@3286: cg@3286: selectedKey := self selectedKey. cg@3286: selectedKey isNil ifTrue:[^ Dialog information: 'No selected key']. cg@3286: cg@3286: methods := methodsUsingKey at:selectedKey ifAbsent:nil. cg@3286: methods isEmptyOrNil ifTrue:[ cg@3522: Dialog information:(resources stringWithCRs:'oops - no method remembered.\Please rerun the extract from XXX menu operation'). cg@3522: ^ self. cg@3522: ]. cg@3286: browser := UserPreferences systemBrowserClass browseMethods:methods. cg@3286: browser autoSearch:selectedKey ignoreCase:true. cg@3286: ! cg@3286: fm@2163: changeLastNameSpace fm@2163: fm@2163: |nameSpace defaultNameSpace| fm@2163: fm@2163: lastNameSpace notNil ifTrue:[defaultNameSpace := lastNameSpace name]. fm@2163: nameSpace := Dialog requestNameSpace:'NameSpace:' title:'Search String in Name Space:' initialAnswer:defaultNameSpace. fm@2163: nameSpace isNil ifTrue:[^self]. fm@2163: nameSpace := Smalltalk at:nameSpace asSymbol. fm@2163: nameSpace isNil ifTrue:[ cg@2434: ^Dialog information:(resources string:'No such nameSpace exists.') fm@2163: ]. fm@2163: lastNameSpace := nameSpace. fm@2163: ! fm@2163: fm@2327: changeLastPackage fm@2327: fm@2327: |package defaultPackage| fm@2327: fm@2327: lastPackage notNil ifTrue:[defaultPackage := lastPackage]. fm@2327: package := Dialog cg@2434: requestProject:'Package:' cg@2434: initialAnswer:defaultPackage cg@2434: suggestions:#('foo' 'bar' 'baz'). fm@2327: package isNil ifTrue:[ cg@2434: ^ self "/ Dialog information:(resources string:'No such package exists.') fm@2327: ]. fm@2327: lastPackage := package. fm@2327: ! fm@2327: cg@2015: extractTranslationsFromClass cg@2015: |aClass newTranslations| cg@2015: cg@2434: aClass := Dialog cg@2434: requestClass:'Class to extract translations from:' cg@2434: okLabel:'OK' cg@2434: initialAnswer:(lastExtractedClass ? LastExtractedClass). cg@2015: aClass isNil ifTrue:[^ self ]. cg@2015: cg@2015: lastExtractedClass := LastExtractedClass := aClass. cg@2015: cg@2032: newTranslations := self extractTranslationsFromClass:aClass. cg@2032: self addAllTranslations:newTranslations. cg@2032: ! cg@2032: fm@2163: extractTranslationsFromNameSpace fm@2163: fm@2163: |newTranslations| fm@2163: fm@2163: self changeLastNameSpace. fm@2163: lastNameSpace isNil ifTrue:[^self.]. fm@2163: newTranslations := OrderedCollection new. fm@2163: lastNameSpace allClassesDo:[:eachClass | cg@2434: newTranslations addAll:( self extractTranslationsFromClass:eachClass theNonMetaclass). fm@2163: ]. fm@2163: self addAllTranslations:newTranslations. fm@2163: ! fm@2163: cg@2032: extractTranslationsFromProject mawalch@3455: |projectID newTranslations initialAnswer suggestions| mawalch@3455: mawalch@3455: initialAnswer := lastExtractedProject ? LastExtractedProject. mawalch@3455: suggestions := initialAnswer isNil ifTrue:[ cg@3522: OrderedCollection new mawalch@3455: ] ifFalse:[ cg@3522: OrderedCollection with:initialAnswer mawalch@3455: ]. mawalch@3455: projectID := Dialog requestProject:(resources string:'Package to extract translations from:') initialAnswer:initialAnswer suggestions:suggestions. cg@2032: projectID notNil ifTrue:[ cg@3522: projectID := projectID withoutSeparators asSymbol. cg@2032: ]. cg@2032: projectID isEmptyOrNil ifTrue:[^ self ]. cg@2032: cg@2032: lastExtractedProject := LastExtractedProject := projectID. cg@2032: cg@2015: newTranslations := Set new. cg@3282: self withWaitCursorDo:[ cg@3522: Smalltalk allClassesDo:[:eachClass | cg@3522: eachClass theNonMetaclass instAndClassMethodsDo:[:eachMethod | cg@3522: eachMethod package == projectID ifTrue:[ cg@3522: newTranslations addAll:( self extractTranslationsFromMethod:eachMethod ). cg@3522: ] cg@3522: ]. cg@3522: ]. cg@3522: cg@3522: self addAllTranslations:newTranslations. cg@2015: ]. mawalch@3454: jan@3189: "Modified: / 19-02-2015 / 11:44:24 / Jan Vrany " mawalch@3455: "Modified: / 16-08-2017 / 12:29:21 / mawalch" jan@3189: ! jan@3189: cg@3522: generateMissingTranslations: keys for: languages using: translator jan@3189: keys do:[:string | cg@3522: languages do:[:lang | cg@3522: | translation | cg@3522: cg@3522: translation := keyStringsToLanguageMappings at:string language:lang. cg@3522: translation isNil ifTrue:[ cg@3522: translation := translator value: lang value: string. cg@3522: translation notNil ifTrue:[ cg@3522: keyStringsToLanguageMappings at: string language: lang put: translation. cg@3522: ]. cg@3522: ]. cg@3522: ]. jan@3189: ]. jan@3189: jan@3189: "Created: / 19-02-2015 / 12:31:25 / Jan Vrany " jan@3189: ! jan@3189: jan@3189: generateMissingTranslationsFor: languages cg@3522: self cg@3522: generateMissingTranslations: keyStringsToLanguageMappings keys cg@3522: for: languages cg@3522: using: [ :lang :string | '**%1** %2' bindWith: lang asUppercase with: string ] jan@3189: jan@3189: "Created: / 19-02-2015 / 12:39:46 / Jan Vrany " jan@3189: ! jan@3189: jan@3189: generateMissingTranslationsForAll jan@3189: self generateMissingTranslationsFor: keyStringsToLanguageMappings languages jan@3189: jan@3189: "Created: / 19-02-2015 / 12:40:01 / Jan Vrany " cg@2015: ! cg@2015: fm@2327: importExistingTranslationsFromFile cg@2410: self information:'The import function is not available in this release'. fm@2327: ! fm@2327: fm@2163: inspectCanvasMissingStrings fm@2163: fm@2163: |spec nameSpace missingStrings| fm@2163: fm@2163: missingStrings := OrderedCollection new. fm@2163: nameSpace := Dialog requestNameSpace:'NameSpace:' title:'Specify NameSpace to look for missing strings' initialAnswer:nil. fm@2163: nameSpace := Smalltalk at:nameSpace asSymbol. fm@2163: nameSpace isNil ifTrue:[ cg@2434: ^Dialog information:(resources string:'No such nameSpace exists.?') fm@2163: ]. fm@2163: fm@2163: nameSpace allClassesDo:[:cls | cg@2434: cls theMetaclass methodsDo:[:m | cg@2434: m hasResource ifTrue:[ cg@2434: (m resources includesKey:#canvas) ifTrue:[ cg@2434: spec := (cls perform:m selector) decodeAsLiteralArray. cg@2434: spec do:[:eachComponent | cg@2434: eachComponent translationKeysDo:[:k | cg@2434: (self includesKey: k) ifFalse:[ cg@2434: missingStrings add: k. cg@2434: Transcript showCR: k storeString, ' ', m printString]] cg@2434: ] cg@2434: ] cg@2434: ] cg@2434: ] fm@2163: ]. fm@2163: missingStrings asSet inspect fm@2163: ! fm@2163: cg@2015: menuNew cg@2015: modified ifTrue:[ cg@2434: (Dialog cg@2434: confirm:(resources stringWithCRs:'Modified translations have not been changed.\\Create new translations set anyway ?') cg@2434: default:false) ifFalse:[^ self]. cg@2015: ]. cg@2015: cg@2015: keyStringsToLanguageMappings initialize. cg@2015: keyStringsToLanguageMappings changed. cg@2015: cg@2015: self languagesList contents:self keyStringAndLanguageSelectionTable languages. cg@2015: self shownLanguages contents:self keyStringAndLanguageSelectionTable languages. cg@2015: modified := false. cg@2015: ! cg@2015: cg@2015: menuOpen fm@2050: |aFilename| cg@2015: fm@2163: self withWaitCursorDo:[ cg@2434: aFilename := self requestFilename. cg@2434: aFilename isNil ifTrue:[^ self ]. cg@2434: self readResourceFile:aFilename. fm@2163: ] cg@2015: ! cg@2015: cg@2410: menuOpenByPackage cg@2410: |package| cg@2410: cg@2410: self withWaitCursorDo:[ cg@2434: package := self requestPackage. cg@2434: package isNil ifTrue:[^ self ]. cg@2434: self readResourceFileForPackage:package. cg@2410: ] cg@2410: ! cg@2410: cg@2015: menuSave fm@2050: "Saves the language selected in the fileName from where the language resource was obtained." fm@2053: |lang| cg@2015: fm@2327: lang := self requestLanguageToSave. fm@2050: lang isNil ifTrue:[^ self]. fm@2053: self saveLanguage: lang fm@2053: ! fm@2053: fm@2053: menuSaveAll fm@2053: "Saves all the languages in the fileName from where the language resource was obtained." cg@2434: keyStringsToLanguageMappings languagesInUse do:[:each | self saveLanguage: each]. cg@2015: ! cg@2015: cg@2015: menuSaveAs fm@2050: "Saves the language selected in the specified fileName." fm@2050: |lang aFilename| cg@2015: fm@2327: lang := self requestLanguageToSave. cg@2434: lang isNil ifTrue:[^ self]. fm@2053: aFilename := self requestFilenameFor:lang. fm@2050: aFilename isNil ifTrue:[^ self]. fm@2050: self saveResourceFile:aFilename for:lang asSymbol cg@2015: ! cg@2015: cg@3599: mergeLanguages cg@3599: |sourceLanguage destLanguage possibleDestinationLanguages| cg@3599: cg@3599: sourceLanguage := Dialog cg@3599: request:'Merge entries from:' cg@3599: initialAnswer:nil cg@3599: list:(self languagesList) cg@3599: title:'Source language'. cg@3599: sourceLanguage isEmptyOrNil ifTrue:[^ self]. cg@3599: cg@3599: possibleDestinationLanguages := self languagesList copyWithout:sourceLanguage. cg@3599: cg@3599: destLanguage := Dialog cg@3599: request:'Destination language:\(Missing entries in destination are filled in from source)' withCRs cg@3599: initialAnswer:(possibleDestinationLanguages size == 1 cg@3599: ifTrue:[possibleDestinationLanguages first] cg@3599: ifFalse:[nil]) cg@3599: list:possibleDestinationLanguages cg@3599: title:'Destination language'. cg@3599: destLanguage isEmptyOrNil ifTrue:[^ self]. cg@3599: cg@3599: "/ all empty entries of dest are filled in from source cg@3599: keyStringsToLanguageMappings keys do:[:eachKey | cg@3599: |newXlation| cg@3599: cg@3599: (keyStringsToLanguageMappings at:eachKey language:destLanguage) isEmptyOrNil ifTrue:[ cg@3599: newXlation := keyStringsToLanguageMappings at:eachKey language:sourceLanguage. cg@3599: newXlation notNil ifTrue:[ cg@3599: self halt. cg@3599: keyStringsToLanguageMappings at:eachKey language:destLanguage put:newXlation. cg@3599: ] cg@3599: ] cg@3599: ] cg@3599: ! cg@3599: cg@2015: openAboutThisApplication cg@2015: "This method was generated by the Browser. cg@2015: It will be invoked when the menu-item 'help-about' is selected." cg@2015: cg@2015: "/ could open a customized aboutBox here ... cg@2015: super openAboutThisApplication cg@2015: ! cg@2015: cg@2015: openDocumentation cg@2015: "This method was generated by the Browser. cg@2015: It will be invoked when the menu-item 'help-documentation' is selected." cg@2015: cg@2015: "/ change below as required ... cg@2015: cg@2015: "/ to open an HTML viewer on some document (under 'doc/online//' ): cg@2413: HTMLDocumentView openFullOnDocumentationFile:'tools/languageEditor/TOP.html'. cg@2015: cg@2015: "/ add application-specific help files under the 'doc/online//help/appName' cg@2015: "/ directory, and open a viewer with: cg@2015: "/ HTMLDocumentView openFullOnDocumentationFile:'help//TOP.html'. cg@2015: ! cg@2015: cg@2015: readResourceFile:aFilename cg@2031: |lang| cg@2031: fm@2327: lang := self requestLanguage. cg@2031: lang isNil ifTrue:[^ self ]. cg@2031: cg@2031: self readResourceFile:aFilename asLanguage:lang asSymbol cg@2031: ! cg@2031: cg@2410: readResourceFileForPackage:aPackage cg@2410: |allLanguages lang packageDir resourceDir langFile| cg@2410: cg@2410: packageDir := Smalltalk packageDirectoryForPackageId:aPackage. cg@2410: resourceDir := packageDir asFilename construct:'resources'. cg@2410: cg@2410: allLanguages := Set new. cg@2410: resourceDir directoryContentsAsFilenamesDo:[:eachFile | cg@2434: eachFile suffix = 'rs' ifTrue:[ cg@2434: (('##.rs' match:eachFile baseName) cg@2434: or:[('##-##.rs' match:eachFile baseName)]) ifTrue:[ cg@2434: allLanguages add:(eachFile withoutSuffix baseName) cg@2434: ]. cg@2434: ]. cg@2410: ]. cg@2410: cg@2410: allLanguages addAll:languagesList. cg@2410: allLanguages := allLanguages asSortedCollection. cg@2410: cg@2434: lang := Dialog cg@2434: choose:(resources string:'For which language ?') cg@2434: fromList:allLanguages cg@2434: values:allLanguages cg@2434: buttons:(resources array:#('All')) cg@2434: values:#(all) cg@2434: lines:10 cg@2434: cancel:nil. cg@2410: cg@2410: lang isNil ifTrue:[^ self ]. cg@2410: cg@2410: langFile := resourceDir construct:lang,'.rs'. cg@2410: cg@2410: lang == #all ifTrue:[ cg@2434: allLanguages do:[:lang | cg@2434: self addLanguage:lang. cg@2434: self readResourceFile:(resourceDir construct:lang,'.rs') asLanguage:lang. cg@2434: ]. cg@2410: ] ifFalse:[ cg@2434: self readResourceFile:langFile asLanguage:lang asSymbol cg@2410: ]. cg@2410: ! cg@2410: fm@2050: removeLanguage sv@3246: |languagesToRemove| sv@3246: sv@3246: languagesToRemove := Dialog chooseMultiple:'Which language(s) do you want to remove?' fromList:languagesList lines:10. sv@3246: languagesToRemove isEmptyOrNil ifTrue:[^ self ]. sv@3246: (Dialog confirm: 'Are you sure to remove the languages: ', languagesToRemove printString) ifTrue:[ cg@3522: self languagesList removeAll:languagesToRemove. cg@3522: self shownLanguages removeAll:languagesToRemove. cg@2434: ]. cg@2015: ! cg@2015: cg@2015: removeTranslation cg@2015: |rowSelectionIndex selectedKey| cg@2015: cg@2015: rowSelectionIndex := self selectedKeyRow value. fm@2163: rowSelectionIndex isNil ifTrue:[^self]. cg@2015: rowSelectionIndex ~~ 0 ifTrue:[ cg@2434: selectedKey := keyStringsToLanguageMappings keyAt:rowSelectionIndex ifAbsent:nil. cg@2434: selectedKey isNil ifTrue:[^self]. cg@2434: (Dialog confirm:(resources string:'Really remove key %1' with:selectedKey)) ifTrue:[ cg@2434: keyStringsToLanguageMappings removeKey:selectedKey. cg@2434: ]. cg@2015: ]. cg@2015: ! cg@2015: cg@2015: runApplicationAndCollectTranslations cg@2047: |applicationClass newTranslations pseudoPack app startSelector| cg@2015: cg@2015: monitoredApplication notNil ifTrue:[ cg@3522: monitoredApplication terminate. cg@3522: [monitoredApplication notNil] whileTrue:[ cg@3522: Delay waitForSeconds:0.1 cg@3522: ]. cg@2015: ]. cg@2015: cg@2434: applicationClass := Dialog cg@3522: requestClass:'Application class to start and collect translations from:' cg@3522: okLabel:'OK' cg@3522: initialAnswer:(lastExtractedApplicationClass ? LastExtractedApplicationClass ). cg@2015: applicationClass isNil ifTrue:[^ self ]. cg@3286: applicationClass isNameSpace ifTrue:[ cg@3522: Dialog warn:'Entered class is a NameSpace'. cg@3522: ^ self. cg@2047: ]. cg@2047: cg@2047: applicationClass isVisualStartable ifTrue:[ cg@3522: startSelector := #open cg@2047: ] ifFalse:[ cg@3522: startSelector := Dialog cg@3522: request:'Entered class seems to be no application class. Ok to start using selector:' cg@3522: initialAnswer:((applicationClass respondsTo:#'start') cg@3522: ifTrue:#'start' cg@3522: ifFalse:#'new') cg@3522: okLabel:'START' cg@3522: title:'Start Application'. cg@3522: startSelector isNil ifTrue:[ cg@3522: ^ self cg@3522: ]. cg@3522: startSelector := startSelector asSymbol. cg@2047: ]. cg@2015: cg@2015: lastExtractedApplicationClass := LastExtractedApplicationClass := applicationClass. cg@2015: cg@2015: newTranslations := Set new. cg@2015: cg@2015: pseudoPack := AccessCollectingPseudoResourcePack new. cg@2015: pseudoPack realResourcePack:(applicationClass classResources). cg@3286: pseudoPack watchingTranslationEditor:self. cg@2015: cg@2015: self stopApplicationIconVisibleHolder value:true. cg@2015: cg@3522: monitoredApplication := cg@3522: [ cg@3522: [ cg@3522: app := applicationClass new. cg@3522: app resources:pseudoPack. cg@3522: cg@3522: app perform:startSelector. cg@3522: app window waitUntilVisible. cg@3522: app window waitUntilClosed. cg@3522: ] ensure:[ cg@3522: app closeRequest. cg@3522: self stopApplicationIconVisibleHolder value:false. cg@3522: monitoredApplication := nil. cg@3522: ]. cg@3522: ] fork. fm@2163: ! fm@2163: fm@2163: searchStringInLastNameSpace fm@2163: fm@2323: |selectedKey browser lastSearchPatterns| fm@2163: fm@2163: selectedKey := self selectedKey. fm@2163: selectedKey isNil ifTrue:[^Dialog information: 'No selected key']. fm@2163: browser := NewSystemBrowser new "open". fm@2163: browser allButOpen. fm@2323: lastSearchPatterns := browser lastSearchPatterns. fm@2323: (lastSearchPatterns notNil and:[lastSearchPatterns first ~= selectedKey]) ifTrue:[ cg@2434: browser lastSearchPatterns addFirst: selectedKey fm@2163: ]. fm@2327: SearchDialog lastStringSearchArea: #currentNameSpace. fm@2163: lastNameSpace isNil ifTrue:[ cg@2434: self changeLastNameSpace. fm@2163: ]. fm@2163: lastNameSpace notNil ifTrue:[ fm@2163: "/ browser navigationState selectedClasses value: lastNameSpace allClasses. cg@2434: browser navigationState nameSpaceFilter value: (OrderedCollection with:lastNameSpace name). cg@2434: browser navigationState selectedNamespaces value: (OrderedCollection with:lastNameSpace name). fm@2163: ]. fm@2163: self withWaitCursorDo:[ cg@2434: browser browseMenuMethodsWithString fm@2163: ]. fm@2327: ! fm@2327: fm@2327: searchStringInLastPackage fm@2327: fm@2327: | selectedKey browser lastSearchPatterns| fm@2327: fm@2327: selectedKey := self selectedKey. cg@3286: selectedKey isNil ifTrue:[^ Dialog information: 'No selected key']. cg@3286: fm@2327: browser := NewSystemBrowser new "open". fm@2327: browser allButOpen. cg@3522: fm@2327: lastSearchPatterns := browser lastSearchPatterns. fm@2327: (lastSearchPatterns notNil and:[lastSearchPatterns first ~= selectedKey]) ifTrue:[ cg@3522: browser lastSearchPatterns addFirst: selectedKey fm@2327: ]. fm@2327: SearchDialog lastStringSearchArea: #currentPackage. fm@2327: lastPackage isNil ifTrue:[ cg@3522: self changeLastPackage. fm@2327: ]. fm@2327: lastPackage notNil ifTrue:[ fm@2327: "/ browser navigationState selectedClasses value: lastNameSpace allClasses. cg@3522: browser navigationState packageFilter value: (OrderedCollection with:lastPackage). cg@3522: browser navigationState selectedProjects value: (OrderedCollection with:lastPackage). fm@2327: ]. fm@2327: self withWaitCursorDo:[ cg@3522: browser cg@3522: askForMethodAndSpawnSearchTitle:'String to Search for in Sources:' cg@3522: browserLabel:'Methods containing "%1"' cg@3522: searchWith:#( #'findString:in:ignoreCase:match:' #'findString:inMethods:ignoreCase:match:' ) cg@3522: searchWhat:#string cg@3522: searchArea:#currentPackage cg@3522: withCaseIgnore:false cg@3522: withTextEntry:false cg@3522: withMatch:true cg@3522: withMethodList:false cg@3522: setSearchPattern:[:brwsr :string :ignoreCase :doMatch| cg@3522: brwsr autoSearchPattern:string ignoreCase:ignoreCase. cg@3522: ] cg@3522: initialText:selectedKey "/ does not work: ('''*',selectedKey,'*''') check match!! fm@2327: ]. cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor methodsFor:'menus dynamic'! cg@2015: cg@2015: disableLanguageDisplayFor:lang cg@2015: self shownLanguages remove:lang ifAbsent:[] cg@2015: ! cg@2015: cg@2015: enableLanguageDisplayFor:newLang cg@2015: |shownLanguagesInOrder| cg@2015: cg@2015: (self shownLanguages includes:newLang) ifFalse:[ cg@2048: "/ shownLanguagesInOrder := self languagesList cg@2048: "/ select:[:lang | (self shownLanguages includes:lang) cg@2048: "/ or:[ lang = newLang ]]. cg@2048: "/ self shownLanguages contents:shownLanguagesInOrder. cg@2434: self shownLanguages add:newLang. cg@2015: ] cg@2015: ! cg@2015: cg@2015: isLanguageShown:lang cg@2015: ^ self shownLanguages includes:lang cg@2015: ! cg@2015: jan@3189: menuSliceTranslateGenerate jan@3189: | menu | jan@3189: jan@3189: menu := Menu new. cg@3522: keyStringsToLanguageMappings notNil ifTrue:[ cg@3522: keyStringsToLanguageMappings languages do:[:lang | cg@3522: menu addItem: cg@3522: (MenuItem cg@3522: label: (resources string: 'Generate Missing Translations - %1' with: lang asUppercase) cg@3522: itemValue: [ self generateMissingTranslationsFor: (Array with: lang) ]) cg@3522: ]. jan@3189: ]. jan@3189: ^ menu jan@3189: jan@3189: "Created: / 19-02-2015 / 12:44:13 / Jan Vrany " jan@3189: ! jan@3189: cg@2015: shownLanguagesMenu cg@2015: cg@2015: cg@2015: ^ [ cg@2434: |m selected| cg@2434: cg@2434: m := Menu new. cg@2434: cg@2434: self languagesList do:[:lang | cg@2434: |item| cg@2434: cg@2434: item := MenuItem label:lang. cg@2434: item indication:(self languageShownHolderFor:lang). cg@2434: item hideMenuOnActivated:false. cg@2434: m addItem:item. cg@2434: ]. cg@2434: m cg@2015: ]. cg@2015: ! cg@2015: cg@2015: toggleLanguageDisplayFor:lang cg@2015: (self shownLanguages includes:lang) ifTrue:[ cg@2434: self disableLanguageDisplayFor:lang cg@2015: ] ifFalse:[ cg@2434: self enableLanguageDisplayFor:lang cg@2015: ]. cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor methodsFor:'private-key extraction'! cg@2015: cg@2032: addAllTranslations:newTranslations cg@3286: "merge found xlations into the list of already present xlations" cg@3522: cg@2034: |newTranslationKeys stringKeys nonStringKeys| cg@2032: sv@3245: newTranslationKeys := newTranslations select:[:k | k notEmptyOrNil and:[k isString not or:[k isBlank not]]]. cg@2032: newTranslationKeys := newTranslationKeys select:[:k | (keyStringsToLanguageMappings includesKey:k) not]. cg@3286: "/ follow the common-xlations algrithm of ResourcePack cg@3286: "/ (which knows how to xlate strings with additional special chars.) cg@3522: newTranslationKeys := cg@3522: newTranslationKeys collect:[:oldKey | cg@3522: |newKey methods| cg@3522: cg@3522: (oldKey endsWith:' ...') ifTrue:[ cg@3522: newKey := oldKey copyButLast:4. cg@3522: ] ifFalse:[ (oldKey endsWith:'...') ifTrue:[ cg@3522: newKey := oldKey copyButLast:3. cg@3522: ] ifFalse:[ ('\.:?=,!! ' includes:oldKey last) ifTrue:[ cg@3522: newKey := oldKey copyButLast:1. cg@3522: ] ifFalse:[ ((oldKey first == $() and:[ oldKey last == $) ]) ifTrue:[ cg@3522: newKey := oldKey copyFrom:2 to:oldKey size - 1 cg@3522: ] ifFalse:[ ((oldKey first == $[) and:[ oldKey last == $] ]) ifTrue:[ cg@3522: newKey := oldKey copyFrom:2 to:oldKey size - 1 cg@3522: ] ifFalse:[ cg@3522: newKey :=oldKey cg@3522: ]]]]]. cg@3522: "/ must attach oldKey-methods to newKey cg@3522: methods := methodsUsingKey at:oldKey ifAbsent:nil. cg@3522: methods notNil ifTrue:[ cg@3522: (methodsUsingKey at:newKey ifAbsentPut:[Set new]) addAll:methods cg@3522: ]. cg@3522: newKey cg@3522: ]. cg@3522: cg@2034: newTranslationKeys := newTranslationKeys asSet. sv@3246: newTranslationKeys := newTranslationKeys select:[:k | (keyStringsToLanguageMappings includesKey:k) not]. cg@2034: cg@2032: newTranslationKeys notEmpty ifTrue:[ cg@3522: stringKeys := newTranslationKeys select:[:k | k isString]. cg@3522: nonStringKeys := newTranslationKeys select:[:k | k isString not]. cg@3522: cg@3522: stringKeys := stringKeys asSortedCollection. cg@3522: keyStringsToLanguageMappings addKeys:stringKeys. cg@3522: keyStringsToLanguageMappings addKeys:nonStringKeys. cg@3522: modified := true. cg@2032: ]. cg@2032: ! cg@2032: cg@2032: extractTranslationsFromClass:aClass cg@2032: |newTranslations| cg@2032: cg@2032: newTranslations := Set new. cg@2032: cg@2032: self withWaitCursorDo:[ cg@3522: "/ now, the hard part: cg@3522: "/ possible translations are in the specs, cg@3522: "/ and all arguments to (resources string:) messages. cg@3522: aClass instAndClassMethodsDo:[:eachMethod | cg@3522: newTranslations addAll:( self extractTranslationsFromMethod:eachMethod ). cg@3522: ]. sv@3248: ]. cg@3522: cg@3522: newTranslations := cg@3522: newTranslations select:[:eachTranslation| cg@3522: (aClass resources at:eachTranslation ifAbsent:nil) isNil cg@3522: ]. cg@2032: ^ newTranslations cg@2032: ! cg@2032: cg@2015: extractTranslationsFromHelpSpecMethod:aMethod cg@3286: "return strings which need translation from a help-spec method" cg@3286: cg@2015: |codeStrings matcher parseTree resourceKeys| cg@2015: cg@2434: parseTree := RBParser cg@3522: parseMethod:aMethod source cg@3522: onError: [:str :pos | Transcript showCR:str. Transcript showCR:pos. cg@3522: nil]. cg@2015: parseTree isNil ifTrue:[^ #() ]. cg@2015: cg@2434: codeStrings := cg@3522: #( cg@3522: '`@dict addPairsFrom: `#helpKeysAndStrings' cg@3522: '^ `#lit' cg@3522: ). cg@2015: cg@2015: resourceKeys := Set new. cg@2015: cg@2015: matcher := ParseTreeSearcher new. cg@2434: matcher cg@3522: matchesAnyOf: codeStrings cg@3522: do: [:aNode :answer | cg@3522: |sel argNode arg| cg@3522: cg@3522: aNode isReturn ifTrue:[ cg@3522: "/ a ^ #(...) cg@3522: aNode value isLiteralArray ifTrue:[ cg@3522: aNode value value pairWiseDo:[:helpKey :helpString | cg@3522: self rememberMethod:aMethod usingKey:helpString. cg@3522: resourceKeys add:helpString. cg@3522: ]. cg@3522: ]. cg@3522: ] ifFalse:[ cg@3522: sel := aNode selector. cg@3522: (sel startsWith:'addPairsFrom:') ifTrue:[ cg@3522: argNode := aNode arguments at:1. cg@3522: argNode isLiteralArray ifTrue:[ cg@3522: arg := argNode value. cg@3522: arg doWithIndex:[:el :index | cg@3522: index even ifTrue:[ cg@3522: el isString ifTrue:[ cg@3522: self rememberMethod:aMethod usingKey:el. cg@3522: resourceKeys add:el. cg@3522: ] cg@3522: ]. cg@3522: ]. cg@3522: ] ifFalse:[ cg@3522: Transcript halt cg@3522: showCR:(resources cg@3522: string:'Cannot derive resourceKey from non-literal array: %1 in %2' cg@3522: with:argNode formattedCode cg@3522: with:aMethod selector). cg@3522: ]. cg@3522: ]. cg@3522: ]. cg@3522: aNode cg@3522: ]. cg@2015: cg@2015: matcher executeTree: parseTree initialAnswer: nil. cg@2015: ^ resourceKeys cg@2015: ! cg@2015: cg@2015: extractTranslationsFromMenuSpecMethod:aMethod cg@3286: "return strings which need translation from a menu-spec method" cg@3286: cg@2015: |menu resourceKeys| cg@2015: cg@2015: menu := aMethod mclass theNonMetaclass perform:aMethod selector. cg@2015: menu isNil ifTrue:[ ^ #() ]. cg@2015: cg@2015: (menu isKindOf:Menu) ifFalse:[ cg@3522: menu := Menu new fromLiteralArrayEncoding:menu cg@2015: ]. cg@2015: cg@2015: resourceKeys := Set new. cg@2015: menu allItemsDo:[:aMenuItem | cg@3522: aMenuItem translateLabel ifTrue:[ cg@3522: (aMenuItem isSeparatorItem or:[aMenuItem isMenuSlice]) ifFalse:[ cg@3522: self rememberMethod:aMethod usingKey:aMenuItem label. cg@3522: resourceKeys add:aMenuItem label. cg@3522: ] cg@3522: ] cg@2015: ]. cg@2015: ^ resourceKeys cg@2015: ! cg@2015: cg@2015: extractTranslationsFromMethod:aMethod cg@3286: "return strings which need translation from a method." cg@3522: cg@2015: |mResources| cg@2015: cg@2015: mResources := aMethod resources. cg@2015: mResources notNil ifTrue:[ cg@3522: (mResources includesKey:#menu) ifTrue:[ cg@3522: ^ self extractTranslationsFromMenuSpecMethod:aMethod. cg@3522: ]. cg@3522: (mResources includesKey:#canvas) ifTrue:[ cg@3522: ^ self extractTranslationsFromUISpecMethod:aMethod. cg@3522: ]. cg@3522: (mResources includesKey:#help) ifTrue:[ cg@3522: ^ self extractTranslationsFromHelpSpecMethod:aMethod. cg@3522: ]. cg@3522: (mResources includesKey:#tableColumns) ifTrue:[ cg@3522: ^ self extractTranslationsFromTableColumnsSpecMethod:aMethod. cg@3522: ]. cg@3522: cg@3522: ^ self extractTranslationsFromSpecMethod:aMethod. cg@2015: ]. cg@2015: ^ self extractTranslationsFromMethodsCode:aMethod cg@2015: ! cg@2015: cg@2015: extractTranslationsFromMethodsCode:aMethod cg@3286: "return strings which need translation from a normal method. cg@3286: detects messages to the resource translation mechanism" cg@3286: cg@2015: |codeStrings matcher parseTree resourceKeys| cg@2015: cg@2434: parseTree := RBParser cg@3522: parseMethod:aMethod source cg@3522: onError: [:str :pos | Transcript showCR:str. Transcript showCR:pos. cg@3522: nil]. cg@2015: parseTree isNil ifTrue:[^ #() ]. cg@2015: cg@2434: codeStrings := cg@3522: #( cg@3522: 'resources `@msg: `@args' cg@3522: 'self resources `@msg: `@args' cg@3522: 'self class resources `@msg: `@args' cg@3522: 'self class classResources `@msg: `@args' cg@3522: 'self classResources `@msg: `@args' cg@3522: '`V classResources `@msg: `@args' cg@3522: ). cg@2015: cg@2015: resourceKeys := Set new. cg@2015: cg@2015: matcher := ParseTreeSearcher new. cg@2434: matcher cg@3522: matchesAnyOf: codeStrings cg@3522: do: [:aNode :answer | cg@3522: |sel keyStringArgNode keyStringArg| cg@3522: cg@3522: sel := aNode selector. cg@3522: ((sel startsWith:'string:') or:[(sel startsWith:'at:') or:[sel startsWith:'stringWithCRs:']]) ifTrue:[ cg@3522: keyStringArgNode := aNode arguments at:1. cg@3522: (keyStringArg := self literalStringOrStringConcatenation:keyStringArgNode) notNil ifTrue:[ cg@3522: self rememberMethod:aMethod usingKey:keyStringArg. cg@3522: resourceKeys add:keyStringArg. cg@3522: ] ifFalse:[ cg@3522: Transcript cg@3522: showCR:(resources cg@3522: string:'[LanguageTranslator] warning: Cannot derive resourceKey from non-string: %1 in %2' cg@3522: with:keyStringArgNode formattedCode cg@3522: with:aMethod whoString). cg@3522: ]. cg@3522: ]. cg@3522: aNode cg@3522: ]. cg@2015: cg@2015: matcher executeTree: parseTree initialAnswer: nil. cg@2015: ^ resourceKeys jan@3189: jan@3189: "Modified: / 19-02-2015 / 11:42:04 / Jan Vrany " cg@2015: ! cg@2015: cg@2015: extractTranslationsFromSpecMethod:aMethod cg@2015: ^ #() cg@2015: ! cg@2015: cg@2015: extractTranslationsFromTableColumnsSpecMethod:aMethod cg@3286: "return strings which need translation from a table-spec method" cg@3286: cg@2015: |columnDescription resourceKeys| cg@2015: cg@2015: columnDescription := aMethod mclass theNonMetaclass perform:aMethod selector. cg@2015: columnDescription isNil ifTrue:[ ^ #() ]. cg@2015: cg@2015: (columnDescription first isKindOf:DataSetColumnSpec) ifFalse:[ cg@3522: columnDescription := columnDescription collect:[:el | DataSetColumnSpec new fromLiteralArrayEncoding:el]. cg@2015: ]. cg@2015: cg@2015: resourceKeys := Set new. cg@2015: columnDescription do:[:aColumnSpec | cg@3522: aColumnSpec translateLabel ifTrue:[ cg@3522: self rememberMethod:aMethod usingKey:aColumnSpec label. cg@3522: resourceKeys add:aColumnSpec label. cg@3522: ] cg@2015: ]. cg@2015: ^ resourceKeys cg@2015: ! cg@2015: cg@2015: extractTranslationsFromUISpecMethod:aMethod cg@3286: "return strings which need translation from a UI-spec method" cg@3522: cg@2015: |spec resourceKeys visitor| cg@2015: cg@2015: spec := aMethod mclass theNonMetaclass perform:aMethod selector. cg@2015: spec isNil ifTrue:[ ^ #() ]. cg@2015: cg@2015: (spec isKindOf:UISpecification) ifFalse:[ cg@3522: spec := UISpecification from:spec cg@2015: ]. cg@2015: cg@2015: resourceKeys := Set new. cg@2015: cg@2015: visitor := UISpecVisitor new. cg@2015: spec acceptVisitor:visitor. cg@3286: visitor translatedLabels do:[:each | cg@3522: self rememberMethod:aMethod usingKey:each. cg@3286: ]. cg@2015: ^ visitor translatedLabels cg@3284: ! cg@3284: cg@3284: literalStringOrStringConcatenation:aParseNode cg@3284: "nil if not a literal or a string concatenation" cg@3522: cg@3284: aParseNode isLiteralString ifTrue:[^ aParseNode value]. cg@3284: (aParseNode isMessage and:[aParseNode selector == #,]) ifTrue:[ cg@3522: |leftString rightString| cg@3522: cg@3522: aParseNode receiver isLiteralString ifTrue:[ cg@3522: leftString := aParseNode receiver value cg@3522: ] ifFalse:[ cg@3522: leftString := self literalStringOrStringConcatenation:aParseNode receiver. cg@3522: ]. cg@3522: aParseNode arguments first isLiteralString ifTrue:[ cg@3522: rightString := aParseNode arguments first value cg@3522: ] ifFalse:[ cg@3522: rightString := self literalStringOrStringConcatenation:aParseNode arguments first. cg@3522: ]. cg@3522: (leftString notNil and:[rightString notNil]) ifTrue:[ cg@3522: ^ leftString , rightString cg@3522: ]. cg@3284: ]. cg@3284: ^ nil cg@3286: ! cg@3286: cg@3286: recordNewTranslation:aString cg@3286: "called from recorder, when the monitored application does a translation" cg@3522: cg@3286: self addAllTranslations:{ aString } cg@3286: ! cg@3286: cg@3286: rememberMethod:aMethod usingKey:aKey cg@3286: (methodsUsingKey at:aKey ifAbsentPut:[Set new]) add:aMethod cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor methodsFor:'queries'! cg@2015: cg@2434: autoAccept fm@2050: fm@2050: ^ self autoAcceptHolder value fm@2050: ! fm@2050: cg@2434: currentExampleLanguageText fm@2050: "Returns the language text corresponding for the current selected key and the example language selection" fm@2050: fm@2050: ^self languageTextFromSelectedKeyFor: self exampleLanguageSelectionHolder value fm@2050: ! fm@2050: fm@2051: currentLanguage fm@2051: fm@2163: |colSelectionIndex | fm@2051: fm@2051: colSelectionIndex := dataSetView selectedColIndex. fm@2051: ^colSelectionIndex > 1 ifTrue:[ shownLanguages at:colSelectionIndex-1 ] ifFalse:nil. fm@2051: ! fm@2051: fm@2050: exampleLanguageByDefault fm@2050: fm@2163: ^self shownLanguages isEmpty cg@2434: ifTrue:[nil] cg@2434: ifFalse:[self shownLanguages first] fm@2050: ! fm@2050: fm@2051: hasFirstRowSelection fm@2051: self selectedKeyRow isNil ifTrue:[^false]. fm@2051: ^ self selectedKeyRow value > 1 fm@2051: ! fm@2051: fm@2051: hasLanguageSelection fm@2051: dataSetView selectedColIndex isNil ifTrue:[^false]. fm@2051: ^ dataSetView selectedColIndex > 1 fm@2051: ! fm@2051: cg@2015: hasUnsavedChanges cg@2015: ^ modified fm@2050: ! fm@2050: fm@2163: includesKey: aKey fm@2163: keyStringsToLanguageMappings isNil ifTrue:[^false]. fm@2163: ^keyStringsToLanguageMappings includesKey:aKey fm@2163: ! fm@2163: fm@2051: isSearchForSimilarTranslationEnabled fm@2051: fm@2163: ^self searchForSimilarTranslationEnableHolder value fm@2051: ! fm@2051: fm@2051: languageTextFromKey: aKeyIndex for: language cg@2434: "Returns the language text corresponding for the aKeyIndex and the received language" fm@2051: fm@2051: language isNil ifTrue:[^'']. cg@2434: ^keyStringsToLanguageMappings at: aKeyIndex language:language. fm@2051: ! fm@2051: fm@2050: languageTextFromSelectedKeyFor: language cg@2434: "Returns the language text corresponding for the current selected key and the received language" cg@2434: cg@2434: ^self languageTextFromKey: self selectedKey for: language fm@2051: ! fm@2051: fm@2051: shouldCopyPreviousTranslationButtonBeEnabled cg@2434: ^ self hasLanguageSelection cg@2434: and:[self hasFirstRowSelection] fm@2051: ! fm@2051: fm@2323: shouldPasteOriginalButtonBeEnabled cg@2434: ^ self hasLanguageSelection cg@2434: and:[self hasFirstRowSelection] fm@2323: ! fm@2323: fm@2051: shouldSearchForSimilarTranslation fm@2051: fm@2163: self isSearchForSimilarTranslationEnabled ifFalse:[^false]. fm@2163: (self languageTextHolder value notNil and:[self languageTextHolder value notEmpty]) ifTrue:[^false]. fm@2163: (self hasLanguageSelection and:[self selectedKeyRow notNil]) ifFalse:[^false]. fm@2163: ^true fm@2050: ! ! fm@2050: fm@2050: !InternationalLanguageTranslationEditor methodsFor:'read/write resourceFile'! fm@2050: fm@2053: encoderAt: lang fm@2053: fm@2163: self alwaysWriteUTF8Holder value ifTrue:[^CharacterEncoder encoderForUTF8]. fm@2163: ^keyStringsToLanguageMappings encoderAt: lang. fm@2053: ! fm@2053: fm@2050: printEditingWarningOn: aStream fm@2050: fm@2163: aStream nextPutAll: ';'; cg@3522: cr; cg@3522: nextPutAll: '; WARNING:'; cg@3522: cr; cg@3522: nextPutAll: '; this file contains national characters.'; cg@3522: cr; cg@3522: nextPutAll: '; DO NOT EDIT this file with an old vi!!'; cg@3522: cr; cg@3522: nextPutAll: ';'; cg@3522: cr; cg@3522: cr. fm@2050: ! fm@2050: fm@2050: printEncoderFor: lang on: aStream fm@2163: |characterEncoder encoderString| fm@2050: fm@2163: characterEncoder := self encoderAt: lang. cg@2434: encoderString := characterEncoder isNil cg@2434: ifTrue:[self requestEncoderStringFor: lang] cg@2434: ifFalse:[characterEncoder nameOfEncoding printString]. fm@2050: fm@2163: aStream nextPutAll: '#encoding'; cg@2434: space; cg@2434: nextPutAll: encoderString; cg@2434: cr; cg@2434: cr. fm@2050: ! fm@2050: fm@2050: printLanguage: lang on: aStream fm@2050: fm@2163: self printEncoderFor: lang on: aStream. fm@2163: self printEditingWarningOn: aStream. fm@2163: self printLanguageMappingsFor: lang on: aStream. fm@2050: ! fm@2050: fm@2050: printLanguageMappingsFor: lang on: aStream fm@2050: cg@2434: |orderedAssociations maxKeySize characterEncoder| fm@2050: fm@2163: characterEncoder := self encoderAt: lang. fm@2163: characterEncoder isNil ifTrue:[ characterEncoder := CharacterEncoder::NullEncoder ]. cg@2434: orderedAssociations := keyStringsToLanguageMappings orderedLanguageMappingsAssociationsFor: lang. cg@2434: cg@2434: maxKeySize := keyStringsToLanguageMappings maxKeySizeForLanguage: lang. fm@2050: fm@2163: orderedAssociations do:[:association | cg@3522: "use #basicStoreString to avoid implicit utf8Encoding for UnicodeStrings" cg@3522: aStream nextPutAll: ((characterEncoder encodeString:association key basicStoreString) paddedTo: maxKeySize) ; cg@3522: tab; cg@3522: nextPutAll: (characterEncoder encodeString: association value basicStoreString); cg@3522: cr. cg@3522: ]. fm@2050: ! fm@2050: fm@2050: readResourceFile:aFilename asLanguage:lang cg@3595: |resourcePack inStream lineString encoding cg@3595: decoder sortedKeys remainingKeys lineNr| fm@2050: cg@2410: aFilename exists ifFalse:[ cg@3595: Dialog information:(resources string:'Language file: "%1" does not exist' with:aFilename baseName). cg@3595: ^ self cg@2410: ]. fm@2050: fm@2050: resourcePack := ResourcePack new. fm@2050: cg@3595: inStream := LineNumberReadStream on:(aFilename readStream). fm@2050: [inStream atEnd] whileFalse:[ cg@3595: lineNr := inStream lineNumber. cg@3595: lineString := inStream nextLine. cg@3595: (lineString notEmpty cg@3595: and:[ (lineString startsWith:';') not and:[ (lineString startsWith:'"/') not]]) ifTrue:[ cg@3595: ((lineString startsWith:'#') and:[(lineString startsWith:'#(') not]) ifTrue:[ cg@3595: lineString := (lineString copyFrom:2) withoutSeparators. cg@3595: (lineString startsWith:'encoding ') ifTrue:[ cg@3595: encoding := ResourcePack extractEncodingFromLine:lineString. cg@3595: decoder := CharacterEncoder encoderFor:encoding ifAbsent:nil. cg@3595: ]. cg@3595: ] ifFalse:[ cg@3595: ResourcePack cg@3595: processResourceLine:lineString cg@3595: encoding:decoder cg@3595: file:aFilename pathName cg@3595: printErrorWith:[:msg | cg@3595: Transcript cg@3595: showCR:'%1[%2]: %3' cg@3595: with:(aFilename baseName) cg@3595: with:lineNr cg@3595: with:msg cg@3595: ] cg@3595: for:resourcePack cg@3595: keepUselessTranslations:true. cg@3595: ]. cg@3595: ]. fm@2050: ]. cg@2434: inStream close. fm@2050: fm@2050: sortedKeys := (resourcePack keys select:[:k | k isString]) asSortedCollection. fm@2050: remainingKeys := resourcePack keys select:[:k | k isString not]. fm@2050: fm@2050: keyStringsToLanguageMappings atLanguage: lang putFilename: aFilename. cg@2410: keyStringsToLanguageMappings atLanguage: lang putEncoder: decoder. fm@2050: fm@2050: sortedKeys do:[:k | cg@3595: keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k) sendChange:false fm@2050: ]. fm@2050: remainingKeys do:[:k | cg@3595: keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k) sendChange:false fm@2050: ]. cg@2410: keyStringsToLanguageMappings changed. cg@3595: cg@3595: "Modified: / 20-09-2018 / 11:09:39 / Claus Gittinger" fm@2050: ! fm@2050: fm@2053: saveLanguage: lang cg@3594: "Saves the language in the fileName from where the language resource was obtained." cg@3594: |filename| fm@2053: fm@2053: lang isNil ifTrue:[^ self]. cg@3594: filename := keyStringsToLanguageMappings filenameAt:lang. cg@3594: filename isNil ifTrue:[ cg@3594: "/ ask cg@3594: filename := self requestFilenameFor: lang. cg@3594: filename isNil ifTrue:[^ self]. fm@2053: ]. cg@3594: self saveResourceFile:filename for:lang asSymbol cg@3594: cg@3594: "Modified (format): / 15-09-2018 / 12:29:59 / Claus Gittinger" fm@2053: ! fm@2053: fm@2050: saveResourceFile: aFilename for: lang fm@2050: fm@2163: |aStream | fm@2050: fm@2163: keyStringsToLanguageMappings atLanguage: lang putFilename: aFilename. cg@2434: aStream := FileStream newFileNamed: aFilename. fm@2163: self printLanguage: lang on: aStream. fm@2163: aStream flush; cg@2434: close. fm@2163: DialogBox information: 'The resource file for the language ', lang printString storeString, ' was saved in the file: ', aFilename nameString cg@2015: ! ! cg@2015: fm@2327: !InternationalLanguageTranslationEditor methodsFor:'searching'! fm@2327: fm@2327: ignoreCaseHolderChanged fm@2327: fm@2327: self searchNextTextIncludingCurrentSelection: true. fm@2327: fm@2327: "Created: / 16-06-2007 / 09:33:33 / Administrador" fm@2327: ! fm@2327: fm@2327: searchNextText fm@2327: fm@2327: self searchNextTextIncludingCurrentSelection: false. fm@2327: fm@2327: "Modified: / 16-06-2007 / 09:21:14 / Administrador" fm@2327: ! fm@2327: fm@2327: searchNextTextFromBeginning fm@2327: |searchText rowFoundIndex| fm@2327: fm@2327: searchText := searchTextView contents. fm@2327: searchText isEmptyOrNil ifTrue:[^self]. fm@2327: self objectsList isEmpty ifTrue:[^self]. cg@2434: rowFoundIndex := self tableView findFirstRowWithString: searchText cg@2434: from:1 cg@2434: to:self objectsList size cg@2434: ignoreCase:self ignoreCaseHolder value. fm@2327: rowFoundIndex isNil ifTrue:[ cg@2434: self searchTextNotFound. cg@2434: ^self fm@2327: ]. fm@2327: self selectListIndex: rowFoundIndex fm@2327: fm@2327: "Created: / 16-06-2007 / 10:54:51 / Administrador" fm@2327: "Modified: / 19-06-2007 / 15:38:59 / Administrador" fm@2327: ! fm@2327: fm@2327: searchNextTextIncludingCurrentSelection: includeCurrentSelection fm@2327: |searchText currentSelectionIndex rowFoundIndex fromIndex listSize| fm@2327: fm@2327: self searchTextStarted. fm@2327: searchText := searchTextView contents. fm@2327: searchText isEmptyOrNil ifTrue:[^self]. fm@2327: self objectsList isEmpty ifTrue:[^self]. fm@2327: currentSelectionIndex := self currentSelectionIndex. fm@2327: (currentSelectionIndex isNil or:[currentSelectionIndex == 0]) ifTrue:[ cg@2434: self searchNextTextFromBeginning. cg@2434: ^self. fm@2327: ]. fm@2327: listSize := self objectsList size. fm@2327: (currentSelectionIndex == listSize and:[includeCurrentSelection not]) ifTrue:[ cg@2434: self searchNextTextReachEnd. cg@2434: ^self. fm@2327: ]. fm@2327: fromIndex := includeCurrentSelection cg@2434: ifTrue:[currentSelectionIndex] cg@2434: ifFalse:[currentSelectionIndex + 1]. cg@2434: rowFoundIndex := self tableView findFirstRowWithString: searchText cg@2434: from:fromIndex cg@2434: to:listSize cg@2434: ignoreCase:self ignoreCaseHolder value. fm@2327: rowFoundIndex isNil ifTrue:[ cg@2434: self searchNextTextReachEnd. cg@2434: ^self fm@2327: ]. fm@2327: self selectListIndex: rowFoundIndex fm@2327: fm@2327: "Created: / 16-06-2007 / 09:20:57 / Administrador" fm@2327: "Modified: / 19-06-2007 / 15:38:06 / Administrador" fm@2327: ! fm@2327: fm@2327: searchNextTextReachEnd fm@2327: |message| fm@2327: message := 'End of list reached, starting from the beginning'. fm@2327: self searchTextRestarted: message. fm@2330: Smalltalk beep. fm@2327: self searchNextTextFromBeginning. fm@2327: fm@2327: "Created: / 16-06-2007 / 11:00:59 / Administrador" fm@2327: ! fm@2327: fm@2327: searchPreviousText fm@2327: fm@2327: |searchText currentSelectionIndex rowFoundIndex fromIndex| fm@2327: fm@2327: self searchTextStarted. fm@2327: searchText := searchTextView contents. fm@2327: searchText isEmptyOrNil ifTrue:[^self]. fm@2327: self objectsList isEmpty ifTrue:[^self]. fm@2327: currentSelectionIndex := self currentSelectionIndex. fm@2327: currentSelectionIndex == 1 ifTrue:[ cg@2434: self searchPreviousTextReachBeginning. cg@2434: ^self. fm@2327: ]. fm@2327: (currentSelectionIndex isNil or:[currentSelectionIndex == 0]) cg@2434: ifTrue:[ cg@2434: self searchPreviousTextFromEnd. cg@2434: ^self. cg@2434: ] cg@2434: ifFalse:[fromIndex := currentSelectionIndex - 1]. cg@2434: rowFoundIndex := self tableView findFirstRowWithString: searchText cg@2434: from: fromIndex cg@2434: to: 1 cg@2434: by: -1 cg@2434: ignoreCase:self ignoreCaseHolder value. fm@2327: rowFoundIndex isNil ifTrue:[ cg@2434: self searchPreviousTextReachBeginning. cg@2434: ^self fm@2327: ]. fm@2327: self selectListIndex: rowFoundIndex. fm@2327: fm@2327: "Modified: / 19-06-2007 / 15:38:16 / Administrador" fm@2327: ! fm@2327: fm@2327: searchPreviousTextFromEnd fm@2327: fm@2327: |searchText rowFoundIndex| fm@2327: fm@2327: searchText := searchTextView contents. fm@2327: searchText isEmptyOrNil ifTrue:[^self]. fm@2327: self objectsList isEmpty ifTrue:[^self]. cg@2434: rowFoundIndex := self tableView findFirstRowWithString: searchText cg@2434: from: self objectsList size cg@2434: to: 1 cg@2434: by: -1 cg@2434: ignoreCase:self ignoreCaseHolder value. fm@2327: rowFoundIndex isNil ifTrue:[ cg@2434: self searchTextNotFound. cg@2434: ^self fm@2327: ]. fm@2327: self selectListIndex: rowFoundIndex. fm@2327: fm@2327: "Created: / 16-06-2007 / 10:55:43 / Administrador" fm@2327: "Modified: / 19-06-2007 / 15:38:26 / Administrador" fm@2327: ! fm@2327: fm@2327: searchPreviousTextReachBeginning fm@2327: |message| fm@2327: message := 'Beginning of list reached, starting from the end'. fm@2327: self searchTextRestarted: message. fm@2330: Smalltalk beep. fm@2327: self searchPreviousTextFromEnd. fm@2327: fm@2327: "Created: / 16-06-2007 / 11:01:23 / Administrador" fm@2327: ! fm@2327: fm@2327: searchTextModifiedHolderChanged fm@2327: fm@2327: self searchNextTextIncludingCurrentSelection: true. fm@2327: self searchTextModifiedHolder setValue: false. fm@2327: fm@2327: "/Transcript showCR: 'searchTextModifiedHolderChanged: ',(self searchTextHolder value ? ''). fm@2327: "/Transcript showCR: 'searchTextView contents: ',(searchTextView contents ? ''). fm@2327: fm@2327: "Created: / 15-06-2007 / 18:07:57 / Administrador" fm@2327: "Modified: / 16-06-2007 / 09:21:27 / Administrador" fm@2327: ! fm@2327: fm@2327: searchTextNotFound fm@2327: fm@2327: self selectListIndex: 0. fm@2327: self searchBarImageInfoLabelHolder value: self warningSearchBarIcon. fm@2327: self searchBarInfoLabelHolder value: 'Text not found'. fm@2327: self setSearchTextNotFoundColors. fm@2327: fm@2327: "Created: / 16-06-2007 / 06:51:01 / Administrador" fm@2327: "Modified: / 16-06-2007 / 11:43:53 / Administrador" fm@2327: ! fm@2327: fm@2327: searchTextRestarted: message fm@2327: fm@2327: self searchBarImageInfoLabelHolder value: self restartSearchBarIcon. fm@2327: self searchBarInfoLabelHolder value: message. fm@2327: "/ self setSearchTextNotFoundColors. fm@2327: fm@2327: "Created: / 16-06-2007 / 11:02:06 / Administrador" fm@2327: ! fm@2327: fm@2327: searchTextStarted fm@2327: fm@2327: self searchBarImageInfoLabelHolder value: nil. fm@2327: self searchBarInfoLabelHolder value: ''. fm@2327: self setSearchTextFoundColors. fm@2327: fm@2327: "Created: / 16-06-2007 / 06:54:03 / Administrador" fm@2327: "Modified: / 16-06-2007 / 10:07:06 / Administrador" fm@2327: ! fm@2327: fm@2327: setSearchTextFoundColors fm@2327: fm@2327: searchTextView foregroundColor: Color black. fm@2327: searchTextView backgroundColor: Color white. fm@2327: fm@2327: "Created: / 16-06-2007 / 06:28:32 / Administrador" fm@2327: ! fm@2327: fm@2327: setSearchTextNotFoundColors fm@2327: fm@2327: searchTextView foregroundColor: Color white. fm@2327: searchTextView backgroundColor: Color lightRed. fm@2327: fm@2327: "Created: / 16-06-2007 / 06:29:00 / Administrador" fm@2327: ! ! fm@2327: cg@2015: !InternationalLanguageTranslationEditor methodsFor:'specs-dynamic'! cg@2015: cg@2015: columnInRow:row at:colIndex cg@2015: |lang| cg@2015: cg@2015: lang := self languageAtCol:colIndex. cg@2015: ^ row atLanguage:lang cg@2015: ! cg@2015: cg@2015: getBackgroundForRow:row rowNr:rowNr col:colIndex cg@2015: |lang| cg@2015: cg@2015: colIndex == 1 ifTrue:[^ nil]. cg@2015: lang := self languageAtCol:colIndex. cg@2015: ^ (row atLanguage:lang) isNil ifTrue:[Color red lightened] ifFalse:nil cg@2015: ! cg@2015: cg@2015: keyStringAndLanguageSelectionTableColumnDescription cg@2015: |spec| cg@2015: cg@2015: spec := OrderedCollection new. cg@2015: cg@2047: spec add:(self class keyTableColumn first). cg@2015: cg@2015: self shownLanguages do:[:lang | cg@2434: |entry| cg@2434: cg@2434: entry := self class languageTableColumn first. cg@2434: entry := entry copy replaceAll:#lang with:lang. cg@2434: spec add: entry cg@2015: ]. cg@2015: ^ spec cg@2015: ! cg@2015: cg@2015: keyStringInRow:row cg@2015: ^ row keyString cg@2015: ! ! cg@2015: fm@2327: !InternationalLanguageTranslationEditor methodsFor:'update'! fm@2327: fm@2327: updateToolVisibility fm@2327: | bottomOffset searchBarVisible | fm@2327: fm@2327: bottomOffset := 0. fm@2327: fm@2327: searchBarVisible := self searchBoxVisible value. fm@2327: searchBarVisible ifTrue:[ cg@2434: bottomOffset := bottomOffset - searchBoxView height. fm@2327: ]. fm@2327: translationsPanel layout bottomOffset:bottomOffset-1. fm@2327: translationsPanel container notNil ifTrue:[ cg@2434: translationsPanel containerChangedSize. fm@2327: ]. fm@2327: fm@2327: "Created: / 16-06-2007 / 11:58:25 / Administrador" fm@2327: ! ! fm@2327: cg@2015: !InternationalLanguageTranslationEditor methodsFor:'user actions'! cg@2015: fm@2327: closeSearchBar fm@2327: fm@2327: self searchBoxVisible value: false. fm@2327: self updateToolVisibility. fm@2327: fm@2327: "Created: / 15-06-2007 / 18:03:05 / Administrador" fm@2327: "Modified: / 16-06-2007 / 11:58:52 / Administrador" fm@2327: ! fm@2327: fm@2050: exampleLanguageSelectionChanged fm@2050: fm@2050: self updateExampleLanguageText. fm@2050: ! fm@2050: cg@2434: languageTextAccepted cg@2416: |nextRowIndex selRow| cg@2416: cg@2416: selRow := self selectedKeyRow value. cg@2416: selRow notNil ifTrue:[ cg@2434: keyStringsToLanguageMappings size = selRow cg@2434: ifTrue:[ self updateLanguageTextModification.] cg@2434: ifFalse:[ cg@2434: nextRowIndex := selRow + 1. cg@2434: self selectedKeyRow value: nextRowIndex] cg@2416: ]. fm@2051: ! fm@2051: fm@2323: pasteOriginalInLanguageText fm@2323: fm@2323: fm@2323: | originalText| fm@2323: fm@2323: originalText := self selectedKey. fm@2323: languageEditor selectAll. fm@2323: languageEditor pasteOrReplace:originalText. fm@2323: self languageTextModifiedHolder value:true. fm@2323: ! fm@2323: fm@2051: pastePreviousTranslationInLanguageText fm@2051: "Obtain the text from the previous translation and paste it into the languageTextEditor" cg@2434: fm@2051: | previousLanguageText previousLanguageRow| fm@2051: fm@2051: previousLanguageRow := dataSetView at:self selectedKeyRow value - 1 cg@2434: ifAbsent:[^self]. fm@2051: previousLanguageText := previousLanguageRow atLanguage: self currentLanguage. fm@2051: languageEditor selectAll. fm@2051: languageEditor pasteOrReplace:previousLanguageText. fm@2051: self languageTextModifiedHolder value:true. fm@2051: ! fm@2051: fm@2327: search cg@3286: "make the searchbox visible" cg@3522: fm@2327: self searchBoxVisible value: true. fm@2327: self updateToolVisibility. fm@2327: searchTextView takeFocus. fm@2327: fm@2327: "Modified: / 16-06-2007 / 11:58:44 / Administrador" fm@2327: ! fm@2327: cg@2434: selectionChanged cg@2048: fm@2049: self updateOriginalTextModification. fm@2049: self updateLanguageTextModification. fm@2049: self updateLanguageAndKeySelection. fm@2050: self updateExampleLanguageText. cg@2015: fm@2051: self updateCopyPreviousTranslationButtonEnabled. fm@2323: self updatePasteOriginalButtonEnabled. fm@2051: fm@2049: self originalTextModifiedHolder value:false. fm@2049: self languageTextModifiedHolder value:false. fm@2051: fm@2051: self searchForSimilarTranslation. fm@2051: ! fm@2051: fm@2051: showMissingTranslationsOnlyChanged cg@2015: ! cg@2015: cg@2015: shownLanguagesChanged cg@2434: self keyStringAndLanguageSelectionTableColumnDescriptionHolder cg@2434: value:(self keyStringAndLanguageSelectionTableColumnDescription). cg@2015: ! cg@2015: cg@2015: stopApplication cg@2015: |p| cg@2015: cg@2015: (p := monitoredApplication) notNil ifTrue:[ cg@2434: p terminate. cg@2015: ]. cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::AccessCollectingPseudoResourcePack methodsFor:'accessing'! cg@2015: cg@2015: realResourcePack:something cg@2015: realResourcePack := something. cg@3286: ! cg@3286: cg@3286: watchingTranslationEditor:something cg@3286: watchingTranslationEditor := something. cg@3286: ! ! cg@3286: cg@3286: !InternationalLanguageTranslationEditor::AccessCollectingPseudoResourcePack methodsFor:'resource pack protocol'! cg@3286: cg@3286: forwardFor:aString cg@3286: collectedKeys isNil ifTrue:[ cg@3522: collectedKeys := Set new. cg@3286: ]. cg@3286: collectedKeys add:aString. cg@3286: watchingTranslationEditor notNil ifTrue:[ cg@3522: watchingTranslationEditor recordNewTranslation:aString. cg@3286: ]. cg@3286: ^ realResourcePack perform:(thisContext sender selector) withArguments:(thisContext sender args). cg@3286: ! cg@3286: cg@3286: string:aString cg@3286: ^ self forwardFor:aString cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings class methodsFor:'instance creation'! cg@2015: cg@2015: new cg@2015: ^ self basicNew initialize cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'accessing'! cg@2015: cg@2015: addKey:aKey cg@2410: self addKey:aKey sendChange:true cg@2410: ! cg@2410: cg@2410: addKey:aKey sendChange:aBoolean cg@2031: (keys includes:aKey) ifFalse:[ cg@2434: keys add:aKey. cg@2434: aBoolean ifTrue:[ self changed ]. cg@2031: ] cg@2015: ! cg@2015: cg@2015: addKeys:aCollectionOfKey cg@2015: keys addAll:aCollectionOfKey. cg@2015: self changed. cg@2015: ! cg@2015: cg@2015: addLanguage:lang cg@2031: (languages includes:lang) ifFalse:[ cg@2434: languages add:lang. cg@2434: perLanguageMappings at:lang put:(OrderedDictionary new). cg@2031: ] cg@2015: ! cg@2015: cg@2015: at:aKey language:language cg@2032: ^ (perLanguageMappings at:language) at:aKey ifAbsent:nil cg@2015: ! cg@2015: cg@2015: at:aKey language:language put:value cg@2015: self addKey:aKey. fm@2049: (perLanguageMappings at:language) at:aKey put:value. fm@2049: (self rowForKey:aKey) changed cg@2015: ! cg@2015: cg@2410: at:aKey language:language put:value sendChange:sendChange cg@2410: self addKey:aKey sendChange:sendChange. cg@2410: (perLanguageMappings at:language) at:aKey put:value. cg@2410: (self rowForKey:aKey) changed cg@2410: ! cg@2410: fm@2050: atLanguage: lang putEncoder: aDecoder fm@2050: fm@2050: ^(self languageInfoAt: lang) at: self encoderKey put: aDecoder fm@2050: ! fm@2050: fm@2050: atLanguage: lang putFilename: aFilename fm@2050: fm@2050: ^(self languageInfoAt: lang) at: self fileNameKey put: aFilename fm@2050: ! fm@2050: fm@2050: decoderKey fm@2050: ^#decoder fm@2050: ! fm@2050: cg@2434: encoderAt:lang fm@2050: ^ (self languageInfoAt:lang) at: self encoderKey ifAbsent:[nil] fm@2050: ! fm@2050: fm@2050: encoderKey fm@2050: ^#encoder fm@2050: ! fm@2050: fm@2050: fileNameKey fm@2050: ^ #filename fm@2050: ! fm@2050: cg@2434: filenameAt:lang fm@2050: ^ (self languageInfoAt:lang) at: self fileNameKey ifAbsent:[nil] fm@2050: ! fm@2050: cg@2015: keyAt:index fm@2051: ^ keys at:index ifAbsent:[nil]. cg@2015: ! cg@2015: cg@2015: keyAt:index ifAbsent:exceptionalValue cg@2015: ^ keys at:index ifAbsent:exceptionalValue. cg@2015: ! cg@2015: cg@2015: keys cg@2015: ^ keys cg@2015: ! cg@2015: cg@2434: languageInfoAt: lang fm@2050: fm@2050: ^self perLanguageInfo at: lang ifAbsentPut:[Dictionary new] fm@2050: ! fm@2050: cg@2015: languages cg@2015: ^ languages cg@2015: ! cg@2015: fm@2053: languagesInUse fm@2053: "Returns a collection of symbols for the languages that have mappings" fm@2053: fm@2053: ^self languages select:[:each | (self atLanguage: each) notEmpty] fm@2053: ! fm@2053: fm@2051: orderedLanguageMappingsAssociationsFor: language fm@2051: "Returns a collection of languageMappings associations (alphabetically ordered by keys) " cg@3522: ^(self atLanguage: language) associations cg@3522: asSortedCollection:[:a :b | a key isArray or:[b key isArray or:[a key < b key]]]. fm@2051: ! fm@2051: fm@2050: perLanguageInfo fm@2050: ^ perLanguageInfo fm@2050: ! fm@2050: fm@2050: perLanguageInfo:something fm@2050: perLanguageInfo := something. fm@2050: ! fm@2050: cg@2015: removeKey:aKey cg@2015: keys remove:aKey ifAbsent:[]. cg@2032: perLanguageMappings do:[:eachMapping | cg@2434: eachMapping removeKey:aKey ifAbsent:[]. cg@2015: ]. cg@2015: self changed. cg@2015: ! cg@2015: fm@2049: rowForKey:aKey cg@2434: ^ rowPerKey cg@2434: at:aKey cg@2434: ifAbsentPut:[InternationalLanguageTranslationEditor::LanguageMappingRow new cg@2434: key:aKey; mappings:self]. fm@2049: ! fm@2049: cg@2015: size cg@2015: ^ keys size cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'enumerating'! cg@2015: cg@2015: do:aBlock cg@2015: keys do:[:eachKey | cg@2434: aBlock value:(self rowForKey:eachKey). cg@2015: ]. cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'initialization'! cg@2015: cg@2015: initialize cg@2015: super initialize. cg@2015: cg@2015: keys := OrderedSet new. cg@2015: languages := OrderedCollection new. cg@2032: perLanguageMappings := Dictionary new. cg@2434: perLanguageInfo := Dictionary new. fm@2049: rowPerKey := Dictionary new. cg@2015: cg@2031: self addLanguage:#'de'. cg@2031: self addLanguage:#'fr'. cg@3077: self addLanguage:#'en'. cg@3077: self addLanguage:#'it'. cg@2031: self addLanguage:#'es'. cg@2031: self addLanguage:(Smalltalk language). cg@2031: cg@2031: "/ self initializeDemoMappings. cg@2031: ! cg@2031: cg@2031: initializeDemoMappings cg@2015: keys add:'open'. cg@2015: keys add:'close'. cg@2015: keys add:'yes'. cg@2015: keys add:'no'. cg@2015: cg@2015: self addLanguage:#'de'. cg@2015: self addLanguage:#'fr'. cg@2015: cg@3594: self at:'open' language:#'de' put:'öffnen'. cg@3594: self at:'close' language:#'de' put:'schließen'. cg@2434: self at:'yes' language:#'de' put:'ja'. cg@2434: self at:'no' language:#'de' put:'nein'. cg@2434: self at:'cancel' language:#'de' put:'abbrechen'. cg@2434: cg@2434: self at:'open' language:#'fr' put:'ouvrir'. cg@2434: self at:'close' language:#'fr' put:'fermer'. cg@2434: self at:'yes' language:#'fr' put:'oui'. cg@2434: self at:'no' language:#'fr' put:'non'. cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'private'! cg@2015: cg@2015: atLanguage:lang cg@2032: ^ perLanguageMappings at:lang cg@2015: ! cg@2015: cg@2015: atLanguageIndex:idx cg@2015: |lang| cg@2015: cg@2015: lang := languages at:idx. cg@2015: ^ self atLanguage:lang. cg@2032: ! cg@2032: cg@2032: mappingAtLanguage:lang cg@2032: ^ perLanguageMappings at:lang cg@2032: ! cg@2032: cg@2032: mappingAtLanguageIndex:idx cg@2032: |lang| cg@2032: cg@2032: lang := languages at:idx. cg@2032: ^ self mappingAtLanguage:lang. cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'queries'! cg@2015: cg@2015: includesKey:aKey cg@2015: ^ keys includes:aKey cg@2015: ! cg@2015: cg@2015: includesLanguage:lang cg@2015: ^ languages includes:lang cg@2015: ! cg@2015: cg@2015: indexOfKey:aKey cg@2015: ^ keys indexOf:aKey fm@2050: ! fm@2050: fm@2050: maxKeySizeForLanguage: lang fm@2050: fm@2050: ^(self atLanguage: lang) keys inject: 0 into:[:maxSize :each | fm@2051: (maxSize < each size and:[each size < 100]) cg@2434: ifTrue:[each size] cg@2434: ifFalse:[maxSize].]. fm@2051: ! fm@2051: fm@2051: searchForSimilarTranslation: aKey in: language fm@2327: "Returns a collection of translation associations that corresponds to a quite similar key comparing with aKey" fm@2327: fm@2327: |similarAssociations| cg@2434: cg@2434: similarAssociations:= fm@2327: (self mappingAtLanguage: language) associationsSelect:[:each | cg@3522: |eachKey| cg@3522: cg@3522: eachKey := eachKey. cg@3522: eachKey isString cg@3522: and:[(eachKey sameAs: aKey) cg@3522: or:[(aKey asUppercase startsWith: eachKey asUppercase) cg@3522: or:[((eachKey asUppercase levenshteinTo: aKey asUppercase)/ eachKey size) < 0.3 cg@3522: ]]] cg@3522: and:[each value notEmptyOrNil] fm@2327: ]. fm@2327: ^similarAssociations cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::LanguageMappingRow methodsFor:'accessing'! cg@2015: cg@2015: atLanguage:language cg@2032: |translation| cg@2032: cg@2032: translation := (mappings mappingAtLanguage:language) at:key ifAbsent:nil. cg@2032: ^ translation isNil ifTrue:nil ifFalse:[translation printString] cg@2015: ! cg@2015: cg@2015: columnAt:columnNr cg@2032: ^ (mappings mappingAtLanguageIndex:columnNr-1) at: key ifAbsent:nil cg@2015: ! cg@2015: cg@2015: key:something cg@2015: key := something. cg@2015: ! cg@2015: cg@2015: keyString cg@2032: ^ key printString cg@2015: ! cg@2015: cg@2015: mappings:something cg@2015: mappings := something. cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::UISpecVisitor methodsFor:'accessing'! cg@2015: cg@2015: translatedLabels cg@2015: ^ translatedLabels ? #() cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor::UISpecVisitor methodsFor:'visiting'! cg@2015: cg@2015: visitObject:anObject with:aParameter cg@2033: |l| cg@2033: cg@2015: (anObject isKindOf:UISpecification) ifTrue:[ cg@2434: (anObject respondsTo:#translateLabel) ifTrue:[ cg@2434: anObject translateLabel == true ifTrue:[ cg@2434: translatedLabels isNil ifTrue:[ cg@2434: translatedLabels := Set new. cg@2434: ]. cg@2434: l := anObject perform:#label ifNotUnderstood:nil. cg@2434: l notNil ifTrue:[ cg@2434: translatedLabels add:l. cg@2434: ]. cg@2434: ]. cg@2434: ]. cg@2015: ]. cg@2015: self visitChildrenOf:anObject. cg@2015: ! ! cg@2015: cg@2015: !InternationalLanguageTranslationEditor class methodsFor:'documentation'! cg@2015: cg@2015: version cg@2015: ^ '$Header$' sv@3246: ! sv@3246: sv@3246: version_CVS sv@3246: ^ '$Header$' cg@2015: ! ! cg@3594: