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