diff --git a/src/blocks/mrc_get_python_enum_value.ts b/src/blocks/mrc_get_python_enum_value.ts index 660225c5..d1b8cf87 100644 --- a/src/blocks/mrc_get_python_enum_value.ts +++ b/src/blocks/mrc_get_python_enum_value.ts @@ -30,6 +30,7 @@ import { createFieldDropdown } from '../fields/FieldDropdown'; import { createFieldNonEditableText } from '../fields/FieldNonEditableText'; import { MRC_STYLE_ENUM } from '../themes/styles' import * as toolboxItems from '../toolbox/items'; +import { replaceTokens } from './tokens'; // A block to access a python enum. @@ -75,7 +76,10 @@ const GET_PYTHON_ENUM_VALUE = { this.setTooltip(() => { const enumClassName = this.getFieldValue(FIELD_ENUM_CLASS_NAME); const enumValue = this.getFieldValue(FIELD_ENUM_VALUE); - let tooltip = 'Gets the enum value ' + enumClassName + '.' + enumValue + '.'; + let tooltip = replaceTokens(Blockly.Msg['GET_ENUM_VALUE_TOOLTIP'], { + enumName: enumClassName, + valueName: enumValue + }); const enumTooltip = PythonEnumTooltips[enumClassName] if (enumTooltip) { if (typeof enumTooltip === 'string') { diff --git a/src/blocks/mrc_get_python_variable.ts b/src/blocks/mrc_get_python_variable.ts index 0edbfaa5..2d7b5ac7 100644 --- a/src/blocks/mrc_get_python_variable.ts +++ b/src/blocks/mrc_get_python_variable.ts @@ -34,6 +34,7 @@ import { createFieldDropdown } from '../fields/FieldDropdown'; import { createFieldNonEditableText } from '../fields/FieldNonEditableText'; import { MRC_STYLE_VARIABLES } from '../themes/styles'; import * as toolboxItems from '../toolbox/items'; +import { replaceTokens } from './tokens'; // A block to get a python variable. @@ -132,7 +133,7 @@ const GET_PYTHON_VARIABLE = { */ init: function(this: GetPythonVariableBlock): void { this.appendDummyInput('VAR') - .appendField('get') + .appendField(Blockly.Msg['GET']) .appendField(createFieldNonEditableText(''), FIELD_MODULE_OR_CLASS_NAME) .appendField('.'); this.setStyle(MRC_STYLE_VARIABLES); @@ -142,21 +143,30 @@ const GET_PYTHON_VARIABLE = { switch (this.mrcVarKind) { case VariableKind.MODULE: { const moduleName = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME); - tooltip = 'Gets the variable ' + moduleName + '.' + varName + '.'; + tooltip = replaceTokens(Blockly.Msg['GET_MODULE_VARIABLE_TOOLTIP'], { + moduleName: moduleName, + varName: varName + }); break; } case VariableKind.CLASS: { const className = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME); - tooltip = 'Gets the variable ' + className + '.' + varName + '.'; + tooltip = replaceTokens(Blockly.Msg['GET_CLASS_VARIABLE_TOOLTIP'], { + className: className, + varName: varName + }); break; } case VariableKind.INSTANCE: { const className = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME); - tooltip = 'Gets the variable ' + varName + ' for the given ' + className + ' object.'; + tooltip = replaceTokens(Blockly.Msg['GET_INSTANCE_VARIABLE_TOOLTIP'], { + varName: varName, + className: className + }); break; } default: - throw new Error('mrcVarKind must be "module", "class", or "instance".') + throw new Error(Blockly.Msg['VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE']); } const varTooltips = PythonVariableGetterTooltips[this.mrcKey]; if (varTooltips) { @@ -286,7 +296,7 @@ export const pythonFromBlock = function( return [code, Order.MEMBER]; } default: - throw new Error('mrcVarKind must be "module", "class", or "instance".') + throw new Error(Blockly.Msg['VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE']); } }; diff --git a/src/blocks/mrc_mechanism.ts b/src/blocks/mrc_mechanism.ts index ffda819f..286d6b56 100644 --- a/src/blocks/mrc_mechanism.ts +++ b/src/blocks/mrc_mechanism.ts @@ -74,7 +74,7 @@ const MECHANISM = { nameField.setValidator(this.mrcNameFieldValidator.bind(this, nameField)); this.appendDummyInput() .appendField(nameField, FIELD_NAME) - .appendField(Blockly.Msg.OF_TYPE) + .appendField(Blockly.Msg['OF_TYPE']) .appendField(createFieldNonEditableText(''), FIELD_TYPE); this.setPreviousStatement(true, OUTPUT_NAME); this.setNextStatement(true, OUTPUT_NAME); @@ -240,7 +240,7 @@ const MECHANISM = { this.updateBlock_(); } else { // Did not find the mechanism. - warnings.push('This block refers to a mechanism that no longer exists.'); + warnings.push(Blockly.Msg['MECHANISM_NOT_FOUND_WARNING']); } } diff --git a/src/blocks/mrc_set_python_variable.ts b/src/blocks/mrc_set_python_variable.ts index f0ea1637..1cab8ca1 100644 --- a/src/blocks/mrc_set_python_variable.ts +++ b/src/blocks/mrc_set_python_variable.ts @@ -31,6 +31,7 @@ import { createFieldDropdown } from '../fields/FieldDropdown'; import { createFieldNonEditableText } from '../fields/FieldNonEditableText'; import { MRC_STYLE_VARIABLES } from '../themes/styles'; import * as toolboxItems from '../toolbox/items'; +import { replaceTokens } from './tokens'; // A block to set a python variable. @@ -123,7 +124,7 @@ const SET_PYTHON_VARIABLE = { */ init: function(this: SetPythonVariableBlock): void { this.appendValueInput('VALUE') - .appendField('set') + .appendField(Blockly.Msg['SET']) .appendField(createFieldNonEditableText(''), FIELD_MODULE_OR_CLASS_NAME) .appendField('.'); this.setStyle(MRC_STYLE_VARIABLES); @@ -133,21 +134,30 @@ const SET_PYTHON_VARIABLE = { switch (this.mrcVarKind) { case VariableKind.MODULE: { const moduleName = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME); - tooltip = 'Sets the variable ' + moduleName + '.' + varName + '.'; + tooltip = replaceTokens(Blockly.Msg['SET_MODULE_VARIABLE_TOOLTIP'], { + moduleName: moduleName, + varName: varName + }); break; } case VariableKind.CLASS: { const className = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME); - tooltip = 'Sets the variable ' + className + '.' + varName + '.'; + tooltip = replaceTokens(Blockly.Msg['SET_CLASS_VARIABLE_TOOLTIP'], { + className: className, + varName: varName + }); break; } case VariableKind.INSTANCE: { const className = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME); - tooltip = 'Sets the variable ' + varName + ' for the given ' + className + ' object.'; + tooltip = replaceTokens(Blockly.Msg['SET_INSTANCE_VARIABLE_TOOLTIP'], { + varName: varName, + className: className + }); break; } default: - throw new Error('mrcVarKind must be "module", "class", or "instance".') + throw new Error(Blockly.Msg['VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE']); } const varTooltips = PythonVariableSetterTooltips[this.mrcKey]; if (varTooltips) { @@ -226,7 +236,7 @@ const SET_PYTHON_VARIABLE = { } else { input.appendField(createFieldNonEditableText(''), FIELD_VARIABLE_NAME); } - input.appendField('to'); + input.appendField(Blockly.Msg['TO']); if (this.mrcVarType) { input.setCheck(getAllowedTypesForSetCheck(this.mrcVarType)); } @@ -279,7 +289,7 @@ export const pythonFromBlock = function( return code; } default: - throw new Error('mrcVarKind must be "module", "class", or "instance".') + throw new Error(Blockly.Msg['VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE']); } }; diff --git a/src/blocks/tokens.ts b/src/blocks/tokens.ts index bf8c4dea..3f995cf7 100644 --- a/src/blocks/tokens.ts +++ b/src/blocks/tokens.ts @@ -71,6 +71,18 @@ export function customTokens(t: (key: string) => string): typeof Blockly.Msg { ROBOT_LOWER_CASE: t('BLOCKLY.ROBOT_LOWER_CASE'), CREATE: t('BLOCKLY.CREATE'), FIRE: t('BLOCKLY.FIRE'), + GET: t('BLOCKLY.GET'), + GET_MODULE_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.GET_MODULE_VARIABLE'), + GET_CLASS_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.GET_CLASS_VARIABLE'), + GET_INSTANCE_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.GET_INSTANCE_VARIABLE'), + GET_ENUM_VALUE_TOOLTIP: t('BLOCKLY.TOOLTIP.GET_ENUM_VALUE'), + SET: t('BLOCKLY.SET'), + TO: t('BLOCKLY.TO'), + SET_MODULE_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.SET_MODULE_VARIABLE'), + SET_CLASS_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.SET_CLASS_VARIABLE'), + SET_INSTANCE_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.SET_INSTANCE_VARIABLE'), + VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE: t('BLOCKLY.ERROR.VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE'), + MECHANISM_NOT_FOUND_WARNING: t('BLOCKLY.WARNING.MECHANISM_NOT_FOUND'), WARNING_CALL_COMPONENT_INSTANCE_METHOD_PRIVATE_COMPONENT: t('BLOCKLY.WARNING.CALL_COMPONENT_INSTANCE_METHOD_PRIVATE_COMPONENT'), WARNING_CALL_COMPONENT_INSTANCE_METHOD_MISSING_COMPONENT: t('BLOCKLY.WARNING.CALL_COMPONENT_INSTANCE_METHOD_MISSING_COMPONENT'), WARNING_CALL_MECHANISM_COMPONENT_INSTANCE_METHOD_MISSING_MECHANISM: t('BLOCKLY.WARNING.CALL_MECHANISM_COMPONENT_INSTANCE_METHOD_MISSING_MECHANISM'), @@ -115,4 +127,16 @@ export function customTokens(t: (key: string) => string): typeof Blockly.Msg { MORE_OPMODE_METHODS_LABEL: t('BLOCKLY.MORE_OPMODE_METHODS_LABEL'), COMMENT_DEFAULT_TEXT: t('BLOCKLY.COMMENT_DEFAULT_TEXT'), } -}; \ No newline at end of file +}; + +/** + * Replaces tokens in a string with values from a dictionary. + * @param template String containing tokens in the format {{token}} + * @param values Dictionary mapping token names to their replacement values + * @return String with all tokens replaced by their corresponding values + */ +export function replaceTokens(template: string, values: Record): string { + return template.replace(/\{\{(\w+)\}\}/g, (match, token) => { + return values[token] !== undefined ? values[token] : match; + }); +} \ No newline at end of file diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index fd60a5ab..0634f76d 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -114,6 +114,9 @@ "ROBOT": "robot", "CREATE": "create", "FIRE": "fire", + "GET": "get", + "SET": "set", + "TO": "to", "CUSTOM_EVENTS_LABEL": "Custom Events", "CUSTOM_METHODS_LABEL": "Custom Methods", "MORE_ROBOT_METHODS_LABEL": "More Robot Methods", @@ -139,7 +142,14 @@ "CALL_MECHANISM_COMPONENT_INSTANCE_METHOD": "Calls the instance method {{className}}.{{functionName}} on the component named {{componentName}} in the mechanism named {{mechanismName}}.", "CALL_COMPONENT_INSTANCE_METHOD": "Calls the instance method {{className}}.{{functionName}} on the component named {{componentName}}.", "CALL_ROBOT_INSTANCE_METHOD": "Calls the robot method {{functionName}}.", - "CALL_MECHANISM_INSTANCE_METHOD": "Calls the instance method {{className}}.{{functionName}} on the mechanism named {{mechanismName}}." + "CALL_MECHANISM_INSTANCE_METHOD": "Calls the instance method {{className}}.{{functionName}} on the mechanism named {{mechanismName}}.", + "GET_MODULE_VARIABLE": "Gets the variable {{moduleName}}.{{varName}}.", + "GET_CLASS_VARIABLE": "Gets the variable {{className}}.{{varName}}.", + "GET_INSTANCE_VARIABLE": "Gets the variable {{varName}} for the given {{className}} object.", + "GET_ENUM_VALUE": "Gets the enum value {{enumName}}.{{valueName}}.", + "SET_MODULE_VARIABLE": "Sets the variable {{moduleName}}.{{varName}}.", + "SET_CLASS_VARIABLE": "Sets the variable {{className}}.{{varName}}.", + "SET_INSTANCE_VARIABLE": "Sets the variable {{varName}} for the given {{className}} object." }, "CATEGORY":{ "LISTS": "Lists", @@ -169,7 +179,11 @@ "CALL_MECHANISM_INSTANCE_METHOD_INSIDE_MECHANISM": "This block is not allowed to be used inside a mechanism.", "CALL_MECHANISM_INSTANCE_METHOD_MISSING_METHOD": "This block calls a method that no longer exists in the mechanism.", "CALL_MECHANISM_INSTANCE_METHOD_MISSING_MECHANISM": "This block calls a method in a mechanism that no longer exists.", - "EVENT_NOT_IN_HOLDER": "This block can only go in the events section of the robot or mechanism." + "EVENT_NOT_IN_HOLDER": "This block can only go in the events section of the robot or mechanism.", + "MECHANISM_NOT_FOUND": "This block refers to a mechanism that no longer exists." + }, + "ERROR":{ + "VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE": "mrcVarKind must be \"module\", \"class\", or \"instance\"." } } } diff --git a/src/i18n/locales/es/translation.json b/src/i18n/locales/es/translation.json index b71dc4bc..c4ecd328 100644 --- a/src/i18n/locales/es/translation.json +++ b/src/i18n/locales/es/translation.json @@ -115,6 +115,9 @@ "ROBOT": "robot", "CREATE": "crear", "FIRE": "disparar", + "GET": "obtener", + "SET": "establecer", + "TO": "a", "CUSTOM_EVENTS_LABEL": "Eventos Personalizados", "CUSTOM_METHODS_LABEL": "Métodos Personalizados", "MORE_ROBOT_METHODS_LABEL": "Más Métodos del Robot", @@ -140,7 +143,14 @@ "CALL_MECHANISM_COMPONENT_INSTANCE_METHOD": "Llama al método de instancia {{className}}.{{functionName}} en el componente llamado {{componentName}} en el mecanismo llamado {{mechanismName}}.", "CALL_COMPONENT_INSTANCE_METHOD": "Llama al método de instancia {{className}}.{{functionName}} en el componente llamado {{componentName}}.", "CALL_ROBOT_INSTANCE_METHOD": "Llama al método robot {{functionName}}.", - "CALL_MECHANISM_INSTANCE_METHOD": "Llama al método de instancia {{className}}.{{functionName}} en el mecanismo llamado {{mechanismName}}." + "CALL_MECHANISM_INSTANCE_METHOD": "Llama al método de instancia {{className}}.{{functionName}} en el mecanismo llamado {{mechanismName}}.", + "GET_MODULE_VARIABLE": "Obtiene la variable {{moduleName}}.{{varName}}.", + "GET_CLASS_VARIABLE": "Obtiene la variable {{className}}.{{varName}}.", + "GET_INSTANCE_VARIABLE": "Obtiene la variable {{varName}} para el objeto {{className}} dado.", + "GET_ENUM_VALUE": "Obtiene el valor de enumeración {{enumName}}.{{valueName}}.", + "SET_MODULE_VARIABLE": "Establece la variable {{moduleName}}.{{varName}}.", + "SET_CLASS_VARIABLE": "Establece la variable {{className}}.{{varName}}.", + "SET_INSTANCE_VARIABLE": "Establece la variable {{varName}} para el objeto {{className}} dado." }, "CATEGORY": { "LISTS": "Listas", @@ -170,7 +180,11 @@ "CALL_MECHANISM_INSTANCE_METHOD_INSIDE_MECHANISM": "No se permite utilizar este bloque dentro de un mecanismo.", "CALL_MECHANISM_INSTANCE_METHOD_MISSING_METHOD": "Este bloque llama a un método que ya no existe en el mecanismo.", "CALL_MECHANISM_INSTANCE_METHOD_MISSING_MECHANISM": "Este bloque llama a un método en un mecanismo que ya no existe.", - "EVENT_NOT_IN_HOLDER": "Este bloque solo puede ir en la sección de eventos del robot o mecanismo." + "EVENT_NOT_IN_HOLDER": "Este bloque solo puede ir en la sección de eventos del robot o mecanismo.", + "MECHANISM_NOT_FOUND": "Este bloque se refiere a un mecanismo que ya no existe." + }, + "ERROR":{ + "VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE": "mrcVarKind debe ser \"module\", \"class\" o \"instance\"." } } } diff --git a/src/i18n/locales/he/translation.json b/src/i18n/locales/he/translation.json index 2154a0ca..709d7bcc 100644 --- a/src/i18n/locales/he/translation.json +++ b/src/i18n/locales/he/translation.json @@ -114,6 +114,9 @@ "ROBOT": "רובוט", "CREATE": "צור", "FIRE": "הפעל", + "GET": "קבל", + "SET": "הגדר", + "TO": "ל", "CUSTOM_EVENTS_LABEL": "אירועים מותאמים אישית", "CUSTOM_METHODS_LABEL": "מתודות מותאמות אישית", "MORE_ROBOT_METHODS_LABEL": "מתודות נוספות לרובוט", @@ -139,7 +142,14 @@ "CALL_MECHANISM_COMPONENT_INSTANCE_METHOD": "קורא למתודה {{className}}.{{functionName}} על הרכיב {{componentName}} במנגנון {{mechanismName}}.", "CALL_COMPONENT_INSTANCE_METHOD": "קורא למתודה {{className}}.{{functionName}} על הרכיב {{componentName}}.", "CALL_ROBOT_INSTANCE_METHOD": "קורא למתודת הרובוט {{functionName}}.", - "CALL_MECHANISM_INSTANCE_METHOD": "קורא למתודה {{className}}.{{functionName}} במנגנון {{mechanismName}}." + "CALL_MECHANISM_INSTANCE_METHOD": "קורא למתודה {{className}}.{{functionName}} במנגנון {{mechanismName}}.", + "GET_MODULE_VARIABLE": "מקבל את המשתנה {{moduleName}}.{{varName}}.", + "GET_CLASS_VARIABLE": "מקבל את המשתנה {{className}}.{{varName}}.", + "GET_INSTANCE_VARIABLE": "מקבל את המשתנה {{varName}} עבור אובייקט {{className}} נתון.", + "GET_ENUM_VALUE": "מקבל את ערך ההספירה {{enumName}}.{{valueName}}.", + "SET_MODULE_VARIABLE": "מגדיר את המשתנה {{moduleName}}.{{varName}}.", + "SET_CLASS_VARIABLE": "מגדיר את המשתנה {{className}}.{{varName}}.", + "SET_INSTANCE_VARIABLE": "מגדיר את המשתנה {{varName}} עבור אובייקט {{className}} נתון." }, "CATEGORY": { "LISTS": "רשימות", @@ -169,7 +179,11 @@ "CALL_MECHANISM_INSTANCE_METHOD_INSIDE_MECHANISM": "בלוק זה אינו מורשה לשימוש בתוך מנגנון.", "CALL_MECHANISM_INSTANCE_METHOD_MISSING_METHOD": "בלוק זה קורא למתודה שכבר לא קיימת במנגנון.", "CALL_MECHANISM_INSTANCE_METHOD_MISSING_MECHANISM": "בלוק זה קורא למתודה במנגנון שכבר לא קיים.", - "EVENT_NOT_IN_HOLDER": "בלוק זה יכול להיכנס רק לאזור האירועים של הרובוט או המנגנון." + "EVENT_NOT_IN_HOLDER": "בלוק זה יכול להיכנס רק לאזור האירועים של הרובוט או המנגנון.", + "MECHANISM_NOT_FOUND": "בלוק זה מתייחס למנגנון שכבר לא קיים." + }, + "ERROR": { + "VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE": "mrcVarKind חייב להיות \"module\", \"class\" או \"instance\"." } } }