diff --git a/packages/renderer/src/lang/en_us.ts b/packages/renderer/src/lang/en_us.ts new file mode 100644 index 0000000..f1cafd3 --- /dev/null +++ b/packages/renderer/src/lang/en_us.ts @@ -0,0 +1,171 @@ + +const en = { + lang:"English", + usbconfig:{ + title:{ + button:{ + file:"file", + project:"project", + view:"view", + compile:"compile", + help:"help", + about:"about", + lang: "Language", + }, + dropdown:{ + file0:"Create New File", + file1:"Open a file", + file2:"Close a file", + file3:"Save a file", + file4:"Save As...", + file5:"Save ALL", + file6:"Exit", + project0:"Create a new project", + project1:"Open Project", + project2:"Close Project", + project3:"Save project", + project4:"Save As...", + view0:"Dark mode", + view1:"Light mode", + view2:"High Contrast Dark", + view3:"high Contrast Light", + compile0:"Generate CherryUSB style descriptors", + compile1:"Generate STM32 style descriptors", + compile2:"Generate ESP32 style descriptors", + help0:"Documentation tutorials", + help1:"Video tutorials", + help2:"GITHUB", + about0:"Contact us", + about1:"Donate to us", + about2:"Software Instructions" + }, + str_desc: { + add: "Add a string descriptor", + delete:"Delete a string descriptor" + }, + conf_desc: { + add: "Add a config descriptor", + delete:"Delete a config descriptor" + }, + group_conf: { + add:"Add group config", + delete:"Delete group config" + }, + intf_desc: { + add: "Add interface descriptor", + delete: "Delete interface descriptor", + }, + alt: { + add: "Add alternate descriptor", + delete: "Delete alternate descriptor", + }, + spec: { + delete: "Delete specific descriptor" + }, + endpoint: { + add: "Add endpoint descriptor", + delete: "Delete endpoint descriptor" + }, + iad: { + add: "", + delete: "Delete intf assoc descriptor" + }, + treeselect: "Init project, reset descriptor", + }, + file:{ + basename:"CherryUSB project file (*.chrybase)", + filename:"CherryUSB description file (*.chry)", + cname:"C name", + savebase:"savebase", + savefile:"savefile", + savec:"save C file", + openbase:"openbas", + openfile:"openfile", + fileok:"fileOK", + filefaild:"fileFAILD", + filecancel:"fileCANCEL", + parseok:"parseOK" + }, + jsonerror:{ + error0:"syntax error at character [", + error1:"] error type: ", + error2:"", + "0":"Success", + "1":"Invalid identifier", + "2":"Invalid number format", + "3":"Missing attribute name", + "4":"Missing attribute value", + "5":"Missing ':'", + "6":"Misisng ','", + "7":"Misisng '}'", + "8":"Misisng ']'", + "9":"Misisng 'EOF'", + "10":"Illegal comment", + "11":"Extra multi-line comment terminator", + "12":"Extra '\'' or '\"'", + "13":"Extra decimal point", + "14":"Illegal unicode character", + "15":"Illegal escape character", + "16":"Illegal character" + }, + group:{ + add_iad_desc: "Add IAD", + init_as_msc: "Init as MSC", + init_as_hid: "Init as HID", + init_as_cdc: "Init as CDC ACM", + init_as_uac1: "Init as UAC 1.0", + init_as_uac2: "Init as UAC 2.0", + init_as_uvc: "Init as UVC" + } + }, + dialogs: { + buttons: { + ok: "OK", + exit: "Exit", + save_close: "Save and close", + save_close_all: "Save and close all files", + close_no_save: "Close without saving", + close_no_save_all: "Close all files without saving", + cancel: "Cancel", + }, + init_project: { + title: "Initialize project", + msg: "Are you sure you want to init project? The descriptor will be reset", + }, + unsaved_file: { + title: "Unsaved file", + msg: "Are you sure you want to close the file? You haven't saved it yet...", + }, + init_packet_interface: { + title:"Initialize packet interface", + msg: "Initialize as CDC ACM serial communication device.\nA packet file is used to describe a group of functional classes. Do not combine multiple classes in a single packet file.\nAre you sure you want to initialize? The descriptor will be reset.", + }, + init_msc: { + title: "Initialize group MSC", + msg: "Initialize to MSC Mass Storage Device. Group files are used to describe a group of functional classes. Do not combine multiple classes into one group file. Are you sure you want to initialize? The descriptors will be reset" + }, + init_hid: { + title: "Initialize group HID", + msg: "Initialize to HID Human-Computer Interaction Device. Group files are used to describe a group of functional classes. Do not combine multiple classes into one group file. Are you sure you want to initialize? The descriptors will be reset." + }, + close_file: { + title: "Close file", + msg: "Are you sure? file has not been saved. Please choose whether to save" + }, + close_project: { + title: "Close project", + msg: "Are you sure? project has not been saved. Please choose whether to save project and all files" + }, + exit: { + title: "Close software", + msg: "Are you sure you want to exit?" + }, + save_project: { + title: "Save project", + msg: "Select whether to save all project files", + }, + + } +} + +export default en \ No newline at end of file diff --git a/packages/renderer/src/lang/index.ts b/packages/renderer/src/lang/index.ts index 1f9354d..1995bdd 100644 --- a/packages/renderer/src/lang/index.ts +++ b/packages/renderer/src/lang/index.ts @@ -1,11 +1,13 @@ import { createI18n } from 'vue-i18n' +import en_us from './en_us' import zh_cn from './zh_cn' const i18n = createI18n({ - locale: 'zh-cn', + locale: 'en-us', fallbackLocale: 'zh-cn', messages: { + "en-us": en_us, "zh-cn": zh_cn } }) diff --git a/packages/renderer/src/lang/zh_cn.ts b/packages/renderer/src/lang/zh_cn.ts index 9ab8d8b..9425143 100644 --- a/packages/renderer/src/lang/zh_cn.ts +++ b/packages/renderer/src/lang/zh_cn.ts @@ -9,7 +9,8 @@ const zh = { view:"视图", compile:"编译", help:"帮助", - about:"关于" + about:"关于", + lang: "语言", }, dropdown:{ file0:"新建文件", @@ -37,7 +38,39 @@ const zh = { about0:"联系我们", about1:"赞助我们", about2:"软件说明" - } + }, + str_desc: { + add: "添加字符串描述符", + delete:"删除字符串描述符" + }, + conf_desc: { + add: "添加配置描述符", + delete: "删除配置描述符", + }, + group_conf: { + add:"添加分组配置", + delete:"删除分组配置" + }, + intf_desc: { + add: "添加接口描述符", + delete: "删除接口描述符", + }, + alt: { + add: "添加接口复用描述符", + delete: "删除接口复用描述符", + }, + spec: { + delete: "删除特定描述符" + }, + endpoint: { + add: "添加端点描述符", + delete: "删除端点描述符" + }, + iad: { + add: "", + delete: "删除接口关联描述符" + }, + treeselect: "初始化工程, 重置描述符", }, file:{ basename:"CherryUSB 工程文件", @@ -74,8 +107,66 @@ const zh = { "14":"非法的Unicode字符", "15":"非法的转义字符", "16":"非法的字符" + }, + group:{ + add_iad_desc: "添加 IAD 接口关联描述符", + init_as_msc: "初始化为 MSC", + init_as_hid: "初始化为 HID", + init_as_cdc: "初始化为 CDC ACM", + init_as_uac1: "初始化为 UAC 1.0", + init_as_uac2: "初始化为 UAC 2.0", + init_as_uvc: "初始化为 UVC" } + }, + dialogs: { + buttons: { + ok: "确定", + exit: "退出", + save_close: "保存并关闭", + save_close_all: "保存并关闭所有文件", + close_no_save: "仅关闭不保存", + close_no_save_all: "仅关闭所有文件不保存", + cancel: "取消" + }, + init_project: { + title: "初始化工程", + msg: "确定要初始化工程文件吗? 将会重置描述符", + }, + unsaved_file: { + title: "初始化工程", + msg: "确定要关闭文件吗? 您还没有保存文件, 请选择是否保存文件", + }, + init_packet_interface: { + title:"初始化分组接口", + msg: "初始化为 CDC ACM 串行通信设备\n分组文件用于描述一组功能类, 请勿将多个类合并在一个分组文件中\n确定要初始化吗? 将会重置描述符", + }, + init_msc: { + title: "初始化分组接口", + msg: "初始化为 MSC 大容量存储设备\n分组文件用于描述一组功能类, 请勿将多个类合并在一个分组文件中\n确定要初始化吗? 将会重置描述符" + }, + init_hid: { + title: "初始化分组接口", + msg: "初始化为 HID 人机交互设备\n分组文件用于描述一组功能类, 请勿将多个类合并在一个分组文件中\n确定要初始化吗? 将会重置描述符" + }, + close_file: { + title: "关闭文件", + msg: "确定要关闭文件吗? 您还没有保存文件, 请选择是否保存文件" + }, + close_project: { + title: "关闭工程", + msg: "确定要关闭工程吗? 请选择是否保存并关闭所有工程相关文件" + }, + exit: { + title: "关闭软件", + msg: "确定要退出软件吗?" + }, + save_project: { + title: "保存工程", + msg: "请选择是否保存所有工程相关文件", + }, + } + } export default zh \ No newline at end of file diff --git a/packages/renderer/src/pages/UsbConfig.vue b/packages/renderer/src/pages/UsbConfig.vue index 09780b7..9a64c5d 100644 --- a/packages/renderer/src/pages/UsbConfig.vue +++ b/packages/renderer/src/pages/UsbConfig.vue @@ -8,6 +8,7 @@ {{ $tm("usbconfig.title.button.compile") }} {{ $tm("usbconfig.title.button.help") }} {{ $tm("usbconfig.title.button.about") }} + {{ $tm("usbconfig.title.button.lang") }} @@ -180,7 +181,7 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v if (select == false) { BUSBIndex = ButtonIndex.ProjectInit; - BUSBTitle.value = "初始化工程, 重置描述符"; + BUSBTitle.value = tm("usbconfig.title.treeselect"); BUSBGroupShow.value = true; } else{ @@ -200,7 +201,7 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v CUSBDeviceInfoView.version = CUSBBaseInfoView.device.version; CUSBDeviceInfoShow.value = true; BUSBIndex = ButtonIndex.ProjectInit; - BUSBTitle.value = "初始化工程, 重置描述符"; + BUSBTitle.value = tm("usbconfig.title.treeselect"); break; } case "string":{ @@ -210,10 +211,10 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v CUSBStringInfoView.value = CUSBBaseInfoView.string[CUSBStringInfoIndex].value; CUSBStringInfoShow.value = true; BUSBIndex = ButtonIndex.StringDel; - BUSBTitle.value = "删除字符串描述符"; + BUSBTitle.value = tm("usbconfig.title.str_desc.delete"); } else { BUSBIndex = ButtonIndex.StringAdd; - BUSBTitle.value = "添加字符串描述符"; + BUSBTitle.value = tm("usbconfig.title.str_desc.add");; } break; } @@ -227,7 +228,7 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v CUSBConfigInfoView.power = CUSBBaseInfoView.config[CUSBConfigInfoIndex].power; CUSBConfigInfoShow.value = true; BUSBIndex = ButtonIndex.ConfigDel; - BUSBTitle.value = "删除配置描述符"; + BUSBTitle.value = tm("usbconfig.title.conf_desc.delete"); } else if (path[2]=='group') { CUSBConfigInfoIndex = path[1] as number; if(path.length == 4){ @@ -235,14 +236,14 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v CUSBConfigGroupinfoView.path = CUSBBaseInfoView.config[CUSBConfigInfoIndex].group[CUSBConfigGroupInfoIndex]; CUSBConfigGroupInfoShow.value = true; BUSBIndex = ButtonIndex.ConfigGroupDel; - BUSBTitle.value = "删除分组配置"; + BUSBTitle.value = tm("usbconfig.title.group_conf.delete"); } else { BUSBIndex = ButtonIndex.ConfigGroupAdd; - BUSBTitle.value = "添加分组配置"; + BUSBTitle.value = tm("usbconfig.title.group_conf.add"); } } else { BUSBIndex = ButtonIndex.ConfigAdd; - BUSBTitle.value = "添加配置描述符"; + BUSBTitle.value = tm("usbconfig.title.conf_desc.add"); } break; } @@ -252,7 +253,7 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v CUSBInterfaceInfoIndex = path[1] as number; CUSBInterfaceInfoShow.value = true; BUSBIndex = ButtonIndex.InterfaceDel; - BUSBTitle.value = "删除接口描述符"; + BUSBTitle.value = tm("usbconfig.title.intf_desc.delete"); BUSBShow.value = true; } else if (path[2] === 'alternate'){ @@ -266,7 +267,7 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v CUSBAlternateInfoView.protocol = CUSBGroupInfoViews[fileIndex.value-1].interface[CUSBInterfaceInfoIndex].alternate[CUSBAlternateInfoIndex].protocol; CUSBAlternateInfoShow.value = true; BUSBIndex = ButtonIndex.AlternateDel; - BUSBTitle.value = "删除接口复用描述符"; + BUSBTitle.value = tm("usbconfig.title.alt.delete"); BUSBShow.value = true; } else if (path[4] === 'specific' || path[4] === 'endpoint'){ CUSBAlternateInfoIndex = path[3] as number; @@ -276,7 +277,7 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v CUSBSpecificInfoShow.value = true; CUSBSpecificInfoView.type = (CUSBGroupInfoViews[fileIndex.value-1].interface[CUSBInterfaceInfoIndex].alternate[CUSBAlternateInfoIndex].specific as IUSBSpecificInfo).type BUSBIndex = ButtonIndex.SpecificDel; - BUSBTitle.value = "删除特定描述符"; + BUSBTitle.value = tm("usbconfig.title.spec.delete"); BUSBShow.value = true; } @@ -290,23 +291,23 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v CUSBEndpointInfoView.interval = CUSBGroupInfoViews[fileIndex.value-1].interface[CUSBInterfaceInfoIndex].alternate[CUSBAlternateInfoIndex].endpoint[CUSBEndpointInfoIndex].interval; CUSBEndpointInfoShow.value = true; BUSBIndex = ButtonIndex.EndpointDel; - BUSBTitle.value = "删除端点描述符"; + BUSBTitle.value = tm("usbconfig.title.endpoint.delete"); BUSBShow.value = true; } else { BUSBIndex = ButtonIndex.EndpointAdd; - BUSBTitle.value = "添加端点描述符"; + BUSBTitle.value = tm("usbconfig.title.endpoint.add"); BUSBShow.value = true; } } } else { BUSBIndex = ButtonIndex.AlternateAdd; - BUSBTitle.value = "添加接口复用描述符"; + BUSBTitle.value = tm("usbconfig.title.alt.add"); BUSBShow.value = true; } } else { BUSBIndex = ButtonIndex.InterfaceAdd; - BUSBTitle.value = "添加接口描述符"; + BUSBTitle.value = tm("usbconfig.title.intf_desc.add"); BUSBShow.value = true; } break; @@ -323,7 +324,7 @@ function TreeSelect(index:number, select?:boolean, radios?:Array):v CUSBAssociateInfoView.protocol = (CUSBGroupInfoViews[fileIndex.value-1].associate as IUSBAssociateInfo).protocol; CUSBAssociateInfoShow.value = true; BUSBIndex = ButtonIndex.AssociateDel; - BUSBTitle.value = "删除接口关联描述符"; + BUSBTitle.value = tm("usbconfig.title.iad.delete"); BUSBShow.value = true; } break; @@ -368,6 +369,11 @@ let r = new UsbConfigResize(reactive({ size:<[number,number,number]> [init_treePanel_w,init_buttonPanel_h, init_messagePanel_h] })) +let kavailableLocales: any = reactive([ + {disable: false, label: "中文简体", icon: "mdi-translate"}, + {disable: false, label: "English", icon: "mdi-translate"}, +]) + /** * 标题下拉菜单 */ @@ -520,7 +526,7 @@ let CUSBConfigGroupInfoShow = ref(false); let CUSBConfigGroupinfoView = reactive({path:""}); let CUSBConfigGroupInfoIndex = 0; -let BUSBTitle:Ref = ref("初始化工程, 重置描述符") +let BUSBTitle:Ref = ref(tm("usbconfig.title.treeselect")) let BUSBIndex:number = 0; let BUSBGroupShow = ref(false); @@ -643,9 +649,9 @@ function updateTreeView(file?:UsbConfigFile):void */ async function exit():Promise{ var sel = await messageBox({ - title:"关闭软件", - message:"确定要退出软件吗?", - buttons:["退出", "取消"], + title:tm("dialogs.exit.title"), + message:tm("dialogs.exit.title"), + buttons:[tm("dialogs.buttons.exit"), tm("dialogs.buttons.cancel")], cancelId: 1 }) @@ -659,9 +665,9 @@ async function exit():Promise{ } sel = await messageBox({ - title:"保存工程", - message:"请选择是否保存所有工程相关文件", - buttons:["保存", "不保存", "取消"], + title:tm("dialogs.save_project.title"), + message:tm("dialogs.save_project.msg"), + buttons:[tm("dialogs.buttons.save_close"), tm("dialogs.buttons.close_no_save"), tm("dialogs.buttons.cancel")], cancelId: 2 }) @@ -734,9 +740,9 @@ const OnFileRadios: Pvl.IOnRadios = async function (index: number, radios?: Arra var saved = files[index].checkSaved(); if (!saved){ var sel = await messageBox({ - title:"关闭文件", - message:"确定要关闭文件吗? 您还没有保存文件, 请选择是否保存文件", - buttons:["保存并关闭", "仅关闭不保存", "取消"], + title:tm("dialogs.unsaved_file.title"), + message:tm("dialogs.unsaved_file.msg"), + buttons:[tm("dialogs.buttons.save_close"), tm("dialogs.buttons.close_no_save"), tm("dialogs.buttons.cancel")], cancelId: 2 }) @@ -807,9 +813,9 @@ const BUSBClick = async (): Promise => { switch(BUSBIndex){ case ButtonIndex.ProjectInit:{ var sel = await messageBox({ - title:"初始化工程", - message:"确定要初始化工程文件吗? 将会重置描述符", - buttons:["确定", "取消"], + title:tm("dialogs.init_project.title"), + message:tm("dialogs.init_project.msg"), + buttons:[tm("dialogs.buttons.ok"), tm("dialogs.buttons.cancel")], cancelId: 1 }) @@ -919,9 +925,9 @@ const BUSBGroupClick = async (index:EUSBClass):Promise=>{ } case EUSBClass.MSC:{ var sel = await messageBox({ - title:"初始化分组接口", - message:"初始化为 MSC 大容量存储设备\n分组文件用于描述一组功能类, 请勿将多个类合并在一个分组文件中\n确定要初始化吗? 将会重置描述符", - buttons:["确定", "取消"], + title:tm("dialogs.init_msc.title"), + message:tm("dialogs.init_msc.msg"), + buttons:[tm("dialogs.buttons.ok"), tm("dialogs.buttons.cancel")], cancelId: 1 }) @@ -935,9 +941,9 @@ const BUSBGroupClick = async (index:EUSBClass):Promise=>{ } case EUSBClass.HID:{ var sel = await messageBox({ - title:"初始化分组接口", - message:"初始化为 HID 人机交互设备\n分组文件用于描述一组功能类, 请勿将多个类合并在一个分组文件中\n确定要初始化吗? 将会重置描述符", - buttons:["确定", "取消"], + title:tm("dialogs.init_hid.title"), + message:tm("dialogs.init_hid.msg"), + buttons:[tm("dialogs.buttons.ok"), tm("dialogs.buttons.cancel")], cancelId: 1 }) @@ -952,9 +958,9 @@ const BUSBGroupClick = async (index:EUSBClass):Promise=>{ case EUSBClass.CDC_ACM: case EUSBClass.CDC_ACM_DATA:{ var sel = await messageBox({ - title:"初始化分组接口", - message:"初始化为 CDC ACM 串行通信设备\n分组文件用于描述一组功能类, 请勿将多个类合并在一个分组文件中\n确定要初始化吗? 将会重置描述符", - buttons:["确定", "取消"], + title:tm("dialogs.init_packet_interface.title"), + message:tm("dialogs.init_packet_interface.msg"), + buttons:[tm("dialogs.buttons.ok"), tm("dialogs.buttons.cancel")], cancelId: 1 }) @@ -1096,9 +1102,9 @@ const fileOnList: Pvl.IOnList = async (index:number, list?: Array): P var saved = files[fileIndex.value].checkSaved(); if (!saved){ var sel = await messageBox({ - title:"关闭文件", - message:"确定要关闭文件吗? 您还没有保存文件, 请选择是否保存文件", - buttons:["保存并关闭", "仅关闭不保存", "取消"], + title:tm("dialogs.close_file.title"), + message:tm("dialogs.close_file.msg"), + buttons:[tm("dialogs.buttons.save_close"), tm("dialogs.buttons.close_no_save"), tm("dialogs.buttons.cancel")], cancelId: 2 }) @@ -1241,9 +1247,9 @@ const projectOnList: Pvl.IOnList = async (index:number, list?: Array) /*!< 关闭工程 */ case 2: { var sel = await messageBox({ - title:"关闭工程", - message:"确定要关闭工程吗? 请选择是否保存并关闭所有工程相关文件", - buttons:["保存并关闭所有文件", "仅关闭所有文件不保存", "取消"], + title:tm("dialogs.close_project.title"), + message:tm("dialogs.close_project.msg"), + buttons:[tm("dialogs.buttons.save_close_all"), tm("dialogs.buttons.close_no_save_all"), tm("dialogs.buttons.cancel")], cancelId: 2 }) @@ -1359,6 +1365,22 @@ const aboutOnList: Pvl.IOnList = (index:number, list?: Array): void = } } +const localeOnList: Pvl.IOnList = (index:number, list?: Array): void => { + switch(index){ + case 0: { + LogI("K: selected lang 0"); + i18n.global.locale = "zh-cn"; + break; + } + case 1: { + LogI("K: selected lang 1") + i18n.global.locale = "en-us"; + break; + } + } +} + + /*!< 日志输出 */ function LogI(msg: any): void { diff --git a/packages/renderer/src/pages/usbConfigPages/BUSBGroup.vue b/packages/renderer/src/pages/usbConfigPages/BUSBGroup.vue index 94d4034..3b6529d 100644 --- a/packages/renderer/src/pages/usbConfigPages/BUSBGroup.vue +++ b/packages/renderer/src/pages/usbConfigPages/BUSBGroup.vue @@ -1,12 +1,12 @@ @@ -37,11 +37,14 @@ /* import --------------------------------------------------------------------*/ +import i18n from "../../lang"; + import PvlBtn from '../../components/util/PvlBtn.vue'; import {EUSBClass} from '../../mainModules/UsbConfigRender'; /* declare -------------------------------------------------------------------*/ /* props ---------------------------------------------------------------------*/ +const tm = i18n.global.tm; /* emits ---------------------------------------------------------------------*/ interface Emit {