getting translation into etoy tiles

Ned Konz ned at squeakland.org
Fri Sep 17 16:20:14 UTC 2004


On Thursday 16 September 2004 11:52 pm, Hilaire Fernandes wrote:
> Hum, I will say that Squeak i18n may need more care upstream.
> For example, in last image release 3.7, the language editor was shipped
> with, sadly it is not fully functional, the crucial gettext .po
> import/export functionnality is not working. But we badly need it when
> working with a translation team. (ie we can use all the i18n/l10 tools
> from the Free Software Foundation to translate, validate & merge
> messages)

The attached changeset may help with the language editor.

-- 
Ned Konz
http://bike-nomad.com/squeak/
-------------- next part --------------
'From Squeakland 3.8.5976 of 25 August 2004 [latest update: #278] on 1 September 2004 at 7:17:23 am'!
"Change Set:		LanguageEditorFixes-nk
Date:			29 August 2004
Author:			Ned Konz

Various fixes for the LanguageEditor downloaded from impara.de:

* use proper Window Color
* compatibilities with latest m17n changes to Locale and NaturalLanguageTranslator
* adds 'edit' choice to FileList
* better 'where' function
* window label fixed
"!


!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/29/2004 14:23'!
applyTranslations
	"private - try to apply the translations as much as possible all  
	over the image"
	((translator == NaturalLanguageTranslator defaultEToy)
		or: [translator == NaturalLanguageTranslator default ])
		ifTrue: [ Vocabulary changeMadeToViewerAdditions ].
	Project current updateLocaleDependents! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 08:59'!
browseMethodsWithTranslation
	| translation |
	self selectedTranslation isZero 
		ifTrue: 
			[""

			Beeper beep.
			self inform: 'select the translation to look for' translated.
			^self].
	""
	translation := self translations at: self selectedTranslation.
	self systemNavigation browseMethodsWithString: translation matchCase: false! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 08:59'!
browseMethodsWithUntranslated
	| untranslated |
	self selectedUntranslated isZero 
		ifTrue: 
			[""

			Beeper beep.
			self inform: 'select the untranslated phrase to look for' translated.
			^self].
	""
	untranslated := self untranslated at: self selectedUntranslated.
	SystemNavigation default browseMethodsWithStringOrSymbol: untranslated
		matchCase: false! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 08:40'!
getTextExport
	Smalltalk at: #GetTextExporter ifPresent: [ :gte | gte new export: self model ]! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 08:59'!
loadFromFile
	| fileName |
	fileName := self selectTranslationFileName.
	fileName isNil 
		ifTrue: 
			[""

			Beeper beep.
			^self].
	""
	Cursor wait showWhile: 
			[self translator loadFromFileNamed: fileName.
			self changed: #translations.
			self changed: #untranslated]! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 08:59'!
mergeFromFile
	| fileName |
	fileName := self selectTranslationFileName.
	fileName isNil 
		ifTrue: 
			[""

			Beeper beep.
			^self].
	""
	Cursor wait showWhile: 
			[self translator loadFromFileNamed: fileName.
			self changed: #translations.
			self changed: #untranslated]! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 9/1/2004 06:10'!
removeDups
	translator removeDuplicates.! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 08:59'!
removeTranslation
	"remove the selected translation"

	| translation |
	self selectedTranslation isZero 
		ifTrue: 
			[""

			Beeper beep.
			self inform: 'select the translation to remove' translated.
			^self].
	""
	translation := self translations at: self selectedTranslation.
	""
	(self 
		confirm: ('Removing "{1}".
Are you sure you want to do this?' translated 
				format: { 
						translation})) 
			ifFalse: [^self].
	""
	self translator removeTranslationFor: translation! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 09:00'!
removeUntranslated
	"remove the selected untranslated phrase"

	| untranslated |
	self selectedUntranslated isZero 
		ifTrue: 
			[""

			Beeper beep.
			self inform: 'select the untranslated phrase to remove' translated.
			^self].
	""
	untranslated := self untranslated at: self selectedUntranslated.
	""
	(self 
		confirm: ('Removing "{1}".
Are you sure you want to do this?' translated 
				format: { 
						untranslated})) 
			ifFalse: [^self].
	""
	self translator removeUntranslated: untranslated! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 09:00'!
saveToFile
	"save the translator to a file"

	| fileName |
	fileName := FillInTheBlank request: 'file name' translated
				initialAnswer: self model localeID isoString , '.translation'.
	(fileName isNil or: [fileName isEmpty]) 
		ifTrue: 
			[""

			Beeper beep.
			^self].
	""
	Cursor wait showWhile: [self translator saveToFileNamed: fileName]! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 09:00'!
searchTranslation
	| search |
	search := FillInTheBlank request: 'search for' translated initialAnswer: ''.
	(search isNil or: [search isEmpty]) 
		ifTrue: 
			[""

			Beeper beep.
			^self].
	""
	self searchTranslation: search! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 09:00'!
searchTranslation: aString 
	| translations results index |
	translations := self translations.
	results := translations select: 
					[:each | 
					""

					('*' , aString , '*' match: each) 
						or: ['*' , aString , '*' match: (self translator translationFor: each)]].
	""
	results isEmpty 
		ifTrue: 
			[""

			self inform: 'no matches for' translated , ' ''' , aString , ''''.
			^self].
	""
	results size = 1 
		ifTrue: 
			[""

			self selectTranslationPhrase: results first.
			^self].
	""
	index := (PopUpMenu 
				labelArray: (results collect: 
							[:each | 
							""

							(each copy replaceAll: Character cr with: $\) , ' -> ' 
								, ((self translator translationFor: each) copy replaceAll: Character cr
										with: $\)])) 
					startUpWithCaption: 'select the translation...' translated.
	""
	index isZero 
		ifTrue: 
			[""

			Beeper beep.
			^self].
	""
	self selectTranslationPhrase: (results at: index)! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 09:00'!
searchUntranslated
	| search |
	search := FillInTheBlank request: 'search for' translated initialAnswer: ''.
	(search isNil or: [search isEmpty]) 
		ifTrue: 
			[""

			Beeper beep.
			^self].
	""
	self searchUntranslated: search! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 09:00'!
searchUntranslated: aString 
	| untranslateds results index |
	untranslateds := self untranslated.
	results := untranslateds select: [:each | '*' , aString , '*' match: each].
	""
	results isEmpty 
		ifTrue: 
			[""

			self inform: 'no matches for' translated , ' ''' , aString , ''''.
			^self].
	""
	results size = 1 
		ifTrue: 
			[""

			self selectUntranslatedPhrase: results first.
			^self].
	""
	index := (PopUpMenu labelArray: (results 
						collect: [:each | each copy replaceAll: Character cr with: $\])) 
				startUpWithCaption: 'select the untranslated phrase...' translated.
	""
	index isZero 
		ifTrue: 
			[""

			Beeper beep.
			^self].
	""
	self selectUntranslatedPhrase: (results at: index)! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 09:00'!
translate
	"translate a phrase"

	| phrase |
	phrase := self phraseToTranslate.
	""
	(phrase isNil or: [phrase = '']) 
		ifTrue: 
			[""

			Beeper beep.
			^self].
	""
	self translatePhrase: phrase! !

!LanguageEditor methodsFor: 'gui methods' stamp: 'nk 8/31/2004 09:00'!
translatePhrase: aString 
	"translate aString"

	| translation |
	translation := FillInTheBlank 
				multiLineRequest: 'translation for: ' translated , '''' , aString , ''''
				centerAt: Sensor cursorPoint
				initialAnswer: aString
				answerHeight: 200.
	""
	(translation isNil or: [translation = '']) 
		ifTrue: 
			[""

			Beeper beep.
			^self].
	""
	self phrase: aString translation: translation! !

!LanguageEditor methodsFor: 'initialization - toolbar' stamp: 'nk 9/1/2004 06:09'!
createMainToolbar
	"create a toolbar for the receiver"
	| toolbar |
	toolbar := self createRow.
	""
	"toolbar 
	addMorphBack: (self 
	createUpdatingButtonWording: #debugWording 
	action: #switchDebug 
	help: 'Switch the debug flag')."
	toolbar addTransparentSpacerOfSize: 5 @ 0.
	""
	toolbar
		addMorphBack: (self
				createButtonLabel: 'save'
				action: #saveToFile
				help: 'Save the translations to a file').
	toolbar
		addMorphBack: (self
				createButtonLabel: 'load'
				action: #loadFromFile
				help: 'Load the translations from a file').
	toolbar
		addMorphBack: (self
				createButtonLabel: 'merge'
				action: #mergeFromFile
				help: 'Merge the current translations with the translations in a file').
	""
	toolbar addTransparentSpacerOfSize: 5 @ 0.
	toolbar
		addMorphBack: (self
				createButtonLabel: 'apply'
				action: #applyTranslations
				help: 'Apply the translations as much as possible.').
	""
	toolbar addTransparentSpacerOfSize: 5 @ 0.
	toolbar
		addMorphBack: (self
				createButtonLabel: 'check translations'
				action: #check
				help: 'Check the translations and report the results.').
	toolbar
		addMorphBack: (self
				createButtonLabel: 'report'
				action: #report
				help: 'Create a report.').
	(Smalltalk includesKey: #GetTextExporter)
		ifTrue: [toolbar
				addMorphBack: (self
						createButtonLabel: 'gettext export'
						action: #getTextExport
						help: 'Exports the translations in GetText format.')].
	toolbar
		addMorphBack: (self
				createButtonLabel: 'remove dups'
				action: #removeDups
				help: 'Remove translations that are the same as their untranslated phrase.').
	""
	^ toolbar! !

!LanguageEditor methodsFor: 'initialization' stamp: 'nk 8/29/2004 11:32'!
initializeOn: aLanguage 
	"initialize the receiver on aLanguage"
	""
	selectedTranslation := 0.
	selectedUntranslated := 0.
	""
	translator := NaturalLanguageTranslator localeID: aLanguage.
	self model: translator.
	""
	self setLabel: 'Language editor for: ' translated , aLanguage printString.
	""
	self initializeToolbars.
	self initializePanels.
	self initializeStatusbar! !

!LanguageEditor methodsFor: 'initialization' stamp: 'nk 8/29/2004 11:56'!
initializeOnTranslator: aLanguageTranslator
	"initialize the receiver on aLanguageTranslator"
	""
	selectedTranslation := 0.
	selectedUntranslated := 0.
	""
	translator := aLanguageTranslator.
	self model: translator.
	""
	self setLabel: 'Language editor for: ' translated , aLanguageTranslator localeID printString.
	""
	self initializeToolbars.
	self initializePanels.
	self initializeStatusbar! !

!LanguageEditor methodsFor: 'accessing' stamp: 'nk 8/29/2004 12:58'!
translations
	"answet the translator's translations"
	| allTranslations filterString |
	allTranslations := self translator translations keys.
	""
	filterString := self translationsFilter.
	""
	filterString isEmpty
		ifFalse: [allTranslations := allTranslations
						select: [:each | ""
							('*' , filterString , '*' match: each)
								or: ['*' , filterString , '*'
										match: (self translator translationFor: each)]]].
""
	^ allTranslations asSortedCollection: [ :a :b | a caseInsensitiveLessOrEqual: b ]! !

!LanguageEditor methodsFor: 'accessing' stamp: 'nk 8/29/2004 12:59'!
untranslated
	"answer the translator's untranslated phrases"
	

| all filterString |
	all := self translator untranslated.
	""
	filterString := self untranslatedFilter.
	""
	filterString isEmpty
		ifFalse: [all := all
						select: [:each | ""
							('*' , filterString , '*' match: each)
								or: ['*' , filterString , '*'
										match: (self translator translationFor: each)]]].
	""
	^ all asSortedCollection: [ :a :b | a caseInsensitiveLessOrEqual: b ]! !


!LanguageEditor class methodsFor: 'file list services' stamp: 'nk 8/29/2004 11:57'!
editTranslationFileNamed: fileFullNameString

	| stream localeID translator |
	stream := FileStream readOnlyFileNamed: fileFullNameString.
	[localeID := LocaleID isoString: stream localName sansPeriodSuffix.
	translator := NaturalLanguageTranslator localeID: localeID.
	translator loadFromStream: stream]
		ensure: [stream close].

	^(self new initializeOnTranslator: translator) openInWorld! !

!LanguageEditor class methodsFor: 'file list services' stamp: 'nk 8/29/2004 11:47'!
fileReaderServicesForFile: fullName suffix: suffix 
	"Answer the file services associated with given file"
	^ (suffix = NaturalLanguageTranslator translationSuffix) | (suffix = '*')
		ifTrue: [{self serviceEditTranslationFile}]
		ifFalse: [#()]! !

!LanguageEditor class methodsFor: 'file list services' stamp: 'nk 8/29/2004 12:30'!
openOnTranslator: translator
	^(self new initializeOnTranslator: translator) openInWorld! !

!LanguageEditor class methodsFor: 'file list services' stamp: 'nk 8/29/2004 11:49'!
serviceEditTranslationFile
	"Answer a service for editing of translation files"
	^ SimpleServiceEntry
		provider: self
		label: 'edit the translation file'
		selector: #editTranslationFileNamed:
		description: 'edit the selected translation file in a Language Editor'
		buttonLabel: 'edit'! !

!LanguageEditor class methodsFor: 'initialize-release' stamp: 'nk 8/29/2004 11:50'!
initialize
	"initialize the receiver"
	(TheWorldMenu respondsTo: #registerOpenCommand:)
		ifTrue: [""
			TheWorldMenu registerOpenCommand: {'Language Editor'. {self. #openOnDefault}}.
			TheWorldMenu registerOpenCommand: {'Language Editor for...'. {self. #open}}].
	FileList registerFileReader: self.! !

!LanguageEditor class methodsFor: 'instance creation' stamp: 'nk 8/29/2004 10:53'!
on: aLanguage
	"answer an instance of the receiver on aLanguage"
	^ self new initializeOn: aLanguage! !

!LanguageEditor class methodsFor: 'instance creation' stamp: 'nk 8/29/2004 11:54'!
openOn: aLanguage 
	"open an instance on aLanguage"
	World submorphs
		do: [:each | ""
			((each isKindOf: self)
					and: [each translator localeID == aLanguage])
				ifTrue: [""
					self ensureVisibilityOfWindow: each.
					^ self]].
	""
	^ (self on: aLanguage) openInWorld! !

!LanguageEditor class methodsFor: 'opening' stamp: 'nk 8/29/2004 10:57'!
openOnDefault
	"open the receiver on the default language"
	^self openOn: NaturalLanguageTranslator current localeID! !


!NaturalLanguageTranslator methodsFor: 'printing' stamp: 'nk 8/29/2004 10:51'!
printOn: aStream
	aStream nextPutAll: self class name; nextPut: $(; print: self localeID; nextPut: $)! !

!NaturalLanguageTranslator methodsFor: 'editing' stamp: 'nk 9/1/2004 06:38'!
removeDuplicates
	| dups |
	dups := Set new.
	self generics keysAndValuesDo: [ :k :v | k = v ifTrue: [ dups add: k ]].
	dups do: [ :dup | self generics removeKey: dup ].
	self changed: #translations.
	self changed: #untranslated.! !

!NaturalLanguageTranslator methodsFor: 'translation' stamp: 'nk 8/29/2004 13:36'!
removeTranslationFor: phraseString
	self generics removeKey: phraseString ifAbsent: [].
	self changed: #translations.
	self changed: #untranslated.! !


!NaturalLanguageTranslator class methodsFor: 'accessing' stamp: 'nk 8/29/2004 14:23'!
default
	^self localeID: (LocaleID default)
! !

!NaturalLanguageTranslator class methodsFor: 'accessing' stamp: 'nk 8/29/2004 14:03'!
defaultEToy
	^self localeID: (LocaleID defaultEToy)
! !

!NaturalLanguageTranslator class methodsFor: 'window color' stamp: 'nk 8/29/2004 11:33'!
windowColorSpecification
	"Answer a WindowColorSpec object that declares my preference"

	^ WindowColorSpec classSymbol: self name wording: 'Language Editor' brightColor: #(0.645 1.0 1.0)	pastelColor: #(0.886 1.0 1.0) helpMessage: 'A tool to define and edit natural language translations'! !


!ObjectWithDocumentation methodsFor: 'translation' stamp: 'nk 8/29/2004 12:03'!
addTranslatablePhrasesTo: aDictionary

	{ self untranslatedHelpMessage asString.
	self untranslatedWording asString } do: [ :phrase |
		phrase ifNotNil: [ aDictionary at: phrase put: phrase ]].

	^aDictionary! !


!SystemNavigation methodsFor: 'browse' stamp: 'nk 8/29/2004 11:25'!
browseMethodsWithStringOrSymbol: aString matchCase: caseSensitive
	"Launch a browser on all methods that contain string literals with aString as a substring. Make the search case-sensitive or insensitive as dictated by the caseSensitive boolean parameter"

	self browseAllSelect:
			[:method |
				method  hasLiteralSuchThat: [:lit |
					(lit class == String and:
					[lit includesSubstring: aString caseSensitive: caseSensitive]) or: [ lit isSymbol and: [ lit = aString ]]
]]
		name:  'Methods with string ', aString printString, (caseSensitive ifTrue: [' (case-sensitive)'] ifFalse: [' (case-insensitive)'])
		autoSelect: aString.
! !


!NaturalLanguageTranslator reorganize!
('accessing' displayLanguage isoCountry isoLanguage localeID translations untranslated)
('initialize-release' delete empty localeID:)
('printing' printOn:)
('editing' addNewTranslationsFoundIn: removeDuplicates removeIdenticalTranslationsFoundIn:)
('translation' checkPhrase:translation: phrase:translation: removeTranslationFor: translate: translate:in: translationFor:)
('private' generics)
('private store-retrieve' loadFromFileNamed: loadFromStream: mergeTranslations: processExternalObject: saveToFileNamed:)
!

LanguageEditor initialize!

!LanguageEditor class reorganize!
('file list services' editTranslationFileNamed: fileReaderServicesForFile:suffix: openOnTranslator: serviceEditTranslationFile)
('initialize-release' initCheckMethods initialize unload)
('instance creation' on: openOn:)
('opening' open openOnDefault)
('private' checkMethods ensureVisibilityOfWindow:)
!



More information about the Squeak-dev mailing list