# HG changeset patch # User Claus Gittinger # Date 1461875809 -7200 # Node ID 1ea9a6fbe2b42e4bbc749a002a686ab073e45700 # Parent 5b8697869e72c1e4b11c43de62fb788612f0d12f #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; diff -r 5b8697869e72 -r 1ea9a6fbe2b4 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 + + + ^ 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 + " + + + + ^ 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'!