Tools__InternationalLanguageTranslationEditor.st
author Claus Gittinger <cg@exept.de>
Tue, 14 May 2019 09:46:21 +0200
changeset 3663 9d49ecf8661a
parent 3642 9b49ded14b95
child 3744 71fa6500e535
permissions -rw-r--r--
#UI_ENHANCEMENT by cg
class: TabListEditor class
changed:
#canvasSpec
#menu
#windowSpec
     1 "{ Encoding: utf8 }"
     2 
     3 "{ Package: 'stx:libtool2' }"
     4 
     5 "{ NameSpace: Tools }"
     6 
     7 ApplicationModel subclass:#InternationalLanguageTranslationEditor
     8 	instanceVariableNames:'languagesList keyStringsToLanguageMappings languageTextHolder
     9 		originalTextHolder modified shownLanguages selectedKeyRow
    10 		showMissingTranslationsOnly
    11 		keyStringAndLanguageSelectionTableColumnDescriptionHolder
    12 		languageShownHolders dataSetView lastExtractedClass
    13 		lastExtractedApplicationClass stopApplicationIconVisibleHolder
    14 		monitoredApplication originalTextModifiedHolder
    15 		languageTextModifiedHolder languageTextAcceptHolder
    16 		inSingleFileMode lastExtractedProject lastLanguage
    17 		lastSelectedKey autoAcceptHolder languageEditor
    18 		selectedColIndexHolder exampleLanguageSelectionHolder
    19 		exampleLanguageTextHolder pastePreviousTranslationEnableHolder
    20 		searchForSimilarTranslationEnableHolder alwaysWriteUTF8Holder
    21 		lastNameSpace pasteOriginalEnableHolder ignoreCaseHolder
    22 		closeSearchBar searchTextModifiedHolder searchNextText
    23 		searchBarImageInfoLabelHolder searchPreviousText searchBoxVisible
    24 		searchBarInfoLabelHolder searchTextHolder searchTextView
    25 		searchBoxView translationsPanel lastPackage methodsUsingKey'
    26 	classVariableNames:'LastExtractedClass LastExtractedApplicationClass
    27 		LastExtractedProject LastProject'
    28 	poolDictionaries:''
    29 	category:'Interface-UIPainter'
    30 !
    31 
    32 Object subclass:#AccessCollectingPseudoResourcePack
    33 	instanceVariableNames:'collectedKeys realResourcePack watchingTranslationEditor'
    34 	classVariableNames:''
    35 	poolDictionaries:''
    36 	privateIn:InternationalLanguageTranslationEditor
    37 !
    38 
    39 Collection subclass:#KeyStringsToLanguageMappings
    40 	instanceVariableNames:'keys keyInfo perLanguageInfo perLanguageMappings languageMappings
    41 		languages rowPerKey'
    42 	classVariableNames:''
    43 	poolDictionaries:''
    44 	privateIn:InternationalLanguageTranslationEditor
    45 !
    46 
    47 Object subclass:#LanguageMappingRow
    48 	instanceVariableNames:'key mappings'
    49 	classVariableNames:''
    50 	poolDictionaries:''
    51 	privateIn:InternationalLanguageTranslationEditor
    52 !
    53 
    54 Visitor subclass:#UISpecVisitor
    55 	instanceVariableNames:'translatedLabels'
    56 	classVariableNames:''
    57 	poolDictionaries:''
    58 	privateIn:InternationalLanguageTranslationEditor
    59 !
    60 
    61 !InternationalLanguageTranslationEditor class methodsFor:'documentation'!
    62 
    63 documentation
    64 "
    65     documentation to be added.
    66 
    67     [author:]
    68 	cg (cg@FUSI)
    69 
    70     [instance variables:]
    71 
    72     [class variables:]
    73 
    74     [see also:]
    75 
    76 "
    77 !
    78 
    79 examples
    80 "
    81   Starting the application:
    82 								[exBegin]
    83     InternationalLanguageTranslationEditor open
    84 
    85 								[exEnd]
    86 
    87   more examples to be added:
    88 								[exBegin]
    89     ... add code fragment for
    90     ... executable example here ...
    91 								[exEnd]
    92 "
    93 !
    94 
    95 history
    96     "Created: / 04-03-2006 / 09:07:19 / cg"
    97 ! !
    98 
    99 !InternationalLanguageTranslationEditor class methodsFor:'help spec'!
   100 
   101 helpSpec
   102     <resource: #help>
   103 
   104     ^ super helpSpec addPairsFrom:#(
   105 
   106 #searchBox
   107 'Show a search box at the bottom to search for substrings in the string keys'
   108 
   109 #browseReferringMethods
   110 'Browse methods which refer to this string'
   111 
   112 )
   113 ! !
   114 
   115 !InternationalLanguageTranslationEditor class methodsFor:'image specs'!
   116 
   117 closeSearchBarIcon
   118     "This resource specification was automatically generated
   119      by the ImageEditor of ST/X."
   120 
   121     "Do not manually edit this!! If it is corrupted,
   122      the ImageEditor may not be able to read the specification."
   123 
   124     "
   125      self closeSearchBar inspect
   126      ImageEditor openOnClass:self andSelector:#closeSearchBar
   127      Icon flushCachedIcons
   128     "
   129 
   130     <resource: #image>
   131 
   132     ^Icon
   133 	constantNamed:#'Psiware::SystemManagement class closeSearchBar'
   134 	ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
   135 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@GQ\SD1LSD1LSD1LSD1LWGP@@@@@@
   136 @ATGA@HA@PDA@PDA@PHDA1T@@@@@@@@TAENG!!(VB XA?_''57QPPT@@@@@@@@E NJ^V)&X%)UTT5IV7 KE @@@@@@@A A"7Q,#&9VS%^MQ$E<DQ @@@@@@@@Z
   137 @X%-#9NRX52R$80:^1@Z@@@@@@@@F0FHY6>R$9JR$9ION''(PF0@@@@@@@A<A 5ABT)FS$9D=KR13C1<@@@@@@@@)@WUCND*Q$9NQM"T!!XP8)@@@@@@@@K E2
   138 O4RQ$9FQ$9@2G%8JK @@@@@@@CLA\S2D$9D9M)BS]!!1]BSL@@@@@@@@7@W@5LXP6J2\2]"P"VP 7@@@@@@@@O U+R3@*I2T#HA0&N5 RO @@@@@@@D LPF%(
   139 YVQ W59]VU 4CD @@@@@@@AGFP4F@PDA@PDA@PDFCQ%G@@@@@@@@K41TUEQTUEQTUEQTUEQLK0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   140 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 167 25 15 170 49 40 171 50 39 174 68 60 176 56 48 176 58 49 183 118 110 184 45 32 184 46 32 184 47 34 184 71 58 184 85 78 184 86 79 185 53 39 186 57 42 186 59 43 186 60 45 186 68 58 190 187 180 192 188 181 193 189 182 194 190 183 195 192 184 197 194 186 202 148 142 202 199 191 205 202 195 207 64 48 207 203 195 208 65 49 208 205 198 209 65 49 209 66 49 209 69 52 210 66 49 210 78 64 211 67 51 211 71 54 212 69 51 212 208 200 212 208 202 213 69 52 213 70 52 213 79 57 215 80 59 215 212 206 217 214 207 218 79 62 218 84 67 219 107 95 219 216 210 221 84 63 221 84 67 221 109 96 221 218 213 222 76 56 222 110 96 222 113 79 223 87 67 223 87 70 223 115 99 224 221 216 225 89 72 225 105 91 225 117 84 227 89 64 227 91 73 227 112 98 227 115 95 227 122 92 227 224 219 227 225 219 228 113 83 228 113 99 229 102 87 229 226 221 230 115 84 230 117 81 230 142 117 231 102 80 231 116 86 231 120 103 231 131 119 231 228 224 232 118 88 232 119 82 233 143 117 234 99 76 234 102 79 234 119 89 234 127 100 234 145 119 235 104 82 235 106 86 236 108 89 236 110 92 236 113 92 236 121 91 236 146 119 237 113 95 237 115 98 237 122 92 237 132 100 238 117 101 238 119 104 238 123 93 238 123 109 238 131 98 238 133 102 238 146 120 238 148 121 239 125 112 239 127 115 239 129 118 239 131 105 239 134 102 240 135 122 240 200 196 242 135 113 242 141 116 242 141 119 242 145 116 242 147 118 242 148 120 243 137 115 243 138 118 243 141 121 243 142 123 243 144 126 243 145 129 243 151 134 243 202 197 244 147 132 244 149 135 244 152 137 244 163 142 244 164 145 245 160 143 245 164 146 245 213 204 246 213 203 248 215 205 249 215 206 252 244 243 253 244 243 253 247 245 255 255 255]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@G?? G?? G?? G?? G?? G?? G?? G?? G?? G?? G?? G?? G?? G?? G?? G?? @@@@@@@@@@@@') ; yourself); yourself]
   141 
   142     "Created: / 15-06-2007 / 18:04:38 / Administrador"
   143 !
   144 
   145 restartSearchBarIcon
   146     "This resource specification was automatically generated
   147      by the ImageEditor of ST/X."
   148 
   149     "Do not manually edit this!! If it is corrupted,
   150      the ImageEditor may not be able to read the specification."
   151 
   152     "
   153      self restartSearchBarIcon inspect
   154      ImageEditor openOnClass:self andSelector:#restartSearchBarIcon
   155      Icon flushCachedIcons
   156     "
   157 
   158     <resource: #image>
   159 
   160     ^Icon
   161 	constantNamed:#'Psiware::SystemManagement class restartSearchBarIcon'
   162 	ifAbsentPut:[(Depth24Image new) width: 20; height: 20; photometric:(#rgb); bitsPerSample:(#[8 8 8]); samplesPerPixel:(3); bits:(ByteArray fromPackedString:'
   163 @@@@@@@@@@@@@@@@@@@@@@@@?>SX?>''V?>;)?>O!!?>G]?>WY@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?=3\:[>''5;JF/Y-.+XY),(U.
   164 6JZK?=J1?>V<>.+I@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?>?'':+:!!19]U6*-Q?]Y/?>RC?>*!!?>F_>+=939UL2Y!!L>MJT??W[@@@@@@@@@@@@@@@@@@@@
   165 @@@@??[-=\^&1IEP=<Q[?>1/?=5$?=52?>NT?=^Q?>BP?>FG>;1]6JEO8;^H?]3I@@@@@@@@@@@@@@@@@@@@?\*95Y-)<+!!$??.F?>)17+-U8,E40Y-.09I)
   166 :Z1-?=I??=)8?<1.>K597;NL??K,@@@@@@@@@@@@?=#M6I>B>+:@?>2U=,]]5[IN7,^C5LB[<MWL?]#O=,BZ7)=\>;Y[??FP?=>O1YEW8<B$;=WH@@@@@@@@
   167 >,"%8Z:A?>N#?>._5KA$9-JW7=+FX6M+V%U3"''*T0Y>V4ZA7595T=;1"?=&D?=&L,W(93IU\:KE9=LBG9[Q9;K1<?=^R:K591*-6??''[@@@@RE%37>7?=?/?
   168 >^_''3*.M0YAU<K5,?>ZO?=>G?<!!6?<Y6>+U(69YI3:IG?=Z@?>NU5:=19,6%@@@@@@@@OU5*2.+7;O??5-KF2;JS?=*&?>&"?=.E?>2R?=&F?>"X8I-N5)ED
   169 29$&?>M:?=*F3:E&>]/A@@@@@@@@O5=.7O??5^/(?O++<M.>0I-/;LNE??2)?=&B?>^%,W)A8:14?=FX3)TR?>U/?=Q:3IAZ?=?T@@@@@@@@P5Y68_#?7.70
   170 ??[1??C_:,F%6;A=>MJA?>6":,6+&G91?>+^?>+]79<$?<1\?=:C5IM[?<;F@@@@@@@@Q$1>6N_?<?+?<.W.?>3*??S(=,.(2Z!!#=-:^+9>P4,[P<>''46=O^
   171 =+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''?
   172 >/C???K??NK/??[1???#9M?B??3;(IV#/[WD;^_5@@@@;KR]<[10?=Q68[9,8,>W@@@@TU9&;/??9__9:.;/?_#<??/?>?[==?79>_?=<_S9T5M[0,WN7^G*
   173 @@@@@@@@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
   174 U5AWV5%.U5);R5M:Q5M;S%-=TE]*[GI>):696M;*@@@@@@@@@@@@6\F[2Y914)9.;[VF?L"!!8[^_3J>''0KB:0;?V0,_''-<C),K/(,;7!!+[OI,K[D2=G_9N+8
   175 @@@@@@@@@@@@@@@@@@@@?\*_7*]>3))5/II9+9FF+9> 0;7I5-#-7NO?7^#?8^/?:/G?7NK07>W3@@@@@@@@@@@@@@@@@@@@@@@@?>N;?>N;?=:9?>7T?>#X
   176 >^_%=N?6<OK?@@@@@@@@@@@@@@@@@@@@@@@@@@@@') ; mask:((Depth1Image new) width: 20; height: 20; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@?@OC?0OO?8O_?<O_?>O???O?????_??>_??>_??>_??>_??>_??>_??__??O???O???G???A??/A? O') ; yourself); yourself]
   177 !
   178 
   179 searchNextIcon
   180     "This resource specification was automatically generated
   181      by the ImageEditor of ST/X."
   182 
   183     "Do not manually edit this!! If it is corrupted,
   184      the ImageEditor may not be able to read the specification."
   185 
   186     "
   187      self searchNextIcon inspect
   188      ImageEditor openOnClass:self andSelector:#searchNextIcon
   189      Icon flushCachedIcons
   190     "
   191 
   192     <resource: #image>
   193 
   194     ^Icon
   195 	constantNamed:#'Psiware::SystemManagement class searchNextIcon'
   196 	ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
   197 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ZE)ZZ@@@@@@@@@@@@@@@
   198 @@@@@@AFF XA@PXUQ @@@@@@@@@@@@@@@@@*@Q5G^WX6E0D*@@@@@@@@@@@@@@@,AVQ?\&1#W&X8@20@@@@@@@@@@@A[@U==\F-"VUQOUSLAV0@@@@@@@@@@
   199 G19-D <NCP0KB!!@7D1<@@@@@@@@@  ]MT5JY&Y&Y&Y%RLR4G  @@@@@@@H\A WL $)&Y&Y&RF35B@X\@@@@@@@BK@XA1WA"X&Y&XE#T:P@FK@@@@@@@@# !!H
   200 ]F$<II&YH3H>N2 H# @@@@@@@@@''GG)*Y2$9NRIDO4DQHP@@@@@@@@@@!!@EP[6U]I"UIQTL.@XP@@@@@@@@@@@ALAD-.XE]VS$(/@$0@@@@@@@@@@@@@@EDA
   201 FSQ!!VC@T@UD@@@@@@@@@@@@@@@@@#R,I@PDIJ84@@@@@@@@@@@@@@@@@@@@@%)^W% @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   202 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@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@?<CA?>CC??CC??CG??#G??#G??#G??#C??CC??CA?>C@?<C@_8C@G C@@@C@@@C@@@C') ; yourself); yourself]
   203 !
   204 
   205 searchPreviousIcon
   206     "This resource specification was automatically generated
   207      by the ImageEditor of ST/X."
   208 
   209     "Do not manually edit this!! If it is corrupted,
   210      the ImageEditor may not be able to read the specification."
   211 
   212     "
   213      self searchPreviousIcon inspect
   214      ImageEditor openOnClass:self andSelector:#searchPreviousIcon
   215      Icon flushCachedIcons
   216     "
   217 
   218     <resource: #image>
   219 
   220     ^Icon
   221 	constantNamed:#'Psiware::SystemManagement class searchPreviousIcon'
   222 	ifAbsentPut:[(Depth8Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
   223 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%)^W% @@@@@@@@@@@@@@
   224 @@@@@@BMJ0$A@P$+#P@@@@@@@@@@@@@@@@AQ@Q$4XU 0E@EQ@@@@@@@@@@@@@@ALAD-.XE]VS$(/@$0@@@@@@@@@@@BD@UA/YU4&IT%EP28A!!@@@@@@@@@@@
   225 I11:Z&\)NS$"QC=ADRD@@@@@@@@@# !!H]F$<II&YH3H>N2 H# @@@@@@@H,A GE\FI"Y&Y VMS)@@X,@@@@@@@BG@XE3HIJY&Y&Y$!!,=P FG@@@@@@@@  ]M
   226 T5JY&Y&Y&Y%RLR4G  @@@@@@@@@_G&4RC08MC@,JDC\SG0@@@@@@@@@@V0E__WA+X%%TS5T3@U,@@@@@@@@@@@@,AVQ?\&1#W&X8@20@@@@@@@@@@@@@@B(A
   227 GT]9]#XW@R(@@@@@@@@@@@@@@@@@Q!!(F@PDFETX@@@@@@@@@@@@@@@@@@@@@ZE)ZZ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   228 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@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@?<CA?>CC??CC??CG??#G??#G??#G??#C??CC??CA?>C@?<C@_8C@G C@@@C@@@C@@@C') ; yourself); yourself]
   229 !
   230 
   231 searchToolBarIcon
   232     "This resource specification was automatically generated
   233      by the ImageEditor of ST/X."
   234 
   235     "Do not manually edit this!! If it is corrupted,
   236      the ImageEditor may not be able to read the specification."
   237 
   238     "
   239      self searchToolBarIcon inspect
   240      ImageEditor openOnClass:self andSelector:#searchToolBarIcon
   241      Icon flushCachedIcons
   242     "
   243 
   244     <resource: #image>
   245 
   246     ^Icon
   247 	constantNamed:#'Psiware::SystemManagement class searchToolBarIcon'
   248 	ifAbsentPut:[(Depth24Image new) width: 22; height: 22; photometric:(#rgb); bitsPerSample:(#[8 8 8]); samplesPerPixel:(3); bits:(ByteArray fromPackedString:'
   249 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   250 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   251 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4][>4][>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   252 @@@@@@@@@@@@@@@@@@@@@@@@@@@@;>#8/L#+!!:KS!!:KS/,'',;>''9@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2];>^)WH
   253 NE:+KU*:J5&9NE6*_I#K4^S>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4][>RV3DLER"SWR6$K#0#;[.SGJ4L5"''UG_N4][>@@@@
   254 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*K''\JT*,U6Z7:^S?>/C*;.3,6>C>RFF(KEZ"3-_-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   255 @@@@@@@@@@@@&Z''HFTF &Z7">N#:7NK?7NK?6=W>!!Y''YH4N -+3T@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%I>;FDV)#ZWU??''57NK?
   256 7NK?:>_?\8WKFCN".K#T@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@1L;.A#V[O5")3=W;=/[4</W:1,??K$JVI4Z\7-''4@@@@@@@@@@@@
   257 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7NK?-,[1E#:&C"ZZH3F U6_EU63FHS^XHS.K JOX7-''4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7NK?
   258 ,K_*O5ZTCRBLPU&0FCBHDB&RDR6RH$NI Y#I4][>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7NK?-;#%ND&KC">BYV.*4=;>7.+>-<K!!,K/!!7NK?
   259 :^C;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7NK?/K3^PT%<CBI/NE>==O;8@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   260 @@@@@@@@@@@@7NK? (J9GB1SZV>W:M3?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@5MS&++3H6M/#@@@@
   261 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7NK?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   262 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   263 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   264 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   265 @@@@@@@@@@@@@@@@') ; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@C@@@C@@@C@A C@G8C@O<C@_>C@_>C@_>C@_>C@_>C@?>CA?<CC?8CG8@CG0@CC @CA@@C@@@C@@@C@@@C@@@C') ; yourself); yourself]
   266 !
   267 
   268 warningSearchBarIcon
   269     "This resource specification was automatically generated
   270      by the ImageEditor of ST/X."
   271 
   272     "Do not manually edit this!! If it is corrupted,
   273      the ImageEditor may not be able to read the specification."
   274 
   275     "
   276      self warningSearchBarIcon inspect
   277      ImageEditor openOnClass:self andSelector:#warningSearchBarIcon
   278      Icon flushCachedIcons
   279     "
   280 
   281     <resource: #image>
   282 
   283     ^Icon
   284 	constantNamed:#'Psiware::SystemManagement class warningSearchBarIcon'
   285 	ifAbsentPut:[(Depth24Image new) width: 22; height: 19; photometric:(#rgb); bitsPerSample:(#[8 8 8]); samplesPerPixel:(3); bits:(ByteArray fromPackedString:'
   286 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?:.+<Y"P??C\@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@>_;?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   287 @@@@?]SZ)5]X.6!! -HM2??''*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?>39-7*B4H&G>[N+%%MJ>\#A@@@@@@@@
   288 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<+R?*U1&?=CN?>W^4HJ@+FY$?>+"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   289 @@@@@@@@@@@@@@@@@@@@?>G_)U!!^>Z^->,B><+"4?*^-%C8?;;Z+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??#1-(E;.65+?<#H
   290 ?=_T?=GP?::65W-=(EQF?>WQ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?\#D*VAY?;61<;"0;,C@6J^+;*"0>ZN$&CX)6(-:@@@@@@@@
   291 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?>#+/7Q148E6?<"4<L&:W#(:G@@@392!!48^G9WM(%24_?=WN@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   292 ??C?7Y&$.E5\?;V*=<:8??K_R3X5DP@@4+R49ZZ!!7VIZ/#85)%UR??G/@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?=7.2&)6=IJQ?;..=]W@??7*PS$7E@,N
   293 4<OC?>K^>(M=1S8;)$ID8Y6^@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@;HNR4U%%<)&S?<^9??_(??;3REEN@P,J2<[C??K/?:R!!/C8?&R(0(T-N?>GZ@@@@
   294 @@@@@@@@@@@@@@@@@@@@?<;H,31B3T9U2'')1?L3@?>3&=^7*XWE0@@<M7=;\??S3?=_U46-,#Q(!!$B,/18"A@@@@@@@@@@@@@@@@@@@@??G&1G!!*,S03)SP,
   295 3()?>=WL??_:<>33[G:@D2T%;^/,??#8??K19Y6^&R(0!!QPX#S8:;K22@@@@@@@@@@@@@@@@<*RZ+5I@*$D+*T48<[N&?>C_7,+U??3?7N''/(J.-?/+;??W5
   296 ;.O!!?>G_3&]+ 0(O#B8.(U9X@@@@@@@@@@@@?<?Y/%MM.487%$P^7I)7?<&=?=+ <^W3;?C?YV]3JR .-*60=/W35.[#<>W"?:*+*3@3$R\)^R ''2)^T@@@@
   297 ?>K2;(ZO2DQ@-SP!!,5H/?<F!!?<V=?;3B?=_"?>7:)72EUBT+<,GD?>?,<M;Z>]GO?<#J8VM& P4P_A0^ C(:?>+''?:"+34%H13L/02("13T(13\,5$H>3S<=
   298 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
   299 (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@?<C@?<CA?>CC??CC??CC??#G??#O??3O??3_??;????????????????') ; yourself); yourself]
   300 ! !
   301 
   302 !InternationalLanguageTranslationEditor class methodsFor:'interface specs'!
   303 
   304 windowSpec
   305     "This resource specification was automatically generated
   306      by the UIPainter of ST/X."
   307 
   308     "Do not manually edit this!! If it is corrupted,
   309      the UIPainter may not be able to read the specification."
   310 
   311     "
   312      UIPainter new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#windowSpec
   313      Tools::InternationalLanguageTranslationEditor new openInterface:#windowSpec
   314      Tools::InternationalLanguageTranslationEditor open
   315     "
   316 
   317     <resource: #canvas>
   318 
   319     ^ 
   320     #(FullSpec
   321        name: windowSpec
   322        uuid: 'ba9bc312-367b-11e9-8e9b-b8f6b1108e05'
   323        window: 
   324       (WindowSpec
   325          label: 'InternationalLanguageTranslationEditor'
   326          name: 'InternationalLanguageTranslationEditor'
   327          uuid: '37d7f60e-b8d0-11e8-aeef-b8f6b1108e05'
   328          min: (Point 10 10)
   329          bounds: (Rectangle 0 0 774 610)
   330          menu: mainMenu
   331        )
   332        component: 
   333       (SpecCollection
   334          collection: (
   335           (MenuPanelSpec
   336              name: 'ToolBar'
   337              layout: (LayoutFrame 0 0 0 0 0 1 30 0)
   338              uuid: '37d7f820-b8d0-11e8-aeef-b8f6b1108e05'
   339              menu: menuToolBar
   340              textDefault: true
   341            )
   342           (VariableVerticalPanelSpec
   343              name: 'TranslationsVariableVerticalPanel'
   344              layout: (LayoutFrame 0 0 30 0 0 1 -32 1)
   345              uuid: '37d7f9ce-b8d0-11e8-aeef-b8f6b1108e05'
   346              component: 
   347             (SpecCollection
   348                collection: (
   349                 (DataSetSpec
   350                    name: 'KeyStringAndLanguageSelectionTable'
   351                    uuid: '37d7fb2c-b8d0-11e8-aeef-b8f6b1108e05'
   352                    model: selectedKeyRow
   353                    menu: keyStringAndLanguageSelectionTableMenu
   354                    hasHorizontalScrollBar: true
   355                    hasVerticalScrollBar: true
   356                    dataList: keyStringAndLanguageSelectionTable
   357                    columnHolder: keyStringAndLanguageSelectionTableColumnDescriptionHolder
   358                    beDependentOfRows: true
   359                    columnAdaptor: yourself
   360                    postBuildCallback: postBuildDataSet:
   361                  )
   362                 (VariableVerticalPanelSpec
   363                    name: 'VariableVerticalPanel1'
   364                    uuid: '37d7fd48-b8d0-11e8-aeef-b8f6b1108e05'
   365                    component: 
   366                   (SpecCollection
   367                      collection: (
   368                       (ViewSpec
   369                          name: 'Box1'
   370                          uuid: '37d7fe24-b8d0-11e8-aeef-b8f6b1108e05'
   371                          component: 
   372                         (SpecCollection
   373                            collection: (
   374                             (LabelSpec
   375                                label: 'Original String (Key):'
   376                                name: 'Label2'
   377                                layout: (LayoutFrame 0 0 -2 0 0 1 28 0)
   378                                uuid: '37d7fee2-b8d0-11e8-aeef-b8f6b1108e05'
   379                                translateLabel: true
   380                                adjust: left
   381                              )
   382                             (TextEditorSpec
   383                                name: 'OriginalText'
   384                                layout: (LayoutFrame 0 0 27 0 0 1 -2 1)
   385                                uuid: '37d8002c-b8d0-11e8-aeef-b8f6b1108e05'
   386                                model: originalTextHolder
   387                                hasHorizontalScrollBar: true
   388                                hasVerticalScrollBar: true
   389                                modifiedChannel: originalTextModifiedHolder
   390                                acceptCallBack: languageTextAccepted
   391                                hasKeyboardFocusInitially: false
   392                              )
   393                             )
   394                           
   395                          )
   396                        )
   397                       (ViewSpec
   398                          name: 'Box3'
   399                          uuid: '37d801bc-b8d0-11e8-aeef-b8f6b1108e05'
   400                          component: 
   401                         (SpecCollection
   402                            collection: (
   403                             (LabelSpec
   404                                label: 'Select Another Language as example:'
   405                                name: 'Label3'
   406                                layout: (LayoutFrame 0 0 -6 0 0 1 24 0)
   407                                uuid: '37d80270-b8d0-11e8-aeef-b8f6b1108e05'
   408                                translateLabel: true
   409                                adjust: left
   410                              )
   411                             (ComboBoxSpec
   412                                name: 'ComboBox1'
   413                                layout: (LayoutFrame 281 0 -2 0 406 0 18 0)
   414                                uuid: '37d80360-b8d0-11e8-aeef-b8f6b1108e05'
   415                                model: exampleLanguageSelectionHolder
   416                                immediateAccept: false
   417                                acceptOnLeave: true
   418                                acceptOnLostFocus: true
   419                                acceptOnPointerLeave: false
   420                                comboList: shownLanguages
   421                                useIndex: false
   422                              )
   423                             (TextEditorSpec
   424                                name: 'ExampleLanguageText'
   425                                layout: (LayoutFrame 0 0 30 0 0 1 0 1)
   426                                uuid: '37d805cc-b8d0-11e8-aeef-b8f6b1108e05'
   427                                model: exampleLanguageTextHolder
   428                                hasHorizontalScrollBar: true
   429                                hasVerticalScrollBar: true
   430                                isReadOnly: true
   431                                hasKeyboardFocusInitially: false
   432                              )
   433                             )
   434                           
   435                          )
   436                        )
   437                       (ViewSpec
   438                          name: 'Box2'
   439                          uuid: '37d8070c-b8d0-11e8-aeef-b8f6b1108e05'
   440                          component: 
   441                         (SpecCollection
   442                            collection: (
   443                             (LabelSpec
   444                                label: 'Translated String:'
   445                                name: 'Label1'
   446                                layout: (LayoutFrame 0 0 0 0 0 1 30 0)
   447                                uuid: '37d807ca-b8d0-11e8-aeef-b8f6b1108e05'
   448                                translateLabel: true
   449                                adjust: left
   450                              )
   451                             (TextEditorSpec
   452                                name: 'LanguageText'
   453                                layout: (LayoutFrame 0 0 30 0 0 1 0 1)
   454                                uuid: '37d808ba-b8d0-11e8-aeef-b8f6b1108e05'
   455                                model: languageTextHolder
   456                                hasHorizontalScrollBar: true
   457                                hasVerticalScrollBar: true
   458                                acceptChannel: languageTextAcceptHolder
   459                                modifiedChannel: languageTextModifiedHolder
   460                                acceptCallBack: languageTextAccepted
   461                                hasKeyboardFocusInitially: false
   462                                postBuildCallback: languageEditorBuilt:
   463                              )
   464                             (ActionButtonSpec
   465                                label: 'Add'
   466                                name: 'Button2'
   467                                layout: (LayoutFrame -344 0.83085250338295003 0 0 -255 0.83085250338295003 27 0)
   468                                uuid: '37d809fa-b8d0-11e8-aeef-b8f6b1108e05'
   469                                translateLabel: true
   470                                model: addTranslationEntry
   471                              )
   472                             (ActionButtonSpec
   473                                label: 'Paste Original'
   474                                name: 'Button1'
   475                                layout: (LayoutFrame -202 0.83085250338295003 0 0 -71 0.83085250338295003 27 0)
   476                                uuid: '37d809fa-b8d0-11e8-aeef-b8f6b1108e05'
   477                                translateLabel: true
   478                                model: pasteOriginalInLanguageText
   479                                enableChannel: pasteOriginalEnableHolder
   480                                disabledLogo: 'Paste Original'
   481                              )
   482                             (ActionButtonSpec
   483                                label: 'Paste Previous'
   484                                name: 'pastePreviousTranslation'
   485                                layout: (LayoutFrame -66 0.83085250338295003 0 0 127 0.83085250338295003 27 0)
   486                                uuid: '37d80b80-b8d0-11e8-aeef-b8f6b1108e05'
   487                                translateLabel: true
   488                                model: pastePreviousTranslationInLanguageText
   489                                enableChannel: pastePreviousTranslationEnableHolder
   490                                disabledLogo: 'Paste Previous'
   491                              )
   492                             )
   493                           
   494                          )
   495                        )
   496                       )
   497                     
   498                    )
   499                    handles: (Any 0.33000000000000002 0.67000000000000004 1.0)
   500                  )
   501                 )
   502               
   503              )
   504              handles: (Any 0.5 1.0)
   505              postBuildCallback: postBuildTranslationsPanel:
   506            )
   507           (ViewSpec
   508              name: 'SearchBox'
   509              layout: (LayoutFrame 0 0 -32 1 0 1 0 1)
   510              uuid: '37d80cf2-b8d0-11e8-aeef-b8f6b1108e05'
   511              level: -1
   512              visibilityChannel: searchBoxVisible
   513              component: 
   514             (SpecCollection
   515                collection: (
   516                 (ActionButtonSpec
   517                    label: 'closeSearchBarIcon'
   518                    name: 'closeSearchBarButton'
   519                    layout: (LayoutFrame 4 0 5 0 25 0 26 0)
   520                    uuid: '37d80dc4-b8d0-11e8-aeef-b8f6b1108e05'
   521                    hasCharacterOrientedLabel: false
   522                    translateLabel: true
   523                    model: closeSearchBar
   524                  )
   525                 (LabelSpec
   526                    label: 'Search:'
   527                    name: 'SearchLabel'
   528                    layout: (LayoutFrame 30 0 5 0 100 0 27 0)
   529                    uuid: '37d80ef0-b8d0-11e8-aeef-b8f6b1108e05'
   530                    translateLabel: true
   531                    adjust: right
   532                  )
   533                 (InputFieldSpec
   534                    name: 'SearchEntryField'
   535                    layout: (LayoutFrame 100 0 5 0 257 0 27 0)
   536                    uuid: '37d80fd6-b8d0-11e8-aeef-b8f6b1108e05'
   537                    model: searchTextHolder
   538                    immediateAccept: true
   539                    acceptOnReturn: true
   540                    acceptOnTab: true
   541                    acceptOnLostFocus: true
   542                    modifiedChannel: searchTextModifiedHolder
   543                    acceptOnPointerLeave: false
   544                    postBuildCallback: postBuildSearchTextView:
   545                  )
   546                 (ActionButtonSpec
   547                    label: 'searchNextIcon'
   548                    name: 'SearchNextButton'
   549                    layout: (LayoutFrame 264 0 5 0 285 0 26 0)
   550                    uuid: '37d8117a-b8d0-11e8-aeef-b8f6b1108e05'
   551                    hasCharacterOrientedLabel: false
   552                    translateLabel: true
   553                    model: searchNextText
   554                  )
   555                 (ActionButtonSpec
   556                    label: 'searchPreviousIcon'
   557                    name: 'searchPreviousButton'
   558                    layout: (LayoutFrame 292 0 5 0 313 0 26 0)
   559                    uuid: '37d812b0-b8d0-11e8-aeef-b8f6b1108e05'
   560                    hasCharacterOrientedLabel: false
   561                    translateLabel: true
   562                    model: searchPreviousText
   563                  )
   564                 (CheckBoxSpec
   565                    label: 'Ignore case'
   566                    name: 'IgnoreCaseCheckBox'
   567                    layout: (LayoutFrame 322 0 5 0 518 0 27 0)
   568                    uuid: '37d813d2-b8d0-11e8-aeef-b8f6b1108e05'
   569                    model: ignoreCaseHolder
   570                    translateLabel: true
   571                  )
   572                 (LabelSpec
   573                    label: 'SearchBarImageInfoLabel'
   574                    name: 'SearchBarImageInfoLabel'
   575                    layout: (LayoutFrame 524 0 5 0 548 0 27 0)
   576                    uuid: '37d81512-b8d0-11e8-aeef-b8f6b1108e05'
   577                    hasCharacterOrientedLabel: false
   578                    translateLabel: true
   579                    labelChannel: searchBarImageInfoLabelHolder
   580                  )
   581                 (LabelSpec
   582                    label: 'SearchBarInfoLabel'
   583                    name: 'SearchBarInfoLabel'
   584                    layout: (LayoutFrame 551 0 5 0 829 0 27 0)
   585                    uuid: '37d8160c-b8d0-11e8-aeef-b8f6b1108e05'
   586                    translateLabel: true
   587                    labelChannel: searchBarInfoLabelHolder
   588                    adjust: left
   589                  )
   590                 )
   591               
   592              )
   593              postBuildCallback: postBuildSearchBoxView:
   594            )
   595           )
   596         
   597        )
   598      )
   599 ! !
   600 
   601 !InternationalLanguageTranslationEditor class methodsFor:'menu specs'!
   602 
   603 keyStringAndLanguageSelectionTableMenu
   604     "This resource specification was automatically generated
   605      by the MenuEditor of ST/X."
   606 
   607     "Do not manually edit this!! If it is corrupted,
   608      the MenuEditor may not be able to read the specification."
   609 
   610 
   611     "
   612      MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#keyStringAndLanguageSelectionTableMenu
   613      (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor keyStringAndLanguageSelectionTableMenu)) startUp
   614     "
   615 
   616     <resource: #menu>
   617 
   618     ^
   619      #(Menu
   620 	(
   621 	 (MenuItem
   622 	    label: 'Browse Methods Containing this String'
   623 	    itemValue: browseReferringMethods
   624 	  )
   625 	 (MenuItem
   626 	    label: '-'
   627 	  )
   628 	 (MenuItem
   629 	    label: 'Set Current NameSpace...'
   630 	    itemValue: changeLastNameSpace
   631 	  )
   632 	 (MenuItem
   633 	    label: 'Search String in Current NameSpace'
   634 	    itemValue: searchStringInLastNameSpace
   635 	  )
   636 	 (MenuItem
   637 	    label: '-'
   638 	    isVisible: false
   639 	  )
   640 	 (MenuItem
   641 	    label: 'Set Current Package...'
   642 	    itemValue: changeLastPackage
   643 	    isVisible: false
   644 	  )
   645 	 (MenuItem
   646 	    label: 'Search String in Current Package'
   647 	    itemValue: searchStringInLastPackage
   648 	    isVisible: false
   649 	  )
   650 	 )
   651 	nil
   652 	nil
   653       )
   654 !
   655 
   656 mainMenu
   657     "This resource specification was automatically generated
   658      by the MenuEditor of ST/X."
   659 
   660     "Do not manually edit this!! If it is corrupted,
   661      the MenuEditor may not be able to read the specification."
   662 
   663 
   664     "
   665      MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#mainMenu
   666      (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor mainMenu)) startUp
   667     "
   668 
   669     <resource: #menu>
   670 
   671     ^ 
   672      #(Menu
   673         (
   674          (MenuItem
   675             label: 'File'
   676             submenu: 
   677            (Menu
   678               (
   679                (MenuItem
   680                   label: 'New'
   681                   itemValue: menuNew
   682                 )
   683                (MenuItem
   684                   label: '-'
   685                 )
   686                (MenuItem
   687                   label: 'Open Resources for Package or Project...'
   688                   itemValue: menuOpenByPackage
   689                 )
   690                (MenuItem
   691                   label: 'Open Resource File...'
   692                   itemValue: menuOpen
   693                 )
   694                (MenuItem
   695                   label: '-'
   696                 )
   697                (MenuItem
   698                   label: 'Save All Resource Files'
   699                   itemValue: menuSaveAll
   700                 )
   701                (MenuItem
   702                   label: 'Save Resource File'
   703                   itemValue: menuSave
   704                 )
   705                (MenuItem
   706                   label: 'Save Resource File As...'
   707                   itemValue: menuSaveAs
   708                 )
   709                (MenuItem
   710                   label: '-'
   711                 )
   712                (MenuItem
   713                   label: 'Import existing translations from file...'
   714                   itemValue: importExistingTranslationsFromFile
   715                 )
   716                (MenuItem
   717                   label: '-'
   718                 )
   719                (MenuItem
   720                   label: 'File Browser on Resource Directory'
   721                   itemValue: openFileBrowserOnResourceDirectory
   722                 )
   723                (MenuItem
   724                   label: '-'
   725                 )
   726                (MenuItem
   727                   label: 'Set Current NameSpace'
   728                   itemValue: changeLastNameSpace
   729                 )
   730                (MenuItem
   731                   label: 'Set Current Package'
   732                   itemValue: changeLastPackage
   733                   isVisible: false
   734                 )
   735                (MenuItem
   736                   label: '-'
   737                 )
   738                (MenuItem
   739                   label: 'Exit'
   740                   itemValue: closeRequest
   741                 )
   742                )
   743               nil
   744               nil
   745             )
   746           )
   747          (MenuItem
   748             label: 'View'
   749             submenu: 
   750            (Menu
   751               (
   752                (MenuItem
   753                   label: 'Show Missing Translations Only'
   754                   indication: showMissingTranslationsOnly
   755                 )
   756                (MenuItem
   757                   label: 'Show Search Box'
   758                   indication: searchBoxVisible
   759                 )
   760                (MenuItem
   761                   label: '-'
   762                 )
   763                (MenuItem
   764                   label: 'Shown Languages'
   765                   submenuChannel: shownLanguagesMenu
   766                 )
   767                )
   768               nil
   769               nil
   770             )
   771           )
   772          (MenuItem
   773             label: 'Languages'
   774             submenu: 
   775            (Menu
   776               (
   777                (MenuItem
   778                   label: 'Add Language...'
   779                   itemValue: addLanguage
   780                 )
   781                (MenuItem
   782                   label: 'Remove Language...'
   783                   itemValue: removeLanguage
   784                 )
   785                (MenuItem
   786                   label: '-'
   787                 )
   788                (MenuItem
   789                   label: 'Merge...'
   790                   itemValue: mergeLanguages
   791                 )
   792                )
   793               nil
   794               nil
   795             )
   796           )
   797          (MenuItem
   798             label: 'Translations'
   799             submenuChannel: translationsMenuSpec
   800           )
   801          (MenuItem
   802             label: 'Preferences'
   803             submenu: 
   804            (Menu
   805               (
   806                (MenuItem
   807                   label: 'Auto Accept Changes'
   808                   indication: autoAcceptHolder
   809                 )
   810                (MenuItem
   811                   label: 'Search For Similar Translations'
   812                   indication: searchForSimilarTranslationEnableHolder
   813                 )
   814                (MenuItem
   815                   label: 'Always Write UTF8'
   816                   indication: alwaysWriteUTF8Holder
   817                 )
   818                )
   819               nil
   820               nil
   821             )
   822           )
   823          (MenuItem
   824             label: 'Help'
   825             startGroup: right
   826             submenu: 
   827            (Menu
   828               (
   829                (MenuItem
   830                   label: 'Documentation'
   831                   itemValue: openDocumentation
   832                 )
   833                (MenuItem
   834                   label: '-'
   835                 )
   836                (MenuItem
   837                   label: 'About this Application...'
   838                   itemValue: openAboutThisApplication
   839                 )
   840                )
   841               nil
   842               nil
   843             )
   844           )
   845          )
   846         nil
   847         nil
   848       )
   849 
   850     "Modified: / 30-10-2018 / 16:31:32 / Claus Gittinger"
   851 !
   852 
   853 menuItemsEditLanguage
   854     "This resource specification was automatically generated
   855      by the MenuEditor of ST/X."
   856 
   857     "Do not manually edit this!! If it is corrupted,
   858      the MenuEditor may not be able to read the specification."
   859 
   860     "
   861      MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#menu
   862      (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor menu)) startUp
   863     "
   864 
   865     <resource: #menu>
   866 
   867     ^
   868      #(Menu
   869 	(
   870 	 (MenuItem
   871 	    enabled: pastePreviousTranslationEnableHolder
   872 	    label: 'Paste Previous Translation'
   873 	    itemValue: pastePreviousTranslationInLanguageText
   874 	    nameKey: pastePreviousTranslationInLanguageText
   875 	    translateLabel: true
   876 	  )
   877 	 )
   878 	nil
   879 	nil
   880       )
   881 !
   882 
   883 menuToolBar
   884     "This resource specification was automatically generated
   885      by the MenuEditor of ST/X."
   886 
   887     "Do not manually edit this!! If it is corrupted,
   888      the MenuEditor may not be able to read the specification."
   889 
   890 
   891     "
   892      MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#menuToolBar
   893      (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor menuToolBar)) startUp
   894     "
   895 
   896     <resource: #menu>
   897 
   898     ^
   899      #(Menu
   900 	(
   901 	 (MenuItem
   902 	    label: 'Save'
   903 	    itemValue: menuSave
   904 	    isButton: true
   905 	    labelImage: (ResourceRetriever XPToolbarIconLibrary saveImageIcon)
   906 	  )
   907 	 (MenuItem
   908 	    label: '-'
   909 	  )
   910 	 (MenuItem
   911 	    label: 'Add Translation'
   912 	    itemValue: addTranslation
   913 	    isButton: true
   914 	    labelImage: (ResourceRetriever XPToolbarIconLibrary newRowIcon)
   915 	  )
   916 	 (MenuItem
   917 	    label: 'Remove Translation'
   918 	    itemValue: removeTranslation
   919 	    isButton: true
   920 	    labelImage: (ResourceRetriever XPToolbarIconLibrary removeRowIcon)
   921 	  )
   922 	 (MenuItem
   923 	    label: '-'
   924 	  )
   925 	 (MenuItem
   926 	    activeHelpKey: browseReferringMethods
   927 	    label: 'Browse'
   928 	    itemValue: browseReferringMethods
   929 	    labelImage: (ResourceRetriever ToolbarIconLibrary systemBrowserIcon)
   930 	  )
   931 	 (MenuItem
   932 	    label: ''
   933 	  )
   934 	 (MenuItem
   935 	    label: 'Stop Application'
   936 	    itemValue: stopApplication
   937 	    isButton: true
   938 	    isVisible: stopApplicationIconVisibleHolder
   939 	    labelImage: (ResourceRetriever XPToolbarIconLibrary stop16x16Icon)
   940 	  )
   941 	 (MenuItem
   942 	    activeHelpKey: searchBox
   943 	    label: 'Search'
   944 	    isButton: true
   945 	    startGroup: right
   946 	    hideMenuOnActivated: false
   947 	    indication: searchBoxVisible
   948 	    shortcutKey: Ctrlf
   949 	    labelImage: (ResourceRetriever #'Tools::InternationalLanguageTranslationEditor' searchToolBarIcon)
   950 	  )
   951 	 )
   952 	nil
   953 	nil
   954       )
   955 !
   956 
   957 translationsMenuSpec
   958     "This resource specification was automatically generated
   959      by the MenuEditor of ST/X."
   960 
   961     "Do not manually edit this!! If it is corrupted,
   962      the MenuEditor may not be able to read the specification."
   963 
   964 
   965     "
   966      MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#translationsMenuSpec
   967      (Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor translationsMenuSpec)) startUp
   968     "
   969 
   970     <resource: #menu>
   971 
   972     ^ 
   973      #(Menu
   974         (
   975          (MenuItem
   976             label: 'Add Translation...'
   977             itemValue: addTranslation
   978           )
   979          (MenuItem
   980             label: 'Remove Translation...'
   981             itemValue: removeTranslation
   982           )
   983          (MenuItem
   984             label: '-'
   985             isVisible: false
   986           )
   987          (MenuItem
   988             label: 'Search Translation...'
   989             itemValue: searchTranslation
   990             isVisible: false
   991           )
   992          (MenuItem
   993             label: '-'
   994           )
   995          (MenuItem
   996             label: 'Extract from Package...'
   997             itemValue: extractTranslationsFromProject
   998           )
   999          (MenuItem
  1000             label: 'Extract from Class...'
  1001             itemValue: extractTranslationsFromClass
  1002           )
  1003          (MenuItem
  1004             label: 'Extract from NameSpace...'
  1005             itemValue: extractTranslationsFromNameSpace
  1006           )
  1007          (MenuItem
  1008             label: '-'
  1009           )
  1010          (MenuItem
  1011             label: 'Run Application and Collect Translations...'
  1012             itemValue: runApplicationAndCollectTranslations
  1013           )
  1014          (MenuItem
  1015             label: '-'
  1016           )
  1017          (MenuItem
  1018             label: 'Generate Missing Translations'
  1019             itemValue: generateMissingTranslations
  1020           )
  1021          (MenuItem
  1022             label: 'Generate Missing Translations Slice'
  1023             submenuChannel: menuSliceTranslateGenerate
  1024             isMenuSlice: true
  1025           )
  1026          )
  1027         nil
  1028         nil
  1029       )
  1030 ! !
  1031 
  1032 !InternationalLanguageTranslationEditor class methodsFor:'startup'!
  1033 
  1034 openOnFile:aFilename
  1035     "opens an editor on a single resources file; returns the editor"
  1036     
  1037     |fn|
  1038 
  1039     fn := aFilename asFilename.
  1040 
  1041     ^ self new
  1042         allButOpen;
  1043         readResourceFile:fn asLanguage:(fn withoutSuffix baseName);
  1044         beUnmodified;
  1045         openWindow;
  1046         yourself.
  1047 
  1048     "Modified: / 20-02-2019 / 12:36:13 / Claus Gittinger"
  1049 !
  1050 
  1051 openOnPackage:aPackageId
  1052     "opens an editor on all languages of a package; returns the editor"
  1053 
  1054     ^ self new
  1055         allButOpen;
  1056         readResourceFileForPackage:aPackageId language:#all;
  1057         beUnmodified;
  1058         openWindow;
  1059         yourself.
  1060 
  1061     "Modified: / 20-02-2019 / 12:36:18 / Claus Gittinger"
  1062 ! !
  1063 
  1064 !InternationalLanguageTranslationEditor class methodsFor:'tableColumns specs'!
  1065 
  1066 keyTableColumn
  1067     "This resource specification was automatically generated
  1068      by the DataSetBuilder of ST/X."
  1069 
  1070     "Do not manually edit this!! If it is corrupted,
  1071      the DataSetBuilder may not be able to read the specification."
  1072 
  1073     "
  1074      DataSetBuilder new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#keyTableColumn
  1075     "
  1076 
  1077     <resource: #tableColumns>
  1078 
  1079     ^#(
  1080       (DataSetColumnSpec
  1081 	 label: 'Key'
  1082 	 labelButtonType: Button
  1083 	 minWidth: 50
  1084 	 model: keyStringInRow:
  1085        )
  1086       )
  1087 !
  1088 
  1089 languageTableColumn
  1090     "This resource specification was automatically generated
  1091      by the DataSetBuilder of ST/X."
  1092 
  1093     "Do not manually edit this!! If it is corrupted,
  1094      the DataSetBuilder may not be able to read the specification."
  1095 
  1096     "
  1097      DataSetBuilder new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#languageTableColumn
  1098     "
  1099 
  1100     <resource: #tableColumns>
  1101 
  1102     ^#(
  1103       (DataSetColumnSpec
  1104 	 label: lang
  1105 	 labelButtonType: Button
  1106 	 minWidth: 50
  1107 	 editorType: None
  1108 	 model: columnInRow:at:
  1109 	 backgroundSelector: getBackgroundForRow:rowNr:col:
  1110        )
  1111       )
  1112 ! !
  1113 
  1114 !InternationalLanguageTranslationEditor methodsFor:'accessing'!
  1115 
  1116 beUnmodified
  1117     modified := false.
  1118 
  1119     "Created: / 20-02-2019 / 12:36:03 / Claus Gittinger"
  1120 !
  1121 
  1122 currentSelectionIndex
  1123 
  1124     ^ self selectedKeyRow value
  1125 
  1126     "Created: / 16-06-2007 / 09:04:11 / Administrador"
  1127     "Modified: / 19-06-2007 / 17:28:38 / Administrador"
  1128 !
  1129 
  1130 exists: anObject
  1131 
  1132     ^self objectsList includes: anObject
  1133 
  1134     "Created: / 19-06-2007 / 16:42:22 / Administrador"
  1135 !
  1136 
  1137 indexOf: anObject
  1138 
  1139     ^self objectsList indexOf: anObject
  1140 
  1141     "Created: / 19-06-2007 / 16:39:44 / Administrador"
  1142 !
  1143 
  1144 newLanguageText
  1145 "/   languageEditor accept
  1146     ^self languageTextHolder value isEmptyOrNil
  1147 	ifTrue:['']
  1148 	ifFalse:[self languageTextHolder value asCollectionOfLines first.]
  1149 !
  1150 
  1151 objectsList
  1152 
  1153     ^ keyStringsToLanguageMappings
  1154 
  1155     "Modified: / 25-10-2018 / 16:25:08 / Claus Gittinger"
  1156 !
  1157 
  1158 selectKey:aKey
  1159     "selects aKey if there is a corresponding row"
  1160 
  1161     | index |
  1162 
  1163     keyStringsToLanguageMappings isNil ifTrue:[^false].
  1164     index := keyStringsToLanguageMappings keys indexOf:aKey.
  1165     index == 0 ifTrue:[^ false].
  1166     
  1167     self selectedKeyRow value:index.
  1168     ^ true
  1169 
  1170     "Created: / 20-02-2019 / 12:31:01 / Claus Gittinger"
  1171 !
  1172 
  1173 selectListIndex: rowIndex
  1174 "/    |selection list|
  1175 "/    list := self objectsList.
  1176 "/    list isEmpty ifTrue:[^self].
  1177 "/    selection := list at:rowIndex ifAbsent:nil.
  1178     self selectedKeyRow value: rowIndex.
  1179 
  1180     "Created: / 16-06-2007 / 09:06:46 / Administrador"
  1181     "Modified: / 22-06-2007 / 13:45:54 / Administrador"
  1182 !
  1183 
  1184 selectOrAddKey:aKey
  1185     "selects aKey if there is a corresponding row,
  1186      otherwise fills in the fields for editing"
  1187 
  1188     (self selectKey:aKey) ifFalse:[
  1189         self addTranslationForKey:aKey.
  1190         self languageTextHolder value:aKey.
  1191     ].
  1192 
  1193     "Created: / 21-02-2019 / 17:09:36 / Claus Gittinger"
  1194     "Modified: / 22-02-2019 / 09:25:43 / Claus Gittinger"
  1195 !
  1196 
  1197 selectedKey
  1198     "Returns the current selected key if there is one row seleted. Otherwise, returns nil"
  1199 
  1200     | rowSelectionIndex |
  1201 
  1202     keyStringsToLanguageMappings isNil ifTrue:[^nil].
  1203     (rowSelectionIndex := self selectedKeyRow value) isNil ifTrue:[^nil].
  1204     rowSelectionIndex == 0 ifTrue:[^nil].
  1205 
  1206     ^ keyStringsToLanguageMappings keyAt:rowSelectionIndex.
  1207 
  1208     "Modified: / 20-02-2019 / 12:28:18 / Claus Gittinger"
  1209 !
  1210 
  1211 tableView
  1212 
  1213     ^dataSetView scrolledView
  1214 
  1215     "Created: / 15-06-2007 / 18:59:51 / Administrador"
  1216 ! !
  1217 
  1218 !InternationalLanguageTranslationEditor methodsFor:'aspects'!
  1219 
  1220 alwaysWriteUTF8Holder
  1221     alwaysWriteUTF8Holder isNil ifTrue:[alwaysWriteUTF8Holder := true asValue].
  1222     ^ alwaysWriteUTF8Holder
  1223 !
  1224 
  1225 autoAcceptHolder
  1226     autoAcceptHolder isNil ifTrue:[autoAcceptHolder := true asValue].
  1227     ^ autoAcceptHolder
  1228 !
  1229 
  1230 exampleLanguageSelectionHolder
  1231     exampleLanguageSelectionHolder isNil ifTrue:[
  1232 	exampleLanguageSelectionHolder := self exampleLanguageByDefault asValue.
  1233 	exampleLanguageSelectionHolder addDependent:self.
  1234     ].
  1235     ^ exampleLanguageSelectionHolder
  1236 !
  1237 
  1238 exampleLanguageTextHolder
  1239     exampleLanguageTextHolder isNil ifTrue:[
  1240 	exampleLanguageTextHolder := '' asValue.
  1241     ].
  1242     ^ exampleLanguageTextHolder.
  1243 !
  1244 
  1245 ignoreCaseHolder
  1246 
  1247     ignoreCaseHolder isNil ifTrue:[
  1248 	ignoreCaseHolder := false asValue.
  1249 "/ if your app needs to be notified of changes, uncomment one of the lines below:
  1250 "/       ignoreCaseHolder addDependent:self.
  1251 	ignoreCaseHolder onChangeSend:#ignoreCaseHolderChanged to:self.
  1252 
  1253     ].
  1254     ^ ignoreCaseHolder.
  1255 
  1256     "Created: / 16-06-2007 / 06:45:04 / Administrador"
  1257     "Modified: / 16-06-2007 / 19:32:15 / Administrador"
  1258 !
  1259 
  1260 keyStringAndLanguageSelectionTable
  1261     keyStringsToLanguageMappings isNil ifTrue:[
  1262 	keyStringsToLanguageMappings := KeyStringsToLanguageMappings new.
  1263     ].
  1264     ^ keyStringsToLanguageMappings.
  1265 !
  1266 
  1267 keyStringAndLanguageSelectionTableColumnDescriptionHolder
  1268     keyStringAndLanguageSelectionTableColumnDescriptionHolder isNil ifTrue:[
  1269 	keyStringAndLanguageSelectionTableColumnDescriptionHolder := ValueHolder new.
  1270 	keyStringAndLanguageSelectionTableColumnDescriptionHolder value:(self keyStringAndLanguageSelectionTableColumnDescription).
  1271     ].
  1272     ^ keyStringAndLanguageSelectionTableColumnDescriptionHolder.
  1273 !
  1274 
  1275 languageAtCol:colNr
  1276     ^ shownLanguages at:colNr-1.
  1277 !
  1278 
  1279 languageShownHolderFor:lang
  1280     |holder|
  1281 
  1282     languageShownHolders isNil ifTrue:[
  1283 	languageShownHolders := Dictionary new
  1284     ].
  1285     holder := languageShownHolders
  1286 		at:lang
  1287 		ifAbsentPut:[
  1288 		    |h|
  1289 
  1290 		    h := true asValue.
  1291 		    h onChangeEvaluate:[
  1292 			h value ifTrue:[
  1293 			   self enableLanguageDisplayFor:lang
  1294 			] ifFalse:[
  1295 			   self disableLanguageDisplayFor:lang
  1296 			].
  1297 		    ].
  1298 		    h
  1299 		].
  1300     ^ holder.
  1301 !
  1302 
  1303 languageTextAcceptHolder
  1304     languageTextAcceptHolder isNil ifTrue:[
  1305 	languageTextAcceptHolder := false asValue.
  1306     ].
  1307     ^ languageTextAcceptHolder.
  1308 !
  1309 
  1310 languageTextHolder
  1311     languageTextHolder isNil ifTrue:[
  1312 	languageTextHolder := '' asValue.
  1313     ].
  1314     ^ languageTextHolder.
  1315 !
  1316 
  1317 languageTextModifiedHolder
  1318     languageTextModifiedHolder isNil ifTrue:[
  1319 	languageTextModifiedHolder := false asValue.
  1320     ].
  1321     ^ languageTextModifiedHolder.
  1322 !
  1323 
  1324 languagesList
  1325     languagesList isNil ifTrue:[
  1326         languagesList := List withAll:(keyStringsToLanguageMappings languages).
  1327     ].
  1328     ^ languagesList.
  1329 !
  1330 
  1331 originalTextHolder
  1332     originalTextHolder isNil ifTrue:[
  1333 	originalTextHolder := '' asValue.
  1334     ].
  1335     ^ originalTextHolder.
  1336 !
  1337 
  1338 originalTextModifiedHolder
  1339     originalTextModifiedHolder isNil ifTrue:[
  1340 	originalTextModifiedHolder := false asValue.
  1341     ].
  1342     ^ originalTextModifiedHolder.
  1343 !
  1344 
  1345 pasteOriginalEnableHolder
  1346    pasteOriginalEnableHolder isNil ifTrue:[pasteOriginalEnableHolder := false asValue].
  1347     ^ pasteOriginalEnableHolder
  1348 !
  1349 
  1350 pastePreviousTranslationEnableHolder
  1351    pastePreviousTranslationEnableHolder isNil ifTrue:[pastePreviousTranslationEnableHolder := false asValue].
  1352     ^ pastePreviousTranslationEnableHolder
  1353 !
  1354 
  1355 searchBarImageInfoLabelHolder
  1356 
  1357     searchBarImageInfoLabelHolder isNil ifTrue:[
  1358 	searchBarImageInfoLabelHolder := nil asValue .
  1359     ].
  1360     ^ searchBarImageInfoLabelHolder.
  1361 
  1362     "Created: / 16-06-2007 / 10:06:28 / Administrador"
  1363 !
  1364 
  1365 searchBarInfoLabelHolder
  1366 
  1367     searchBarInfoLabelHolder isNil ifTrue:[
  1368 	searchBarInfoLabelHolder := '' asValue .
  1369     ].
  1370     ^ searchBarInfoLabelHolder.
  1371 
  1372     "Created: / 16-06-2007 / 06:20:49 / Administrador"
  1373 !
  1374 
  1375 searchBoxVisible
  1376 
  1377     searchBoxVisible isNil ifTrue:[
  1378 	searchBoxVisible := false asValue.
  1379 	searchBoxVisible
  1380 	    onChangeEvaluate:[
  1381 		self updateToolVisibility.
  1382 		searchBoxVisible value ifTrue:[
  1383 		    searchTextView takeFocus.
  1384 		].
  1385 	    ].
  1386     ].
  1387     ^ searchBoxVisible.
  1388 
  1389     "Created: / 15-06-2007 / 18:15:52 / Administrador"
  1390 !
  1391 
  1392 searchForSimilarTranslationEnableHolder
  1393    searchForSimilarTranslationEnableHolder isNil
  1394 	ifTrue:[searchForSimilarTranslationEnableHolder := true asValue].
  1395     ^ searchForSimilarTranslationEnableHolder
  1396 !
  1397 
  1398 searchTextHolder
  1399 
  1400     searchTextHolder isNil ifTrue:[
  1401 	searchTextHolder := ValueHolder new.
  1402 "/ if your app needs to be notified of changes, uncomment one of the lines below:
  1403 "/       userSelectedHolder addDependent:self.
  1404 "/       userSelectedHolder onChangeSend:#searchTextHolderChanged to:self.
  1405     ].
  1406     ^ searchTextHolder.
  1407 
  1408     "Created: / 15-06-2007 / 18:06:08 / Administrador"
  1409 !
  1410 
  1411 searchTextModifiedHolder
  1412 
  1413     searchTextModifiedHolder isNil ifTrue:[
  1414 	searchTextModifiedHolder := false asValue .
  1415 "/ if your app needs to be notified of changes, uncomment one of the lines below:
  1416 "/       searchTextModifiedHolder addDependent:self.
  1417        searchTextModifiedHolder onChangeSend:#searchTextModifiedHolderChanged to:self.
  1418     ].
  1419     ^ searchTextModifiedHolder.
  1420 
  1421     "Created: / 15-06-2007 / 18:07:19 / Administrador"
  1422 !
  1423 
  1424 selectedKeyRow
  1425     selectedKeyRow isNil ifTrue:[
  1426 	selectedKeyRow := ValueHolder new.
  1427 	selectedKeyRow onChangeSend:#selectionChanged to:self.
  1428     ].
  1429     ^ selectedKeyRow.
  1430 !
  1431 
  1432 showMissingTranslationsOnly
  1433     showMissingTranslationsOnly isNil ifTrue:[
  1434 	showMissingTranslationsOnly := false asValue.
  1435 	showMissingTranslationsOnly onChangeSend:#showMissingTranslationsOnlyChanged to:self.
  1436     ].
  1437     ^ showMissingTranslationsOnly.
  1438 !
  1439 
  1440 shownLanguages
  1441     shownLanguages isNil ifTrue:[
  1442 	shownLanguages := List new.
  1443 	shownLanguages addAll:(self languagesList).
  1444 	shownLanguages onChangeSend:#shownLanguagesChanged to:self.
  1445     ].
  1446     ^ shownLanguages.
  1447 !
  1448 
  1449 stopApplicationIconVisibleHolder
  1450     stopApplicationIconVisibleHolder isNil ifTrue:[
  1451 	stopApplicationIconVisibleHolder := false asValue.
  1452     ].
  1453     ^ stopApplicationIconVisibleHolder.
  1454 ! !
  1455 
  1456 !InternationalLanguageTranslationEditor methodsFor:'change & update'!
  1457 
  1458 languageTextHolderValue: aString
  1459 
  1460     self languageTextHolder value: aString.
  1461     self languageTextModifiedHolder value:true.
  1462 !
  1463 
  1464 update:something with:aParameter from:changedObject
  1465     languageEditor modified ifTrue:[
  1466         languageEditor accept
  1467     ].    
  1468     changedObject == shownLanguages ifTrue:[
  1469          self shownLanguagesChanged.
  1470          ^ self.
  1471     ].
  1472     changedObject == languageTextAcceptHolder ifTrue:[
  1473          self updateLanguageTextModification.
  1474          ^ self.
  1475     ].
  1476     changedObject == exampleLanguageSelectionHolder ifTrue:[
  1477         self updateExampleLanguageText.
  1478         ^ self.
  1479     ].
  1480     changedObject == showMissingTranslationsOnly ifTrue:[
  1481         self showMissingTranslationsOnlyChanged.
  1482         ^ self.
  1483     ].
  1484 
  1485     "Modified: / 15-09-2018 / 12:17:07 / Claus Gittinger"
  1486 !
  1487 
  1488 updateCopyPreviousTranslationButtonEnabled
  1489 
  1490      self pastePreviousTranslationEnableHolder value: self shouldCopyPreviousTranslationButtonBeEnabled
  1491 !
  1492 
  1493 updateExampleLanguageText
  1494 
  1495     self selectedKeyRow value isNil ifTrue:[^ self].
  1496     self exampleLanguageTextHolder value:self currentExampleLanguageText
  1497 !
  1498 
  1499 updateKeyStringsToLanguageMappings
  1500 
  1501     keyStringsToLanguageMappings
  1502         at:lastSelectedKey language:lastLanguage put: self newLanguageText.
  1503 !
  1504 
  1505 updateLanguageAndKeySelection
  1506 
  1507     self originalTextHolder value: self selectedKey.
  1508     self languageTextHolder value: (self languageTextFromSelectedKeyFor: self currentLanguage).
  1509     lastLanguage := self currentLanguage.
  1510     lastSelectedKey := self selectedKey.
  1511 !
  1512 
  1513 updateLanguageTextModification
  1514      self languageTextModifiedHolder value ifTrue:[
  1515 	(self autoAccept or:[Dialog confirm:'Accept changed translation ?']) ifTrue:[
  1516 	    self languageTextModifiedHolder value:false.
  1517 	    self languageTextHolder value:languageEditor contents.
  1518 	    lastLanguage notNil ifTrue:[self updateKeyStringsToLanguageMappings.]
  1519 	]
  1520     ].
  1521 !
  1522 
  1523 updateOriginalTextModification
  1524 
  1525     |answer|
  1526 
  1527 	self originalTextModifiedHolder value ifTrue:[
  1528 	    answer := OptionBox
  1529 			  request:'Accept changed original text (key) ?'
  1530 			  label:'Original text (key) changed'
  1531 			  image:(WarningBox iconBitmap)
  1532 			  buttonLabels:#('Cancel' 'Accept' 'Accept As New')
  1533 			  values:#(nil #accept #acceptAsNew)
  1534 			  default:#acceptAsNew.
  1535 
  1536 	    answer isNil ifTrue:[^ self originalTextModifiedHolder value:false. ].
  1537 	    answer == #accept ifTrue:[
  1538     self shouldImplement.        ].
  1539 	    answer == #acceptAsNew ifTrue:[
  1540     self shouldImplement.        ].
  1541 	].
  1542 !
  1543 
  1544 updatePasteOriginalButtonEnabled
  1545 
  1546      self pasteOriginalEnableHolder value: self shouldPasteOriginalButtonBeEnabled
  1547 ! !
  1548 
  1549 !InternationalLanguageTranslationEditor methodsFor:'dialogs'!
  1550 
  1551 requestEncoderDialog
  1552 
  1553    |box val characterCollection|
  1554 
  1555     val := '' asValue.
  1556     box := Dialog new.
  1557     (box addTextLabel:'Select or write the encoder') adjust:#left.
  1558     box addVerticalSpace.
  1559     characterCollection := CharacterEncoder supportedExternalEncodings
  1560 	inject: OrderedCollection new
  1561 	into:[:collection :each |
  1562 	    collection add: each first;
  1563 			yourself].
  1564     (box addComboBoxOn:val) list: characterCollection.
  1565     box addOkButton.
  1566     box open.
  1567     ^val value
  1568 !
  1569 
  1570 requestEncoderStringFor: lang
  1571     "Returns an encoder string and updates the language's info"
  1572   
  1573     |encoderString encoder|
  1574 
  1575     encoderString := self requestEncoderDialog.
  1576     encoderString notEmpty ifTrue:[
  1577         encoder := CharacterEncoder encoderFor: encoderString ifAbsent:nil.
  1578         encoder notNil ifTrue:[
  1579             keyStringsToLanguageMappings atLanguage: lang putEncoder: encoder.
  1580         ].
  1581     ].
  1582     ^encoderString
  1583 !
  1584 
  1585 requestFilename
  1586 
  1587     |aFilename|
  1588 
  1589     aFilename := Dialog
  1590 	requestFileName:(resources string:'Name of resource file:')
  1591 	default:nil
  1592 	pattern:'*.rs'.
  1593 
  1594     aFilename isEmptyOrNil ifTrue:[^ nil ].
  1595     ^aFilename asFilename
  1596 !
  1597 
  1598 requestFilenameFor: lang
  1599     "Returns a filename to save the language resource and updates the language's info"
  1600 
  1601     |aFilename|
  1602 
  1603     aFilename := Dialog
  1604         requestFileName:(resources string:'Name of resource file to save %1:' with:lang asString)
  1605         default:nil
  1606         pattern:'*.rs'.
  1607 
  1608     aFilename isEmptyOrNil ifTrue:[^ nil ].
  1609     keyStringsToLanguageMappings atLanguage: lang putFilename: aFilename.
  1610     ^aFilename asFilename
  1611 
  1612     "Modified (format): / 15-09-2018 / 12:28:28 / Claus Gittinger"
  1613 !
  1614 
  1615 requestLanguage
  1616     ^ Dialog
  1617 	choose:(resources string:'For which language ?')
  1618 	fromList:languagesList
  1619 	lines:10.
  1620 !
  1621 
  1622 requestLanguageToSave
  1623     |question filename|
  1624 
  1625     question := resources string:'Which language do you want to save?'.
  1626     
  1627     lastLanguage notNil ifTrue:[
  1628         filename := keyStringsToLanguageMappings filenameAt:lastLanguage.
  1629         filename notNil ifTrue:[
  1630             question := question , Character cr , 
  1631                         (resources string:'(Last was "%1" in "%2")'
  1632                                    with:lastLanguage
  1633                                    with:(filename asFilename pathName)).
  1634         ].    
  1635     ].    
  1636 
  1637     ^ Dialog
  1638         choose:question
  1639         fromList:languagesList
  1640         lines:10
  1641 
  1642     "Modified: / 15-09-2018 / 12:39:30 / Claus Gittinger"
  1643 !
  1644 
  1645 requestPackage
  1646     |package allProjects projectsWithResources|
  1647 
  1648     allProjects := Smalltalk allPackageIDs.
  1649     projectsWithResources := allProjects
  1650                                 select:[:pID |
  1651                                     |dir|
  1652                                     dir := Smalltalk projectDirectoryForPackage:pID.
  1653                                     dir notNil and:[ (dir asFilename construct:'resources') exists]
  1654                                 ].
  1655 
  1656     package := Dialog
  1657         requestProject:(resources string:'Name of Package:')
  1658         from:projectsWithResources
  1659         initialAnswer:LastProject
  1660         suggestions:nil.
  1661 
  1662     package isEmptyOrNil ifTrue:[^ nil ].
  1663     LastProject := package.
  1664     ^ package
  1665 ! !
  1666 
  1667 !InternationalLanguageTranslationEditor methodsFor:'images'!
  1668 
  1669 restartSearchBarIcon
  1670 
  1671     ^ self class restartSearchBarIcon
  1672 !
  1673 
  1674 warningSearchBarIcon
  1675 
  1676     ^ self class warningSearchBarIcon
  1677 ! !
  1678 
  1679 !InternationalLanguageTranslationEditor methodsFor:'initialization & release'!
  1680 
  1681 closeRequest
  1682     "asks for permission before closing"
  1683 
  1684     self hasUnsavedChanges ifTrue:[
  1685 	(Dialog
  1686 	    confirm:(resources string:'Close without saving ?')
  1687 	    default:false) ifFalse:[
  1688 	    ^ self
  1689 	]
  1690     ].
  1691 
  1692     super closeRequest
  1693 !
  1694 
  1695 editedLanguage:aSingleLanguageKey
  1696     self languagesList contents:{ aSingleLanguageKey }.
  1697     self shownLanguages contents:{ aSingleLanguageKey }.
  1698 !
  1699 
  1700 initialize
  1701     modified := false.
  1702     inSingleFileMode := false.
  1703     methodsUsingKey := Dictionary new.
  1704     keyStringsToLanguageMappings := KeyStringsToLanguageMappings new.
  1705     languagesList := List withAll:(keyStringsToLanguageMappings languages).
  1706     
  1707     super initialize
  1708 !
  1709 
  1710 languageEditorBuilt:aView
  1711     languageEditor := aView.
  1712 
  1713     "Modified: / 15-09-2018 / 12:16:22 / Claus Gittinger"
  1714 !
  1715 
  1716 postBuildDataSet:aView
  1717     dataSetView := aView.
  1718     aView selectedColIndexHolder onChangeSend:#selectionChanged to:self.
  1719 !
  1720 
  1721 postBuildSearchBoxView: aBoxView
  1722 
  1723     searchBoxView := aBoxView
  1724 
  1725     "Created: / 15-06-2007 / 18:02:38 / Administrador"
  1726 !
  1727 
  1728 postBuildSearchTextView: anEditFieldView
  1729 
  1730     searchTextView := anEditFieldView
  1731 
  1732     "Created: / 15-06-2007 / 18:17:15 / Administrador"
  1733 !
  1734 
  1735 postBuildTranslationsPanel: aPanel
  1736 
  1737     translationsPanel := aPanel
  1738 !
  1739 
  1740 postBuildWith:aBuilder
  1741 
  1742     super postBuildWith:aBuilder.
  1743     self updateToolVisibility.
  1744 ! !
  1745 
  1746 !InternationalLanguageTranslationEditor methodsFor:'menu actions'!
  1747 
  1748 addLanguage
  1749     |lang|
  1750 
  1751     lang := Dialog request:(resources string:'New language (ISO symbol):').
  1752     lang isEmptyOrNil ifTrue:[^ self].
  1753     self addLanguage:lang
  1754 !
  1755 
  1756 addLanguage:langArg
  1757     |lang|
  1758 
  1759     lang := langArg asSymbol.
  1760     (keyStringsToLanguageMappings includesLanguage:lang) ifTrue:[^ self ].
  1761 
  1762     keyStringsToLanguageMappings addLanguage:lang.
  1763     self languagesList add:lang.
  1764     self shownLanguages add:lang.
  1765     modified := true.
  1766 !
  1767 
  1768 addTranslation
  1769     |key|
  1770 
  1771     key := Dialog request:'New Key:'.
  1772     key isEmptyOrNil ifTrue:[^self].
  1773     
  1774     self addTranslationForKey:key
  1775 
  1776     "Modified: / 22-02-2019 / 09:25:17 / Claus Gittinger"
  1777 !
  1778 
  1779 addTranslationForKey:newKey
  1780     |index|
  1781 
  1782     newKey isEmptyOrNil ifTrue:[^self].
  1783 
  1784     (self includesKey:newKey) ifFalse:[
  1785         keyStringsToLanguageMappings addKey:newKey.
  1786         modified := true.
  1787     ].
  1788    index := keyStringsToLanguageMappings indexOfKey:newKey.
  1789    self selectedKeyRow value:index.
  1790 
  1791     "Created: / 22-02-2019 / 09:24:59 / Claus Gittinger"
  1792 !
  1793 
  1794 browseReferringMethods
  1795     |selectedKey methods browser|
  1796 
  1797     selectedKey := self selectedKey.
  1798     selectedKey isNil ifTrue:[^ Dialog information: 'No selected key'].
  1799 
  1800     methods := methodsUsingKey at:selectedKey ifAbsent:nil.
  1801     methods isEmptyOrNil ifTrue:[
  1802 	Dialog information:(resources stringWithCRs:'oops - no method remembered.\Please rerun the extract from XXX menu operation').
  1803 	^ self.
  1804     ].
  1805     browser := UserPreferences systemBrowserClass browseMethods:methods.
  1806     browser autoSearch:selectedKey ignoreCase:true.
  1807 !
  1808 
  1809 changeLastNameSpace
  1810 
  1811     |nameSpace defaultNameSpace|
  1812 
  1813     lastNameSpace notNil ifTrue:[defaultNameSpace := lastNameSpace name].
  1814     nameSpace := Dialog requestNameSpace:'NameSpace:' title:'Search String in Name Space:' initialAnswer:defaultNameSpace.
  1815     nameSpace isNil ifTrue:[^self].
  1816     nameSpace := Smalltalk at:nameSpace asSymbol.
  1817     nameSpace isNil ifTrue:[
  1818 	^Dialog information:(resources string:'No such nameSpace exists.')
  1819     ].
  1820     lastNameSpace := nameSpace.
  1821 !
  1822 
  1823 changeLastPackage
  1824 
  1825     |package defaultPackage|
  1826 
  1827     lastPackage notNil ifTrue:[defaultPackage := lastPackage].
  1828     package := Dialog
  1829 	    requestProject:'Package:'
  1830 	    initialAnswer:defaultPackage
  1831 	    suggestions:#('foo' 'bar' 'baz').
  1832     package isNil ifTrue:[
  1833 	^ self "/ Dialog information:(resources string:'No such package exists.')
  1834     ].
  1835     lastPackage := package.
  1836 !
  1837 
  1838 extractTranslationsFromClass
  1839     |aClass newTranslations|
  1840 
  1841     aClass := Dialog
  1842 		requestClass:'Class to extract translations from:'
  1843 		okLabel:'OK'
  1844 		initialAnswer:(lastExtractedClass ? LastExtractedClass).
  1845     aClass isNil ifTrue:[^ self ].
  1846 
  1847     lastExtractedClass := LastExtractedClass := aClass.
  1848 
  1849     newTranslations := self extractTranslationsFromClass:aClass.
  1850     self addAllTranslations:newTranslations.
  1851 !
  1852 
  1853 extractTranslationsFromNameSpace
  1854 
  1855     |newTranslations|
  1856 
  1857     self changeLastNameSpace.
  1858     lastNameSpace isNil ifTrue:[^self.].
  1859     newTranslations := OrderedCollection new.
  1860     lastNameSpace allClassesDo:[:eachClass |
  1861 	newTranslations addAll:( self extractTranslationsFromClass:eachClass theNonMetaclass).
  1862     ].
  1863     self addAllTranslations:newTranslations.
  1864 !
  1865 
  1866 extractTranslationsFromProject
  1867     |projectID newTranslations initialAnswer suggestions|
  1868 
  1869     initialAnswer := lastExtractedProject ? LastExtractedProject.
  1870     suggestions := initialAnswer isNil ifTrue:[
  1871 	OrderedCollection new
  1872     ] ifFalse:[
  1873 	OrderedCollection with:initialAnswer
  1874     ].
  1875     projectID := Dialog requestProject:(resources string:'Package to extract translations from:') initialAnswer:initialAnswer suggestions:suggestions.
  1876     projectID notNil ifTrue:[
  1877 	projectID := projectID withoutSeparators asSymbol.
  1878     ].
  1879     projectID isEmptyOrNil ifTrue:[^ self ].
  1880 
  1881     lastExtractedProject := LastExtractedProject := projectID.
  1882 
  1883     newTranslations := Set new.
  1884     self withWaitCursorDo:[
  1885 	Smalltalk allClassesDo:[:eachClass |
  1886 	    eachClass theNonMetaclass instAndClassMethodsDo:[:eachMethod |
  1887 		eachMethod package == projectID ifTrue:[
  1888 		    newTranslations addAll:( self extractTranslationsFromMethod:eachMethod ).
  1889 		]
  1890 	    ].
  1891 	].
  1892 
  1893 	self addAllTranslations:newTranslations.
  1894     ].
  1895 
  1896     "Modified: / 19-02-2015 / 11:44:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  1897     "Modified: / 16-08-2017 / 12:29:21 / mawalch"
  1898 !
  1899 
  1900 generateMissingTranslations: keys for: languages using: translator
  1901     keys do:[:string |
  1902         languages do:[:lang |
  1903             | translation |
  1904 
  1905             translation := keyStringsToLanguageMappings at:string language:lang.
  1906             translation isNil ifTrue:[
  1907                 translation := translator value: lang value: string.
  1908                 translation notNil ifTrue:[
  1909                     keyStringsToLanguageMappings at: string language: lang put: translation.
  1910                 ].
  1911             ].
  1912         ].
  1913     ].
  1914 
  1915     "Created: / 19-02-2015 / 12:31:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  1916 !
  1917 
  1918 generateMissingTranslationsFor: languages
  1919     self
  1920         generateMissingTranslations: keyStringsToLanguageMappings keys
  1921         for: languages
  1922         using: [ :lang :string | '**%1** %2' bindWith: lang asUppercase with: string ]
  1923 
  1924     "Created: / 19-02-2015 / 12:39:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  1925 !
  1926 
  1927 generateMissingTranslationsForAll
  1928     self generateMissingTranslationsFor: keyStringsToLanguageMappings languages
  1929 
  1930     "Created: / 19-02-2015 / 12:40:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  1931 !
  1932 
  1933 importExistingTranslationsFromFile
  1934     self information:'The import function is not available in this release'.
  1935 !
  1936 
  1937 inspectCanvasMissingStrings
  1938 
  1939     |spec nameSpace missingStrings|
  1940 
  1941     missingStrings := OrderedCollection new.
  1942     nameSpace := Dialog requestNameSpace:'NameSpace:' title:'Specify NameSpace to look for missing strings' initialAnswer:nil.
  1943     nameSpace := Smalltalk at:nameSpace asSymbol.
  1944     nameSpace isNil ifTrue:[
  1945 	^Dialog information:(resources string:'No such nameSpace exists.?')
  1946     ].
  1947 
  1948     nameSpace allClassesDo:[:cls |
  1949 	cls theMetaclass methodsDo:[:m |
  1950 	    m hasResource ifTrue:[
  1951 		(m resources includesKey:#canvas) ifTrue:[
  1952 		    spec := (cls perform:m selector) decodeAsLiteralArray.
  1953 		    spec do:[:eachComponent |
  1954 			eachComponent translationKeysDo:[:k |
  1955 			    (self includesKey: k) ifFalse:[
  1956 				missingStrings add: k.
  1957 				Transcript showCR: k storeString, '                         ', m printString]]
  1958 		    ]
  1959 		]
  1960 	    ]
  1961 	]
  1962     ].
  1963     missingStrings asSet inspect
  1964 !
  1965 
  1966 menuNew    
  1967     modified ifTrue:[
  1968         (Dialog
  1969             confirm:(resources stringWithCRs:'Modified translations have not been changed.\\Create new translations set anyway ?')
  1970             default:false) ifFalse:[^ self].
  1971     ].
  1972 
  1973     keyStringsToLanguageMappings initialize.
  1974     keyStringsToLanguageMappings changed.
  1975 
  1976     self languagesList contents:keyStringsToLanguageMappings languages.
  1977     self shownLanguages contents:keyStringsToLanguageMappings languages.
  1978     modified := false.
  1979 !
  1980 
  1981 menuOpen
  1982     |aFilename|
  1983 
  1984     self withWaitCursorDo:[
  1985 	aFilename := self requestFilename.
  1986 	aFilename isNil ifTrue:[^ self ].
  1987 	self readResourceFile:aFilename.
  1988     ]
  1989 !
  1990 
  1991 menuOpenByPackage
  1992     self withWaitCursorDo:[
  1993         |package|
  1994 
  1995         package := self requestPackage.
  1996         package isNil ifTrue:[^ self ].
  1997         self readResourceFileForPackage:package.
  1998     ]
  1999 
  2000     "Modified (format): / 20-02-2019 / 11:47:01 / Claus Gittinger"
  2001 !
  2002 
  2003 menuSave
  2004 "Saves the language selected in the fileName from where the language resource was obtained."
  2005     |lang|
  2006 
  2007     lang := self requestLanguageToSave.
  2008     lang isNil ifTrue:[^ self].
  2009     self saveLanguage: lang
  2010 !
  2011 
  2012 menuSaveAll
  2013     "Saves all the languages in the fileName from where the language resource was obtained."
  2014     keyStringsToLanguageMappings languagesInUse do:[:each | self saveLanguage: each].
  2015 !
  2016 
  2017 menuSaveAs
  2018 "Saves the language selected in the specified fileName."
  2019      |lang aFilename|
  2020 
  2021     lang := self requestLanguageToSave.
  2022     lang isNil ifTrue:[^ self].
  2023     
  2024     aFilename := self requestFilenameFor:lang.
  2025     aFilename isNil ifTrue:[^ self].
  2026     self saveResourceFile:aFilename for:lang asSymbol
  2027 
  2028     "Modified (format): / 30-10-2018 / 16:33:04 / Claus Gittinger"
  2029 !
  2030 
  2031 mergeLanguages
  2032     |sourceLanguage destLanguage possibleDestinationLanguages|
  2033 
  2034     sourceLanguage := Dialog 
  2035                         request:'Merge entries from:' 
  2036                         initialAnswer:nil 
  2037                         list:(self languagesList)
  2038                         title:'Source language'.
  2039     sourceLanguage isEmptyOrNil ifTrue:[^ self].
  2040 
  2041     possibleDestinationLanguages := self languagesList copyWithout:sourceLanguage.
  2042     
  2043     destLanguage := Dialog 
  2044                         request:'Destination language:\(Missing entries in destination are filled in from source)' withCRs 
  2045                         initialAnswer:(possibleDestinationLanguages size == 1
  2046                                         ifTrue:[possibleDestinationLanguages first]
  2047                                         ifFalse:[nil])
  2048                         list:possibleDestinationLanguages
  2049                         title:'Destination language'.
  2050     destLanguage isEmptyOrNil ifTrue:[^ self].
  2051 
  2052     "/ all empty entries of dest are filled in from source
  2053     keyStringsToLanguageMappings keys do:[:eachKey |
  2054         |newXlation|
  2055         
  2056         (keyStringsToLanguageMappings at:eachKey language:destLanguage) isEmptyOrNil ifTrue:[
  2057             newXlation := keyStringsToLanguageMappings at:eachKey language:sourceLanguage.
  2058             newXlation notNil ifTrue:[
  2059                 self halt.
  2060                 keyStringsToLanguageMappings at:eachKey language:destLanguage put:newXlation.
  2061             ]
  2062         ]
  2063     ]
  2064 !
  2065 
  2066 openAboutThisApplication
  2067     "This method was generated by the Browser.
  2068      It will be invoked when the menu-item 'help-about' is selected."
  2069 
  2070     "/ could open a customized aboutBox here ...
  2071     super openAboutThisApplication
  2072 !
  2073 
  2074 openDocumentation
  2075     "This method was generated by the Browser.
  2076      It will be invoked when the menu-item 'help-documentation' is selected."
  2077 
  2078     "/ change below as required ...
  2079 
  2080     "/ to open an HTML viewer on some document (under 'doc/online/<language>/' ):
  2081     HTMLDocumentView openFullOnDocumentationFile:'tools/languageEditor/TOP.html'.
  2082 
  2083     "/ add application-specific help files under the 'doc/online/<language>/help/appName'
  2084     "/ directory, and open a viewer with:
  2085     "/ HTMLDocumentView openFullOnDocumentationFile:'help/<MyApplication>/TOP.html'.
  2086 !
  2087 
  2088 openFileBrowserOnResourceDirectory
  2089     |files dirs|
  2090 
  2091     files := keyStringsToLanguageMappings perLanguageInfo 
  2092                 keysAndValuesCollect:[:lang :eachInfo |
  2093                     eachInfo at:#filename ifAbsent:nil
  2094                 ].
  2095     files := files reject:[:f | f isNil].
  2096     dirs := files collect:[:fn | fn asFilename directoryName] as:Set.
  2097     dirs do:[:eachDir |
  2098         UserPreferences current fileBrowserClass openOn:eachDir
  2099     ]
  2100 
  2101     "Created: / 30-10-2018 / 16:32:21 / Claus Gittinger"
  2102 !
  2103 
  2104 readResourceFile:aFilename
  2105     |lang|
  2106 
  2107     lang := self requestLanguage.
  2108     lang isNil ifTrue:[^ self ].
  2109 
  2110     self readResourceFile:aFilename asLanguage:(lang asSymbol)
  2111 
  2112     "Modified (format): / 20-02-2019 / 11:52:39 / Claus Gittinger"
  2113 !
  2114 
  2115 readResourceFileForPackage:aPackage
  2116     |allLanguages lang packageDir resourceDir|
  2117 
  2118     packageDir := Smalltalk packageDirectoryForPackageId:aPackage.
  2119     resourceDir := packageDir asFilename construct:'resources'.
  2120     resourceDir exists ifFalse:[
  2121         Dialog information:'No resource directory present for package: ',aPackage.
  2122         ^ self
  2123     ].    
  2124 
  2125     allLanguages := Set new.
  2126     resourceDir directoryContentsAsFilenamesDo:[:eachFile |
  2127         eachFile suffix = 'rs' ifTrue:[
  2128             (('##.rs' match:eachFile baseName)
  2129             or:[('##-##.rs' match:eachFile baseName)]) ifTrue:[
  2130                 allLanguages add:(eachFile withoutSuffix baseName)
  2131             ].
  2132         ].
  2133     ].
  2134 
  2135     allLanguages addAll:languagesList.
  2136     allLanguages := allLanguages asSortedCollection.
  2137 
  2138     lang := Dialog
  2139         choose:(resources string:'For which language ?')
  2140         fromList:allLanguages
  2141         values:allLanguages
  2142         buttons:(resources array:#('All'))
  2143         values:#(all)
  2144         lines:10
  2145         cancel:nil.
  2146 
  2147     lang isNil ifTrue:[^ self ].
  2148     self readResourceFileForPackage:aPackage language:lang
  2149 
  2150     "Modified: / 20-02-2019 / 12:20:35 / Claus Gittinger"
  2151 !
  2152 
  2153 readResourceFileForPackage:aPackage language:lang
  2154     "lang may be a language (de, en) or #all"
  2155 
  2156     |allLanguages packageDir resourceDir langFile|
  2157 
  2158     packageDir := Smalltalk packageDirectoryForPackageId:aPackage.
  2159     resourceDir := packageDir asFilename construct:'resources'.
  2160     resourceDir exists ifFalse:[
  2161         Dialog information:'No resource directory present for package: ',aPackage.
  2162         ^ self
  2163     ].    
  2164 
  2165     lang = #all ifTrue:[
  2166         allLanguages := Set new.
  2167         resourceDir directoryContentsAsFilenamesDo:[:eachFile |
  2168             eachFile suffix = 'rs' ifTrue:[
  2169                 (('##.rs' match:eachFile baseName)
  2170                 or:[('##-##.rs' match:eachFile baseName)]) ifTrue:[
  2171                     allLanguages add:(eachFile withoutSuffix baseName)
  2172                 ].
  2173             ].
  2174         ].
  2175 
  2176         allLanguages addAll:languagesList.
  2177         allLanguages := allLanguages asSortedCollection.
  2178 
  2179         allLanguages do:[:lang |
  2180             self addLanguage:lang.
  2181             self readResourceFile:(resourceDir construct:lang,'.rs') asLanguage:lang.
  2182         ].
  2183     ] ifFalse:[
  2184         langFile := resourceDir construct:lang,'.rs'.
  2185         self readResourceFile:langFile asLanguage:lang asSymbol
  2186     ].
  2187     self window label:('%1: %2' bindWith:self class nameWithoutPrefix with:aPackage)
  2188 
  2189     "Created: / 20-02-2019 / 12:20:02 / Claus Gittinger"
  2190 !
  2191 
  2192 removeLanguage
  2193     |languagesToRemove|
  2194 
  2195     languagesToRemove := Dialog 
  2196                             chooseMultiple:'Which language(s) do you want to remove?' 
  2197                             fromList:languagesList lines:10.
  2198 
  2199     languagesToRemove isEmptyOrNil ifTrue:[^ self ].
  2200     (Dialog confirm: 'Are you sure to remove the languages: ', languagesToRemove printString) ifTrue:[
  2201           self languagesList removeAll:languagesToRemove.
  2202           self shownLanguages removeAll:languagesToRemove.
  2203     ].
  2204 !
  2205 
  2206 removeTranslation
  2207     |rowSelectionIndex selectedKey|
  2208 
  2209     rowSelectionIndex := self selectedKeyRow value.
  2210     rowSelectionIndex isNil ifTrue:[^self].
  2211     rowSelectionIndex ~~ 0 ifTrue:[
  2212         selectedKey := keyStringsToLanguageMappings keyAt:rowSelectionIndex ifAbsent:nil.
  2213         selectedKey isNil ifTrue:[^self].
  2214         (Dialog confirm:(resources string:'Really remove key %1' with:selectedKey)) ifTrue:[
  2215             keyStringsToLanguageMappings removeKey:selectedKey.
  2216         ].
  2217     ].
  2218 !
  2219 
  2220 runApplicationAndCollectTranslations
  2221     |applicationClass newTranslations pseudoPack app startSelector|
  2222 
  2223     monitoredApplication notNil ifTrue:[
  2224 	monitoredApplication terminate.
  2225 	[monitoredApplication notNil] whileTrue:[
  2226 	    Delay waitForSeconds:0.1
  2227 	].
  2228     ].
  2229 
  2230     applicationClass := Dialog
  2231 		requestClass:'Application class to start and collect translations from:'
  2232 		okLabel:'OK'
  2233 		initialAnswer:(lastExtractedApplicationClass ? LastExtractedApplicationClass ).
  2234     applicationClass isNil ifTrue:[^ self ].
  2235     applicationClass isNameSpace ifTrue:[
  2236 	Dialog warn:'Entered class is a NameSpace'.
  2237 	^ self.
  2238     ].
  2239 
  2240     applicationClass isVisualStartable ifTrue:[
  2241 	startSelector := #open
  2242     ] ifFalse:[
  2243 	startSelector := Dialog
  2244 		    request:'Entered class seems to be no application class. Ok to start using selector:'
  2245 		    initialAnswer:((applicationClass respondsTo:#'start')
  2246 					ifTrue:#'start'
  2247 					ifFalse:#'new')
  2248 		    okLabel:'START'
  2249 		    title:'Start Application'.
  2250 	startSelector isNil ifTrue:[
  2251 	    ^ self
  2252 	].
  2253 	startSelector := startSelector asSymbol.
  2254     ].
  2255 
  2256     lastExtractedApplicationClass := LastExtractedApplicationClass := applicationClass.
  2257 
  2258     newTranslations := Set new.
  2259 
  2260     pseudoPack := AccessCollectingPseudoResourcePack new.
  2261     pseudoPack realResourcePack:(applicationClass classResources).
  2262     pseudoPack watchingTranslationEditor:self.
  2263 
  2264     self stopApplicationIconVisibleHolder value:true.
  2265 
  2266     monitoredApplication :=
  2267 	[
  2268 	    [
  2269 		app := applicationClass new.
  2270 		app resources:pseudoPack.
  2271 
  2272 		app perform:startSelector.
  2273 		app window waitUntilVisible.
  2274 		app window waitUntilClosed.
  2275 	    ] ensure:[
  2276 		app closeRequest.
  2277 		self stopApplicationIconVisibleHolder value:false.
  2278 		monitoredApplication := nil.
  2279 	    ].
  2280 	] fork.
  2281 !
  2282 
  2283 searchStringInLastNameSpace
  2284 
  2285     |selectedKey browser lastSearchPatterns|
  2286 
  2287     selectedKey := self selectedKey.
  2288     selectedKey isNil ifTrue:[^Dialog information: 'No selected key'].
  2289     browser := NewSystemBrowser new "open".
  2290     browser allButOpen.
  2291     lastSearchPatterns := browser lastSearchPatterns.
  2292     (lastSearchPatterns notNil and:[lastSearchPatterns first ~= selectedKey]) ifTrue:[
  2293 	browser lastSearchPatterns addFirst: selectedKey
  2294     ].
  2295     SearchDialog lastStringSearchArea: #currentNameSpace.
  2296     lastNameSpace isNil ifTrue:[
  2297 	self changeLastNameSpace.
  2298     ].
  2299     lastNameSpace notNil ifTrue:[
  2300 "/        browser navigationState selectedClasses value: lastNameSpace allClasses.
  2301 	browser navigationState nameSpaceFilter value: (OrderedCollection with:lastNameSpace name).
  2302 	browser navigationState selectedNamespaces value: (OrderedCollection with:lastNameSpace name).
  2303     ].
  2304     self withWaitCursorDo:[
  2305 	browser browseMenuMethodsWithString
  2306     ].
  2307 !
  2308 
  2309 searchStringInLastPackage
  2310 
  2311     | selectedKey browser lastSearchPatterns|
  2312 
  2313     selectedKey := self selectedKey.
  2314     selectedKey isNil ifTrue:[^ Dialog information: 'No selected key'].
  2315 
  2316     browser := NewSystemBrowser new "open".
  2317     browser allButOpen.
  2318 
  2319     lastSearchPatterns := browser lastSearchPatterns.
  2320     (lastSearchPatterns notNil and:[lastSearchPatterns first ~= selectedKey]) ifTrue:[
  2321 	browser lastSearchPatterns addFirst: selectedKey
  2322     ].
  2323     SearchDialog lastStringSearchArea: #currentPackage.
  2324     lastPackage isNil ifTrue:[
  2325 	self changeLastPackage.
  2326     ].
  2327     lastPackage notNil ifTrue:[
  2328 "/        browser navigationState selectedClasses value: lastNameSpace allClasses.
  2329 	browser navigationState packageFilter value: (OrderedCollection with:lastPackage).
  2330 	browser navigationState selectedProjects value: (OrderedCollection with:lastPackage).
  2331     ].
  2332     self withWaitCursorDo:[
  2333 	browser
  2334 	    askForMethodAndSpawnSearchTitle:'String to Search for in Sources:'
  2335 	    browserLabel:'Methods containing "%1"'
  2336 	    searchWith:#( #'findString:in:ignoreCase:match:' #'findString:inMethods:ignoreCase:match:' )
  2337 	    searchWhat:#string
  2338 	    searchArea:#currentPackage
  2339 	    withCaseIgnore:false
  2340 	    withTextEntry:false
  2341 	    withMatch:true
  2342 	    withMethodList:false
  2343 	    setSearchPattern:[:brwsr :string :ignoreCase :doMatch|
  2344 				brwsr autoSearchPattern:string ignoreCase:ignoreCase.
  2345 			     ]
  2346 	    initialText:selectedKey "/ does not work: ('''*',selectedKey,'*''') check match!!
  2347     ].
  2348 !
  2349 
  2350 searchTranslation
  2351     |searched foundIn foundExactIn foundMatchIn|
  2352 
  2353     searched := Dialog request:'Key or Value to Search:'.
  2354     searched isEmptyOrNil ifTrue:[^self].
  2355 
  2356     foundIn := OrderedCollection new.
  2357     ResourcePack allInstancesDo:[:each |
  2358         each keysAndValuesDo:[:key :val |
  2359             |orig xlation|
  2360 
  2361             orig := key printString.
  2362             xlation := val printString.
  2363             (orig = searched or:[xlation = searched]) ifTrue:[
  2364                 foundExactIn add:each    
  2365             ] ifFalse:[
  2366                 ((orig includesString:searched caseSensitive:false) 
  2367                 or:[xlation includesString:searched caseSensitive:false]) ifTrue:[
  2368                     foundIn add:each 
  2369                 ] ifFalse:[
  2370                     ((searched match:orig caseSensitive:false) 
  2371                     or:[searched match:xlation caseSensitive:false]) ifTrue:[
  2372                         foundMatchIn add:each 
  2373                     ].
  2374                 ].
  2375             ].
  2376         ].
  2377     ].
  2378 self halt.
  2379 
  2380     "Created: / 25-10-2018 / 16:16:13 / Claus Gittinger"
  2381 ! !
  2382 
  2383 !InternationalLanguageTranslationEditor methodsFor:'menus dynamic'!
  2384 
  2385 disableLanguageDisplayFor:lang
  2386     self shownLanguages remove:lang ifAbsent:[]
  2387 !
  2388 
  2389 enableLanguageDisplayFor:newLang
  2390     |shownLanguagesInOrder|
  2391 
  2392     (self shownLanguages includes:newLang) ifFalse:[
  2393 "/        shownLanguagesInOrder := self languagesList
  2394 "/                                    select:[:lang | (self shownLanguages includes:lang)
  2395 "/                                                    or:[ lang = newLang ]].
  2396 "/        self shownLanguages contents:shownLanguagesInOrder.
  2397 	self shownLanguages add:newLang.
  2398     ]
  2399 !
  2400 
  2401 isLanguageShown:lang
  2402     ^ self shownLanguages includes:lang
  2403 !
  2404 
  2405 menuSliceTranslateGenerate
  2406     | menu |
  2407 
  2408     menu := Menu new.
  2409     keyStringsToLanguageMappings notNil ifTrue:[
  2410         keyStringsToLanguageMappings languages do:[:lang |
  2411             menu addItem:
  2412                 (MenuItem
  2413                     label: (resources string: 'Generate Missing Translations - %1' with: lang asUppercase)
  2414                     itemValue: [ self generateMissingTranslationsFor: (Array with: lang) ])
  2415         ].
  2416     ].
  2417     ^ menu
  2418 
  2419     "Created: / 19-02-2015 / 12:44:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2420 !
  2421 
  2422 shownLanguagesMenu
  2423     <resource: #programMenu >
  2424 
  2425     ^ [
  2426 	|m selected|
  2427 
  2428 	m := Menu new.
  2429 
  2430 	self languagesList do:[:lang |
  2431 	    |item|
  2432 
  2433 	    item := MenuItem label:lang.
  2434 	    item indication:(self languageShownHolderFor:lang).
  2435 	    item hideMenuOnActivated:false.
  2436 	    m addItem:item.
  2437 	].
  2438 	m
  2439     ].
  2440 !
  2441 
  2442 toggleLanguageDisplayFor:lang
  2443     (self shownLanguages includes:lang) ifTrue:[
  2444 	self disableLanguageDisplayFor:lang
  2445     ] ifFalse:[
  2446 	self enableLanguageDisplayFor:lang
  2447     ].
  2448 ! !
  2449 
  2450 !InternationalLanguageTranslationEditor methodsFor:'private-key extraction'!
  2451 
  2452 addAllTranslations:newTranslations
  2453     "merge found xlations into the list of already present xlations"
  2454 
  2455     |newTranslationKeys stringKeys nonStringKeys|
  2456 
  2457     newTranslationKeys := newTranslations select:[:k | k notEmptyOrNil and:[k isString not or:[k isBlank not]]].
  2458     newTranslationKeys := newTranslationKeys select:[:k | (keyStringsToLanguageMappings includesKey:k) not].
  2459     "/ follow the common-xlations algrithm of ResourcePack
  2460     "/ (which knows how to xlate strings with additional special chars.)
  2461     newTranslationKeys :=
  2462         newTranslationKeys collect:[:oldKey |
  2463             |newKey methods|
  2464 
  2465             (oldKey endsWith:' ...') ifTrue:[
  2466                 newKey := oldKey copyButLast:4.
  2467             ] ifFalse:[ (oldKey endsWith:'...') ifTrue:[
  2468                 newKey := oldKey copyButLast:3.
  2469             ] ifFalse:[ ('\.:?=,!! ' includes:oldKey last) ifTrue:[
  2470                 newKey := oldKey copyButLast:1.
  2471             ] ifFalse:[ ((oldKey first == $() and:[ oldKey last == $) ]) ifTrue:[
  2472                 newKey := oldKey copyFrom:2 to:oldKey size - 1
  2473             ] ifFalse:[ ((oldKey first == $[) and:[ oldKey last == $] ]) ifTrue:[
  2474                 newKey := oldKey copyFrom:2 to:oldKey size - 1
  2475             ] ifFalse:[
  2476                 newKey :=oldKey
  2477             ]]]]].
  2478             "/ must attach oldKey-methods to newKey
  2479             methods := methodsUsingKey at:oldKey ifAbsent:nil.
  2480             methods notNil ifTrue:[
  2481                 (methodsUsingKey at:newKey ifAbsentPut:[Set new]) addAll:methods
  2482             ].
  2483             newKey
  2484         ].
  2485 
  2486     newTranslationKeys := newTranslationKeys asSet.
  2487     newTranslationKeys := newTranslationKeys select:[:k | (keyStringsToLanguageMappings includesKey:k) not].
  2488 
  2489     newTranslationKeys notEmpty ifTrue:[
  2490         stringKeys := newTranslationKeys select:[:k | k isString].
  2491         nonStringKeys := newTranslationKeys select:[:k | k isString not].
  2492 
  2493         stringKeys := stringKeys asSortedCollection.
  2494         keyStringsToLanguageMappings addKeys:stringKeys.
  2495         keyStringsToLanguageMappings addKeys:nonStringKeys.
  2496         modified := true.
  2497     ].
  2498 !
  2499 
  2500 extractTranslationsFromClass:aClass
  2501     |newTranslations|
  2502 
  2503     newTranslations := Set new.
  2504 
  2505     self withWaitCursorDo:[
  2506 	"/ now, the hard part:
  2507 	"/ possible translations are in the specs,
  2508 	"/ and all arguments to (resources string:) messages.
  2509 	aClass instAndClassMethodsDo:[:eachMethod |
  2510 	    newTranslations addAll:( self extractTranslationsFromMethod:eachMethod ).
  2511 	].
  2512     ].
  2513 
  2514     newTranslations :=
  2515 	newTranslations select:[:eachTranslation|
  2516 	    (aClass resources at:eachTranslation ifAbsent:nil) isNil
  2517 	].
  2518     ^ newTranslations
  2519 !
  2520 
  2521 extractTranslationsFromHelpSpecMethod:aMethod
  2522     "return strings which need translation from a help-spec method"
  2523 
  2524     |codeStrings matcher parseTree resourceKeys|
  2525 
  2526     parseTree := RBParser
  2527 	    parseMethod:aMethod source
  2528 	    onError: [:str :pos | Transcript showCR:str. Transcript showCR:pos.
  2529 				  nil].
  2530     parseTree isNil ifTrue:[^ #() ].
  2531 
  2532     codeStrings  :=
  2533 	#(
  2534 		'`@dict addPairsFrom: `#helpKeysAndStrings'
  2535 		'^ `#lit'
  2536 	).
  2537 
  2538     resourceKeys := Set new.
  2539 
  2540     matcher := ParseTreeSearcher new.
  2541     matcher
  2542 	matchesAnyOf: codeStrings
  2543 	do: [:aNode :answer |
  2544 		|sel argNode arg|
  2545 
  2546 		aNode isReturn ifTrue:[
  2547 		    "/ a ^ #(...)
  2548 		    aNode value isLiteralArray ifTrue:[
  2549 			aNode value value pairWiseDo:[:helpKey :helpString |
  2550 			    self rememberMethod:aMethod usingKey:helpString.
  2551 			    resourceKeys add:helpString.
  2552 			].
  2553 		    ].
  2554 		] ifFalse:[
  2555 		    sel := aNode selector.
  2556 		    (sel startsWith:'addPairsFrom:') ifTrue:[
  2557 			argNode := aNode arguments at:1.
  2558 			argNode isLiteralArray ifTrue:[
  2559 			    arg := argNode value.
  2560 			    arg doWithIndex:[:el :index |
  2561 				index even ifTrue:[
  2562 				    el isString ifTrue:[
  2563 					self rememberMethod:aMethod usingKey:el.
  2564 					resourceKeys add:el.
  2565 				    ]
  2566 				].
  2567 			    ].
  2568 			] ifFalse:[
  2569 			    Transcript halt
  2570 				showCR:(resources
  2571 					    string:'Cannot derive resourceKey from non-literal array: %1 in %2'
  2572 					    with:argNode formattedCode
  2573 					    with:aMethod selector).
  2574 			].
  2575 		    ].
  2576 		].
  2577 		aNode
  2578 	    ].
  2579 
  2580     matcher executeTree: parseTree initialAnswer: nil.
  2581     ^ resourceKeys
  2582 !
  2583 
  2584 extractTranslationsFromMenuSpecMethod:aMethod
  2585     "return strings which need translation from a menu-spec method"
  2586 
  2587     |menu resourceKeys|
  2588 
  2589     menu := aMethod mclass theNonMetaclass perform:aMethod selector.
  2590     menu isNil ifTrue:[ ^ #() ].
  2591 
  2592     (menu isKindOf:Menu) ifFalse:[
  2593 	menu := Menu new fromLiteralArrayEncoding:menu
  2594     ].
  2595 
  2596     resourceKeys := Set new.
  2597     menu allItemsDo:[:aMenuItem |
  2598 	aMenuItem translateLabel ifTrue:[
  2599 	    (aMenuItem isSeparatorItem or:[aMenuItem isMenuSlice])  ifFalse:[
  2600 		self rememberMethod:aMethod usingKey:aMenuItem label.
  2601 		resourceKeys add:aMenuItem label.
  2602 	    ]
  2603 	]
  2604     ].
  2605     ^ resourceKeys
  2606 !
  2607 
  2608 extractTranslationsFromMethod:aMethod
  2609     "return strings which need translation from a method."
  2610 
  2611     |mResources|
  2612 
  2613     mResources := aMethod resources.
  2614     mResources notNil ifTrue:[
  2615 	(mResources includesKey:#menu) ifTrue:[
  2616 	     ^ self extractTranslationsFromMenuSpecMethod:aMethod.
  2617 	].
  2618 	(mResources includesKey:#canvas) ifTrue:[
  2619 	     ^ self extractTranslationsFromUISpecMethod:aMethod.
  2620 	].
  2621 	(mResources includesKey:#help) ifTrue:[
  2622 	     ^ self extractTranslationsFromHelpSpecMethod:aMethod.
  2623 	].
  2624 	(mResources includesKey:#tableColumns) ifTrue:[
  2625 	     ^ self extractTranslationsFromTableColumnsSpecMethod:aMethod.
  2626 	].
  2627 
  2628 	^ self extractTranslationsFromSpecMethod:aMethod.
  2629     ].
  2630     ^ self extractTranslationsFromMethodsCode:aMethod
  2631 !
  2632 
  2633 extractTranslationsFromMethodsCode:aMethod
  2634     "return strings which need translation from a normal method.
  2635      detects messages to the resource translation mechanism"
  2636 
  2637     |codeStrings matcher parseTree resourceKeys|
  2638 
  2639     parseTree := RBParser
  2640 	    parseMethod:aMethod source
  2641 	    onError: [:str :pos | Transcript showCR:str. Transcript showCR:pos.
  2642 				  nil].
  2643     parseTree isNil ifTrue:[^ #() ].
  2644 
  2645     codeStrings  :=
  2646 	#(
  2647 		'resources `@msg: `@args'
  2648 		'self resources `@msg: `@args'
  2649 		'self class resources `@msg: `@args'
  2650 		'self class classResources `@msg: `@args'
  2651 		'self classResources `@msg: `@args'
  2652 		'`V classResources `@msg: `@args'
  2653 	).
  2654 
  2655     resourceKeys := Set new.
  2656 
  2657     matcher := ParseTreeSearcher new.
  2658     matcher
  2659 	matchesAnyOf: codeStrings
  2660 	do: [:aNode :answer |
  2661 		|sel keyStringArgNode keyStringArg|
  2662 
  2663 		sel := aNode selector.
  2664 		((sel startsWith:'string:') or:[(sel startsWith:'at:') or:[sel startsWith:'stringWithCRs:']]) ifTrue:[
  2665 		    keyStringArgNode := aNode arguments at:1.
  2666 		    (keyStringArg := self literalStringOrStringConcatenation:keyStringArgNode) notNil ifTrue:[
  2667 			self rememberMethod:aMethod usingKey:keyStringArg.
  2668 			resourceKeys add:keyStringArg.
  2669 		    ] ifFalse:[
  2670 			Transcript
  2671 			    showCR:(resources
  2672 				    string:'[LanguageTranslator] warning: Cannot derive resourceKey from non-string: %1 in %2'
  2673 				    with:keyStringArgNode formattedCode
  2674 				    with:aMethod whoString).
  2675 		    ].
  2676 		].
  2677 		aNode
  2678 	    ].
  2679 
  2680     matcher executeTree: parseTree initialAnswer: nil.
  2681     ^ resourceKeys
  2682 
  2683     "Modified: / 19-02-2015 / 11:42:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2684 !
  2685 
  2686 extractTranslationsFromSpecMethod:aMethod
  2687     ^ #()
  2688 !
  2689 
  2690 extractTranslationsFromTableColumnsSpecMethod:aMethod
  2691     "return strings which need translation from a table-spec method"
  2692 
  2693     |columnDescription resourceKeys|
  2694 
  2695     columnDescription := aMethod mclass theNonMetaclass perform:aMethod selector.
  2696     columnDescription isNil ifTrue:[ ^ #() ].
  2697 
  2698     (columnDescription first isKindOf:DataSetColumnSpec) ifFalse:[
  2699 	columnDescription := columnDescription collect:[:el | DataSetColumnSpec new fromLiteralArrayEncoding:el].
  2700     ].
  2701 
  2702     resourceKeys := Set new.
  2703     columnDescription do:[:aColumnSpec |
  2704 	aColumnSpec translateLabel ifTrue:[
  2705 	    self rememberMethod:aMethod usingKey:aColumnSpec label.
  2706 	    resourceKeys add:aColumnSpec label.
  2707 	]
  2708     ].
  2709     ^ resourceKeys
  2710 !
  2711 
  2712 extractTranslationsFromUISpecMethod:aMethod
  2713     "return strings which need translation from a UI-spec method"
  2714 
  2715     |spec resourceKeys visitor|
  2716 
  2717     spec := aMethod mclass theNonMetaclass perform:aMethod selector.
  2718     spec isNil ifTrue:[ ^ #() ].
  2719 
  2720     (spec isKindOf:UISpecification) ifFalse:[
  2721 	spec := UISpecification from:spec
  2722     ].
  2723 
  2724     resourceKeys := Set new.
  2725 
  2726     visitor := UISpecVisitor new.
  2727     spec acceptVisitor:visitor.
  2728     visitor translatedLabels do:[:each |
  2729 	self rememberMethod:aMethod usingKey:each.
  2730     ].
  2731     ^ visitor translatedLabels
  2732 !
  2733 
  2734 literalStringOrStringConcatenation:aParseNode
  2735     "nil if not a literal or a string concatenation"
  2736 
  2737     aParseNode isLiteralString ifTrue:[^ aParseNode value].
  2738     (aParseNode isMessage and:[aParseNode selector == #,]) ifTrue:[
  2739 	|leftString rightString|
  2740 
  2741 	aParseNode receiver isLiteralString ifTrue:[
  2742 	    leftString := aParseNode receiver value
  2743 	] ifFalse:[
  2744 	    leftString := self literalStringOrStringConcatenation:aParseNode receiver.
  2745 	].
  2746 	aParseNode arguments first isLiteralString ifTrue:[
  2747 	    rightString := aParseNode arguments first value
  2748 	] ifFalse:[
  2749 	    rightString := self literalStringOrStringConcatenation:aParseNode arguments first.
  2750 	].
  2751 	(leftString notNil and:[rightString notNil]) ifTrue:[
  2752 	    ^ leftString , rightString
  2753 	].
  2754     ].
  2755     ^ nil
  2756 !
  2757 
  2758 recordNewTranslation:aString
  2759     "called from recorder, when the monitored application does a translation"
  2760 
  2761     self addAllTranslations:{ aString }
  2762 !
  2763 
  2764 rememberMethod:aMethod usingKey:aKey
  2765     (methodsUsingKey at:aKey ifAbsentPut:[Set new]) add:aMethod
  2766 ! !
  2767 
  2768 !InternationalLanguageTranslationEditor methodsFor:'queries'!
  2769 
  2770 autoAccept
  2771 
  2772     ^ self autoAcceptHolder value
  2773 !
  2774 
  2775 currentExampleLanguageText
  2776    "Returns the language text corresponding for the current selected key and the example language selection"
  2777 
  2778   ^self languageTextFromSelectedKeyFor: self exampleLanguageSelectionHolder value
  2779 !
  2780 
  2781 currentLanguage
  2782 
  2783     |colSelectionIndex |
  2784 
  2785     colSelectionIndex := dataSetView selectedColIndex.
  2786     ^colSelectionIndex > 1 ifTrue:[ shownLanguages at:colSelectionIndex-1 ] ifFalse:nil.
  2787 !
  2788 
  2789 exampleLanguageByDefault
  2790 
  2791     ^self shownLanguages isEmpty
  2792 	ifTrue:[nil]
  2793 	ifFalse:[self shownLanguages first]
  2794 !
  2795 
  2796 hasFirstRowSelection
  2797     self selectedKeyRow isNil ifTrue:[^false].
  2798     ^ self selectedKeyRow value > 1
  2799 !
  2800 
  2801 hasLanguageSelection
  2802     dataSetView selectedColIndex isNil ifTrue:[^false].
  2803     ^ dataSetView selectedColIndex > 1
  2804 !
  2805 
  2806 hasUnsavedChanges
  2807     ^ modified ? false
  2808 
  2809     "Modified: / 20-02-2019 / 12:33:42 / Claus Gittinger"
  2810 !
  2811 
  2812 includesKey: aKey
  2813     ^ keyStringsToLanguageMappings notNil
  2814     and:[ keyStringsToLanguageMappings includesKey:aKey ]
  2815 !
  2816 
  2817 isSearchForSimilarTranslationEnabled
  2818 
  2819     ^self searchForSimilarTranslationEnableHolder value
  2820 !
  2821 
  2822 languageTextFromKey: aKeyIndex for: language
  2823     "Returns the language text corresponding for the aKeyIndex and the received language"
  2824 
  2825     language isNil ifTrue:[^''].
  2826     ^keyStringsToLanguageMappings at: aKeyIndex language:language.
  2827 !
  2828 
  2829 languageTextFromSelectedKeyFor: language
  2830     "Returns the language text corresponding for the current selected key and the received language"
  2831 
  2832     ^self languageTextFromKey: self selectedKey for: language
  2833 !
  2834 
  2835 shouldCopyPreviousTranslationButtonBeEnabled
  2836     ^ self hasLanguageSelection
  2837 	and:[self hasFirstRowSelection]
  2838 !
  2839 
  2840 shouldPasteOriginalButtonBeEnabled
  2841     ^ self hasLanguageSelection
  2842 	and:[self hasFirstRowSelection]
  2843 !
  2844 
  2845 shouldSearchForSimilarTranslation
  2846 
  2847     self isSearchForSimilarTranslationEnabled ifFalse:[^false].
  2848     (self languageTextHolder value notNil and:[self languageTextHolder value notEmpty]) ifTrue:[^false].
  2849     (self hasLanguageSelection and:[self selectedKeyRow notNil]) ifFalse:[^false].
  2850     ^true
  2851 ! !
  2852 
  2853 !InternationalLanguageTranslationEditor methodsFor:'read/write resourceFile'!
  2854 
  2855 encoderAt: lang
  2856 
  2857     self alwaysWriteUTF8Holder value ifTrue:[^CharacterEncoder encoderForUTF8].
  2858     ^keyStringsToLanguageMappings encoderAt: lang.
  2859 !
  2860 
  2861 printEditingWarningOn: aStream
  2862 
  2863     aStream nextPutAll: ';';
  2864 	    cr;
  2865 	    nextPutAll: '; WARNING:';
  2866 	    cr;
  2867 	    nextPutAll: '; this file contains national characters.';
  2868 	    cr;
  2869 	    nextPutAll: '; DO NOT EDIT this file with an old vi!!';
  2870 	    cr;
  2871 	    nextPutAll: ';';
  2872 	    cr;
  2873 	    cr.
  2874 !
  2875 
  2876 printEncoderFor: lang on: aStream
  2877     |characterEncoder encoderString|
  2878 
  2879     characterEncoder := self encoderAt: lang.
  2880     encoderString := characterEncoder isNil
  2881 	ifTrue:[self requestEncoderStringFor: lang]
  2882 	ifFalse:[characterEncoder nameOfEncoding printString].
  2883 
  2884     aStream nextPutAll: '#encoding';
  2885 	    space;
  2886 	    nextPutAll: encoderString;
  2887 	    cr;
  2888 	    cr.
  2889 !
  2890 
  2891 printLanguage: lang on: aStream
  2892 
  2893     self printEncoderFor: lang on: aStream.
  2894     self printEditingWarningOn: aStream.
  2895     self printLanguageMappingsFor: lang on: aStream.
  2896 !
  2897 
  2898 printLanguageMappingsFor: lang on: aStream
  2899 
  2900     |orderedAssociations maxKeySize characterEncoder|
  2901 
  2902     characterEncoder := self encoderAt: lang.
  2903     characterEncoder isNil ifTrue:[ characterEncoder := CharacterEncoder::NullEncoder ].
  2904     orderedAssociations := keyStringsToLanguageMappings orderedLanguageMappingsAssociationsFor: lang.
  2905 
  2906     maxKeySize := keyStringsToLanguageMappings maxKeySizeForLanguage: lang.
  2907 
  2908     orderedAssociations do:[:association |
  2909 	"use #basicStoreString to avoid implicit utf8Encoding for UnicodeStrings"
  2910 	aStream nextPutAll: ((characterEncoder encodeString:association key basicStoreString) paddedTo: maxKeySize) ;
  2911 	    tab;
  2912 	    nextPutAll: (characterEncoder encodeString: association value basicStoreString);
  2913 	    cr.
  2914 	].
  2915 !
  2916 
  2917 readResourceFile:aFilename asLanguage:lang
  2918     |resourcePack inStream lineString encoding 
  2919      decoder sortedKeys remainingKeys lineNr|
  2920 
  2921     aFilename exists ifFalse:[
  2922         Dialog information:(resources string:'Language file: "%1" does not exist' with:aFilename baseName).
  2923         ^ self
  2924     ].
  2925 
  2926     resourcePack := ResourcePack new.
  2927 
  2928     inStream := LineNumberReadStream on:(aFilename readStream).
  2929     [inStream atEnd] whileFalse:[
  2930         lineNr := inStream lineNumber.
  2931         lineString := inStream nextLine.
  2932         (lineString notEmpty
  2933         and:[ (lineString startsWith:';') not and:[ (lineString startsWith:'"/') not]]) ifTrue:[
  2934             ((lineString startsWith:'#') and:[(lineString startsWith:'#(') not]) ifTrue:[
  2935                 lineString := (lineString copyFrom:2) withoutSeparators.
  2936                 (lineString startsWith:'encoding ') ifTrue:[
  2937                     encoding := ResourcePack extractEncodingFromLine:lineString.
  2938                     decoder := CharacterEncoder encoderFor:encoding ifAbsent:nil.
  2939                 ].
  2940             ] ifFalse:[
  2941                 ResourcePack
  2942                     processResourceLine:lineString
  2943                     encoding:decoder
  2944                     file:aFilename pathName
  2945                     printErrorWith:[:msg | 
  2946                         Transcript 
  2947                             showCR:'%1[%2]: %3'
  2948                             with:(aFilename baseName)
  2949                             with:lineNr
  2950                             with:msg
  2951                     ]
  2952                     for:resourcePack
  2953                     keepUselessTranslations:true.
  2954             ].
  2955         ].
  2956     ].
  2957     inStream close.
  2958 
  2959     sortedKeys := (resourcePack keys select:[:k | k isString]) asSortedCollection.
  2960     remainingKeys := resourcePack keys select:[:k | k isString not].
  2961 
  2962     keyStringsToLanguageMappings atLanguage: lang putFilename: aFilename.
  2963     keyStringsToLanguageMappings atLanguage: lang putEncoder: decoder.
  2964 
  2965     sortedKeys do:[:k |
  2966         keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k) sendChange:false
  2967     ].
  2968     remainingKeys do:[:k |
  2969         keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k) sendChange:false
  2970     ].
  2971     keyStringsToLanguageMappings changed.
  2972 
  2973     "Modified: / 20-09-2018 / 11:09:39 / Claus Gittinger"
  2974 !
  2975 
  2976 saveLanguage: lang
  2977     "Saves the language in the fileName from where the language resource was obtained."
  2978     |filename|
  2979 
  2980     lang isNil ifTrue:[^ self].
  2981     filename := keyStringsToLanguageMappings filenameAt:lang.
  2982     filename isNil ifTrue:[
  2983         "/ ask
  2984         filename := self requestFilenameFor: lang.
  2985         filename isNil ifTrue:[^ self].
  2986     ].
  2987     self saveResourceFile:filename for:lang asSymbol
  2988 
  2989     "Modified (format): / 15-09-2018 / 12:29:59 / Claus Gittinger"
  2990 !
  2991 
  2992 saveResourceFile: aFilename for: lang
  2993 
  2994     |aStream |
  2995 
  2996     keyStringsToLanguageMappings atLanguage: lang putFilename: aFilename.
  2997     aStream := FileStream newFileNamed: aFilename.
  2998     self printLanguage: lang on: aStream.
  2999     aStream flush;
  3000 	    close.
  3001     DialogBox information: 'The resource file for the language ', lang printString storeString, ' was saved in the file: ', aFilename nameString
  3002 ! !
  3003 
  3004 !InternationalLanguageTranslationEditor methodsFor:'searching'!
  3005 
  3006 ignoreCaseHolderChanged
  3007 
  3008     self searchNextTextIncludingCurrentSelection: true.
  3009 
  3010     "Created: / 16-06-2007 / 09:33:33 / Administrador"
  3011 !
  3012 
  3013 searchForSimilarTranslation
  3014     "Looks for a quite similar translation for the key and display a dialog with available options"
  3015 
  3016     |similarTranslationsAssociations selectedTranslation key|
  3017 
  3018     self shouldSearchForSimilarTranslation ifFalse:[^self].
  3019 
  3020     key := self selectedKey.
  3021     key isNil ifTrue:[^ self.].
  3022     
  3023     similarTranslationsAssociations := keyStringsToLanguageMappings searchForSimilarTranslation: key in: self currentLanguage.
  3024     similarTranslationsAssociations isEmpty ifTrue:[^self].
  3025 
  3026     similarTranslationsAssociations := similarTranslationsAssociations associations inject: OrderedCollection new into:[:collection :association |
  3027         collection detect:[:selectedAssociation |
  3028             selectedAssociation value sameAs: association value] ifNone:[collection add: association].
  3029         collection].
  3030     selectedTranslation := Dialog
  3031         choose:'Choose one if you consider it´s usefull to translate:
  3032     ',
  3033         '<', key, '>  ', (self currentExampleLanguageText ifNil:[''])
  3034         fromList: (similarTranslationsAssociations collect:[:each |  '<', each key, '>  ', each value])
  3035         values: (similarTranslationsAssociations collect:[:each | each value])
  3036         lines:10
  3037         cancel: nil.
  3038 
  3039     selectedTranslation notNil ifTrue:[self languageTextHolderValue: selectedTranslation].
  3040 
  3041     "Modified (format): / 20-02-2019 / 12:27:41 / Claus Gittinger"
  3042 !
  3043 
  3044 searchNextText
  3045 
  3046     self searchNextTextIncludingCurrentSelection: false.
  3047 
  3048     "Modified: / 16-06-2007 / 09:21:14 / Administrador"
  3049 !
  3050 
  3051 searchNextTextFromBeginning
  3052     |searchText rowFoundIndex|
  3053 
  3054     searchText := searchTextView contents.
  3055     searchText isEmptyOrNil ifTrue:[^self].
  3056     self objectsList isEmpty ifTrue:[^self].
  3057     rowFoundIndex := self tableView findFirstRowWithString: searchText
  3058 		from:1
  3059 		to:self objectsList size
  3060 		ignoreCase:self ignoreCaseHolder value.
  3061     rowFoundIndex isNil ifTrue:[
  3062 	self searchTextNotFound.
  3063 	^self
  3064     ].
  3065     self selectListIndex: rowFoundIndex
  3066 
  3067     "Created: / 16-06-2007 / 10:54:51 / Administrador"
  3068     "Modified: / 19-06-2007 / 15:38:59 / Administrador"
  3069 !
  3070 
  3071 searchNextTextIncludingCurrentSelection: includeCurrentSelection
  3072     |searchText currentSelectionIndex rowFoundIndex fromIndex listSize|
  3073 
  3074     self searchTextStarted.
  3075     searchText := searchTextView contents.
  3076     searchText isEmptyOrNil ifTrue:[^self].
  3077     self objectsList isEmptyOrNil ifTrue:[^self].
  3078     currentSelectionIndex := self currentSelectionIndex.
  3079     (currentSelectionIndex isNil or:[currentSelectionIndex == 0]) ifTrue:[
  3080         self searchNextTextFromBeginning.
  3081         ^self.
  3082     ].
  3083     listSize := self objectsList size.
  3084     (currentSelectionIndex == listSize and:[includeCurrentSelection not]) ifTrue:[
  3085         self searchNextTextReachEnd.
  3086         ^self.
  3087     ].
  3088     fromIndex := includeCurrentSelection
  3089         ifTrue:[currentSelectionIndex]
  3090         ifFalse:[currentSelectionIndex + 1].
  3091     rowFoundIndex := self tableView findFirstRowWithString: searchText
  3092                 from:fromIndex
  3093                 to:listSize
  3094                 ignoreCase:self ignoreCaseHolder value.
  3095     rowFoundIndex isNil ifTrue:[
  3096         self searchNextTextReachEnd.
  3097         ^self
  3098     ].
  3099     self selectListIndex: rowFoundIndex
  3100 
  3101     "Created: / 16-06-2007 / 09:20:57 / Administrador"
  3102     "Modified: / 19-06-2007 / 15:38:06 / Administrador"
  3103     "Modified: / 25-10-2018 / 16:25:18 / Claus Gittinger"
  3104 !
  3105 
  3106 searchNextTextReachEnd
  3107     |message|
  3108     message := 'End of list reached, starting from the beginning'.
  3109     self searchTextRestarted: message.
  3110     Smalltalk beep.
  3111     self searchNextTextFromBeginning.
  3112 
  3113     "Created: / 16-06-2007 / 11:00:59 / Administrador"
  3114 !
  3115 
  3116 searchPreviousText
  3117 
  3118     |searchText currentSelectionIndex rowFoundIndex fromIndex|
  3119 
  3120     self searchTextStarted.
  3121     searchText := searchTextView contents.
  3122     searchText isEmptyOrNil ifTrue:[^self].
  3123     self objectsList isEmpty ifTrue:[^self].
  3124     currentSelectionIndex := self currentSelectionIndex.
  3125     currentSelectionIndex == 1 ifTrue:[
  3126 	self searchPreviousTextReachBeginning.
  3127 	^self.
  3128     ].
  3129     (currentSelectionIndex isNil or:[currentSelectionIndex == 0])
  3130 	ifTrue:[
  3131 	    self searchPreviousTextFromEnd.
  3132 	    ^self.
  3133 	]
  3134 	ifFalse:[fromIndex := currentSelectionIndex - 1].
  3135     rowFoundIndex := self tableView findFirstRowWithString: searchText
  3136 		from: fromIndex
  3137 		to: 1
  3138 		by: -1
  3139 		ignoreCase:self ignoreCaseHolder value.
  3140     rowFoundIndex isNil ifTrue:[
  3141 	self searchPreviousTextReachBeginning.
  3142 	^self
  3143     ].
  3144     self selectListIndex: rowFoundIndex.
  3145 
  3146     "Modified: / 19-06-2007 / 15:38:16 / Administrador"
  3147 !
  3148 
  3149 searchPreviousTextFromEnd
  3150 
  3151     |searchText rowFoundIndex|
  3152 
  3153     searchText := searchTextView contents.
  3154     searchText isEmptyOrNil ifTrue:[^self].
  3155     self objectsList isEmpty ifTrue:[^self].
  3156     rowFoundIndex := self tableView findFirstRowWithString: searchText
  3157 		from: self objectsList size
  3158 		to: 1
  3159 		by: -1
  3160 		ignoreCase:self ignoreCaseHolder value.
  3161     rowFoundIndex isNil ifTrue:[
  3162 	self searchTextNotFound.
  3163 	^self
  3164     ].
  3165     self selectListIndex: rowFoundIndex.
  3166 
  3167     "Created: / 16-06-2007 / 10:55:43 / Administrador"
  3168     "Modified: / 19-06-2007 / 15:38:26 / Administrador"
  3169 !
  3170 
  3171 searchPreviousTextReachBeginning
  3172     |message|
  3173     message := 'Beginning of list reached, starting from the end'.
  3174     self searchTextRestarted: message.
  3175     Smalltalk beep.
  3176     self searchPreviousTextFromEnd.
  3177 
  3178     "Created: / 16-06-2007 / 11:01:23 / Administrador"
  3179 !
  3180 
  3181 searchTextModifiedHolderChanged
  3182 
  3183     self searchNextTextIncludingCurrentSelection: true.
  3184     self searchTextModifiedHolder setValue: false.
  3185 
  3186 "/Transcript showCR: 'searchTextModifiedHolderChanged: ',(self searchTextHolder value ? '').
  3187 "/Transcript showCR: 'searchTextView contents: ',(searchTextView contents ? '').
  3188 
  3189     "Created: / 15-06-2007 / 18:07:57 / Administrador"
  3190     "Modified: / 16-06-2007 / 09:21:27 / Administrador"
  3191 !
  3192 
  3193 searchTextNotFound
  3194 
  3195     self selectListIndex: 0.
  3196     self searchBarImageInfoLabelHolder value: self warningSearchBarIcon.
  3197     self searchBarInfoLabelHolder value: 'Text not found'.
  3198     self setSearchTextNotFoundColors.
  3199 
  3200     "Created: / 16-06-2007 / 06:51:01 / Administrador"
  3201     "Modified: / 16-06-2007 / 11:43:53 / Administrador"
  3202 !
  3203 
  3204 searchTextRestarted: message
  3205 
  3206     self searchBarImageInfoLabelHolder value: self restartSearchBarIcon.
  3207     self searchBarInfoLabelHolder value: message.
  3208 "/    self setSearchTextNotFoundColors.
  3209 
  3210     "Created: / 16-06-2007 / 11:02:06 / Administrador"
  3211 !
  3212 
  3213 searchTextStarted
  3214 
  3215     self searchBarImageInfoLabelHolder value: nil.
  3216     self searchBarInfoLabelHolder value: ''.
  3217     self setSearchTextFoundColors.
  3218 
  3219     "Created: / 16-06-2007 / 06:54:03 / Administrador"
  3220     "Modified: / 16-06-2007 / 10:07:06 / Administrador"
  3221 !
  3222 
  3223 setSearchTextFoundColors
  3224 
  3225     searchTextView foregroundColor: Color black.
  3226     searchTextView backgroundColor: Color white.
  3227 
  3228     "Created: / 16-06-2007 / 06:28:32 / Administrador"
  3229 !
  3230 
  3231 setSearchTextNotFoundColors
  3232 
  3233     searchTextView foregroundColor: Color white.
  3234     searchTextView backgroundColor: Color lightRed.
  3235 
  3236     "Created: / 16-06-2007 / 06:29:00 / Administrador"
  3237 ! !
  3238 
  3239 !InternationalLanguageTranslationEditor methodsFor:'specs-dynamic'!
  3240 
  3241 columnInRow:row at:colIndex
  3242     |lang|
  3243 
  3244     lang := self languageAtCol:colIndex.
  3245     ^ row atLanguage:lang
  3246 !
  3247 
  3248 getBackgroundForRow:row rowNr:rowNr col:colIndex
  3249     |lang|
  3250 
  3251     colIndex == 1 ifTrue:[^ nil].
  3252     lang := self languageAtCol:colIndex.
  3253     ^ (row atLanguage:lang) isNil ifTrue:[Color red lightened] ifFalse:nil
  3254 !
  3255 
  3256 keyStringAndLanguageSelectionTableColumnDescription
  3257     |spec|
  3258 
  3259     spec := OrderedCollection new.
  3260 
  3261     spec add:(self class keyTableColumn first).
  3262 
  3263     self shownLanguages do:[:lang |
  3264 	|entry|
  3265 
  3266 	entry := self class languageTableColumn first.
  3267 	entry := entry copy replaceAll:#lang with:lang.
  3268 	spec add: entry
  3269     ].
  3270     ^ spec
  3271 !
  3272 
  3273 keyStringInRow:row
  3274     ^ row keyString
  3275 ! !
  3276 
  3277 !InternationalLanguageTranslationEditor methodsFor:'update'!
  3278 
  3279 updateToolVisibility
  3280     | bottomOffset searchBarVisible |
  3281 
  3282     bottomOffset := 0.
  3283 
  3284     searchBarVisible := self searchBoxVisible value.
  3285     searchBarVisible ifTrue:[
  3286 	bottomOffset := bottomOffset - searchBoxView height.
  3287     ].
  3288     translationsPanel layout bottomOffset:bottomOffset-1.
  3289     translationsPanel container notNil ifTrue:[
  3290 	translationsPanel containerChangedSize.
  3291     ].
  3292 
  3293     "Created: / 16-06-2007 / 11:58:25 / Administrador"
  3294 ! !
  3295 
  3296 !InternationalLanguageTranslationEditor methodsFor:'user actions'!
  3297 
  3298 closeSearchBar
  3299 
  3300     self searchBoxVisible value: false.
  3301     self updateToolVisibility.
  3302 
  3303     "Created: / 15-06-2007 / 18:03:05 / Administrador"
  3304     "Modified: / 16-06-2007 / 11:58:52 / Administrador"
  3305 !
  3306 
  3307 exampleLanguageSelectionChanged
  3308 
  3309    self updateExampleLanguageText.
  3310 !
  3311 
  3312 languageTextAccepted
  3313     |nextRowIndex selRow|
  3314 
  3315     selRow := self selectedKeyRow value.
  3316     selRow notNil ifTrue:[
  3317 	keyStringsToLanguageMappings size = selRow
  3318 	    ifTrue:[ self updateLanguageTextModification.]
  3319 	    ifFalse:[
  3320 		nextRowIndex := selRow + 1.
  3321 		self selectedKeyRow value: nextRowIndex]
  3322     ].
  3323 !
  3324 
  3325 pasteOriginalInLanguageText
  3326     <resource: #uiCallback>
  3327 
  3328     | originalText|
  3329 
  3330     originalText := self selectedKey.
  3331     languageEditor selectAll.
  3332     languageEditor pasteOrReplace:originalText.
  3333     self languageTextModifiedHolder value:true.
  3334 !
  3335 
  3336 pastePreviousTranslationInLanguageText
  3337     "Obtain the text from the previous translation and paste it into the languageTextEditor"
  3338 
  3339     | previousLanguageText previousLanguageRow|
  3340 
  3341     previousLanguageRow := dataSetView at:self selectedKeyRow value - 1
  3342 		ifAbsent:[^self].
  3343     previousLanguageText := previousLanguageRow atLanguage: self currentLanguage.
  3344     languageEditor selectAll.
  3345     languageEditor pasteOrReplace:previousLanguageText.
  3346     self languageTextModifiedHolder value:true.
  3347 !
  3348 
  3349 search
  3350     "make the searchbox visible"
  3351 
  3352     self searchBoxVisible value: true.
  3353     self updateToolVisibility.
  3354     searchTextView takeFocus.
  3355 
  3356     "Modified: / 16-06-2007 / 11:58:44 / Administrador"
  3357 !
  3358 
  3359 selectionChanged
  3360 
  3361    self updateOriginalTextModification.
  3362    self updateLanguageTextModification.
  3363    self updateLanguageAndKeySelection.
  3364    self updateExampleLanguageText.
  3365 
  3366    self updateCopyPreviousTranslationButtonEnabled.
  3367    self updatePasteOriginalButtonEnabled.
  3368 
  3369    self originalTextModifiedHolder value:false.
  3370    self languageTextModifiedHolder value:false.
  3371 
  3372    self searchForSimilarTranslation.
  3373 !
  3374 
  3375 showMissingTranslationsOnlyChanged
  3376 !
  3377 
  3378 shownLanguagesChanged
  3379     self keyStringAndLanguageSelectionTableColumnDescriptionHolder
  3380 	value:(self keyStringAndLanguageSelectionTableColumnDescription).
  3381 !
  3382 
  3383 stopApplication
  3384     |p|
  3385 
  3386     (p := monitoredApplication) notNil ifTrue:[
  3387 	p terminate.
  3388     ].
  3389 ! !
  3390 
  3391 !InternationalLanguageTranslationEditor::AccessCollectingPseudoResourcePack methodsFor:'accessing'!
  3392 
  3393 realResourcePack:something
  3394     realResourcePack := something.
  3395 !
  3396 
  3397 watchingTranslationEditor:something
  3398     watchingTranslationEditor := something.
  3399 ! !
  3400 
  3401 !InternationalLanguageTranslationEditor::AccessCollectingPseudoResourcePack methodsFor:'resource pack protocol'!
  3402 
  3403 forwardFor:aString
  3404     collectedKeys isNil ifTrue:[
  3405 	collectedKeys := Set new.
  3406     ].
  3407     collectedKeys add:aString.
  3408     watchingTranslationEditor notNil ifTrue:[
  3409 	watchingTranslationEditor recordNewTranslation:aString.
  3410     ].
  3411     ^ realResourcePack perform:(thisContext sender selector) withArguments:(thisContext sender args).
  3412 !
  3413 
  3414 string:aString
  3415     ^ self forwardFor:aString
  3416 ! !
  3417 
  3418 !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings class methodsFor:'instance creation'!
  3419 
  3420 new
  3421     ^ self basicNew initialize
  3422 ! !
  3423 
  3424 !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'accessing'!
  3425 
  3426 addKey:aKey
  3427     self addKey:aKey sendChange:true
  3428 !
  3429 
  3430 addKey:aKey sendChange:aBoolean
  3431     (keys includes:aKey) ifFalse:[
  3432 	keys add:aKey.
  3433 	aBoolean ifTrue:[ self changed ].
  3434     ]
  3435 !
  3436 
  3437 addKeys:aCollectionOfKey
  3438     keys addAll:aCollectionOfKey.
  3439     self changed.
  3440 !
  3441 
  3442 addLanguage:lang
  3443     (languages includes:lang) ifFalse:[
  3444 	languages add:lang.
  3445 	perLanguageMappings at:lang put:(OrderedDictionary new).
  3446     ]
  3447 !
  3448 
  3449 at:aKey language:language
  3450     ^ (perLanguageMappings at:language) at:aKey ifAbsent:nil
  3451 !
  3452 
  3453 at:aKey language:language put:value
  3454     self addKey:aKey.
  3455     (perLanguageMappings at:language) at:aKey put:value.
  3456     (self rowForKey:aKey) changed
  3457 !
  3458 
  3459 at:aKey language:language put:value sendChange:sendChange
  3460     self addKey:aKey sendChange:sendChange.
  3461     (perLanguageMappings at:language) at:aKey put:value.
  3462     (self rowForKey:aKey) changed
  3463 !
  3464 
  3465 atLanguage: lang putEncoder: aDecoder
  3466 
  3467 ^(self languageInfoAt: lang) at: self encoderKey put: aDecoder
  3468 !
  3469 
  3470 atLanguage: lang putFilename: aFilename
  3471 
  3472 ^(self languageInfoAt: lang) at: self fileNameKey put: aFilename
  3473 !
  3474 
  3475 decoderKey
  3476    ^#decoder
  3477 !
  3478 
  3479 encoderAt:lang
  3480     ^ (self languageInfoAt:lang) at: self encoderKey ifAbsent:[nil]
  3481 !
  3482 
  3483 encoderKey
  3484    ^#encoder
  3485 !
  3486 
  3487 fileNameKey
  3488     ^ #filename
  3489 !
  3490 
  3491 filenameAt:lang
  3492     ^ (self languageInfoAt:lang) at: self fileNameKey ifAbsent:[nil]
  3493 !
  3494 
  3495 keyAt:index
  3496     ^ keys at:index ifAbsent:[nil].
  3497 !
  3498 
  3499 keyAt:index ifAbsent:exceptionalValue
  3500     ^ keys at:index ifAbsent:exceptionalValue.
  3501 !
  3502 
  3503 keys
  3504     ^ keys
  3505 !
  3506 
  3507 languageInfoAt: lang
  3508 
  3509 ^self perLanguageInfo at: lang ifAbsentPut:[Dictionary new]
  3510 !
  3511 
  3512 languages
  3513     ^ languages
  3514 !
  3515 
  3516 languagesInUse
  3517 "Returns a collection of symbols for the languages that have mappings"
  3518 
  3519 ^self languages select:[:each | (self atLanguage: each) notEmpty]
  3520 !
  3521 
  3522 orderedLanguageMappingsAssociationsFor: language
  3523 "Returns a collection of languageMappings associations (alphabetically ordered by keys) "
  3524     ^(self atLanguage: language) associations
  3525 	    asSortedCollection:[:a :b | a key isArray or:[b key isArray or:[a key < b key]]].
  3526 !
  3527 
  3528 perLanguageInfo
  3529     ^ perLanguageInfo
  3530 !
  3531 
  3532 perLanguageInfo:something
  3533     perLanguageInfo := something.
  3534 !
  3535 
  3536 removeKey:aKey
  3537     keys remove:aKey ifAbsent:[].
  3538     perLanguageMappings do:[:eachMapping |
  3539 	eachMapping removeKey:aKey ifAbsent:[].
  3540     ].
  3541     self changed.
  3542 !
  3543 
  3544 rowForKey:aKey
  3545     ^ rowPerKey
  3546 	    at:aKey
  3547 	    ifAbsentPut:[InternationalLanguageTranslationEditor::LanguageMappingRow new
  3548 			    key:aKey; mappings:self].
  3549 !
  3550 
  3551 size
  3552     ^ keys size
  3553 ! !
  3554 
  3555 !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'enumerating'!
  3556 
  3557 do:aBlock
  3558     keys do:[:eachKey |
  3559 	aBlock value:(self rowForKey:eachKey).
  3560     ].
  3561 ! !
  3562 
  3563 !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'initialization'!
  3564 
  3565 initialize
  3566     super initialize.
  3567 
  3568     keys := OrderedSet new.
  3569     languages := OrderedCollection new.
  3570     perLanguageMappings := Dictionary new.
  3571     perLanguageInfo := Dictionary new.
  3572     rowPerKey := Dictionary new.
  3573 
  3574     self addLanguage:#'de'.
  3575     self addLanguage:#'fr'.
  3576     self addLanguage:#'en'.
  3577     self addLanguage:#'it'.
  3578     self addLanguage:#'es'.
  3579     self addLanguage:(Smalltalk language).
  3580 
  3581     "/ self initializeDemoMappings.
  3582 !
  3583 
  3584 initializeDemoMappings
  3585     keys add:'open'.
  3586     keys add:'close'.
  3587     keys add:'yes'.
  3588     keys add:'no'.
  3589 
  3590     self addLanguage:#'de'.
  3591     self addLanguage:#'fr'.
  3592 
  3593     self at:'open' language:#'de' put:'öffnen'.
  3594     self at:'close' language:#'de' put:'schließen'.
  3595     self at:'yes' language:#'de' put:'ja'.
  3596     self at:'no' language:#'de' put:'nein'.
  3597     self at:'cancel' language:#'de' put:'abbrechen'.
  3598 
  3599     self at:'open' language:#'fr' put:'ouvrir'.
  3600     self at:'close' language:#'fr' put:'fermer'.
  3601     self at:'yes' language:#'fr' put:'oui'.
  3602     self at:'no' language:#'fr' put:'non'.
  3603 ! !
  3604 
  3605 !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'private'!
  3606 
  3607 atLanguage:lang
  3608     ^ perLanguageMappings at:lang
  3609 !
  3610 
  3611 atLanguageIndex:idx
  3612     |lang|
  3613 
  3614     lang := languages at:idx.
  3615     ^ self atLanguage:lang.
  3616 !
  3617 
  3618 mappingAtLanguage:lang
  3619     ^ perLanguageMappings at:lang
  3620 !
  3621 
  3622 mappingAtLanguageIndex:idx
  3623     |lang|
  3624 
  3625     lang := languages at:idx.
  3626     ^ self mappingAtLanguage:lang.
  3627 ! !
  3628 
  3629 !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'queries'!
  3630 
  3631 includesKey:aKey
  3632     ^ keys includes:aKey
  3633 !
  3634 
  3635 includesLanguage:lang
  3636     ^ languages includes:lang
  3637 !
  3638 
  3639 indexOfKey:aKey
  3640     ^ keys indexOf:aKey
  3641 !
  3642 
  3643 maxKeySizeForLanguage: lang
  3644 
  3645 ^(self atLanguage: lang) keys inject: 0 into:[:maxSize :each |
  3646     (maxSize < each size and:[each size < 100])
  3647 	ifTrue:[each size]
  3648 	ifFalse:[maxSize].].
  3649 !
  3650 
  3651 searchForSimilarTranslation: aKey in: language
  3652     "Returns a collection of translation associations that corresponds to a quite similar key comparing with aKey"
  3653 
  3654     |similarAssociations|
  3655 
  3656     similarAssociations:=
  3657     (self mappingAtLanguage: language) associationsSelect:[:each |
  3658 	|eachKey|
  3659 
  3660 	eachKey := eachKey.
  3661 	eachKey isString
  3662 	and:[(eachKey sameAs: aKey)
  3663 	     or:[(aKey asUppercase startsWith: eachKey asUppercase)
  3664 	     or:[((eachKey asUppercase levenshteinTo: aKey asUppercase)/ eachKey size) < 0.3
  3665 	 ]]]
  3666 	 and:[each value notEmptyOrNil]
  3667     ].
  3668     ^similarAssociations
  3669 ! !
  3670 
  3671 !InternationalLanguageTranslationEditor::LanguageMappingRow methodsFor:'accessing'!
  3672 
  3673 atLanguage:language
  3674     |translation|
  3675 
  3676     translation := (mappings mappingAtLanguage:language) at:key ifAbsent:nil.
  3677     ^ translation isNil ifTrue:nil ifFalse:[translation printString]
  3678 !
  3679 
  3680 columnAt:columnNr
  3681     ^ (mappings mappingAtLanguageIndex:columnNr-1) at: key ifAbsent:nil
  3682 !
  3683 
  3684 key:something
  3685     key := something.
  3686 !
  3687 
  3688 keyString
  3689     ^ key printString
  3690 !
  3691 
  3692 mappings:something
  3693     mappings := something.
  3694 ! !
  3695 
  3696 !InternationalLanguageTranslationEditor::UISpecVisitor methodsFor:'accessing'!
  3697 
  3698 translatedLabels
  3699     ^ translatedLabels ? #()
  3700 ! !
  3701 
  3702 !InternationalLanguageTranslationEditor::UISpecVisitor methodsFor:'visiting'!
  3703 
  3704 visitObject:anObject with:aParameter
  3705     |l|
  3706 
  3707     (anObject isKindOf:UISpecification) ifTrue:[
  3708 	(anObject respondsTo:#translateLabel) ifTrue:[
  3709 	    anObject translateLabel == true ifTrue:[
  3710 		translatedLabels isNil ifTrue:[
  3711 		    translatedLabels := Set new.
  3712 		].
  3713 		l := anObject perform:#label ifNotUnderstood:nil.
  3714 		l notNil ifTrue:[
  3715 		    translatedLabels add:l.
  3716 		].
  3717 	    ].
  3718 	].
  3719     ].
  3720     self visitChildrenOf:anObject.
  3721 ! !
  3722 
  3723 !InternationalLanguageTranslationEditor class methodsFor:'documentation'!
  3724 
  3725 version
  3726     ^ '$Header$'
  3727 !
  3728 
  3729 version_CVS
  3730     ^ '$Header$'
  3731 ! !
  3732