"{ Package: 'stx:libtool2' }"
"{ NameSpace: Tools }"
ApplicationModel subclass:#InternationalLanguageTranslationEditor
instanceVariableNames:'languagesList keyStringsToLanguageMappings languageTextHolder
originalTextHolder modified shownLanguages selectedKeyRow
showMissingTranslationsOnly
keyStringAndLanguageSelectionTableColumnDescriptionHolder
languageShownHolders dataSetView lastExtractedClass
lastExtractedApplicationClass stopApplicationIconVisibleHolder
monitoredApplication originalTextModifiedHolder
languageTextModifiedHolder languageTextAcceptHolder
inSingleFileMode lastExtractedProject lastLanguage
lastSelectedKey autoAcceptHolder languageEditor
selectedColIndexHolder exampleLanguageSelectionHolder
exampleLanguageTextHolder pastePreviousTranslationEnableHolder
searchForSimilarTranslationEnableHolder alwaysWriteUTF8Holder
lastNameSpace'
classVariableNames:'LastExtractedClass LastExtractedApplicationClass
LastExtractedProject'
poolDictionaries:''
category:'Interface-UIPainter'
!
Object subclass:#AccessCollectingPseudoResourcePack
instanceVariableNames:'collectedKeys realResourcePack'
classVariableNames:''
poolDictionaries:''
privateIn:InternationalLanguageTranslationEditor
!
Collection subclass:#KeyStringsToLanguageMappings
instanceVariableNames:'keys keyInfo perLanguageInfo perLanguageMappings languageMappings
languages rowPerKey'
classVariableNames:''
poolDictionaries:''
privateIn:InternationalLanguageTranslationEditor
!
Object subclass:#LanguageMappingRow
instanceVariableNames:'key mappings'
classVariableNames:''
poolDictionaries:''
privateIn:InternationalLanguageTranslationEditor
!
Visitor subclass:#UISpecVisitor
instanceVariableNames:'translatedLabels'
classVariableNames:''
poolDictionaries:''
privateIn:InternationalLanguageTranslationEditor
!
!InternationalLanguageTranslationEditor class methodsFor:'documentation'!
documentation
"
documentation to be added.
[author:]
cg (cg@FUSI)
[instance variables:]
[class variables:]
[see also:]
"
!
examples
"
Starting the application:
[exBegin]
InternationalLanguageTranslationEditor open
[exEnd]
more examples to be added:
[exBegin]
... add code fragment for
... executable example here ...
[exEnd]
"
!
history
"Created: / 04-03-2006 / 09:07:19 / cg"
! !
!InternationalLanguageTranslationEditor class methodsFor:'interface specs'!
windowSpec
"This resource specification was automatically generated
by the UIPainter of ST/X."
"Do not manually edit this!! If it is corrupted,
the UIPainter may not be able to read the specification."
"
UIPainter new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#windowSpec
Tools::InternationalLanguageTranslationEditor new openInterface:#windowSpec
Tools::InternationalLanguageTranslationEditor open
"
<resource: #canvas>
^
#(FullSpec
name: windowSpec
window:
(WindowSpec
label: 'InternationalLanguageTranslationEditor'
name: 'InternationalLanguageTranslationEditor'
min: (Point 10 10)
bounds: (Rectangle 0 0 778 614)
menu: mainMenu
)
component:
(SpecCollection
collection: (
(MenuPanelSpec
name: 'ToolBar'
layout: (LayoutFrame 0 0 0 0 0 1 30 0)
menu: menuToolBar
textDefault: true
)
(VariableVerticalPanelSpec
name: 'VariableVerticalPanel2'
layout: (LayoutFrame 0 0 30 0 0 1 0 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'
)
)
)
)
)
)
handles: (Any 0.33333333333333 0.66666666666667 1.0)
)
)
)
handles: (Any 0.5 1.0)
)
)
)
)
! !
!InternationalLanguageTranslationEditor class methodsFor:'menu specs'!
keyStringAndLanguageSelectionTableMenu
"This resource specification was automatically generated
by the MenuEditor of ST/X."
"Do not manually edit this!! If it is corrupted,
the MenuEditor may not be able to read the specification."
"
MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#keyStringAndLanguageSelectionTableMenu
(Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor keyStringAndLanguageSelectionTableMenu)) startUp
"
<resource: #menu>
^
#(Menu
(
(MenuItem
label: 'Current NameSpace:'
itemValue: changeLastNameSpace
translateLabel: true
)
(MenuItem
label: 'Search String in Current NameSpace:'
itemValue: searchStringInLastNameSpace
translateLabel: true
)
)
nil
nil
)
!
mainMenu
"This resource specification was automatically generated
by the MenuEditor of ST/X."
"Do not manually edit this!! If it is corrupted,
the MenuEditor may not be able to read the specification."
"
MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#mainMenu
(Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor mainMenu)) startUp
"
<resource: #menu>
^
#(Menu
(
(MenuItem
label: 'File'
translateLabel: true
submenu:
(Menu
(
(MenuItem
label: 'New'
itemValue: menuNew
translateLabel: true
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Open Resource File...'
itemValue: menuOpen
translateLabel: true
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Save All Resource Files'
itemValue: menuSaveAll
translateLabel: true
)
(MenuItem
label: 'Save Resource File'
itemValue: menuSave
translateLabel: true
)
(MenuItem
label: 'Save Resource File As...'
itemValue: menuSaveAs
translateLabel: true
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Current NameSpace:'
itemValue: changeLastNameSpace
translateLabel: true
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Exit'
itemValue: closeRequest
translateLabel: true
)
)
nil
nil
)
)
(MenuItem
label: 'View'
translateLabel: true
submenu:
(Menu
(
(MenuItem
label: 'Show Missing Translations Only'
translateLabel: true
indication: showMissingTranslationsOnly
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Shown Languages'
translateLabel: true
submenuChannel: shownLanguagesMenu
)
)
nil
nil
)
)
(MenuItem
label: 'Languages'
translateLabel: true
submenu:
(Menu
(
(MenuItem
label: 'Add Language...'
itemValue: addLanguage
translateLabel: true
)
(MenuItem
label: 'Remove Language...'
itemValue: removeLanguage
translateLabel: true
)
)
nil
nil
)
)
(MenuItem
label: 'Translations'
translateLabel: true
submenu:
(Menu
(
(MenuItem
label: 'Add Translation...'
itemValue: addTranslation
translateLabel: true
)
(MenuItem
label: 'Remove Translation...'
itemValue: removeTranslation
translateLabel: true
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Extract from Class...'
itemValue: extractTranslationsFromClass
translateLabel: true
)
(MenuItem
label: 'Extract from Project...'
itemValue: extractTranslationsFromProject
translateLabel: true
)
(MenuItem
label: 'Extract from NameSpace...'
itemValue: extractTranslationsFromNameSpace
translateLabel: true
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Run Application and Collect Translations...'
itemValue: runApplicationAndCollectTranslations
translateLabel: true
)
)
nil
nil
)
)
(MenuItem
label: 'Preferences'
translateLabel: true
submenu:
(Menu
(
(MenuItem
label: 'Auto Accept Changes'
translateLabel: true
indication: autoAcceptHolder
)
(MenuItem
label: 'Search For Similar Translations'
translateLabel: true
indication: searchForSimilarTranslationEnableHolder
)
(MenuItem
label: 'Always Write UTF8'
translateLabel: true
indication: alwaysWriteUTF8Holder
)
)
nil
nil
)
)
(MenuItem
label: 'Help'
translateLabel: true
startGroup: right
submenu:
(Menu
(
(MenuItem
label: 'Documentation'
itemValue: openDocumentation
translateLabel: true
)
(MenuItem
label: '-'
)
(MenuItem
label: 'About this Application...'
itemValue: openAboutThisApplication
translateLabel: true
)
)
nil
nil
)
)
)
nil
nil
)
!
menuItemsEditLanguage
"This resource specification was automatically generated
by the MenuEditor of ST/X."
"Do not manually edit this!! If it is corrupted,
the MenuEditor may not be able to read the specification."
"
MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#menu
(Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor menu)) startUp
"
<resource: #menu>
^
#(Menu
(
(MenuItem
enabled: pastePreviousTranslationEnableHolder
label: 'Paste Previous Translation'
itemValue: pastePreviousTranslationInLanguageText
nameKey: pastePreviousTranslationInLanguageText
translateLabel: true
)
)
nil
nil
)
!
menuToolBar
"This resource specification was automatically generated
by the MenuEditor of ST/X."
"Do not manually edit this!! If it is corrupted,
the MenuEditor may not be able to read the specification."
"
MenuEditor new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#menuToolBar
(Menu new fromLiteralArrayEncoding:(Tools::InternationalLanguageTranslationEditor menuToolBar)) startUp
"
<resource: #menu>
^
#(Menu
(
(MenuItem
label: 'Save'
itemValue: menuSave
translateLabel: true
labelImage: (ResourceRetriever XPToolbarIconLibrary saveImageIcon)
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Add Translation'
itemValue: addTranslation
translateLabel: true
labelImage: (ResourceRetriever XPToolbarIconLibrary newRowIcon)
)
(MenuItem
label: 'Remove Translation'
itemValue: removeTranslation
translateLabel: true
labelImage: (ResourceRetriever XPToolbarIconLibrary removeRowIcon)
)
(MenuItem
label: ''
)
(MenuItem
label: 'Stop Application'
itemValue: stopApplication
translateLabel: true
isVisible: stopApplicationIconVisibleHolder
labelImage: (ResourceRetriever XPToolbarIconLibrary stop16x16Icon)
)
)
nil
nil
)
! !
!InternationalLanguageTranslationEditor class methodsFor:'tableColumns specs'!
keyTableColumn
"This resource specification was automatically generated
by the DataSetBuilder of ST/X."
"Do not manually edit this!! If it is corrupted,
the DataSetBuilder may not be able to read the specification."
"
DataSetBuilder new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#keyTableColumn
"
<resource: #tableColumns>
^#(
(DataSetColumnSpec
label: 'Key'
labelButtonType: Button
minWidth: 50
model: keyStringInRow:
)
)
!
languageTableColumn
"This resource specification was automatically generated
by the DataSetBuilder of ST/X."
"Do not manually edit this!! If it is corrupted,
the DataSetBuilder may not be able to read the specification."
"
DataSetBuilder new openOnClass:Tools::InternationalLanguageTranslationEditor andSelector:#languageTableColumn
"
<resource: #tableColumns>
^#(
(DataSetColumnSpec
label: lang
labelButtonType: Button
minWidth: 50
editorType: None
model: columnInRow:at:
backgroundSelector: getBackgroundForRow:rowNr:col:
)
)
! !
!InternationalLanguageTranslationEditor methodsFor:'accessing'!
newLanguageText
"/ languageEditor accept
^self languageTextHolder value isNil
ifTrue:['']
ifFalse:[self languageTextHolder value asCollectionOfLines first.]
!
selectedKey
"Returns the current selected key if there is one row seleted. Otherwise, returns nil"
|rowSelectionIndex |
keyStringsToLanguageMappings isNil ifTrue:[^nil].
self selectedKeyRow value isNil ifTrue:[^nil].
rowSelectionIndex := self selectedKeyRow value.
rowSelectionIndex == 0 ifTrue:[^nil].
^ keyStringsToLanguageMappings keyAt:rowSelectionIndex.
! !
!InternationalLanguageTranslationEditor methodsFor:'additionalFuncionalities'!
searchForSimilarTranslation
"Looks for a quite similar translation for the key and display a dialog with available options"
|similarTranslationsAssociations selectedTranslation|
self shouldSearchForSimilarTranslation ifFalse:[^self].
similarTranslationsAssociations := keyStringsToLanguageMappings searchForSimilarTranslation: self selectedKey in: self currentLanguage.
similarTranslationsAssociations isEmpty ifTrue:[^self].
similarTranslationsAssociations := similarTranslationsAssociations associations inject: OrderedCollection new into:[:collection :association |
collection detect:[:selectedAssociation |
selectedAssociation value sameAs: association value] ifNone:[collection add: association].
collection].
selectedTranslation := Dialog
choose:'Choose one if you consider it´s usefull to translate:
',
'<', self selectedKey, '> ', (self currentExampleLanguageText ifNil:[''])
fromList: (similarTranslationsAssociations collect:[:each | '<', each key, '> ', each value])
values: (similarTranslationsAssociations collect:[:each | each value])
lines:10
cancel: nil.
selectedTranslation notNil ifTrue:[self languageTextHolderValue: selectedTranslation].
! !
!InternationalLanguageTranslationEditor methodsFor:'aspects'!
alwaysWriteUTF8Holder
alwaysWriteUTF8Holder isNil ifTrue:[alwaysWriteUTF8Holder := true asValue].
^ alwaysWriteUTF8Holder
!
autoAcceptHolder
autoAcceptHolder isNil ifTrue:[autoAcceptHolder := true asValue].
^ autoAcceptHolder
!
exampleLanguageSelectionHolder
exampleLanguageSelectionHolder isNil ifTrue:[
exampleLanguageSelectionHolder := self exampleLanguageByDefault asValue.
exampleLanguageSelectionHolder addDependent:self.
].
^ exampleLanguageSelectionHolder
!
exampleLanguageTextHolder
exampleLanguageTextHolder isNil ifTrue:[
exampleLanguageTextHolder := '' asValue.
].
^ exampleLanguageTextHolder.
!
keyStringAndLanguageSelectionTable
keyStringsToLanguageMappings isNil ifTrue:[
keyStringsToLanguageMappings := KeyStringsToLanguageMappings new.
].
^ keyStringsToLanguageMappings.
!
keyStringAndLanguageSelectionTableColumnDescriptionHolder
keyStringAndLanguageSelectionTableColumnDescriptionHolder isNil ifTrue:[
keyStringAndLanguageSelectionTableColumnDescriptionHolder := ValueHolder new.
keyStringAndLanguageSelectionTableColumnDescriptionHolder value:(self keyStringAndLanguageSelectionTableColumnDescription).
].
^ keyStringAndLanguageSelectionTableColumnDescriptionHolder.
!
languageAtCol:colNr
^ shownLanguages at:colNr-1.
!
languageShownHolderFor:lang
|holder|
languageShownHolders isNil ifTrue:[
languageShownHolders := Dictionary new
].
holder := languageShownHolders
at:lang
ifAbsentPut:[
|h|
h := true asValue.
h onChangeEvaluate:[
h value ifTrue:[
self enableLanguageDisplayFor:lang
] ifFalse:[
self disableLanguageDisplayFor:lang
].
].
h
].
^ holder.
!
languageTextAcceptHolder
languageTextAcceptHolder isNil ifTrue:[
languageTextAcceptHolder := false asValue.
].
^ languageTextAcceptHolder.
!
languageTextHolder
languageTextHolder isNil ifTrue:[
languageTextHolder := '' asValue.
].
^ languageTextHolder.
!
languageTextModifiedHolder
languageTextModifiedHolder isNil ifTrue:[
languageTextModifiedHolder := false asValue.
].
^ languageTextModifiedHolder.
!
languagesList
languagesList isNil ifTrue:[
languagesList := List withAll:(self keyStringAndLanguageSelectionTable languages).
].
^ languagesList.
!
originalTextHolder
originalTextHolder isNil ifTrue:[
originalTextHolder := '' asValue.
].
^ originalTextHolder.
!
originalTextModifiedHolder
originalTextModifiedHolder isNil ifTrue:[
originalTextModifiedHolder := false asValue.
].
^ originalTextModifiedHolder.
!
pastePreviousTranslationEnableHolder
pastePreviousTranslationEnableHolder isNil ifTrue:[pastePreviousTranslationEnableHolder := false asValue].
^ pastePreviousTranslationEnableHolder
!
searchForSimilarTranslationEnableHolder
searchForSimilarTranslationEnableHolder isNil
ifTrue:[searchForSimilarTranslationEnableHolder := true asValue].
^ searchForSimilarTranslationEnableHolder
!
selectedKeyRow
selectedKeyRow isNil ifTrue:[
selectedKeyRow := ValueHolder new.
selectedKeyRow onChangeSend:#selectionChanged to:self.
].
^ selectedKeyRow.
!
showMissingTranslationsOnly
showMissingTranslationsOnly isNil ifTrue:[
showMissingTranslationsOnly := false asValue.
showMissingTranslationsOnly onChangeSend:#showMissingTranslationsOnlyChanged to:self.
].
^ showMissingTranslationsOnly.
!
shownLanguages
shownLanguages isNil ifTrue:[
shownLanguages := List new.
shownLanguages addAll:(self languagesList).
shownLanguages onChangeSend:#shownLanguagesChanged to:self.
].
^ shownLanguages.
!
stopApplicationIconVisibleHolder
stopApplicationIconVisibleHolder isNil ifTrue:[
stopApplicationIconVisibleHolder := false asValue.
].
^ stopApplicationIconVisibleHolder.
! !
!InternationalLanguageTranslationEditor methodsFor:'change & update'!
languageTextHolderValue: aString
self languageTextHolder value: aString.
self languageTextModifiedHolder value:true.
!
update:something with:aParameter from:changedObject
changedObject == shownLanguages ifTrue:[
self shownLanguagesChanged.
^ self.
].
changedObject == languageTextAcceptHolder ifTrue:[
self updateLanguageTextModification.
^ self.
].
changedObject == exampleLanguageSelectionHolder ifTrue:[
self updateExampleLanguageText.
^ self.
].
changedObject == showMissingTranslationsOnly ifTrue:[
self showMissingTranslationsOnlyChanged.
^ self.
].
!
updateCopyPreviousTranslationButtonEnabled
self pastePreviousTranslationEnableHolder value: self shouldCopyPreviousTranslationButtonBeEnabled
!
updateExampleLanguageText
self selectedKeyRow value isNil ifTrue:[^ self].
self exampleLanguageTextHolder value:self currentExampleLanguageText
!
updateKeyStringsToLanguageMappings
keyStringsToLanguageMappings
at:lastSelectedKey
language:lastLanguage
put: self newLanguageText.
!
updateLanguageAndKeySelection
self originalTextHolder value: self selectedKey.
self languageTextHolder value: (self languageTextFromSelectedKeyFor: self currentLanguage).
lastLanguage := self currentLanguage.
lastSelectedKey := self selectedKey.
!
updateLanguageTextModification
self languageTextModifiedHolder value ifTrue:[
(self autoAccept or:[Dialog confirm:'Accept changed translation ?']) ifTrue:[
self languageTextModifiedHolder value:false.
self languageTextHolder value:languageEditor contents.
lastLanguage notNil ifTrue:[self updateKeyStringsToLanguageMappings.]
]
].
!
updateOriginalTextModification
|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. ].
].
! !
!InternationalLanguageTranslationEditor methodsFor:'dialogs'!
requestEncoderDialog
|box val characterCollection|
val := '' asValue.
box := Dialog new.
(box addTextLabel:'Select or write the encoder') adjust:#left.
box addVerticalSpace.
characterCollection := CharacterEncoder supportedExternalEncodings
inject: OrderedCollection new
into:[:collection :each |
collection add: each first;
yourself].
(box addComboBoxOn:val) list: characterCollection.
box addOkButton.
box open.
^val value
!
requestEncoderStringFor: lang
"Returns an encoder string and updates the language's info"
|encoderString encoder|
encoderString := self requestEncoderDialog.
encoderString notEmpty ifTrue:[
encoder := CharacterEncoder encoderFor: encoderString ifAbsent:nil.
encoder notNil ifTrue:[keyStringsToLanguageMappings atLanguage: lang putEncoder: encoder.].
].
^encoderString
!
requestFilename
|aFilename|
aFilename := Dialog
requestFileName:'Name of resource file:'
default:nil
pattern:'*.rs'.
aFilename isEmptyOrNil ifTrue:[^ nil ].
^aFilename asFilename
!
requestFilenameFor: lang
"Returns a filename to save the language resource and updates the language's info"
|aFilename|
aFilename := Dialog
requestFileName:'Name of resource file to save ', lang asString, ' :'
default:nil
pattern:'*.rs'.
aFilename isEmptyOrNil ifTrue:[^ nil ].
keyStringsToLanguageMappings atLanguage: lang putFilename: aFilename.
^aFilename asFilename
!
requestLanguage
^ Dialog
choose:'Which language do you want to save?'
fromList:languagesList
lines:10
! !
!InternationalLanguageTranslationEditor methodsFor:'initialization & release'!
closeRequest
"asks for permission before closing"
self hasUnsavedChanges ifTrue:[
(Dialog
confirm:(resources string:'Close without saving ?')
default:false) ifFalse:[
^ self
]
].
super closeRequest
!
initialize
modified := false.
inSingleFileMode := false.
super initialize
!
languageEditorBuilt:aView
languageEditor := aView.
!
postBuildDataSet:aView
dataSetView := aView.
aView selectedColIndexHolder onChangeSend:#selectionChanged to:self.
! !
!InternationalLanguageTranslationEditor methodsFor:'menu actions'!
addLanguage
|lang|
lang := Dialog request:'New language (ISO symbol):'.
lang isEmptyOrNil ifTrue:[^ self].
lang := lang asSymbol.
(keyStringsToLanguageMappings includesLanguage:lang) ifTrue:[^ self ].
keyStringsToLanguageMappings addLanguage:lang.
self languagesList add:lang.
self shownLanguages add:lang.
modified := true.
!
addTranslation
|key index|
key := Dialog request:'New Key:'.
key isEmpty ifTrue:[^self].
(self includesKey:key) ifFalse:[
keyStringsToLanguageMappings addKey:key.
modified := true.
].
index := keyStringsToLanguageMappings indexOfKey:key.
self selectedKeyRow value:index
!
changeLastNameSpace
|nameSpace defaultNameSpace|
lastNameSpace notNil ifTrue:[defaultNameSpace := lastNameSpace name].
nameSpace := Dialog requestNameSpace:'NameSpace:' title:'Search String in Name Space:' initialAnswer:defaultNameSpace.
nameSpace isNil ifTrue:[^self].
nameSpace := Smalltalk at:nameSpace asSymbol.
nameSpace isNil ifTrue:[
^Dialog information:(resources string:'No such nameSpace exists.?')
].
lastNameSpace := nameSpace.
!
extractTranslationsFromClass
|aClass newTranslations|
aClass := Dialog
requestClass:'Class to extract translations from:'
okLabel:'OK'
initialAnswer:(lastExtractedClass ? LastExtractedClass).
aClass isNil ifTrue:[^ self ].
lastExtractedClass := LastExtractedClass := aClass.
newTranslations := self extractTranslationsFromClass:aClass.
self addAllTranslations:newTranslations.
!
extractTranslationsFromNameSpace
|newTranslations|
self changeLastNameSpace.
lastNameSpace isNil ifTrue:[^self.].
newTranslations := OrderedCollection new.
lastNameSpace allClassesDo:[:eachClass |
newTranslations addAll:( self extractTranslationsFromClass:eachClass theNonMetaclass).
].
self addAllTranslations:newTranslations.
!
extractTranslationsFromProject
|box projectID newTranslations|
box := ListSelectionBox new.
"/ box useComboBoxWithList:(Smalltalk allProjectIDs).
box title:(resources string:'Project to extract translations from:').
box list:Smalltalk allProjectIDs.
box okAction:[:sel | projectID := sel].
box initialText:(lastExtractedProject ? LastExtractedProject).
box label:'Find Translations in Project'.
box showAtPointer.
projectID notNil ifTrue:[
projectID := projectID withoutSeparators asSymbol.
].
projectID isEmptyOrNil ifTrue:[^ self ].
lastExtractedProject := LastExtractedProject := projectID.
newTranslations := Set new.
Smalltalk allClassesDo:[:eachClass |
eachClass theNonMetaclass package == projectID ifTrue:[
"/ eachClass isLoaded ifTrue:[ self halt. ].
newTranslations addAll:( self extractTranslationsFromClass:eachClass theNonMetaclass).
]
].
self addAllTranslations:newTranslations.
!
inspectCanvasMissingStrings
|spec nameSpace missingStrings|
missingStrings := OrderedCollection new.
nameSpace := Dialog requestNameSpace:'NameSpace:' title:'Specify NameSpace to look for missing strings' initialAnswer:nil.
nameSpace := Smalltalk at:nameSpace asSymbol.
nameSpace isNil ifTrue:[
^Dialog information:(resources string:'No such nameSpace exists.?')
].
nameSpace allClassesDo:[:cls |
cls theMetaclass methodsDo:[:m |
m hasResource ifTrue:[
(m resources includesKey:#canvas) ifTrue:[
spec := (cls perform:m selector) decodeAsLiteralArray.
spec do:[:eachComponent |
eachComponent translationKeysDo:[:k |
(self includesKey: k) ifFalse:[
missingStrings add: k.
Transcript showCR: k storeString, ' ', m printString]]
]
]
]
]
].
missingStrings asSet inspect
!
menuNew
modified ifTrue:[
(Dialog
confirm:(resources stringWithCRs:'Modified translations have not been changed.\\Create new translations set anyway ?')
default:false) ifFalse:[^ self].
].
keyStringsToLanguageMappings initialize.
keyStringsToLanguageMappings changed.
self languagesList contents:self keyStringAndLanguageSelectionTable languages.
self shownLanguages contents:self keyStringAndLanguageSelectionTable languages.
modified := false.
!
menuOpen
|aFilename|
self withWaitCursorDo:[
aFilename := self requestFilename.
aFilename isNil ifTrue:[^ self ].
self readResourceFile:aFilename.
]
!
menuSave
"Saves the language selected in the fileName from where the language resource was obtained."
|lang|
lang := self requestLanguage.
lang isNil ifTrue:[^ self].
self saveLanguage: lang
!
menuSaveAll
"Saves all the languages in the fileName from where the language resource was obtained."
keyStringsToLanguageMappings languagesInUse do:[:each | self saveLanguage: each].
!
menuSaveAs
"Saves the language selected in the specified fileName."
|lang aFilename|
lang := self requestLanguage.
lang isNil ifTrue:[^ self].
aFilename := self requestFilenameFor:lang.
aFilename isNil ifTrue:[^ self].
self saveResourceFile:aFilename for:lang asSymbol
!
openAboutThisApplication
"This method was generated by the Browser.
It will be invoked when the menu-item 'help-about' is selected."
"/ could open a customized aboutBox here ...
super openAboutThisApplication
!
openDocumentation
"This method was generated by the Browser.
It will be invoked when the menu-item 'help-documentation' is selected."
"/ change below as required ...
"/ to open an HTML viewer on some document (under 'doc/online/<language>/' ):
HTMLDocumentView openFullOnDocumentationFile:'TOP.html'.
"/ add application-specific help files under the 'doc/online/<language>/help/appName'
"/ directory, and open a viewer with:
"/ HTMLDocumentView openFullOnDocumentationFile:'help/<MyApplication>/TOP.html'.
!
readResourceFile:aFilename
|lang|
lang := Dialog choose:'For which language ?' fromList:languagesList lines:10.
lang isNil ifTrue:[^ self ].
self readResourceFile:aFilename asLanguage:lang asSymbol
!
removeLanguage
|lang|
lang := Dialog choose:'Which language do you want to remove?' fromList:languagesList lines:10.
lang isNil ifTrue:[^ self ].
(Dialog confirm: 'Are you sure to remove the language ', lang ) ifTrue:[
self languagesList remove:lang.
self shownLanguages remove:lang.
].
!
removeTranslation
|rowSelectionIndex selectedKey|
rowSelectionIndex := self selectedKeyRow value.
rowSelectionIndex isNil ifTrue:[^self].
rowSelectionIndex ~~ 0 ifTrue:[
selectedKey := keyStringsToLanguageMappings keyAt:rowSelectionIndex ifAbsent:nil.
selectedKey isNil ifTrue:[^self].
(Dialog confirm:(resources string:'Really remove key %1' with:selectedKey)) ifTrue:[
keyStringsToLanguageMappings removeKey:selectedKey.
].
].
!
runApplicationAndCollectTranslations
|applicationClass newTranslations pseudoPack app startSelector|
monitoredApplication notNil ifTrue:[
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 ).
applicationClass isNil ifTrue:[^ self ].
applicationClass isNamespace ifTrue:[
Dialog warn:'Entered class is a NameSpace'.
^ self.
].
applicationClass isVisualStartable ifTrue:[
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.
].
lastExtractedApplicationClass := LastExtractedApplicationClass := applicationClass.
newTranslations := Set new.
pseudoPack := AccessCollectingPseudoResourcePack new.
pseudoPack realResourcePack:(applicationClass classResources).
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.
!
searchStringInLastNameSpace
|selectedKey browser|
selectedKey := self selectedKey.
selectedKey isNil ifTrue:[^Dialog information: 'No selected key'].
browser := NewSystemBrowser new "open".
browser allButOpen.
browser lastSearchPatterns first = selectedKey ifFalse:[
browser lastSearchPatterns addFirst: selectedKey
].
lastNameSpace isNil ifTrue:[
self changeLastNameSpace.
].
lastNameSpace notNil ifTrue:[
"/ browser navigationState selectedClasses value: lastNameSpace allClasses.
browser navigationState nameSpaceFilter value: (OrderedCollection with:lastNameSpace name).
browser navigationState selectedNamespaces value: (OrderedCollection with:lastNameSpace name).
].
self withWaitCursorDo:[
browser browseMenuMethodsWithString
].
! !
!InternationalLanguageTranslationEditor methodsFor:'menus dynamic'!
disableLanguageDisplayFor:lang
self shownLanguages remove:lang ifAbsent:[]
!
enableLanguageDisplayFor:newLang
|shownLanguagesInOrder|
(self shownLanguages includes:newLang) ifFalse:[
"/ shownLanguagesInOrder := self languagesList
"/ select:[:lang | (self shownLanguages includes:lang)
"/ or:[ lang = newLang ]].
"/ self shownLanguages contents:shownLanguagesInOrder.
self shownLanguages add:newLang.
]
!
isLanguageShown:lang
^ self shownLanguages includes:lang
!
shownLanguagesMenu
<resource: #programMenu >
^ [
|m selected|
m := Menu new.
self languagesList do:[:lang |
|item|
item := MenuItem label:lang.
item indication:(self languageShownHolderFor:lang).
item hideMenuOnActivated:false.
m addItem:item.
].
m
].
!
toggleLanguageDisplayFor:lang
(self shownLanguages includes:lang) ifTrue:[
self disableLanguageDisplayFor:lang
] ifFalse:[
self enableLanguageDisplayFor:lang
].
! !
!InternationalLanguageTranslationEditor methodsFor:'private-key extraction'!
addAllTranslations:newTranslations
|newTranslationKeys stringKeys nonStringKeys|
newTranslationKeys := newTranslations select:[:k | k notEmpty and:[k isString not or:[k isBlank not]]].
newTranslationKeys := newTranslationKeys select:[:k | (keyStringsToLanguageMappings includesKey:k) not].
newTranslationKeys := newTranslationKeys
collect:[:k |
(k endsWith:'...') ifTrue:[
k copyWithoutLast:3.
] ifFalse:[
('.:?' includes:k last) ifTrue:[
k copyWithoutLast:1.
] ifFalse:[
k
]]].
newTranslationKeys := newTranslationKeys asSet.
newTranslationKeys notEmpty ifTrue:[
stringKeys := newTranslationKeys select:[:k | k isString].
nonStringKeys := newTranslationKeys select:[:k | k isString not].
stringKeys := stringKeys asSortedCollection.
keyStringsToLanguageMappings addKeys:stringKeys.
keyStringsToLanguageMappings addKeys:nonStringKeys.
modified := true.
].
!
extractTranslationsFromClass:aClass
|newTranslations|
newTranslations := Set new.
self withWaitCursorDo:[
"/ now, the hard part:
"/ possible translations are in the specs,
"/ and all arguments to (resources string:) messages.
aClass instAndClassMethodsDo:[:eachMethod |
newTranslations addAll:( self extractTranslationsFromMethod:eachMethod ).
].
].
^ newTranslations
!
extractTranslationsFromHelpSpecMethod:aMethod
|codeStrings matcher parseTree resourceKeys|
parseTree := RBParser
parseMethod:aMethod source
onError: [:str :pos | Transcript showCR:str. Transcript showCR:pos.
nil].
parseTree isNil ifTrue:[^ #() ].
codeStrings :=
#(
'`@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
].
matcher executeTree: parseTree initialAnswer: nil.
^ resourceKeys
!
extractTranslationsFromMenuSpecMethod:aMethod
|menu resourceKeys|
menu := aMethod mclass theNonMetaclass perform:aMethod selector.
menu isNil ifTrue:[ ^ #() ].
(menu isKindOf:Menu) ifFalse:[
menu := Menu new fromLiteralArrayEncoding:menu
].
resourceKeys := Set new.
menu allItemsDo:[:aMenuItem |
aMenuItem translateLabel ifTrue:[
aMenuItem isSeparatorItem ifFalse:[
resourceKeys add:aMenuItem label.
]
]
].
^ resourceKeys
!
extractTranslationsFromMethod:aMethod
|mResources|
mResources := aMethod resources.
mResources notNil ifTrue:[
(mResources includesKey:#menu) ifTrue:[
^ self extractTranslationsFromMenuSpecMethod:aMethod.
].
(mResources includesKey:#canvas) ifTrue:[
^ self extractTranslationsFromUISpecMethod:aMethod.
].
(mResources includesKey:#help) ifTrue:[
^ self extractTranslationsFromHelpSpecMethod:aMethod.
].
(mResources includesKey:#tableColumns) ifTrue:[
^ self extractTranslationsFromTableColumnsSpecMethod:aMethod.
].
^ self extractTranslationsFromSpecMethod:aMethod.
].
^ self extractTranslationsFromMethodsCode:aMethod
!
extractTranslationsFromMethodsCode:aMethod
"/method:mthd selector:sel inClass:cls matchesParseTreeMatcher:aMatcher
|codeStrings matcher parseTree resourceKeys|
parseTree := RBParser
parseMethod:aMethod source
onError: [:str :pos | Transcript showCR:str. Transcript showCR:pos.
nil].
parseTree isNil ifTrue:[^ #() ].
codeStrings :=
#(
'resources `@msg: `@args'
'self resources `@msg: `@args'
'self class resources `@msg: `@args'
'self classResources `@msg: `@args'
).
resourceKeys := Set new.
matcher := ParseTreeSearcher new.
matcher
matchesAnyOf: codeStrings
do: [:aNode :answer |
|sel keyStringArgNode keyStringArg|
sel := aNode selector.
((sel startsWith:'string:') or:[(sel startsWith:'at:')]) ifTrue:[
keyStringArgNode := aNode arguments at:1.
keyStringArgNode isLiteral ifTrue:[
keyStringArg := keyStringArgNode value.
keyStringArg isString ifTrue:[
resourceKeys add:keyStringArg.
] ifFalse:[
Transcript
showCR:(resources
string:'Cannot derive resourceKey from non-string: %1 in %2'
with:keyStringArgNode formattedCode
with:aMethod selector).
].
] ifFalse:[
Transcript
showCR:(resources
string:'Cannot derive resourceKey from non-literal: %1 in %2'
with:keyStringArgNode formattedCode
with:aMethod selector).
].
].
aNode
].
matcher executeTree: parseTree initialAnswer: nil.
^ resourceKeys
!
extractTranslationsFromSpecMethod:aMethod
^ #()
!
extractTranslationsFromTableColumnsSpecMethod:aMethod
|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].
].
resourceKeys := Set new.
columnDescription do:[:aColumnSpec |
aColumnSpec translateLabel ifTrue:[
resourceKeys add:aColumnSpec label.
]
].
^ resourceKeys
!
extractTranslationsFromUISpecMethod:aMethod
|spec resourceKeys visitor|
spec := aMethod mclass theNonMetaclass perform:aMethod selector.
spec isNil ifTrue:[ ^ #() ].
(spec isKindOf:UISpecification) ifFalse:[
spec := UISpecification from:spec
].
resourceKeys := Set new.
visitor := UISpecVisitor new.
spec acceptVisitor:visitor.
^ visitor translatedLabels
! !
!InternationalLanguageTranslationEditor methodsFor:'queries'!
autoAccept
^ self autoAcceptHolder value
!
currentExampleLanguageText
"Returns the language text corresponding for the current selected key and the example language selection"
^self languageTextFromSelectedKeyFor: self exampleLanguageSelectionHolder value
!
currentLanguage
|colSelectionIndex |
colSelectionIndex := dataSetView selectedColIndex.
^colSelectionIndex > 1 ifTrue:[ shownLanguages at:colSelectionIndex-1 ] ifFalse:nil.
!
exampleLanguageByDefault
^self shownLanguages isEmpty
ifTrue:[nil]
ifFalse:[self shownLanguages first]
!
hasFirstRowSelection
self selectedKeyRow isNil ifTrue:[^false].
^ self selectedKeyRow value > 1
!
hasLanguageSelection
dataSetView selectedColIndex isNil ifTrue:[^false].
^ dataSetView selectedColIndex > 1
!
hasUnsavedChanges
^ modified
!
includesKey: aKey
keyStringsToLanguageMappings isNil ifTrue:[^false].
^keyStringsToLanguageMappings includesKey:aKey
!
isSearchForSimilarTranslationEnabled
^self searchForSimilarTranslationEnableHolder value
!
languageTextFromKey: aKeyIndex for: language
"Returns the language text corresponding for the aKeyIndex and the received language"
language isNil ifTrue:[^''].
^keyStringsToLanguageMappings at: aKeyIndex language:language.
!
languageTextFromSelectedKeyFor: language
"Returns the language text corresponding for the current selected key and the received language"
^self languageTextFromKey: self selectedKey for: language
!
shouldCopyPreviousTranslationButtonBeEnabled
^ self hasLanguageSelection
and:[self hasFirstRowSelection]
!
shouldSearchForSimilarTranslation
self isSearchForSimilarTranslationEnabled ifFalse:[^false].
(self languageTextHolder value notNil and:[self languageTextHolder value notEmpty]) ifTrue:[^false].
(self hasLanguageSelection and:[self selectedKeyRow notNil]) ifFalse:[^false].
^true
! !
!InternationalLanguageTranslationEditor methodsFor:'read/write resourceFile'!
encoderAt: lang
self alwaysWriteUTF8Holder value ifTrue:[^CharacterEncoder encoderForUTF8].
^keyStringsToLanguageMappings encoderAt: lang.
!
printEditingWarningOn: aStream
aStream nextPutAll: ';';
cr;
nextPutAll: '; WARNING:';
cr;
nextPutAll: '; this file contains national characters';
cr;
nextPutAll: '; DONT EDIT this file with an old vi !!';
cr;
nextPutAll: ';';
cr;
cr.
!
printEncoderFor: lang on: aStream
|characterEncoder encoderString|
characterEncoder := self encoderAt: lang.
encoderString := characterEncoder isNil
ifTrue:[self requestEncoderStringFor: lang]
ifFalse:[characterEncoder nameOfEncoding printString].
aStream nextPutAll: '#encoding';
space;
nextPutAll: encoderString;
cr;
cr.
!
printLanguage: lang on: aStream
self printEncoderFor: lang on: aStream.
self printEditingWarningOn: aStream.
self printLanguageMappingsFor: lang on: aStream.
!
printLanguageMappingsFor: lang on: aStream
|orderedAssociations maxKeySize characterEncoder|
characterEncoder := self encoderAt: lang.
characterEncoder isNil ifTrue:[ characterEncoder := CharacterEncoder::NullEncoder ].
orderedAssociations := keyStringsToLanguageMappings orderedLanguageMappingsAssociationsFor: lang.
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.
].
!
readResourceFile:aFilename asLanguage:lang
|resourcePack inStream lineString encoding decoder sortedKeys remainingKeys|
aFilename exists ifFalse:[^ 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.
].
].
].
inStream close.
sortedKeys := (resourcePack keys select:[:k | k isString]) asSortedCollection.
remainingKeys := resourcePack keys select:[:k | k isString not].
keyStringsToLanguageMappings atLanguage: lang putFilename: aFilename.
keyStringsToLanguageMappings atLanguage: lang putEncoder: decoder.
sortedKeys do:[:k |
keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k)
].
remainingKeys do:[:k |
keyStringsToLanguageMappings at:k language:lang put:(resourcePack at:k)
].
!
saveLanguage: lang
"Saves the language in the fileName from where the language resource was obtained."
|aFilename|
lang isNil ifTrue:[^ self].
aFilename := keyStringsToLanguageMappings filenameAt:lang.
aFilename isNil ifTrue:[
aFilename := self requestFilenameFor: lang.
aFilename isNil ifTrue:[^ self].
].
self saveResourceFile:aFilename for:lang asSymbol
!
saveResourceFile: aFilename for: lang
|aStream |
keyStringsToLanguageMappings atLanguage: lang putFilename: aFilename.
aStream := FileStream newFileNamed: aFilename.
self printLanguage: lang on: aStream.
aStream flush;
close.
DialogBox information: 'The resource file for the language ', lang printString storeString, ' was saved in the file: ', aFilename nameString
! !
!InternationalLanguageTranslationEditor methodsFor:'specs-dynamic'!
columnInRow:row at:colIndex
|lang|
lang := self languageAtCol:colIndex.
^ row atLanguage:lang
!
getBackgroundForRow:row rowNr:rowNr col:colIndex
|lang|
colIndex == 1 ifTrue:[^ nil].
lang := self languageAtCol:colIndex.
^ (row atLanguage:lang) isNil ifTrue:[Color red lightened] ifFalse:nil
!
keyStringAndLanguageSelectionTableColumnDescription
|spec|
spec := OrderedCollection new.
spec add:(self class keyTableColumn first).
self shownLanguages do:[:lang |
|entry|
entry := self class languageTableColumn first.
entry := entry copy replaceAll:#lang with:lang.
spec add: entry
].
^ spec
!
keyStringInRow:row
^ row keyString
! !
!InternationalLanguageTranslationEditor methodsFor:'user actions'!
exampleLanguageSelectionChanged
self updateExampleLanguageText.
!
languageTextAccepted
|nextRowIndex|
keyStringsToLanguageMappings size = self selectedKeyRow value
ifTrue:[ self updateLanguageTextModification.]
ifFalse:[
nextRowIndex := self selectedKeyRow value + 1.
self selectedKeyRow value: nextRowIndex].
!
pastePreviousTranslationInLanguageText
"Obtain the text from the previous translation and paste it into the languageTextEditor"
| previousLanguageText previousLanguageRow|
previousLanguageRow := dataSetView at:self selectedKeyRow value - 1
ifAbsent:[^self].
previousLanguageText := previousLanguageRow atLanguage: self currentLanguage.
languageEditor selectAll.
languageEditor pasteOrReplace:previousLanguageText.
self languageTextModifiedHolder value:true.
!
selectionChanged
self updateOriginalTextModification.
self updateLanguageTextModification.
self updateLanguageAndKeySelection.
self updateExampleLanguageText.
self updateCopyPreviousTranslationButtonEnabled.
self originalTextModifiedHolder value:false.
self languageTextModifiedHolder value:false.
self searchForSimilarTranslation.
!
showMissingTranslationsOnlyChanged
!
shownLanguagesChanged
self keyStringAndLanguageSelectionTableColumnDescriptionHolder
value:(self keyStringAndLanguageSelectionTableColumnDescription).
!
stopApplication
|p|
(p := monitoredApplication) notNil ifTrue:[
p terminate.
].
! !
!InternationalLanguageTranslationEditor::AccessCollectingPseudoResourcePack methodsFor:'accessing'!
realResourcePack:something
realResourcePack := something.
! !
!InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings class methodsFor:'instance creation'!
new
^ self basicNew initialize
! !
!InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'accessing'!
addKey:aKey
(keys includes:aKey) ifFalse:[
keys add:aKey.
self changed.
]
!
addKeys:aCollectionOfKey
keys addAll:aCollectionOfKey.
self changed.
!
addLanguage:lang
(languages includes:lang) ifFalse:[
languages add:lang.
perLanguageMappings at:lang put:(OrderedDictionary new).
]
!
at:aKey language:language
^ (perLanguageMappings at:language) at:aKey ifAbsent:nil
!
at:aKey language:language put:value
self addKey:aKey.
(perLanguageMappings at:language) at:aKey put:value.
(self rowForKey:aKey) changed
!
atLanguage: lang putEncoder: aDecoder
^(self languageInfoAt: lang) at: self encoderKey put: aDecoder
!
atLanguage: lang putFilename: aFilename
^(self languageInfoAt: lang) at: self fileNameKey put: aFilename
!
decoderKey
^#decoder
!
encoderAt:lang
^ (self languageInfoAt:lang) at: self encoderKey ifAbsent:[nil]
!
encoderKey
^#encoder
!
fileNameKey
^ #filename
!
filenameAt:lang
^ (self languageInfoAt:lang) at: self fileNameKey ifAbsent:[nil]
!
keyAt:index
^ keys at:index ifAbsent:[nil].
!
keyAt:index ifAbsent:exceptionalValue
^ keys at:index ifAbsent:exceptionalValue.
!
keys
^ keys
!
languageInfoAt: lang
^self perLanguageInfo at: lang ifAbsentPut:[Dictionary new]
!
languages
^ languages
!
languagesInUse
"Returns a collection of symbols for the languages that have mappings"
^self languages select:[:each | (self atLanguage: each) notEmpty]
!
orderedLanguageMappingsAssociationsFor: language
"Returns a collection of languageMappings associations (alphabetically ordered by keys) "
^(self atLanguage: language) associations asSortedCollection:[:a :b | a key < b key].
!
perLanguageInfo
^ perLanguageInfo
!
perLanguageInfo:something
perLanguageInfo := something.
!
removeKey:aKey
keys remove:aKey ifAbsent:[].
perLanguageMappings do:[:eachMapping |
eachMapping removeKey:aKey ifAbsent:[].
].
self changed.
!
rowForKey:aKey
^ rowPerKey
at:aKey
ifAbsentPut:[InternationalLanguageTranslationEditor::LanguageMappingRow new
key:aKey; mappings:self].
!
size
^ keys size
! !
!InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'enumerating'!
do:aBlock
keys do:[:eachKey |
aBlock value:(self rowForKey:eachKey).
].
! !
!InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'initialization'!
initialize
super initialize.
keys := OrderedSet new.
languages := OrderedCollection new.
perLanguageMappings := Dictionary new.
perLanguageInfo := Dictionary new.
rowPerKey := Dictionary new.
self addLanguage:#'de'.
self addLanguage:#'fr'.
self addLanguage:#'es'.
self addLanguage:(Smalltalk language).
"/ self initializeDemoMappings.
!
initializeDemoMappings
keys add:'open'.
keys add:'close'.
keys add:'yes'.
keys add:'no'.
self addLanguage:#'de'.
self addLanguage:#'fr'.
self at:'open' language:#'de' put:'öffnen'.
self at:'close' language:#'de' put:'schliessen'.
self at:'yes' language:#'de' put:'ja'.
self at:'no' language:#'de' put:'nein'.
self at:'cancel' language:#'de' put:'abbrechen'.
self at:'open' language:#'fr' put:'ouvrir'.
self at:'close' language:#'fr' put:'fermer'.
self at:'yes' language:#'fr' put:'oui'.
self at:'no' language:#'fr' put:'non'.
! !
!InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'private'!
atLanguage:lang
^ perLanguageMappings at:lang
!
atLanguageIndex:idx
|lang|
lang := languages at:idx.
^ self atLanguage:lang.
!
mappingAtLanguage:lang
^ perLanguageMappings at:lang
!
mappingAtLanguageIndex:idx
|lang|
lang := languages at:idx.
^ self mappingAtLanguage:lang.
! !
!InternationalLanguageTranslationEditor::KeyStringsToLanguageMappings methodsFor:'queries'!
includesKey:aKey
^ keys includes:aKey
!
includesLanguage:lang
^ languages includes:lang
!
indexOfKey:aKey
^ keys indexOf:aKey
!
maxKeySizeForLanguage: lang
^(self atLanguage: lang) keys inject: 0 into:[:maxSize :each |
(maxSize < each size and:[each size < 100])
ifTrue:[each size]
ifFalse:[maxSize].].
!
searchForSimilarTranslation: aKey in: language
"Returns a collection of translation associations that corresponds to a quite similar key comparing with aKey"
|similarAssociations|
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]]
].
^similarAssociations
! !
!InternationalLanguageTranslationEditor::LanguageMappingRow methodsFor:'accessing'!
atLanguage:language
|translation|
translation := (mappings mappingAtLanguage:language) at:key ifAbsent:nil.
^ translation isNil ifTrue:nil ifFalse:[translation printString]
!
columnAt:columnNr
^ (mappings mappingAtLanguageIndex:columnNr-1) at: key ifAbsent:nil
!
key:something
key := something.
!
keyString
^ key printString
!
mappings:something
mappings := something.
! !
!InternationalLanguageTranslationEditor::UISpecVisitor methodsFor:'accessing'!
translatedLabels
^ translatedLabels ? #()
! !
!InternationalLanguageTranslationEditor::UISpecVisitor methodsFor:'visiting'!
visitObject:anObject with:aParameter
|l|
(anObject isKindOf:UISpecification) ifTrue:[
(anObject respondsTo:#translateLabel) ifTrue:[
anObject translateLabel == true ifTrue:[
translatedLabels isNil ifTrue:[
translatedLabels := Set new.
].
l := anObject perform:#label ifNotUnderstood:nil.
l notNil ifTrue:[
translatedLabels add:l.
].
].
].
].
self visitChildrenOf:anObject.
! !
!InternationalLanguageTranslationEditor class methodsFor:'documentation'!
version
^ '$Header$'
! !