#FEATURE by cg expecco_2_9_0 expecco_2_9_0_win75_lx36 expecco_2_9_1
authorClaus Gittinger <cg@exept.de>
Thu, 28 Apr 2016 22:36:49 +0200
changeset 3286 1ea9a6fbe2b4
parent 3285 5b8697869e72
child 3287 0bddeff854d4
#FEATURE by cg class: Tools::InternationalLanguageTranslationEditor class definition added:5 methods comment/format in: #extractTranslationsFromClass: #extractTranslationsFromMethod: #search changed:15 methods many improvements; extract remembers methods; browse-button to navigate there; recorder working;
Tools__InternationalLanguageTranslationEditor.st
--- a/Tools__InternationalLanguageTranslationEditor.st	Thu Apr 28 20:41:04 2016 +0200
+++ b/Tools__InternationalLanguageTranslationEditor.st	Thu Apr 28 22:36:49 2016 +0200
@@ -20,7 +20,7 @@
 		closeSearchBar searchTextModifiedHolder searchNextText
 		searchBarImageInfoLabelHolder searchPreviousText searchBoxVisible
 		searchBarInfoLabelHolder searchTextHolder searchTextView
-		searchBoxView translationsPanel lastPackage'
+		searchBoxView translationsPanel lastPackage methodsUsingKey'
 	classVariableNames:'LastExtractedClass LastExtractedApplicationClass
 		LastExtractedProject LastProject'
 	poolDictionaries:''
@@ -28,7 +28,7 @@
 !
 
 Object subclass:#AccessCollectingPseudoResourcePack
-	instanceVariableNames:'collectedKeys realResourcePack'
+	instanceVariableNames:'collectedKeys realResourcePack watchingTranslationEditor'
 	classVariableNames:''
 	poolDictionaries:''
 	privateIn:InternationalLanguageTranslationEditor
@@ -94,6 +94,45 @@
     "Created: / 04-03-2006 / 09:07:19 / cg"
 ! !
 
+!InternationalLanguageTranslationEditor class methodsFor:'help spec'!
+
+flyByHelpSpec
+    <resource: #help>
+
+    ^ super flyByHelpSpec addPairsFrom:#(
+
+#searchBox
+'Show a search box at the bottom to search for substrings in the string keys'
+
+#browseReferringMethods
+'Browse methods which refer to this string'
+
+)
+! !
+
+!InternationalLanguageTranslationEditor class methodsFor:'help specs'!
+
+helpSpec
+    "This resource specification was automatically generated
+     by the UIHelpTool of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIHelpTool may not be able to read the specification."
+
+    "
+     UIHelpTool openOnClass:Tools::InternationalLanguageTranslationEditor    
+    "
+
+    <resource: #help>
+
+    ^ super helpSpec addPairsFrom:#(
+
+#searchBox
+''
+
+)
+! !
+
 !InternationalLanguageTranslationEditor class methodsFor:'image specs'!
 
 closeSearchBarIcon
@@ -452,7 +491,7 @@
                       )
                     
                    )
-                   handles: (Any 0.33333333333333004 0.66666666666667007 1.0)
+                   handles: (Any 0.3333333333333301 0.66666666666667018 1.0)
                  )
                 )
               
@@ -479,13 +518,13 @@
                 (LabelSpec
                    label: 'Search:'
                    name: 'SearchLabel'
-                   layout: (LayoutFrame 30 0 5 0 81 0 27 0)
+                   layout: (LayoutFrame 30 0 5 0 100 0 27 0)
                    translateLabel: true
                    adjust: right
                  )
                 (InputFieldSpec
                    name: 'SearchEntryField'
-                   layout: (LayoutFrame 87 0 5 0 244 0 27 0)
+                   layout: (LayoutFrame 100 0 5 0 257 0 27 0)
                    model: searchTextHolder
                    immediateAccept: true
                    acceptOnReturn: true
@@ -498,7 +537,7 @@
                 (ActionButtonSpec
                    label: 'searchNextIcon'
                    name: 'SearchNextButton'
-                   layout: (LayoutFrame 251 0 5 0 272 0 26 0)
+                   layout: (LayoutFrame 264 0 5 0 285 0 26 0)
                    hasCharacterOrientedLabel: false
                    translateLabel: true
                    model: searchNextText
@@ -506,7 +545,7 @@
                 (ActionButtonSpec
                    label: 'searchPreviousIcon'
                    name: 'searchPreviousButton'
-                   layout: (LayoutFrame 279 0 5 0 300 0 26 0)
+                   layout: (LayoutFrame 292 0 5 0 313 0 26 0)
                    hasCharacterOrientedLabel: false
                    translateLabel: true
                    model: searchPreviousText
@@ -514,14 +553,14 @@
                 (CheckBoxSpec
                    label: 'Ignore case'
                    name: 'IgnoreCaseCheckBox'
-                   layout: (LayoutFrame 309 0 5 0 505 0 27 0)
+                   layout: (LayoutFrame 322 0 5 0 518 0 27 0)
                    model: ignoreCaseHolder
                    translateLabel: true
                  )
                 (LabelSpec
                    label: 'SearchBarImageInfoLabel'
                    name: 'SearchBarImageInfoLabel'
-                   layout: (LayoutFrame 511 0 5 0 535 0 27 0)
+                   layout: (LayoutFrame 524 0 5 0 548 0 27 0)
                    hasCharacterOrientedLabel: false
                    translateLabel: true
                    labelChannel: searchBarImageInfoLabelHolder
@@ -529,7 +568,7 @@
                 (LabelSpec
                    label: 'SearchBarInfoLabel'
                    name: 'SearchBarInfoLabel'
-                   layout: (LayoutFrame 538 0 5 0 816 0 27 0)
+                   layout: (LayoutFrame 551 0 5 0 829 0 27 0)
                    translateLabel: true
                    labelChannel: searchBarInfoLabelHolder
                    adjust: left
@@ -563,36 +602,45 @@
 
     ^
      #(Menu
-	(
-	 (MenuItem
-	    label: 'Set Current NameSpace'
-	    itemValue: changeLastNameSpace
-	    translateLabel: true
-	  )
-	 (MenuItem
-	    label: 'Search String in Current NameSpace'
-	    itemValue: searchStringInLastNameSpace
-	    translateLabel: true
-	  )
-	 (MenuItem
-	    label: '-'
-	    isVisible: #false
-	  )
-	 (MenuItem
-	    label: 'Set Current Package'
-	    itemValue: changeLastPackage
-	    translateLabel: true
-	    isVisible: #false
-	  )
-	 (MenuItem
-	    label: 'Search String in Current Package'
-	    itemValue: searchStringInLastPackage
-	    translateLabel: true
-	    isVisible: #false
-	  )
-	 )
-	nil
-	nil
+        (
+         (MenuItem
+            label: 'Browse Methods Containing this String'
+            itemValue: browseReferringMethods
+            translateLabel: true
+          )
+         (MenuItem
+            label: '-'
+            isVisible: #false
+          )
+         (MenuItem
+            label: 'Set Current NameSpace...'
+            itemValue: changeLastNameSpace
+            translateLabel: true
+          )
+         (MenuItem
+            label: 'Search String in Current NameSpace'
+            itemValue: searchStringInLastNameSpace
+            translateLabel: true
+          )
+         (MenuItem
+            label: '-'
+            isVisible: #false
+          )
+         (MenuItem
+            label: 'Set Current Package...'
+            itemValue: changeLastPackage
+            translateLabel: true
+            isVisible: #false
+          )
+         (MenuItem
+            label: 'Search String in Current Package'
+            itemValue: searchStringInLastPackage
+            translateLabel: true
+            isVisible: #false
+          )
+         )
+        nil
+        nil
       )
 !
 
@@ -690,6 +738,10 @@
                   indication: showMissingTranslationsOnly
                 )
                (MenuItem
+                  label: 'Show Search Box'
+                  indication: searchBoxVisible
+                )
+               (MenuItem
                   label: '-'
                 )
                (MenuItem
@@ -824,7 +876,6 @@
          (MenuItem
             label: 'Save'
             itemValue: menuSave
-            translateLabel: true
             isButton: true
             labelImage: (ResourceRetriever XPToolbarIconLibrary saveImageIcon)
           )
@@ -834,14 +885,12 @@
          (MenuItem
             label: 'Add Translation'
             itemValue: addTranslation
-            translateLabel: true
             isButton: true
             labelImage: (ResourceRetriever XPToolbarIconLibrary newRowIcon)
           )
          (MenuItem
             label: 'Remove Translation'
             itemValue: removeTranslation
-            translateLabel: true
             isButton: true
             labelImage: (ResourceRetriever XPToolbarIconLibrary removeRowIcon)
           )
@@ -849,12 +898,10 @@
             label: '-'
           )
          (MenuItem
-            label: 'Search'
-            itemValue: search
-            translateLabel: true
-            isButton: true
-            shortcutKey: Ctrlf
-            labelImage: (ResourceRetriever #'Tools::InternationalLanguageTranslationEditor' searchToolBarIcon)
+            activeHelpKey: browseReferringMethods
+            label: 'Browse'
+            itemValue: browseReferringMethods
+            labelImage: (ResourceRetriever ToolbarIconLibrary systemBrowserIcon)
           )
          (MenuItem
             label: ''
@@ -862,11 +909,20 @@
          (MenuItem
             label: 'Stop Application'
             itemValue: stopApplication
-            translateLabel: true
             isButton: true
             isVisible: stopApplicationIconVisibleHolder
             labelImage: (ResourceRetriever XPToolbarIconLibrary stop16x16Icon)
           )
+         (MenuItem
+            activeHelpKey: searchBox
+            label: 'Search'
+            isButton: true
+            startGroup: right
+            hideMenuOnActivated: false
+            indication: searchBoxVisible
+            shortcutKey: Ctrlf
+            labelImage: (ResourceRetriever #'Tools::InternationalLanguageTranslationEditor' searchToolBarIcon)
+          )
          )
         nil
         nil
@@ -903,14 +959,14 @@
             label: '-'
           )
          (MenuItem
+            label: 'Extract from Package...'
+            itemValue: extractTranslationsFromProject
+          )
+         (MenuItem
             label: 'Extract from Class...'
             itemValue: extractTranslationsFromClass
           )
          (MenuItem
-            label: 'Extract from Project...'
-            itemValue: extractTranslationsFromProject
-          )
-         (MenuItem
             label: 'Extract from NameSpace...'
             itemValue: extractTranslationsFromNameSpace
           )
@@ -1265,7 +1321,14 @@
 searchBoxVisible
 
     searchBoxVisible isNil ifTrue:[
-	searchBoxVisible := false asValue.
+        searchBoxVisible := false asValue.
+        searchBoxVisible 
+            onChangeEvaluate:[ 
+                self updateToolVisibility.
+                searchBoxVisible value ifTrue:[
+                    searchTextView takeFocus.
+                ].
+            ].
     ].
     ^ searchBoxVisible.
 
@@ -1553,6 +1616,7 @@
 initialize
     modified := false.
     inSingleFileMode := false.
+    methodsUsingKey := Dictionary new.
     super initialize
 !
 
@@ -1627,6 +1691,21 @@
    self selectedKeyRow value:index
 !
 
+browseReferringMethods
+    |selectedKey methods browser|
+
+    selectedKey := self selectedKey.
+    selectedKey isNil ifTrue:[^ Dialog information: 'No selected key'].
+
+    methods := methodsUsingKey at:selectedKey ifAbsent:nil.
+    methods isEmptyOrNil ifTrue:[
+        Dialog information:(resources stringWithCRs:'oops - no method remembered.\Please rerun the extract from XXX menu operation').
+        ^ self.
+    ].    
+    browser := UserPreferences systemBrowserClass browseMethods:methods.
+    browser autoSearch:selectedKey ignoreCase:true.
+!
+
 changeLastNameSpace
 
     |nameSpace defaultNameSpace|
@@ -1939,36 +2018,36 @@
     |applicationClass newTranslations pseudoPack app startSelector|
 
     monitoredApplication notNil ifTrue:[
-	monitoredApplication terminate.
-	[monitoredApplication notNil] whileTrue:[
-	    Delay waitForSeconds:0.1
-	].
+        monitoredApplication terminate.
+        [monitoredApplication notNil] whileTrue:[
+            Delay waitForSeconds:0.1
+        ].
     ].
 
     applicationClass := Dialog
-		requestClass:'Application class to start and collect translations from:'
-		okLabel:'OK'
-		initialAnswer:(lastExtractedApplicationClass ? LastExtractedApplicationClass ).
+                requestClass:'Application class to start and collect translations from:'
+                okLabel:'OK'
+                initialAnswer:(lastExtractedApplicationClass ? LastExtractedApplicationClass ).
     applicationClass isNil ifTrue:[^ self ].
-    applicationClass isNamespace ifTrue:[
-	Dialog warn:'Entered class is a NameSpace'.
-	^ self.
+    applicationClass isNameSpace ifTrue:[
+        Dialog warn:'Entered class is a NameSpace'.
+        ^ self.
     ].
 
     applicationClass isVisualStartable ifTrue:[
-	startSelector := #open
+        startSelector := #open
     ] ifFalse:[
-	startSelector := Dialog
-		    request:'Entered class seems to be no application class. Ok to start using selector:'
-		    initialAnswer:((applicationClass respondsTo:#'start')
-					ifTrue:#'start'
-					ifFalse:#'new')
-		    okLabel:'START'
-		    title:'Start Application'.
-	startSelector isNil ifTrue:[
-	    ^ self
-	].
-	startSelector := startSelector asSymbol.
+        startSelector := Dialog
+                    request:'Entered class seems to be no application class. Ok to start using selector:'
+                    initialAnswer:((applicationClass respondsTo:#'start')
+                                        ifTrue:#'start'
+                                        ifFalse:#'new')
+                    okLabel:'START'
+                    title:'Start Application'.
+        startSelector isNil ifTrue:[
+            ^ self
+        ].
+        startSelector := startSelector asSymbol.
     ].
 
     lastExtractedApplicationClass := LastExtractedApplicationClass := applicationClass.
@@ -1977,21 +2056,25 @@
 
     pseudoPack := AccessCollectingPseudoResourcePack new.
     pseudoPack realResourcePack:(applicationClass classResources).
+    pseudoPack watchingTranslationEditor:self.
 
     self stopApplicationIconVisibleHolder value:true.
 
-    monitoredApplication := [
-	[
-	    app := applicationClass new.
-	    app perform:startSelector.
-	    app window waitUntilVisible.
-	    app window waitUntilClosed.
-	] ensure:[
-	    app closeRequest.
-	    self stopApplicationIconVisibleHolder value:false.
-	    monitoredApplication := nil.
-	].
-    ] fork.
+    monitoredApplication := 
+        [
+            [
+                app := applicationClass new.
+                app resources:pseudoPack.
+                
+                app perform:startSelector.
+                app window waitUntilVisible.
+                app window waitUntilClosed.
+            ] ensure:[
+                app closeRequest.
+                self stopApplicationIconVisibleHolder value:false.
+                monitoredApplication := nil.
+            ].
+        ] fork.
 !
 
 searchStringInLastNameSpace
@@ -2025,24 +2108,39 @@
     | selectedKey browser lastSearchPatterns|
 
     selectedKey := self selectedKey.
-    selectedKey isNil ifTrue:[^Dialog information: 'No selected key'].
+    selectedKey isNil ifTrue:[^ Dialog information: 'No selected key'].
+
     browser := NewSystemBrowser new "open".
     browser allButOpen.
+    
     lastSearchPatterns := browser lastSearchPatterns.
     (lastSearchPatterns notNil and:[lastSearchPatterns first ~= selectedKey]) ifTrue:[
-	browser lastSearchPatterns addFirst: selectedKey
+        browser lastSearchPatterns addFirst: selectedKey
     ].
     SearchDialog lastStringSearchArea: #currentPackage.
     lastPackage isNil ifTrue:[
-	self changeLastPackage.
+        self changeLastPackage.
     ].
     lastPackage notNil ifTrue:[
 "/        browser navigationState selectedClasses value: lastNameSpace allClasses.
-	browser navigationState packageFilter value: (OrderedCollection with:lastPackage).
-	browser navigationState selectedProjects value: (OrderedCollection with:lastPackage).
+        browser navigationState packageFilter value: (OrderedCollection with:lastPackage).
+        browser navigationState selectedProjects value: (OrderedCollection with:lastPackage).
     ].
     self withWaitCursorDo:[
-	browser browseMenuMethodsWithString
+        browser 
+            askForMethodAndSpawnSearchTitle:'String to Search for in Sources:'
+            browserLabel:'Methods containing "%1"'
+            searchWith:#( #'findString:in:ignoreCase:match:' #'findString:inMethods:ignoreCase:match:' )
+            searchWhat:#string
+            searchArea:#currentPackage
+            withCaseIgnore:false
+            withTextEntry:false
+            withMatch:true
+            withMethodList:false
+            setSearchPattern:[:brwsr :string :ignoreCase :doMatch|
+                                brwsr autoSearchPattern:string ignoreCase:ignoreCase.
+                             ]
+            initialText:selectedKey "/ does not work: ('''*',selectedKey,'*''') check match!!               
     ].
 ! !
 
@@ -2116,22 +2214,39 @@
 !InternationalLanguageTranslationEditor methodsFor:'private-key extraction'!
 
 addAllTranslations:newTranslations
+    "merge found xlations into the list of already present xlations"
+    
     |newTranslationKeys stringKeys nonStringKeys|
 
     newTranslationKeys := newTranslations select:[:k | k notEmptyOrNil and:[k isString not or:[k isBlank not]]].
     newTranslationKeys := newTranslationKeys select:[:k | (keyStringsToLanguageMappings includesKey:k) not].
-    newTranslationKeys := newTranslationKeys
-                                collect:[:k |
-                                        (k endsWith:' ...') ifTrue:[
-                                            k copyButLast:4.
-                                        ] ifFalse:[(k endsWith:'...') ifTrue:[
-                                            k copyButLast:3.
-                                        ] ifFalse:[
-                                            ('\.:?=,!! ' includes:k last) ifTrue:[
-                                                k copyButLast:1.
-                                            ] ifFalse:[
-                                                k
-                                        ]]]].
+    "/ follow the common-xlations algrithm of ResourcePack
+    "/ (which knows how to xlate strings with additional special chars.)
+    newTranslationKeys := 
+        newTranslationKeys collect:[:oldKey |
+            |newKey methods|
+            
+            (oldKey endsWith:' ...') ifTrue:[
+                newKey := oldKey copyButLast:4.
+            ] ifFalse:[ (oldKey endsWith:'...') ifTrue:[
+                newKey := oldKey copyButLast:3.
+            ] ifFalse:[ ('\.:?=,!! ' includes:oldKey last) ifTrue:[
+                newKey := oldKey copyButLast:1.
+            ] ifFalse:[ ((oldKey first == $() and:[ oldKey last == $) ]) ifTrue:[
+                newKey := oldKey copyFrom:2 to:oldKey size - 1
+            ] ifFalse:[ ((oldKey first == $[) and:[ oldKey last == $] ]) ifTrue:[
+                newKey := oldKey copyFrom:2 to:oldKey size - 1
+            ] ifFalse:[
+                newKey :=oldKey
+            ]]]]].
+            "/ must attach oldKey-methods to newKey
+            methods := methodsUsingKey at:oldKey ifAbsent:nil.
+            methods notNil ifTrue:[
+                (methodsUsingKey at:newKey ifAbsentPut:[Set new]) addAll:methods
+            ].    
+            newKey
+        ].
+        
     newTranslationKeys := newTranslationKeys asSet.
     newTranslationKeys := newTranslationKeys select:[:k | (keyStringsToLanguageMappings includesKey:k) not].
 
@@ -2159,13 +2274,17 @@
             newTranslations addAll:( self extractTranslationsFromMethod:eachMethod ).
         ].
     ].
-    newTranslations := newTranslations select:[:eachTranslation|
-        (aClass resources at:eachTranslation ifAbsent:nil) isNil
-    ].
+    
+    newTranslations := 
+        newTranslations select:[:eachTranslation|
+            (aClass resources at:eachTranslation ifAbsent:nil) isNil
+        ].
     ^ newTranslations
 !
 
 extractTranslationsFromHelpSpecMethod:aMethod
+    "return strings which need translation from a help-spec method"
+
     |codeStrings matcher parseTree resourceKeys|
 
     parseTree := RBParser
@@ -2192,6 +2311,7 @@
                     "/ a ^ #(...)
                     aNode value isLiteralArray ifTrue:[
                         aNode value value pairWiseDo:[:helpKey :helpString |
+                            self rememberMethod:aMethod usingKey:helpString.
                             resourceKeys add:helpString.
                         ].
                     ].    
@@ -2199,27 +2319,20 @@
                     sel := aNode selector.
                     (sel startsWith:'addPairsFrom:') ifTrue:[
                         argNode := aNode arguments at:1.
-                        argNode isLiteral ifTrue:[
+                        argNode isLiteralArray ifTrue:[
                             arg := argNode value.
-                            arg isArray ifTrue:[
-                                arg doWithIndex:[:el :index |
-                                    index even ifTrue:[
-                                        el isString ifTrue:[
-                                            resourceKeys add:el.
-                                        ]
-                                    ].
+                            arg doWithIndex:[:el :index |
+                                index even ifTrue:[
+                                    el isString ifTrue:[
+                                        self rememberMethod:aMethod usingKey:el.
+                                        resourceKeys add:el.
+                                    ]
                                 ].
-                            ] ifFalse:[
-                                Transcript
-                                    showCR:(resources
-                                            string:'Cannot derive resourceKey from non-array in %1 in %2'
-                                            with:argNode formattedCode
-                                            with:aMethod selector).
                             ].
                         ] ifFalse:[
                             Transcript halt
                                 showCR:(resources
-                                            string:'Cannot derive resourceKey from non-literal: %1 in %2'
+                                            string:'Cannot derive resourceKey from non-literal array: %1 in %2'
                                             with:argNode formattedCode
                                             with:aMethod selector).
                         ].
@@ -2233,6 +2346,8 @@
 !
 
 extractTranslationsFromMenuSpecMethod:aMethod
+    "return strings which need translation from a menu-spec method"
+
     |menu resourceKeys|
 
     menu := aMethod mclass theNonMetaclass perform:aMethod selector.
@@ -2246,6 +2361,7 @@
     menu allItemsDo:[:aMenuItem |
         aMenuItem translateLabel ifTrue:[
             (aMenuItem isSeparatorItem or:[aMenuItem isMenuSlice])  ifFalse:[
+                self rememberMethod:aMethod usingKey:aMenuItem label.
                 resourceKeys add:aMenuItem label.
             ]
         ]
@@ -2254,6 +2370,8 @@
 !
 
 extractTranslationsFromMethod:aMethod
+    "return strings which need translation from a method."
+    
     |mResources|
 
     mResources := aMethod resources.
@@ -2277,7 +2395,9 @@
 !
 
 extractTranslationsFromMethodsCode:aMethod
-"/method:mthd selector:sel inClass:cls matchesParseTreeMatcher:aMatcher
+    "return strings which need translation from a normal method.
+     detects messages to the resource translation mechanism"
+
     |codeStrings matcher parseTree resourceKeys|
 
     parseTree := RBParser
@@ -2308,6 +2428,7 @@
                 ((sel startsWith:'string:') or:[(sel startsWith:'at:') or:[sel startsWith:'stringWithCRs:']]) ifTrue:[
                     keyStringArgNode := aNode arguments at:1.
                     (keyStringArg := self literalStringOrStringConcatenation:keyStringArgNode) notNil ifTrue:[
+                        self rememberMethod:aMethod usingKey:keyStringArg.
                         resourceKeys add:keyStringArg.
                     ] ifFalse:[
                         Transcript
@@ -2331,39 +2452,46 @@
 !
 
 extractTranslationsFromTableColumnsSpecMethod:aMethod
+    "return strings which need translation from a table-spec method"
+
     |columnDescription resourceKeys|
 
     columnDescription := aMethod mclass theNonMetaclass perform:aMethod selector.
     columnDescription isNil ifTrue:[ ^ #() ].
 
     (columnDescription first isKindOf:DataSetColumnSpec) ifFalse:[
-	columnDescription := columnDescription collect:[:el | DataSetColumnSpec new fromLiteralArrayEncoding:el].
+        columnDescription := columnDescription collect:[:el | DataSetColumnSpec new fromLiteralArrayEncoding:el].
     ].
 
     resourceKeys := Set new.
     columnDescription do:[:aColumnSpec |
-	aColumnSpec translateLabel ifTrue:[
-	    resourceKeys add:aColumnSpec label.
-	]
+        aColumnSpec translateLabel ifTrue:[
+            self rememberMethod:aMethod usingKey:aColumnSpec label.
+            resourceKeys add:aColumnSpec label.
+        ]
     ].
     ^ resourceKeys
 !
 
 extractTranslationsFromUISpecMethod:aMethod
+    "return strings which need translation from a UI-spec method"
+    
     |spec resourceKeys visitor|
 
     spec := aMethod mclass theNonMetaclass perform:aMethod selector.
     spec isNil ifTrue:[ ^ #() ].
 
     (spec isKindOf:UISpecification) ifFalse:[
-	spec := UISpecification from:spec
+        spec := UISpecification from:spec
     ].
 
     resourceKeys := Set new.
 
     visitor := UISpecVisitor new.
     spec acceptVisitor:visitor.
-
+    visitor translatedLabels do:[:each |
+        self rememberMethod:aMethod usingKey:each.
+    ].
     ^ visitor translatedLabels
 !
 
@@ -2389,6 +2517,16 @@
         ].
     ].
     ^ nil
+!
+
+recordNewTranslation:aString
+    "called from recorder, when the monitored application does a translation"
+    
+    self addAllTranslations:{ aString }
+!
+
+rememberMethod:aMethod usingKey:aKey
+    (methodsUsingKey at:aKey ifAbsentPut:[Set new]) add:aMethod
 ! !
 
 !InternationalLanguageTranslationEditor methodsFor:'queries'!
@@ -2926,7 +3064,8 @@
 !
 
 search
-
+    "make the searchbox visible"
+    
     self searchBoxVisible value: true.
     self updateToolVisibility.
     searchTextView takeFocus.
@@ -2970,6 +3109,27 @@
 
 realResourcePack:something
     realResourcePack := something.
+!
+
+watchingTranslationEditor:something
+    watchingTranslationEditor := something.
+! !
+
+!InternationalLanguageTranslationEditor::AccessCollectingPseudoResourcePack methodsFor:'resource pack protocol'!
+
+forwardFor:aString
+    collectedKeys isNil ifTrue:[
+        collectedKeys := Set new.
+    ].
+    collectedKeys add:aString.
+    watchingTranslationEditor notNil ifTrue:[
+        watchingTranslationEditor recordNewTranslation:aString.
+    ].
+    ^ realResourcePack perform:(thisContext sender selector) withArguments:(thisContext sender args).
+!
+
+string:aString
+    ^ self forwardFor:aString
 ! !
 
 !InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings class methodsFor:'instance creation'!