# HG changeset patch # User Stefan Vogel # Date 1450087461 -3600 # Node ID ff9a2e01e0a592a3a8e8f282f93a54c20eb5d2e5 # Parent 6b83ffb461b54d7a3909e72b31e7a85b63854d2f #BUGFIX class: Tools::InternationalLanguageTranslationEditor changed:8 methods diff -r 6b83ffb461b5 -r ff9a2e01e0a5 Tools__InternationalLanguageTranslationEditor.st --- a/Tools__InternationalLanguageTranslationEditor.st Fri Dec 11 16:38:38 2015 +0100 +++ b/Tools__InternationalLanguageTranslationEditor.st Mon Dec 14 11:04:21 2015 +0100 @@ -298,248 +298,251 @@ - ^ - #(FullSpec - name: windowSpec - window: - (WindowSpec - label: 'InternationalLanguageTranslationEditor' - name: 'InternationalLanguageTranslationEditor' - min: (Point 10 10) - bounds: (Rectangle 0 0 774 610) - menu: mainMenu - ) - component: - (SpecCollection - collection: ( - (MenuPanelSpec - name: 'ToolBar' - layout: (LayoutFrame 0 0 0 0 0 1 30 0) - menu: menuToolBar - textDefault: true - ) - (VariableVerticalPanelSpec - name: 'TranslationsVariableVerticalPanel' - layout: (LayoutFrame 0 0 30 0 0 1 -32 1) - component: - (SpecCollection - collection: ( - (DataSetSpec - name: 'KeyStringAndLanguageSelectionTable' - model: selectedKeyRow - menu: keyStringAndLanguageSelectionTableMenu - hasHorizontalScrollBar: true - hasVerticalScrollBar: true - dataList: keyStringAndLanguageSelectionTable - columnHolder: keyStringAndLanguageSelectionTableColumnDescriptionHolder - beDependentOfRows: true - columnAdaptor: yourself - postBuildCallback: postBuildDataSet: - ) - (VariableVerticalPanelSpec - name: 'VariableVerticalPanel1' - component: - (SpecCollection - collection: ( - (ViewSpec - name: 'Box1' - component: - (SpecCollection - collection: ( - (LabelSpec - label: 'Original String (Key):' - name: 'Label2' - layout: (LayoutFrame 0 0 -2 0 0 1 28 0) - translateLabel: true - adjust: left - ) - (TextEditorSpec - name: 'OriginalText' - layout: (LayoutFrame 0 0 27 0 0 1 -2 1) - model: originalTextHolder - hasHorizontalScrollBar: true - hasVerticalScrollBar: true - modifiedChannel: originalTextModifiedHolder - acceptCallBack: languageTextAccepted - ) - ) - - ) - ) - (ViewSpec - name: 'Box3' - component: - (SpecCollection - collection: ( - (LabelSpec - label: 'Select Another Language as example:' - name: 'Label3' - layout: (LayoutFrame 0 0 -6 0 0 1 24 0) - translateLabel: true - adjust: left - ) - (ComboBoxSpec - name: 'ComboBox1' - layout: (LayoutFrame 197 0 -2 0 322 0 18 0) - model: exampleLanguageSelectionHolder - immediateAccept: false - acceptOnLeave: true - acceptOnLostFocus: true - acceptOnPointerLeave: false - comboList: shownLanguages - useIndex: false - ) - (TextEditorSpec - name: 'ExampleLanguageText' - layout: (LayoutFrame 0 0 30 0 0 1 0 1) - model: exampleLanguageTextHolder - hasHorizontalScrollBar: true - hasVerticalScrollBar: true - isReadOnly: true - ) - ) - - ) - ) - (ViewSpec - name: 'Box2' - component: - (SpecCollection - collection: ( - (LabelSpec - label: 'Translated String:' - name: 'Label1' - layout: (LayoutFrame 0 0 0 0 0 1 30 0) - translateLabel: true - adjust: left - ) - (TextEditorSpec - name: 'LanguageText' - layout: (LayoutFrame 0 0 30 0 0 1 0 1) - model: languageTextHolder - hasHorizontalScrollBar: true - hasVerticalScrollBar: true - acceptChannel: languageTextAcceptHolder - modifiedChannel: languageTextModifiedHolder - acceptCallBack: languageTextAccepted - postBuildCallback: languageEditorBuilt: - ) - (ActionButtonSpec - label: 'Paste Previous' - name: 'pastePreviousTranslation' - layout: (LayoutOrigin 0 0.83085250338295 0 0.03448275862069) - translateLabel: true - model: pastePreviousTranslationInLanguageText - enableChannel: pastePreviousTranslationEnableHolder - disabledLogo: 'Paste Previous' - ) - (ActionButtonSpec - label: 'Paste Original' - name: 'Button1' - layout: (LayoutOrigin -95 0.83085250338295 0 0.03448275862069) - translateLabel: true - model: pasteOriginalInLanguageText - enableChannel: pasteOriginalEnableHolder - disabledLogo: 'Paste Original' - ) - ) - - ) - ) - ) - - ) - handles: (Any 0.33333333333333 0.66666666666667 1.0) - ) - ) - - ) - handles: (Any 0.5 1.0) - postBuildCallback: postBuildTranslationsPanel: - ) - (ViewSpec - name: 'SearchBox' - layout: (LayoutFrame 0 0 -32 1 0 1 0 1) - level: -1 - visibilityChannel: searchBoxVisible - component: - (SpecCollection - collection: ( - (ActionButtonSpec - label: 'closeSearchBarIcon' - name: 'closeSearchBarButton' - layout: (LayoutFrame 4 0 5 0 25 0 26 0) - hasCharacterOrientedLabel: false - translateLabel: true - model: closeSearchBar - ) - (LabelSpec - label: 'Search:' - name: 'SearchLabel' - layout: (LayoutFrame 30 0 5 0 81 0 27 0) - translateLabel: true - adjust: right - ) - (InputFieldSpec - name: 'SearchEntryField' - layout: (LayoutFrame 87 0 5 0 244 0 27 0) - model: searchTextHolder - immediateAccept: true - acceptOnReturn: true - acceptOnTab: true - acceptOnLostFocus: true - modifiedChannel: searchTextModifiedHolder - acceptOnPointerLeave: false - postBuildCallback: postBuildSearchTextView: - ) - (ActionButtonSpec - label: 'searchNextIcon' - name: 'SearchNextButton' - layout: (LayoutFrame 251 0 5 0 272 0 26 0) - hasCharacterOrientedLabel: false - translateLabel: true - model: searchNextText - ) - (ActionButtonSpec - label: 'searchPreviousIcon' - name: 'searchPreviousButton' - layout: (LayoutFrame 279 0 5 0 300 0 26 0) - hasCharacterOrientedLabel: false - translateLabel: true - model: searchPreviousText - ) - (CheckBoxSpec - label: 'Ignore case' - name: 'IgnoreCaseCheckBox' - layout: (LayoutFrame 309 0 5 0 505 0 27 0) - model: ignoreCaseHolder - translateLabel: true - ) - (LabelSpec - label: 'SearchBarImageInfoLabel' - name: 'SearchBarImageInfoLabel' - layout: (LayoutFrame 511 0 5 0 535 0 27 0) - hasCharacterOrientedLabel: false - translateLabel: true - labelChannel: searchBarImageInfoLabelHolder - ) - (LabelSpec - label: 'SearchBarInfoLabel' - name: 'SearchBarInfoLabel' - layout: (LayoutFrame 538 0 5 0 816 0 27 0) - translateLabel: true - labelChannel: searchBarInfoLabelHolder - adjust: left - ) - ) - - ) - postBuildCallback: postBuildSearchBoxView: - ) - ) - - ) - ) + ^ + #(FullSpec + name: windowSpec + window: + (WindowSpec + label: 'InternationalLanguageTranslationEditor' + name: 'InternationalLanguageTranslationEditor' + min: (Point 10 10) + bounds: (Rectangle 0 0 774 610) + menu: mainMenu + ) + component: + (SpecCollection + collection: ( + (MenuPanelSpec + name: 'ToolBar' + layout: (LayoutFrame 0 0 0 0 0 1 30 0) + menu: menuToolBar + textDefault: true + ) + (VariableVerticalPanelSpec + name: 'TranslationsVariableVerticalPanel' + layout: (LayoutFrame 0 0 30 0 0 1 -32 1) + component: + (SpecCollection + collection: ( + (DataSetSpec + name: 'KeyStringAndLanguageSelectionTable' + model: selectedKeyRow + menu: keyStringAndLanguageSelectionTableMenu + hasHorizontalScrollBar: true + hasVerticalScrollBar: true + dataList: keyStringAndLanguageSelectionTable + columnHolder: keyStringAndLanguageSelectionTableColumnDescriptionHolder + beDependentOfRows: true + columnAdaptor: yourself + postBuildCallback: postBuildDataSet: + ) + (VariableVerticalPanelSpec + name: 'VariableVerticalPanel1' + component: + (SpecCollection + collection: ( + (ViewSpec + name: 'Box1' + component: + (SpecCollection + collection: ( + (LabelSpec + label: 'Original String (Key):' + name: 'Label2' + layout: (LayoutFrame 0 0 -2 0 0 1 28 0) + translateLabel: true + adjust: left + ) + (TextEditorSpec + name: 'OriginalText' + layout: (LayoutFrame 0 0 27 0 0 1 -2 1) + model: originalTextHolder + hasHorizontalScrollBar: true + hasVerticalScrollBar: true + modifiedChannel: originalTextModifiedHolder + acceptCallBack: languageTextAccepted + hasKeyboardFocusInitially: false + ) + ) + + ) + ) + (ViewSpec + name: 'Box3' + component: + (SpecCollection + collection: ( + (LabelSpec + label: 'Select Another Language as example:' + name: 'Label3' + layout: (LayoutFrame 0 0 -6 0 0 1 24 0) + translateLabel: true + adjust: left + ) + (ComboBoxSpec + name: 'ComboBox1' + layout: (LayoutFrame 281 0 -2 0 406 0 18 0) + model: exampleLanguageSelectionHolder + immediateAccept: false + acceptOnLeave: true + acceptOnLostFocus: true + acceptOnPointerLeave: false + comboList: shownLanguages + useIndex: false + ) + (TextEditorSpec + name: 'ExampleLanguageText' + layout: (LayoutFrame 0 0 30 0 0 1 0 1) + model: exampleLanguageTextHolder + hasHorizontalScrollBar: true + hasVerticalScrollBar: true + isReadOnly: true + hasKeyboardFocusInitially: false + ) + ) + + ) + ) + (ViewSpec + name: 'Box2' + component: + (SpecCollection + collection: ( + (LabelSpec + label: 'Translated String:' + name: 'Label1' + layout: (LayoutFrame 0 0 0 0 0 1 30 0) + translateLabel: true + adjust: left + ) + (TextEditorSpec + name: 'LanguageText' + layout: (LayoutFrame 0 0 30 0 0 1 0 1) + model: languageTextHolder + hasHorizontalScrollBar: true + hasVerticalScrollBar: true + acceptChannel: languageTextAcceptHolder + modifiedChannel: languageTextModifiedHolder + acceptCallBack: languageTextAccepted + hasKeyboardFocusInitially: false + postBuildCallback: languageEditorBuilt: + ) + (ActionButtonSpec + label: 'Paste Previous' + name: 'pastePreviousTranslation' + layout: (LayoutOrigin 0 0.83085250338295003 0 0.034482758620689995) + translateLabel: true + model: pastePreviousTranslationInLanguageText + enableChannel: pastePreviousTranslationEnableHolder + disabledLogo: 'Paste Previous' + ) + (ActionButtonSpec + label: 'Paste Original' + name: 'Button1' + layout: (LayoutOrigin -95 0.83085250338295003 0 0.034482758620689995) + translateLabel: true + model: pasteOriginalInLanguageText + enableChannel: pasteOriginalEnableHolder + disabledLogo: 'Paste Original' + ) + ) + + ) + ) + ) + + ) + handles: (Any 0.33333333333333004 0.66666666666667007 1.0) + ) + ) + + ) + handles: (Any 0.5 1.0) + postBuildCallback: postBuildTranslationsPanel: + ) + (ViewSpec + name: 'SearchBox' + layout: (LayoutFrame 0 0 -32 1 0 1 0 1) + level: -1 + visibilityChannel: searchBoxVisible + component: + (SpecCollection + collection: ( + (ActionButtonSpec + label: 'closeSearchBarIcon' + name: 'closeSearchBarButton' + layout: (LayoutFrame 4 0 5 0 25 0 26 0) + hasCharacterOrientedLabel: false + translateLabel: true + model: closeSearchBar + ) + (LabelSpec + label: 'Search:' + name: 'SearchLabel' + layout: (LayoutFrame 30 0 5 0 81 0 27 0) + translateLabel: true + adjust: right + ) + (InputFieldSpec + name: 'SearchEntryField' + layout: (LayoutFrame 87 0 5 0 244 0 27 0) + model: searchTextHolder + immediateAccept: true + acceptOnReturn: true + acceptOnTab: true + acceptOnLostFocus: true + modifiedChannel: searchTextModifiedHolder + acceptOnPointerLeave: false + postBuildCallback: postBuildSearchTextView: + ) + (ActionButtonSpec + label: 'searchNextIcon' + name: 'SearchNextButton' + layout: (LayoutFrame 251 0 5 0 272 0 26 0) + hasCharacterOrientedLabel: false + translateLabel: true + model: searchNextText + ) + (ActionButtonSpec + label: 'searchPreviousIcon' + name: 'searchPreviousButton' + layout: (LayoutFrame 279 0 5 0 300 0 26 0) + hasCharacterOrientedLabel: false + translateLabel: true + model: searchPreviousText + ) + (CheckBoxSpec + label: 'Ignore case' + name: 'IgnoreCaseCheckBox' + layout: (LayoutFrame 309 0 5 0 505 0 27 0) + model: ignoreCaseHolder + translateLabel: true + ) + (LabelSpec + label: 'SearchBarImageInfoLabel' + name: 'SearchBarImageInfoLabel' + layout: (LayoutFrame 511 0 5 0 535 0 27 0) + hasCharacterOrientedLabel: false + translateLabel: true + labelChannel: searchBarImageInfoLabelHolder + ) + (LabelSpec + label: 'SearchBarInfoLabel' + name: 'SearchBarInfoLabel' + layout: (LayoutFrame 538 0 5 0 816 0 27 0) + translateLabel: true + labelChannel: searchBarInfoLabelHolder + adjust: left + ) + ) + + ) + postBuildCallback: postBuildSearchBoxView: + ) + ) + + ) + ) ! ! !InternationalLanguageTranslationEditor class methodsFor:'menu specs'! @@ -1034,9 +1037,9 @@ newLanguageText "/ languageEditor accept - ^self languageTextHolder value isNil - ifTrue:[''] - ifFalse:[self languageTextHolder value asCollectionOfLines first.] + ^self languageTextHolder value isEmptyOrNil + ifTrue:[''] + ifFalse:[self languageTextHolder value asCollectionOfLines first.] ! objectsList @@ -1401,21 +1404,21 @@ |answer| - self originalTextModifiedHolder value ifTrue:[ - answer := OptionBox - request:'Accept changed original text (key) ?' - label:'Original text (key) changed' - image:(WarningBox iconBitmap) - buttonLabels:#('Cancel' 'Accept' 'Accept As New') - values:#(nil #accept #acceptAsNew) - default:#acceptAsNew. - - answer isNil ifTrue:[^ self originalTextModifiedHolder value:false. ]. - answer == #accept ifTrue:[ - self halt. ]. - answer == #acceptAsNew ifTrue:[ - self halt. ]. - ]. + self originalTextModifiedHolder value ifTrue:[ + answer := OptionBox + request:'Accept changed original text (key) ?' + label:'Original text (key) changed' + image:(WarningBox iconBitmap) + buttonLabels:#('Cancel' 'Accept' 'Accept As New') + values:#(nil #accept #acceptAsNew) + default:#acceptAsNew. + + answer isNil ifTrue:[^ self originalTextModifiedHolder value:false. ]. + answer == #accept ifTrue:[ + self shouldImplement. ]. + answer == #acceptAsNew ifTrue:[ + self shouldImplement. ]. + ]. ! updatePasteOriginalButtonEnabled @@ -2114,7 +2117,7 @@ addAllTranslations:newTranslations |newTranslationKeys stringKeys nonStringKeys| - newTranslationKeys := newTranslations select:[:k | k notEmpty and:[k isString not or:[k isBlank not]]]. + 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 | @@ -2159,54 +2162,54 @@ |codeStrings matcher parseTree resourceKeys| parseTree := RBParser - parseMethod:aMethod source - onError: [:str :pos | Transcript showCR:str. Transcript showCR:pos. - nil]. + parseMethod:aMethod source + onError: [:str :pos | Transcript showCR:str. Transcript showCR:pos. + nil]. parseTree isNil ifTrue:[^ #() ]. codeStrings := - #( - '`@dict addPairsFrom: `#helpKeysAndStrings' - ). + #( + '`@dict addPairsFrom: `#helpKeysAndStrings' + ). resourceKeys := Set new. matcher := ParseTreeSearcher new. matcher - matchesAnyOf: codeStrings - do: [:aNode :answer | - |sel argNode arg| - - sel := aNode selector. - (sel startsWith:'addPairsFrom:') ifTrue:[ - argNode := aNode arguments at:1. - argNode isLiteral ifTrue:[ - arg := argNode value. - arg isArray ifTrue:[ - arg doWithIndex:[:el :index | - index even ifTrue:[ - el isString ifTrue:[ - 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 - showCR:(resources - string:'Cannot derive resourceKey from non-literal: %1 in %2' - with:argNode formattedCode - with:aMethod selector). - ]. - ]. - aNode - ]. + matchesAnyOf: codeStrings + do: [:aNode :answer | + |sel argNode arg| + + sel := aNode selector. + (sel startsWith:'addPairsFrom:') ifTrue:[ + argNode := aNode arguments at:1. + argNode isLiteral ifTrue:[ + arg := argNode value. + arg isArray ifTrue:[ + arg doWithIndex:[:el :index | + index even ifTrue:[ + el isString ifTrue:[ + 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' + with:argNode formattedCode + with:aMethod selector). + ]. + ]. + aNode + ]. matcher executeTree: parseTree initialAnswer: nil. ^ resourceKeys @@ -2272,6 +2275,7 @@ 'self resources `@msg: `@args' 'self class resources `@msg: `@args' 'self classResources `@msg: `@args' + '`V classResources `@msg: `@args' ). resourceKeys := Set new. @@ -2294,14 +2298,14 @@ showCR:(resources string:'Cannot derive resourceKey from non-string: %1 in %2' with:keyStringArgNode formattedCode - with:aMethod selector). + with:aMethod whoString). ]. ] ifFalse:[ Transcript - showCR:(resources + showCR:(resources string:'Cannot derive resourceKey from non-literal: %1 in %2' with:keyStringArgNode formattedCode - with:aMethod selector). + with:aMethod whoString). ]. ]. aNode @@ -2493,44 +2497,45 @@ maxKeySize := keyStringsToLanguageMappings maxKeySizeForLanguage: lang. orderedAssociations do:[:association | - aStream nextPutAll: (association key storeString paddedTo: maxKeySize) ; - nextPutAll: (String new: 10); - nextPutAll: (characterEncoder encodeString: association value) storeString; - cr. - ]. + "use #basicStoreString to avoid implicit utf8Encoding for UnicodeStrings" + aStream nextPutAll: ((characterEncoder encodeString:association key basicStoreString) paddedTo: maxKeySize) ; + tab; + nextPutAll: (characterEncoder encodeString: association value basicStoreString); + cr. + ]. ! readResourceFile:aFilename asLanguage:lang |resourcePack inStream lineString encoding decoder sortedKeys remainingKeys| aFilename exists ifFalse:[ - Dialog information:(resources string:'Language file: "%1" does not exist' with:aFilename baseName). - ^ self + Dialog information:(resources string:'Language file: "%1" does not exist' with:aFilename baseName). + ^ self ]. resourcePack := ResourcePack new. inStream := aFilename readStream. [inStream atEnd] whileFalse:[ - lineString := inStream nextLine. - (lineString notEmpty - and:[ (lineString startsWith:';') not ]) ifTrue:[ - ((lineString startsWith:'#') and:[(lineString startsWith:'#(') not]) ifTrue:[ - lineString := (lineString copyFrom:2) withoutSeparators. - (lineString startsWith:'encoding ') ifTrue:[ - encoding := ResourcePack extractEncodingFromLine:lineString. - decoder := CharacterEncoder encoderFor:encoding ifAbsent:nil. - ]. - ] ifFalse:[ - ResourcePack - processResourceLine:lineString - encoding:decoder - file:aFilename pathName - printErrorWith:[:msg | Transcript showCR:msg ] - for:resourcePack - keepUselessTranslations:true. - ]. - ]. + lineString := inStream nextLine. + (lineString notEmpty + and:[ (lineString startsWith:';') not and:[ (lineString startsWith:'"/') not]]) ifTrue:[ + ((lineString startsWith:'#') and:[(lineString startsWith:'#(') not]) ifTrue:[ + lineString := (lineString copyFrom:2) withoutSeparators. + (lineString startsWith:'encoding ') ifTrue:[ + encoding := ResourcePack extractEncodingFromLine:lineString. + decoder := CharacterEncoder encoderFor:encoding ifAbsent:nil. + ]. + ] ifFalse:[ + ResourcePack + processResourceLine:lineString + encoding:decoder + file:aFilename pathName + printErrorWith:[:msg | Transcript showCR:msg ] + for:resourcePack + keepUselessTranslations:true. + ]. + ]. ]. inStream close. @@ -2541,10 +2546,10 @@ keyStringsToLanguageMappings atLanguage: lang putEncoder: decoder. sortedKeys do:[:k | - keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k) sendChange:false + keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k) sendChange:false ]. remainingKeys do:[:k | - keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k) sendChange:false + keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k) sendChange:false ]. keyStringsToLanguageMappings changed. ! @@ -3040,7 +3045,8 @@ orderedLanguageMappingsAssociationsFor: language "Returns a collection of languageMappings associations (alphabetically ordered by keys) " -^(self atLanguage: language) associations asSortedCollection:[:a :b | a key < b key]. + ^(self atLanguage: language) associations + asSortedCollection:[:a :b | a key isArray or:[b key isArray or:[a key < b key]]]. ! perLanguageInfo @@ -3173,12 +3179,15 @@ similarAssociations:= (self mappingAtLanguage: language) associationsSelect:[:each | - ((each key sameAs: aKey) - or:[(aKey asUppercase startsWith: each key asUppercase) - or:[((each key asUppercase levenshteinTo: aKey asUppercase)/ each key size) < 0.3 - ]]) - and:[each value notNil - and:[each value notEmpty]] + |eachKey| + + eachKey := eachKey. + eachKey isString + and:[(eachKey sameAs: aKey) + or:[(aKey asUppercase startsWith: eachKey asUppercase) + or:[((eachKey asUppercase levenshteinTo: aKey asUppercase)/ eachKey size) < 0.3 + ]]] + and:[each value notEmptyOrNil] ]. ^similarAssociations ! !