--- 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'!