diff --git a/include/global.h b/include/global.h index c2a2a9f..abafe4b 100644 --- a/include/global.h +++ b/include/global.h @@ -11,20 +11,25 @@ #include #pragma execution_character_set("utf-8") -const std::string softwareVersion = "20260507-2.5.2";//版本号 +const std::string softwareVersion = "20260507-2.5.3";//版本号 const std::string euiJsonVersion = "1.0.6";//json标准版本 #define GigaByte 1073741824//1GB字节大小 #define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径 #define savePathToDataBase true //是否将存储路径存入到数据库中 #define saveImgEnable true//是否存储图片 -#define switchToTongYongUi 1 //是否切换到通用UI界面 #define skipLogin 1 //是否跳过登录界面 #define jsonRpcEnable false //是否启用JSON RPC服务器 #define minimumWindowSize 1280, 720//最小窗口大小 #define histogramLabelTiltFontSize 8 //柱状图标签字体大小 #define windowMoveFreshRate 60//窗口移动每秒的刷新率 -#define pathDataBaseSaveDate 90//存储存图路径的数据库其数据保留的日期 -#define detDataBaseSaveDate 730//存储检测数据的数据库其数据保留的日期 +#define pathDataBaseSaveDays 180//存储存图路径的数据库其数据保留的日期 +#define detDataBaseSaveDays 730//存储检测数据的数据库其数据保留的日期 +#define logSaveDays 365 //日志储存的日期 +#define offlineMode 0//启用离线测试模式 不连接PLC 不与PLC交互 不连接相机 不对重复启动进行检测 +#define dayShiftHour 7//白班小时 +#define dayShiftMin 30//白班分钟 +#define nightShiftHour 19//夜班小时 +#define nightShiftMin 30//夜班分钟 #define sColor_Blue "51, 56, 69" #define sColor_BlueWithWhite "64, 68, 81" diff --git a/include/interface.h b/include/interface.h index 54d5d02..02aad09 100644 --- a/include/interface.h +++ b/include/interface.h @@ -96,8 +96,10 @@ signals: void showMessageBox(const QString& message); //备份及替换halcon算法文件 void backupAndReplaceAlgoFile(const std::string& path); - + //重新加载所有相机为虚拟相机 void reloadAllCameraAsVirtual(); + //更新用户权限 用户名 持续时间 等级(0访客,1管理员,2ROOT根管理员(一般不给予)) + void updateUserPermission(const QString& userName, int duration, int level); }; @@ -116,6 +118,7 @@ public slots: virtual void getCameraNames(std::vector* cameraNames) = 0;//获取所有相机的名称 virtual void getAllParams(std::vector>* params) = 0;//获取所有参数及值 virtual void editParam(QString group, QString name, QVariant value) = 0;//修改指定参数的值 + virtual void launguageChanged(const std::string& language) = 0;//语言变更 }; extern "C" { diff --git a/include/opencvPaintAlgo.hpp b/include/opencvPaintAlgo.hpp index 015f323..865f099 100644 --- a/include/opencvPaintAlgo.hpp +++ b/include/opencvPaintAlgo.hpp @@ -51,7 +51,7 @@ static void drawArrow(cv::Mat& Paint, const cv::Point& start, const int& length, } } -void drawRotatedRect(cv::Mat& img, cv::RotatedRect rotateRect, cv::Scalar color, int thickness, int linType) +static void drawRotatedRect(cv::Mat& img, cv::RotatedRect rotateRect, cv::Scalar color, int thickness, int linType) { std::vector boxPts(4); rotateRect.points(boxPts.data()); diff --git a/include/sql/dataRecorder.h b/include/sql/dataRecorder.h index 7a753f5..31ff5f9 100644 --- a/include/sql/dataRecorder.h +++ b/include/sql/dataRecorder.h @@ -28,8 +28,8 @@ public: } { - QMutexLocker locker(&queueLock); - queue.enqueue(std::make_pair(snCode, data)); + QMutexLocker locker(&dataQueueLock); + dataQueue.enqueue(std::make_pair(snCode, data)); } if (!isRunning()) { @@ -45,19 +45,22 @@ public: protected: void run() override { while (true) { - std::pair> val; + QQueue>> vals; // 从队列获取数据 { - QMutexLocker locker(&queueLock); - if (queue.isEmpty()) { + QMutexLocker locker(&dataQueueLock); + if (dataQueue.isEmpty()) { break; } - val = queue.dequeue(); + dataQueue.swap(vals); } try { - processData(val.first, val.second); + while (!vals.empty()) { + auto val = vals.dequeue(); + processData(val.first, val.second); + } } catch (const std::exception& ex) { qCritical() << "addData: Exception caught:" << ex.what(); @@ -70,8 +73,8 @@ protected: private: // 统一锁顺序:先队列锁,再数据库锁 - QMutex queueLock; - QQueue>> queue; + QMutex dataQueueLock; + QQueue>> dataQueue; std::mutex _mutex; int m_intervalMs = 10000; @@ -197,9 +200,9 @@ private: int hour = currentDateTime.time().hour(); int minute = currentDateTime.time().minute(); //判断是否为白班 - bool isDayShift = (hour > 8 || (hour == 8 && minute >= 30)) && (hour < 20 || (hour == 20 && minute <= 30)); - //判断是否为前一天 - bool isDayBefore = hour < 8 || (hour == 8 && minute <= 29); + bool isDayShift = (hour > dayShiftHour || (hour == dayShiftHour && minute >= dayShiftMin)) && (hour < nightShiftHour || (hour == nightShiftHour && minute <= nightShiftMin)); + //判断是否为前一天(只有夜班可能是前一天的 + bool isDayBefore = hour < dayShiftHour || (hour == dayShiftHour && minute < dayShiftMin); QString dateStr; if (isDayBefore) { @@ -217,9 +220,9 @@ private: int hour = currentDateTime.time().hour(); int minute = currentDateTime.time().minute(); //判断是否为白班 - bool isDayShift = (hour > 8 || (hour == 8 && minute >= 30)) && (hour < 20 || (hour == 20 && minute <= 30)); - //判断是否为前一天 - bool isDayBefore = hour < 8 || (hour == 8 && minute <= 29); + bool isDayShift = (hour > dayShiftHour || (hour == dayShiftHour && minute >= dayShiftMin)) && (hour < nightShiftHour || (hour == nightShiftHour && minute <= nightShiftMin)); + //判断是否为前一天(只有白班可能是前一天的 + bool isDayBefore = hour < nightShiftHour || (hour == nightShiftHour && minute < nightShiftMin); QDateTime lastShiftDateTime; //如果当前为前一天的夜班 那就返回前一天的白班 diff --git a/include/sql/qSqlBase.h b/include/sql/qSqlBase.h index b4563ad..a2a7749 100644 --- a/include/sql/qSqlBase.h +++ b/include/sql/qSqlBase.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -131,8 +133,14 @@ public: bool dropTable(const QString& tableName) { QMutexLocker lock(&db_mutex); - QString sql = QString("DROP TABLE IF EXISTS %1").arg(tableName); - return execute_unsafe(sql); + QString sql = QString("DROP TABLE IF EXISTS \"%1\"").arg(tableName); + QSqlQuery query(db); + if (!query.exec(sql)) { + qCritical() << "SQL error:" << query.lastError().text(); + qCritical() << "Query:" << sql; + return false; + } + return true; } bool addColumn(const QString& tableName, const QString& columnName, const QString& columnType) { @@ -443,15 +451,13 @@ private: } void disconnect() { - QSqlDatabase::removeDatabase(m_connectionName); if (db.isOpen()) { db.close(); qDebug() << "Database closed."; } + QSqlDatabase::removeDatabase(m_connectionName); } QString m_connectionName; QString dbPath; -}; - -#pragma once \ No newline at end of file +}; \ No newline at end of file diff --git a/include/tranlationBuiltInDict.h b/include/tranlationBuiltInDict.h new file mode 100644 index 0000000..ce6ea00 --- /dev/null +++ b/include/tranlationBuiltInDict.h @@ -0,0 +1,2400 @@ +//初始化默认词库 +static void initBuiltInDict(std::vector, std::less<>>>& basicTranslations) { + //KEY 对应语言 翻译(返回值) + std::map> tempMap; +#pragma region 全字匹配字典 + tempMap["AI检测系统"]["zh-CN"] = "AI检测系统"; + tempMap["AI检测系统"]["en-US"] = "AI Detection System"; + tempMap["AI检测系统"]["ms-MY"] = "Sistem Pengesanan AI"; + + tempMap["权限不足"]["zh-CN"] = "权限不足"; + tempMap["权限不足"]["en-US"] = "Insufficient permissions"; + tempMap["权限不足"]["ms-MY"] = "Kebenaran tidak mencukupi"; + + tempMap["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["zh-CN"] = "您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"; + tempMap["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["en-US"] = "You do not have sufficient permissions to perform this action.\n\nRequired level: %1\nCurrent level: %2"; + tempMap["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["ms-MY"] = "Anda tidak mempunyai kebenaran yang mencukupi untuk melaksanakan tindakan ini.\n\nTahap diperlukan: %1\nTahap semasa: %2"; + + tempMap["JSON 表格编辑器"]["zh-CN"] = "JSON 表格编辑器"; + tempMap["JSON 表格编辑器"]["en-US"] = "JSON Table Editor"; + tempMap["JSON 表格编辑器"]["ms-MY"] = "Editor Jadual JSONI"; + + tempMap["通用 JSON 编辑"]["zh-CN"] = "通用 JSON 编辑"; + tempMap["通用 JSON 编辑"]["en-US"] = "General JSON Editor"; + tempMap["通用 JSON 编辑"]["ms-MY"] = "Penyunting JSON Am"; + + tempMap["导出失败"]["zh-CN"] = "导出失败"; + tempMap["导出失败"]["en-US"] = "Export Failed"; + tempMap["导出失败"]["ms-MY"] = "Eksport Gagal"; + + tempMap["售后"]["zh-CN"] = "售后"; + tempMap["售后"]["en-US"] = "After-sales"; + tempMap["售后"]["ms-MY"] = "Perkhidmatan Selepas Jualan"; + + tempMap["所有密码字段都不能为空"]["zh-CN"] = "所有密码字段都不能为空"; + tempMap["所有密码字段都不能为空"]["en-US"] = "All password fields cannot be empty"; + tempMap["所有密码字段都不能为空"]["ms-MY"] = "Semua medan kata laluan tidak boleh kosong"; + + tempMap["确定要执行此操作吗?"]["zh-CN"] = "确定要执行此操作吗?"; + tempMap["确定要执行此操作吗?"]["en-US"] = "Are you sure you want to execute this action?"; + tempMap["确定要执行此操作吗?"]["ms-MY"] = "Adakah anda pasti mahu melaksanakan tindakan ini?"; + + tempMap["自动滚动"]["zh-CN"] = "自动滚动"; + tempMap["自动滚动"]["en-US"] = "Auto Scroll"; + tempMap["自动滚动"]["ms-MY"] = "Tatal Automatik"; + + tempMap["返回目录"]["zh-CN"] = "返回目录"; + tempMap["返回目录"]["en-US"] = "Back to Menu"; + tempMap["返回目录"]["ms-MY"] = "Kembali ke Menu"; + + tempMap["布尔值控件类型错误"]["zh-CN"] = "布尔值控件类型错误"; + tempMap["布尔值控件类型错误"]["en-US"] = "Boolean control type mismatch"; + tempMap["布尔值控件类型错误"]["ms-MY"] = "Jenis kawalan boolean tidak sepadan"; + + tempMap["布尔值只能是 true 或 false"]["zh-CN"] = "布尔值只能是 true 或 false"; + tempMap["布尔值只能是 true 或 false"]["en-US"] = "Boolean must be true or false"; + tempMap["布尔值只能是 true 或 false"]["ms-MY"] = "Boolean mesti true atau false"; + + tempMap["相机标签"]["zh-CN"] = "相机标签"; + tempMap["相机标签"]["en-US"] = "Camera Label"; + tempMap["相机标签"]["ms-MY"] = "Label Kamera"; + + tempMap["取消"]["zh-CN"] = "取消"; + tempMap["取消"]["en-US"] = "Cancel"; + tempMap["取消"]["ms-MY"] = "Batal"; + + tempMap["修改密码"]["zh-CN"] = "修改密码"; + tempMap["修改密码"]["en-US"] = "Change Password"; + tempMap["修改密码"]["ms-MY"] = "Tukar Kata Laluan"; + + tempMap["关闭"]["zh-CN"] = "关闭"; + tempMap["关闭"]["en-US"] = "Close"; + tempMap["关闭"]["ms-MY"] = "Tutup"; + + tempMap["提示"]["zh-CN"] = "提示"; + tempMap["提示"]["en-US"] = "Confirm"; + tempMap["提示"]["ms-MY"] = "Sahkan"; + + tempMap["确认密码:"]["zh-CN"] = "确认密码:"; + tempMap["确认密码:"]["en-US"] = "Confirm Password:"; + tempMap["确认密码:"]["ms-MY"] = "Sahkan Kata Laluan:"; + + tempMap["控制台"]["zh-CN"] = "控制台"; + tempMap["控制台"]["en-US"] = "Console"; + tempMap["控制台"]["ms-MY"] = "Konsol"; + + tempMap["控制台日志..."]["zh-CN"] = "控制台日志..."; + tempMap["控制台日志..."]["en-US"] = "Console Log..."; + tempMap["控制台日志..."]["ms-MY"] = "Log Konsol..."; + + tempMap["控制台设置"]["zh-CN"] = "控制台设置"; + tempMap["控制台设置"]["en-US"] = "Console Settings"; + tempMap["控制台设置"]["ms-MY"] = "Tetapan Konsol"; + + tempMap["转换错误: %1"]["zh-CN"] = "转换错误: %1"; + tempMap["转换错误: %1"]["en-US"] = "Conversion error: %1"; + tempMap["转换错误: %1"]["ms-MY"] = "Ralat penukaran: %1"; + + tempMap["创建用户"]["zh-CN"] = "创建用户"; + tempMap["创建用户"]["en-US"] = "Create User"; + tempMap["创建用户"]["ms-MY"] = "Cipta Pengguna"; + + tempMap["当前密码:"]["zh-CN"] = "当前密码:"; + tempMap["当前密码:"]["en-US"] = "Current Password:"; + tempMap["当前密码:"]["ms-MY"] = "Kata Laluan Semasa:"; + + tempMap["本次运行数据"]["zh-CN"] = "本次运行数据"; + tempMap["本次运行数据"]["en-US"] = "Current Run Data"; + tempMap["本次运行数据"]["ms-MY"] = "Data Larian Semasa"; + + tempMap["当前用户信息"]["zh-CN"] = "当前用户信息"; + tempMap["当前用户信息"]["en-US"] = "Current User Information"; + tempMap["当前用户信息"]["ms-MY"] = "Maklumat Pengguna Semasa"; + + tempMap["当前用户: "]["zh-CN"] = "当前用户: "; + tempMap["当前用户: "]["en-US"] = "Current User: "; + tempMap["当前用户: "]["ms-MY"] = "Pengguna Semasa: "; + + tempMap["当前用户: 未登录"]["zh-CN"] = "当前用户: 未登录"; + tempMap["当前用户: 未登录"]["en-US"] = "Current User: Not logged in"; + tempMap["当前用户: 未登录"]["ms-MY"] = "Pengguna Semasa: Tidak log masuk"; + + tempMap["已注销当前用户"]["zh-CN"] = "已注销当前用户"; + tempMap["已注销当前用户"]["en-US"] = "Current user logged out"; + tempMap["已注销当前用户"]["ms-MY"] = "Pengguna semasa telah log keluar"; + + tempMap["当前版本: v%1"]["zh-CN"] = "当前版本: v%1"; + tempMap["当前版本: v%1"]["en-US"] = "Current version: v%1"; + tempMap["当前版本: v%1"]["ms-MY"] = "Versi semasa: v%1"; + + tempMap["数据已成功导出到:\n"]["zh-CN"] = "数据已成功导出到:\n"; + tempMap["数据已成功导出到:\n"]["en-US"] = "Data successfully exported to:\n"; + tempMap["数据已成功导出到:\n"]["ms-MY"] = "Data berjaya dieksport ke:\n"; + + tempMap["数据库操作界面"]["zh-CN"] = "数据库操作界面"; + tempMap["数据库操作界面"]["en-US"] = "Database Operations"; + tempMap["数据库操作界面"]["ms-MY"] = "Operasi Pangkalan Data"; + + tempMap["故障排查"]["zh-CN"] = "故障排查"; + tempMap["故障排查"]["en-US"] = "Debug"; + tempMap["故障排查"]["ms-MY"] = "Penyelesaian Masalah"; + + tempMap["默认标题"]["zh-CN"] = "默认标题"; + tempMap["默认标题"]["en-US"] = "Default Title"; + tempMap["默认标题"]["ms-MY"] = "Tajuk Lalai"; + + tempMap["正在检测..."]["zh-CN"] = "正在检测..."; + tempMap["正在检测..."]["en-US"] = "Detecting..."; + tempMap["正在检测..."]["ms-MY"] = "Mengesan..."; + + tempMap["是否退出程序?"]["zh-CN"] = "是否退出程序?"; + tempMap["是否退出程序?"]["en-US"] = "Do you want to exit the application?"; + tempMap["是否退出程序?"]["ms-MY"] = "Adakah anda mahu keluar daripada aplikasi?"; + + tempMap["编辑参数"]["zh-CN"] = "编辑参数"; + tempMap["编辑参数"]["en-US"] = "Edit Parameters"; + tempMap["编辑参数"]["ms-MY"] = "Sunting Parameter"; + + tempMap["工程师"]["zh-CN"] = "工程师"; + tempMap["工程师"]["en-US"] = "Engineer"; + tempMap["工程师"]["ms-MY"] = "Jurutera"; + + tempMap["输入 Y 或 y"]["zh-CN"] = "输入 Y 或 y"; + tempMap["输入 Y 或 y"]["en-US"] = "Enter Y or y"; + tempMap["输入 Y 或 y"]["ms-MY"] = "Masukkan Y atau y"; + + tempMap["输入布尔值(true 或 false)"]["zh-CN"] = "输入布尔值(true 或 false)"; + tempMap["输入布尔值(true 或 false)"]["en-US"] = "Enter a boolean value (true or false)"; + tempMap["输入布尔值(true 或 false)"]["ms-MY"] = "Masukkan nilai boolean (true atau false)"; + + tempMap["输入数字值(小数)"]["zh-CN"] = "输入数字值(小数)"; + tempMap["输入数字值(小数)"]["en-US"] = "Enter a decimal value"; + tempMap["输入数字值(小数)"]["ms-MY"] = "Masukkan nilai perpuluhan"; + + tempMap["输入数字值(整数或小数)"]["zh-CN"] = "输入数字值(整数或小数)"; + tempMap["输入数字值(整数或小数)"]["en-US"] = "Enter a numeric value (integer or decimal)"; + tempMap["输入数字值(整数或小数)"]["ms-MY"] = "Masukkan nilai nombor (integer atau perpuluhan)"; + + tempMap["输入字符串值(不需要引号)"]["zh-CN"] = "输入字符串值(不需要引号)"; + tempMap["输入字符串值(不需要引号)"]["en-US"] = "Enter a string value (no quotes required)"; + tempMap["输入字符串值(不需要引号)"]["ms-MY"] = "Masukkan nilai rentetan (tidak perlu tanda petik)"; + + tempMap["输入数字值(整数)"]["zh-CN"] = "输入数字值(整数)"; + tempMap["输入数字值(整数)"]["en-US"] = "Enter an integer value"; + tempMap["输入数字值(整数)"]["ms-MY"] = "Masukkan nilai integer"; + + tempMap["错误"]["zh-CN"] = "错误"; + tempMap["错误"]["en-US"] = "Error"; + tempMap["错误"]["ms-MY"] = "Ralat"; + + tempMap["执行命令"]["zh-CN"] = "执行命令"; + tempMap["执行命令"]["en-US"] = "Execute Command"; + tempMap["执行命令"]["ms-MY"] = "Jalankan Perintah"; + + tempMap["退出"]["zh-CN"] = "退出"; + tempMap["退出"]["en-US"] = "Exit"; + tempMap["退出"]["ms-MY"] = "Keluar"; + + tempMap["退出确认"]["zh-CN"] = "退出确认"; + tempMap["退出确认"]["en-US"] = "Exit Confirmation"; + tempMap["退出确认"]["ms-MY"] = "Pengesahan Keluar"; + + tempMap["退出中,请稍后"]["zh-CN"] = "退出中,请稍后"; + tempMap["退出中,请稍后"]["en-US"] = "Exiting, please wait"; + tempMap["退出中,请稍后"]["ms-MY"] = "Keluar, sila tunggu sebentar"; + + tempMap["正在退出..."]["zh-CN"] = "正在退出..."; + tempMap["正在退出..."]["en-US"] = "Exiting..."; + tempMap["正在退出..."]["ms-MY"] = "Keluar..."; + + tempMap["导出"]["zh-CN"] = "导出"; + tempMap["导出"]["en-US"] = "Export"; + tempMap["导出"]["ms-MY"] = "Eksport"; + + tempMap["导出失败"]["zh-CN"] = "导出失败"; + tempMap["导出失败"]["en-US"] = "Export Failed"; + tempMap["导出失败"]["ms-MY"] = "Eksport Gagal"; + + tempMap["导出成功"]["zh-CN"] = "导出成功"; + tempMap["导出成功"]["en-US"] = "Export Successful"; + tempMap["导出成功"]["ms-MY"] = "Eksport Berjaya"; + + tempMap["导出为CSV"]["zh-CN"] = "导出为CSV"; + tempMap["导出为CSV"]["en-US"] = "Export as CSV"; + tempMap["导出为CSV"]["ms-MY"] = "Eksport sebagai CSV"; + + tempMap["导出CSV文件失败,请检查路径或数据库状态。"]["zh-CN"] = "导出CSV文件失败,请检查路径或数据库状态。"; + tempMap["导出CSV文件失败,请检查路径或数据库状态。"]["en-US"] = "Failed to export CSV. Please check the path or database status."; + tempMap["导出CSV文件失败,请检查路径或数据库状态。"]["ms-MY"] = "Gagal mengeksport CSV. Sila semak laluan atau status pangkalan data."; + + tempMap["通用 JSON 编辑"]["zh-CN"] = "通用 JSON 编辑"; + tempMap["通用 JSON 编辑"]["en-US"] = "General JSON Editor"; + tempMap["通用 JSON 编辑"]["ms-MY"] = "Penyunting JSON Am"; + + tempMap["获取值错误: %1"]["zh-CN"] = "获取值错误: %1"; + tempMap["获取值错误: %1"]["en-US"] = "Get value error: %1"; + tempMap["获取值错误: %1"]["ms-MY"] = "Ralat mendapat nilai: %1"; + + tempMap["返回上一级"]["zh-CN"] = "返回上一级"; + tempMap["返回上一级"]["en-US"] = "Go Back"; + tempMap["返回上一级"]["ms-MY"] = "Kembali"; + + tempMap["访客"]["zh-CN"] = "访客"; + tempMap["访客"]["en-US"] = "Guest"; + tempMap["访客"]["ms-MY"] = "Tetamu"; + + tempMap["硬件信息"]["zh-CN"] = "硬件信息"; + tempMap["硬件信息"]["en-US"] = "Hardware Information"; + tempMap["硬件信息"]["ms-MY"] = "Maklumat Perkakasan"; + + tempMap["历史记录"]["zh-CN"] = "历史记录"; + tempMap["历史记录"]["en-US"] = "History"; + tempMap["历史记录"]["ms-MY"] = "Sejarah"; + + tempMap["正在初始化..."]["zh-CN"] = "正在初始化..."; + tempMap["正在初始化..."]["en-US"] = "Initializing..."; + tempMap["正在初始化..."]["ms-MY"] = "Memulakan..."; + + tempMap["输入值过大(超过10240字符)"]["zh-CN"] = "输入值过大(超过10240字符)"; + tempMap["输入值过大(超过10240字符)"]["en-US"] = "Input value too large (exceeds 10240 characters)"; + tempMap["输入值过大(超过10240字符)"]["ms-MY"] = "Nilai input terlalu besar (melebihi 10240 aksara)"; + + tempMap["数字控件INT类型错误"]["zh-CN"] = "数字控件INT类型错误"; + tempMap["数字控件INT类型错误"]["en-US"] = "Integer number control type mismatch"; + tempMap["数字控件INT类型错误"]["ms-MY"] = "Jenis kawalan nombor integer tidak sepadan"; + + tempMap["无效的数字格式"]["zh-CN"] = "无效的数字格式"; + tempMap["无效的数字格式"]["en-US"] = "Invalid numeric format"; + tempMap["无效的数字格式"]["ms-MY"] = "Format nombor tidak sah"; + + tempMap["JSON 表格编辑器"]["zh-CN"] = "JSON 表格编辑器"; + tempMap["JSON 表格编辑器"]["en-US"] = "JSON Table Editor"; + tempMap["JSON 表格编辑器"]["ms-MY"] = "Editor Jadual JSON"; + + tempMap["JSON 内容不能为空"]["zh-CN"] = "JSON 内容不能为空"; + tempMap["JSON 内容不能为空"]["en-US"] = "JSON content cannot be empty"; + tempMap["JSON 内容不能为空"]["ms-MY"] = "Kandungan JSON tidak boleh kosong"; + + tempMap["JSON 内容过大,可能导致崩溃"]["zh-CN"] = "JSON 内容过大,可能导致崩溃"; + tempMap["JSON 内容过大,可能导致崩溃"]["en-US"] = "JSON content is too large and may cause a crash"; + tempMap["JSON 内容过大,可能导致崩溃"]["ms-MY"] = "Kandungan JSON terlalu besar dan mungkin menyebabkan kerosakan"; + + tempMap["JSON解析错误: %1"]["zh-CN"] = "JSON解析错误: %1"; + tempMap["JSON解析错误: %1"]["en-US"] = "JSON parse error: %1"; + tempMap["JSON解析错误: %1"]["ms-MY"] = "Ralat parse JSON: %1"; + + tempMap["JSON 解析失败:\n%1"]["zh-CN"] = "JSON 解析失败:\n%1"; + tempMap["JSON 解析失败:\n%1"]["en-US"] = "JSON parse failed:\n%1"; + tempMap["JSON 解析失败:\n%1"]["ms-MY"] = "Parse JSON gagal:\n%1"; + + tempMap["语言设置"]["zh-CN"] = "语言设置"; + tempMap["语言设置"]["en-US"] = "Language Settings"; + tempMap["语言设置"]["ms-MY"] = "Tetapan Bahasa"; + + tempMap["长度"]["zh-CN"] = "长度"; + tempMap["长度"]["en-US"] = "Length"; + tempMap["长度"]["ms-MY"] = "Panjang"; + + tempMap["日志分析"]["zh-CN"] = "日志分析"; + tempMap["日志分析"]["en-US"] = "Log"; + tempMap["日志分析"]["ms-MY"] = "Analisis Log"; + + tempMap["登录"]["zh-CN"] = "登录"; + tempMap["登录"]["en-US"] = "Login"; + tempMap["登录"]["ms-MY"] = "Log Masuk"; + + tempMap["登录失败,请检查用户名和密码"]["zh-CN"] = "登录失败,请检查用户名和密码"; + tempMap["登录失败,请检查用户名和密码"]["en-US"] = "Login failed, please check username and password"; + tempMap["登录失败,请检查用户名和密码"]["ms-MY"] = "Log masuk gagal, sila periksa nama pengguna dan kata laluan"; + + tempMap["登录成功!系统将在3分钟后自动注销"]["zh-CN"] = "登录成功!系统将在3分钟后自动注销"; + tempMap["登录成功!系统将在3分钟后自动注销"]["en-US"] = "Login successful! System will auto logout in 3 minutes"; + tempMap["登录成功!系统将在3分钟后自动注销"]["ms-MY"] = "Log masuk berjaya! Sistem akan auto log keluar dalam 3 minit"; + + tempMap["登录/注销"]["zh-CN"] = "登录/注销"; + tempMap["登录/注销"]["en-US"] = "Login/Logout"; + tempMap["登录/注销"]["ms-MY"] = "Log Masuk/Log Keluar"; + + tempMap["注销"]["zh-CN"] = "注销"; + tempMap["注销"]["en-US"] = "Logout"; + tempMap["注销"]["ms-MY"] = "Log Keluar"; + + tempMap["监控错误: %1"]["zh-CN"] = "监控错误: %1"; + tempMap["监控错误: %1"]["en-US"] = "Monitor error: %1"; + tempMap["监控错误: %1"]["ms-MY"] = "Ralat pemantauan: %1"; + + tempMap["监控异常"]["zh-CN"] = "监控异常"; + tempMap["监控异常"]["en-US"] = "Monitoring Error"; + tempMap["监控异常"]["ms-MY"] = "Ralat Pemantauan"; + + tempMap["NG数量"]["zh-CN"] = "NG数量"; + tempMap["NG数量"]["en-US"] = "NG Count"; + tempMap["NG数量"]["ms-MY"] = "Kiraan NG"; + + tempMap["新密码:"]["zh-CN"] = "新密码:"; + tempMap["新密码:"]["en-US"] = "New Password:"; + tempMap["新密码:"]["ms-MY"] = "Kata Laluan Baru:"; + + tempMap["新密码和确认密码不匹配"]["zh-CN"] = "新密码和确认密码不匹配"; + tempMap["新密码和确认密码不匹配"]["en-US"] = "New password and confirm password do not match"; + tempMap["新密码和确认密码不匹配"]["ms-MY"] = "Kata laluan baru dan pengesahan kata laluan tidak sepadan"; + + tempMap["新密码长度至少为4位"]["zh-CN"] = "新密码长度至少为4位"; + tempMap["新密码长度至少为4位"]["en-US"] = "New password must be at least 4 characters"; + tempMap["新密码长度至少为4位"]["ms-MY"] = "Kata laluan baru mestilah sekurang-kurangnya 4 aksara"; + + tempMap["空值(输入 null)"]["zh-CN"] = "空值(输入 null)"; + tempMap["空值(输入 null)"]["en-US"] = "Null (enter null)"; + tempMap["空值(输入 null)"]["ms-MY"] = "Null (masukkan null)"; + + tempMap["空值只能是 null"]["zh-CN"] = "空值只能是 null"; + tempMap["空值只能是 null"]["en-US"] = "Null value must be null"; + tempMap["空值只能是 null"]["ms-MY"] = "Nilai null mesti null"; + + tempMap["数字控件类型错误"]["zh-CN"] = "数字控件类型错误"; + tempMap["数字控件类型错误"]["en-US"] = "Number control type mismatch"; + tempMap["数字控件类型错误"]["ms-MY"] = "Jenis kawalan nombor tidak sepadan"; + + tempMap["确定"]["zh-CN"] = "确定"; + tempMap["确定"]["en-US"] = "OK"; + tempMap["确定"]["ms-MY"] = "OK"; + + tempMap["OK数量"]["zh-CN"] = "OK数量"; + tempMap["OK数量"]["en-US"] = "OK Count"; + tempMap["OK数量"]["ms-MY"] = "Kiraan OK"; + + tempMap["离线模式"]["zh-CN"] = "离线模式"; + tempMap["离线模式"]["en-US"] = "Offline Mode"; + tempMap["离线模式"]["ms-MY"] = "Mod Luar Talian"; + + tempMap["打开日志文件夹"]["zh-CN"] = "打开日志文件夹"; + tempMap["打开日志文件夹"]["en-US"] = "Open Log Folder"; + tempMap["打开日志文件夹"]["ms-MY"] = "Buka Folder Log"; + + tempMap["选项"]["zh-CN"] = "选项"; + tempMap["选项"]["en-US"] = "Option"; + tempMap["选项"]["ms-MY"] = "Pilihan"; + + tempMap["第 %1 行找不到原始类型信息"]["zh-CN"] = "第 %1 行找不到原始类型信息"; + tempMap["第 %1 行找不到原始类型信息"]["en-US"] = "Original type information not found for row %1"; + tempMap["第 %1 行找不到原始类型信息"]["ms-MY"] = "Maklumat jenis asal tidak ditemui untuk baris %1"; + + tempMap["参数设置"]["zh-CN"] = "参数设置"; + tempMap["参数设置"]["en-US"] = "Param"; + tempMap["参数设置"]["ms-MY"] = "Tetapan Parameter"; + + tempMap["编辑参数"]["zh-CN"] = "编辑参数"; + tempMap["编辑参数"]["en-US"] = "Param Edit"; + tempMap["编辑参数"]["ms-MY"] = "Sunting Parameter"; + + tempMap["解析错误"]["zh-CN"] = "解析错误"; + tempMap["解析错误"]["en-US"] = "Parse Error"; + tempMap["解析错误"]["ms-MY"] = "Ralat Parse"; + + tempMap["密码修改失败,请检查当前密码"]["zh-CN"] = "密码修改失败,请检查当前密码"; + tempMap["密码修改失败,请检查当前密码"]["en-US"] = "Password change failed, please check current password"; + tempMap["密码修改失败,请检查当前密码"]["ms-MY"] = "Penukaran kata laluan gagal, sila periksa kata laluan semasa"; + + tempMap["密码修改成功!"]["zh-CN"] = "密码修改成功!"; + tempMap["密码修改成功!"]["en-US"] = "Password changed successfully!"; + tempMap["密码修改成功!"]["ms-MY"] = "Kata laluan berjaya ditukar!"; + + tempMap["密码长度至少为4位"]["zh-CN"] = "密码长度至少为4位"; + tempMap["密码长度至少为4位"]["en-US"] = "Password must be at least 4 characters"; + tempMap["密码长度至少为4位"]["ms-MY"] = "Kata laluan mestilah sekurang-kurangnya 4 aksara"; + + tempMap["密码:"]["zh-CN"] = "密码:"; + tempMap["密码:"]["en-US"] = "Password:"; + tempMap["密码:"]["ms-MY"] = "Kata Laluan:"; + + tempMap["待读取"]["zh-CN"] = "待读取"; + tempMap["待读取"]["en-US"] = "Pending"; + tempMap["待读取"]["ms-MY"] = "Tertunda"; + + tempMap["权限等级:"]["zh-CN"] = "权限等级:"; + tempMap["权限等级:"]["en-US"] = "Permission Level:"; + tempMap["权限等级:"]["ms-MY"] = "Tahap Kebenaran:"; + + tempMap["权限等级: "]["zh-CN"] = "权限等级: "; + tempMap["权限等级: "]["en-US"] = "Permission Level: "; + tempMap["权限等级: "]["ms-MY"] = "Tahap Kebenaran: "; + + tempMap["权限等级: 访客"]["zh-CN"] = "权限等级: 访客"; + tempMap["权限等级: 访客"]["en-US"] = "Permission Level: Guest"; + tempMap["权限等级: 访客"]["ms-MY"] = "Tahap Kebenaran: Tetamu"; + + tempMap["请先创建用户"]["zh-CN"] = "请先创建用户"; + tempMap["请先创建用户"]["en-US"] = "Please create user first"; + tempMap["请先创建用户"]["ms-MY"] = "Sila cipta pengguna dahulu"; + + tempMap["请输入 JSON:"]["zh-CN"] = "请输入 JSON:"; + tempMap["请输入 JSON:"]["en-US"] = "Please enter JSON:"; + tempMap["请输入 JSON:"]["ms-MY"] = "Sila masukkan JSON:"; + + tempMap["请输入 Y 或 y 以退出(%1 秒后取消)"]["zh-CN"] = "请输入 Y 或 y 以退出(%1 秒后取消)"; + tempMap["请输入 Y 或 y 以退出(%1 秒后取消)"]["en-US"] = "Please enter Y or y to exit (will cancel after %1 sec)"; + tempMap["请输入 Y 或 y 以退出(%1 秒后取消)"]["ms-MY"] = "Sila masukkan Y atau y untuk keluar (akan batal selepas %1 saat)"; + + tempMap["请输入有效的JSON值"]["zh-CN"] = "请输入有效的JSON值"; + tempMap["请输入有效的JSON值"]["en-US"] = "Please enter a valid JSON value"; + tempMap["请输入有效的JSON值"]["ms-MY"] = "Sila masukkan nilai JSON yang sah"; + + tempMap["生产数据采集"]["zh-CN"] = "生产数据采集"; + tempMap["生产数据采集"]["en-US"] = "Production Data Collection"; + tempMap["生产数据采集"]["ms-MY"] = "Pengumpulan Data Pengeluaran"; + + tempMap["刷新"]["zh-CN"] = "刷新"; + tempMap["刷新"]["en-US"] = "Refresh"; + tempMap["刷新"]["ms-MY"] = "Segarkan"; + + tempMap["重新进行初始化"]["zh-CN"] = "重新进行初始化"; + tempMap["重新进行初始化"]["en-US"] = "Reinitialize"; + tempMap["重新进行初始化"]["ms-MY"] = "Inisialisasi Semula"; + + tempMap["剩余: "]["zh-CN"] = "剩余: "; + tempMap["剩余: "]["en-US"] = "Remaining: "; + tempMap["剩余: "]["ms-MY"] = "Baki: "; + + tempMap["重试"]["zh-CN"] = "重试"; + tempMap["重试"]["en-US"] = "Retry"; + tempMap["重试"]["ms-MY"] = "Cuba Semula"; + + tempMap["第 %1 行数据不完整"]["zh-CN"] = "第 %1 行数据不完整"; + tempMap["第 %1 行数据不完整"]["en-US"] = "Row %1 data is incomplete"; + tempMap["第 %1 行数据不完整"]["ms-MY"] = "Data baris %1 tidak lengkap"; + + tempMap["第 %1 行 key 为空"]["zh-CN"] = "第 %1 行 key 为空"; + tempMap["第 %1 行 key 为空"]["en-US"] = "Row %1 key is empty"; + tempMap["第 %1 行 key 为空"]["ms-MY"] = "Kekunci baris %1 kosong"; + + tempMap["第 %1 行值验证失败:\n%2"]["zh-CN"] = "第 %1 行值验证失败:\n%2"; + tempMap["第 %1 行值验证失败:\n%2"]["en-US"] = "Row %1 value validation failed:\n%2"; + tempMap["第 %1 行值验证失败:\n%2"]["ms-MY"] = "Pengesahan nilai baris %1 gagal:\n%2"; + + tempMap["运行数据"]["zh-CN"] = "运行数据"; + tempMap["运行数据"]["en-US"] = "Run Data"; + tempMap["运行数据"]["ms-MY"] = "Data Larian"; + + tempMap["SN查询"]["zh-CN"] = "SN查询"; + tempMap["SN查询"]["en-US"] = "SN Search"; + tempMap["SN查询"]["ms-MY"] = "Carian SN"; + + tempMap["保存"]["zh-CN"] = "保存"; + tempMap["保存"]["en-US"] = "Save"; + tempMap["保存"]["ms-MY"] = "Simpan"; + + tempMap["查询"]["zh-CN"] = "查询"; + tempMap["查询"]["en-US"] = "Search"; + tempMap["查询"]["ms-MY"] = "Carian"; + + tempMap["服务已离线"]["zh-CN"] = "服务已离线"; + tempMap["服务已离线"]["en-US"] = "Service is offline"; + tempMap["服务已离线"]["ms-MY"] = "Perkhidmatan luar talian"; + + tempMap["设置"]["zh-CN"] = "设置"; + tempMap["设置"]["en-US"] = "Setting"; + tempMap["设置"]["ms-MY"] = "Tetapan"; + + tempMap["班次"]["zh-CN"] = "班次"; + tempMap["班次"]["en-US"] = "Shift"; + tempMap["班次"]["ms-MY"] = "Syif"; + + tempMap["字符串控件类型错误"]["zh-CN"] = "字符串控件类型错误"; + tempMap["字符串控件类型错误"]["en-US"] = "String control type mismatch"; + tempMap["字符串控件类型错误"]["ms-MY"] = "Jenis kawalan rentetan tidak sepadan"; + + tempMap["成功"]["zh-CN"] = "成功"; + tempMap["成功"]["en-US"] = "Success"; + tempMap["成功"]["ms-MY"] = "Berjaya"; + + tempMap["系统日志"]["zh-CN"] = "系统日志"; + tempMap["系统日志"]["en-US"] = "System Log"; + tempMap["系统日志"]["ms-MY"] = "Log Sistem"; + + tempMap["系统状态: %1\n"]["zh-CN"] = "系统状态: %1\n"; + tempMap["系统状态: %1\n"]["en-US"] = "System status: %1\n"; + tempMap["系统状态: %1\n"]["ms-MY"] = "Status sistem: %1\n"; + + tempMap["工具"]["zh-CN"] = "工具"; + tempMap["工具"]["en-US"] = "TOOLS"; + tempMap["工具"]["ms-MY"] = "Alat"; + + tempMap["已超时"]["zh-CN"] = "已超时"; + tempMap["已超时"]["en-US"] = "Timed out"; + tempMap["已超时"]["ms-MY"] = "Masa tamat"; + + tempMap["总数量"]["zh-CN"] = "总数量"; + tempMap["总数量"]["en-US"] = "Total Count"; + tempMap["总数量"]["ms-MY"] = "Jumlah Kiraan"; + + tempMap["类型验证失败"]["zh-CN"] = "类型验证失败"; + tempMap["类型验证失败"]["en-US"] = "Type Validation Failed"; + tempMap["类型验证失败"]["ms-MY"] = "Pengesahan Jenis Gagal"; + + tempMap["未知的数据类型"]["zh-CN"] = "未知的数据类型"; + tempMap["未知的数据类型"]["en-US"] = "Unknown data type"; + tempMap["未知的数据类型"]["ms-MY"] = "Jenis data tidak diketahui"; + + tempMap["用户管理"]["zh-CN"] = "用户管理"; + tempMap["用户管理"]["en-US"] = "User Management"; + tempMap["用户管理"]["ms-MY"] = "Pengurusan Pengguna"; + + tempMap["用户创建成功!"]["zh-CN"] = "用户创建成功!"; + tempMap["用户创建成功!"]["en-US"] = "User created successfully!"; + tempMap["用户创建成功!"]["ms-MY"] = "Pengguna berjaya dicipta!"; + + tempMap["用户创建失败,用户名可能已存在"]["zh-CN"] = "用户创建失败,用户名可能已存在"; + tempMap["用户创建失败,用户名可能已存在"]["en-US"] = "User creation failed, username may already exist"; + tempMap["用户创建失败,用户名可能已存在"]["ms-MY"] = "Penciptaan pengguna gagal, nama pengguna mungkin sudah wujud"; + + tempMap["用户名和密码不能为空"]["zh-CN"] = "用户名和密码不能为空"; + tempMap["用户名和密码不能为空"]["en-US"] = "Username and password cannot be empty"; + tempMap["用户名和密码不能为空"]["ms-MY"] = "Nama pengguna dan kata laluan tidak boleh kosong"; + + tempMap["用户名:"]["zh-CN"] = "用户名:"; + tempMap["用户名:"]["en-US"] = "Username:"; + tempMap["用户名:"]["ms-MY"] = "Nama Pengguna:"; + + tempMap["值"]["zh-CN"] = "值"; + tempMap["值"]["en-US"] = "Value"; + tempMap["值"]["ms-MY"] = "Nilai"; + + tempMap["值:"]["zh-CN"] = "值:"; + tempMap["值:"]["en-US"] = "Value:"; + tempMap["值:"]["ms-MY"] = "Nilai:"; + + tempMap["预览参数"]["zh-CN"] = "预览参数"; + tempMap["预览参数"]["en-US"] = "View Param"; + tempMap["预览参数"]["ms-MY"] = "Lihat Parameter"; + + tempMap["查看图片"]["zh-CN"] = "查看图片"; + tempMap["查看图片"]["en-US"] = "View Image"; + tempMap["查看图片"]["ms-MY"] = "Lihat Imej"; + + tempMap["警告"]["zh-CN"] = "警告"; + tempMap["警告"]["en-US"] = "Warning"; + tempMap["警告"]["ms-MY"] = "Amaran"; + + tempMap["欢迎!"]["zh-CN"] = "欢迎!"; + tempMap["欢迎!"]["en-US"] = "Welcome!"; + tempMap["欢迎!"]["ms-MY"] = "Selamat Datang!"; + + tempMap["宽度:"]["zh-CN"] = "宽度:"; + tempMap["宽度:"]["en-US"] = "Width:"; + tempMap["宽度:"]["ms-MY"] = "Lebar:"; + + tempMap["窗口设置"]["zh-CN"] = "窗口设置"; + tempMap["窗口设置"]["en-US"] = "Window Settings"; + tempMap["窗口设置"]["ms-MY"] = "Tetapan Tetingkap"; + + tempMap["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["zh-CN"] = "您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"; + tempMap["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["en-US"] = "You do not have sufficient permissions to perform this action.\n\nRequired level: %1\nCurrent level: %2"; + tempMap["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["ms-MY"] = "Anda tidak mempunyai kebenaran yang mencukupi untuk melaksanakan tindakan ini.\n\nTahap diperlukan: %1\nTahap semasa: %2"; + + tempMap["您需要管理员权限才能创建用户"]["zh-CN"] = "您需要管理员权限才能创建用户"; + tempMap["您需要管理员权限才能创建用户"]["en-US"] = "You need administrator permissions to create users"; + tempMap["您需要管理员权限才能创建用户"]["ms-MY"] = "Anda memerlukan kebenaran pentadbir untuk mencipta pengguna"; + + tempMap["放大窗口"]["zh-CN"] = "放大窗口"; + tempMap["放大窗口"]["en-US"] = "Zoom In"; + tempMap["放大窗口"]["ms-MY"] = "Zum Masuk"; + + tempMap["缩小窗口"]["zh-CN"] = "缩小窗口"; + tempMap["缩小窗口"]["en-US"] = "Zoom Out"; + tempMap["缩小窗口"]["ms-MY"] = "Zum Keluar"; + + tempMap["隐藏控制台"]["zh-CN"] = "隐藏控制台"; + tempMap["隐藏控制台"]["en-US"] = "Hide Console"; + tempMap["隐藏控制台"]["ms-MY"] = "Sembunyikan Konsol"; + + tempMap["刷新"]["zh-CN"] = "刷新"; + tempMap["刷新"]["en-US"] = "Refresh"; + tempMap["刷新"]["ms-MY"] = "Segarkan"; + + tempMap["显示控制台"]["zh-CN"] = "显示控制台"; + tempMap["显示控制台"]["en-US"] = "Show Console"; + tempMap["显示控制台"]["ms-MY"] = "Tunjukkan Konsol"; + + tempMap["重启后将会更改"]["zh-CN"] = "重启后将会更改"; + tempMap["重启后将会更改"]["en-US"] = "will change after restart"; + tempMap["重启后将会更改"]["ms-MY"] = "Akan berubah selepas restart"; + + tempMap["退出确认"]["zh-CN"] = "退出确认"; + tempMap["退出确认"]["en-US"] = "Exit Confirmation"; + tempMap["退出确认"]["ms-MY"] = "Pengesahan Keluar"; + + tempMap["选择语言"]["zh-CN"] = "选择语言:"; + tempMap["选择语言"]["en-US"] = "Language:"; + tempMap["选择语言"]["ms-MY"] = "Bahasa"; + + tempMap["打开日志目录"]["zh-CN"] = "打开日志目录"; + tempMap["打开日志目录"]["en-US"] = "Open Log Directory"; + tempMap["打开日志目录"]["ms-MY"] = "Buka Direktori Log"; + + tempMap["控制调试控制台窗口的可见性"]["zh-CN"] = "控制调试控制台窗口的可见性"; + tempMap["控制调试控制台窗口的可见性"]["en-US"] = "Control the visibility of the debug console window"; + tempMap["控制调试控制台窗口的可见性"]["ms-MY"] = "Kawal keterlihatan tetingkap konsol debug"; + + tempMap["工具箱"]["zh-CN"] = "工具箱"; + tempMap["工具箱"]["en-US"] = "Toolbox"; + tempMap["工具箱"]["ms-MY"] = "Kotak Alat"; + + tempMap["设置"]["zh-CN"] = "设置"; + tempMap["设置"]["en-US"] = "Settings"; + tempMap["设置"]["ms-MY"] = "Tetapan"; + + tempMap["打开配置文件"]["zh-CN"] = "打开配置文件"; + tempMap["打开配置文件"]["en-US"] = "Open Config File"; + tempMap["打开配置文件"]["ms-MY"] = "Buka Fail Konfigurasi"; + + tempMap["摄像头实时捕获(仅软触发)"]["zh-CN"] = "摄像头实时捕获(仅软触发)"; + tempMap["摄像头实时捕获(仅软触发)"]["en-US"] = "Camera Real-time Capture (soft-trigger only)"; + tempMap["摄像头实时捕获(仅软触发)"]["ms-MY"] = "Tangkapan Masa Nyata Kamera (hanya pencetus lembut)"; + + tempMap["九点校准"]["zh-CN"] = "九点校准"; + tempMap["九点校准"]["en-US"] = "Nine-Point Calibration"; + tempMap["九点校准"]["ms-MY"] = "Penentukuran Sembilan Titik"; + + tempMap["CSV 文件 (*.csv)"]["zh-CN"] = "CSV 文件 (*.csv)"; + tempMap["CSV 文件 (*.csv)"]["en-US"] = "CSV File (*.csv)"; + tempMap["CSV 文件 (*.csv)"]["ms-MY"] = ""; + + tempMap["停止取流"]["zh-CN"] = "停止取流"; + tempMap["停止取流"]["en-US"] = "Stop Grabbing"; + tempMap["停止取流"]["ms-MY"] = "Hentikan Tangkapan"; + + tempMap["开始取流"]["zh-CN"] = "开始取流"; + tempMap["开始取流"]["en-US"] = "Start Grabbing"; + tempMap["开始取流"]["ms-MY"] = "Mulakan Tangkapan"; + + tempMap["提示"]["zh-CN"] = "提示"; + tempMap["提示"]["en-US"] = "Notice"; + tempMap["提示"]["ms-MY"] = "Notis"; + + tempMap["没有可保存的图像"]["zh-CN"] = "没有可保存的图像"; + tempMap["没有可保存的图像"]["en-US"] = "No image available to save"; + tempMap["没有可保存的图像"]["ms-MY"] = "Tiada imej untuk disimpan"; + + tempMap["保存失败"]["zh-CN"] = "保存失败"; + tempMap["保存失败"]["en-US"] = "Save Failed"; + tempMap["保存失败"]["ms-MY"] = "Gagal Menyimpan"; + + tempMap["无法将图像保存到所选位置"]["zh-CN"] = "无法将图像保存到所选位置"; + tempMap["无法将图像保存到所选位置"]["en-US"] = "Unable to save image to selected location"; + tempMap["无法将图像保存到所选位置"]["ms-MY"] = "Tidak dapat menyimpan imej ke lokasi yang dipilih"; + + tempMap["刷新相机"]["zh-CN"] = "刷新相机"; + tempMap["刷新相机"]["en-US"] = "Refresh Cameras"; + tempMap["刷新相机"]["ms-MY"] = "Muat Semula Kamera"; + + tempMap["保存图片"]["zh-CN"] = "保存图片"; + tempMap["保存图片"]["en-US"] = "Save Image"; + tempMap["保存图片"]["ms-MY"] = "Simpan Imej"; + + tempMap["实时取流"]["zh-CN"] = "实时取流"; + tempMap["实时取流"]["en-US"] = "Real-time Grabbing"; + tempMap["实时取流"]["ms-MY"] = "Tangkapan Masa Nyata"; + + tempMap["导出数据到CSV"]["zh-CN"] = "导出数据到CSV"; + tempMap["导出数据到CSV"]["en-US"] = "Export data to CSV"; + tempMap["导出数据到CSV"]["ms-MY"] = "Eksport data ke CSV"; + + tempMap["生产统计:"]["zh-CN"] = "生产统计:"; + tempMap["生产统计:"]["en-US"] = "Production Statistics:"; + tempMap["生产统计:"]["ms-MY"] = "Statistik Pengeluaran:"; + + tempMap["清零"]["zh-CN"] = "清零"; + tempMap["清零"]["en-US"] = "Reset"; + tempMap["清零"]["ms-MY"] = "Tetapkan Semula"; + + tempMap["确认清零"]["zh-CN"] = "确认清零"; + tempMap["确认清零"]["en-US"] = "Confirm Reset"; + tempMap["确认清零"]["ms-MY"] = "Sahkan Tetapan Semula"; + + tempMap["确定要清零当前统计数据吗?"]["zh-CN"] = "确定要清零当前统计数据吗?"; + tempMap["确定要清零当前统计数据吗?"]["en-US"] = "Are you sure you want to reset the current statistics?"; + tempMap["确定要清零当前统计数据吗?"]["ms-MY"] = "Adakah anda pasti mahu menetapkan semula statistik semasa?"; + + tempMap["检测总数"]["zh-CN"] = "检测总数"; + tempMap["检测总数"]["en-US"] = "Total Inspections"; + tempMap["检测总数"]["ms-MY"] = "Jumlah Pemeriksaan"; + + tempMap["不良数"]["zh-CN"] = "不良数"; + tempMap["不良数"]["en-US"] = "Defect Count"; + tempMap["不良数"]["ms-MY"] = "Kiraan Kecacatan"; + + tempMap["良品数"]["zh-CN"] = "良品数"; + tempMap["良品数"]["en-US"] = "Good Count"; + tempMap["良品数"]["ms-MY"] = "Kiraan Baik"; + + tempMap["良品率"]["zh-CN"] = "良品率"; + tempMap["良品率"]["en-US"] = "Yield Rate"; + tempMap["良品率"]["ms-MY"] = "Kadar Hasil"; + + tempMap["白班"]["zh-CN"] = "白班"; + tempMap["白班"]["en-US"] = "Day Shift"; + tempMap["白班"]["ms-MY"] = "Syif Siang"; + + tempMap["夜班"]["zh-CN"] = "夜班"; + tempMap["夜班"]["en-US"] = "Night Shift"; + tempMap["夜班"]["ms-MY"] = "Syif Malam"; + ///////// + tempMap["主界面"]["zh-CN"] = "主界面"; + tempMap["主界面"]["en-US"] = "Main Interface"; + tempMap["主界面"]["ms-MY"] = "Antaramuka Utama"; + + tempMap["生产数据"]["zh-CN"] = "生产数据"; + tempMap["生产数据"]["en-US"] = "Production Data"; + tempMap["生产数据"]["ms-MY"] = "Data Pengeluaran"; + + tempMap["数据库"]["zh-CN"] = "数据库"; + tempMap["数据库"]["en-US"] = "Database"; + tempMap["数据库"]["ms-MY"] = "Pangkalan Data"; + + tempMap["输入布尔值(true or false)"]["zh-CN"] = "输入布尔值(true or false)"; + tempMap["输入布尔值(true or false)"]["en-US"] = "Enter a boolean value (true or false)"; + tempMap["输入布尔值(true or false)"]["ms-MY"] = "Masukkan nilai boolean (benar atau palsu)"; + +#pragma endregion +#pragma region 逐字翻译字典 + tempMap["预焊"]["zh-CN"] = "预焊"; + tempMap["预焊"]["en-US"] = "Pre-welding"; + tempMap["预焊"]["ms-MY"] = "Pra-kimpalan"; + + tempMap["机"]["zh-CN"] = "机"; + tempMap["机"]["en-US"] = "Station"; + tempMap["机"]["ms-MY"] = "Stesen"; + + tempMap["查看器"]["zh-CN"] = "查看器"; + tempMap["查看器"]["en-US"] = "Viewer"; + tempMap["查看器"]["ms-MY"] = "Pemapar"; + + tempMap["极耳"]["zh-CN"] = "极耳"; + tempMap["极耳"]["en-US"] = "Tab"; + tempMap["极耳"]["ms-MY"] = "Tab"; + + tempMap["撕裂"]["zh-CN"] = "撕裂"; + tempMap["撕裂"]["en-US"] = "Tearing"; + tempMap["撕裂"]["ms-MY"] = "Koyak"; + + tempMap["翻折"]["zh-CN"] = "翻折"; + tempMap["翻折"]["en-US"] = "Folding"; + tempMap["翻折"]["ms-MY"] = "Lipatan"; + + tempMap["铜"]["zh-CN"] = "铜"; + tempMap["铜"]["en-US"] = "Copper"; + tempMap["铜"]["ms-MY"] = "Kuprum"; + + tempMap["铝"]["zh-CN"] = "铝"; + tempMap["铝"]["en-US"] = "Aluminum"; + tempMap["铝"]["ms-MY"] = "Aluminium"; + + tempMap["包膜"]["zh-CN"] = "包膜"; + tempMap["包膜"]["en-US"] = "Wrapping"; + tempMap["包膜"]["ms-MY"] = "Pembalut"; + + tempMap["前"]["zh-CN"] = "前"; + tempMap["前"]["en-US"] = "Front"; + tempMap["前"]["ms-MY"] = "Depan"; + + tempMap["后"]["zh-CN"] = "后"; + tempMap["后"]["en-US"] = "Rear"; + tempMap["后"]["ms-MY"] = "Belakang"; + + tempMap["内"]["zh-CN"] = "内"; + tempMap["内"]["en-US"] = "Inner"; + tempMap["内"]["ms-MY"] = "Dalam"; + + tempMap["外"]["zh-CN"] = "外"; + tempMap["外"]["en-US"] = "Outer"; + tempMap["外"]["ms-MY"] = "Luar"; + + tempMap["左"]["zh-CN"] = "左"; + tempMap["左"]["en-US"] = "Left"; + tempMap["左"]["ms-MY"] = "Kiri"; + + tempMap["右"]["zh-CN"] = "右"; + tempMap["右"]["en-US"] = "Right"; + tempMap["右"]["ms-MY"] = "Kanan"; + + tempMap["通道"]["zh-CN"] = "通道"; + tempMap["通道"]["en-US"] = "Channel"; + tempMap["通道"]["ms-MY"] = "Saluran"; + + tempMap["线"]["zh-CN"] = "线"; + tempMap["线"]["en-US"] = "Line"; + tempMap["线"]["ms-MY"] = "Talian"; + + tempMap["终焊"]["zh-CN"] = "终焊"; + tempMap["终焊"]["en-US"] = "Final Welding"; + tempMap["终焊"]["ms-MY"] = "Kimpalan Akhir"; + + tempMap["焊前"]["zh-CN"] = "焊前"; + tempMap["焊前"]["en-US"] = "Pre-welding"; + tempMap["焊前"]["ms-MY"] = "Pra-kimpalan"; + + tempMap["焊前定位"]["zh-CN"] = "焊前定位"; + tempMap["焊前定位"]["en-US"] = "Pre-welding Positioning"; + tempMap["焊前定位"]["ms-MY"] = "Penentududukan Pra-kimpalan"; + + tempMap["焊后"]["zh-CN"] = "焊后"; + tempMap["焊后"]["en-US"] = "Post-welding"; + tempMap["焊后"]["ms-MY"] = "Pasca-kimpalan"; + + tempMap["点胶"]["zh-CN"] = "点胶"; + tempMap["点胶"]["en-US"] = "Dispensing"; + tempMap["点胶"]["ms-MY"] = "Penyuntikan"; + + tempMap["贴胶"]["zh-CN"] = "贴胶"; + tempMap["贴胶"]["en-US"] = "Taping"; + tempMap["贴胶"]["ms-MY"] = "Pelekatan"; + + tempMap["阈值"]["zh-CN"] = "阈值"; + tempMap["阈值"]["en-US"] = "Threshold"; + tempMap["阈值"]["ms-MY"] = "Ambang"; + + tempMap["包膜前"]["zh-CN"] = "包膜前"; + tempMap["包膜前"]["en-US"] = "Pre-wrapping"; + tempMap["包膜前"]["ms-MY"] = "Pra-pembalut"; + + tempMap["包膜后"]["zh-CN"] = "包膜后"; + tempMap["包膜后"]["en-US"] = "Post-wrapping"; + tempMap["包膜后"]["ms-MY"] = "Pasca-pembalut"; + + tempMap["马甲"]["zh-CN"] = "马甲"; + tempMap["马甲"]["en-US"] = "Jacket"; + tempMap["马甲"]["ms-MY"] = "Jaket"; + + tempMap["相机"]["zh-CN"] = "相机"; + tempMap["相机"]["en-US"] = "Camera"; + tempMap["相机"]["ms-MY"] = "Kamera"; + + tempMap["顶盖"]["zh-CN"] = "顶盖"; + tempMap["顶盖"]["en-US"] = "Top Cover"; + tempMap["顶盖"]["ms-MY"] = "Penutup Atas"; + + tempMap["焊"]["zh-CN"] = "焊"; + tempMap["焊"]["en-US"] = "Welding"; + tempMap["焊"]["ms-MY"] = "Kimpalan"; + + tempMap["打钉"]["zh-CN"] = "打钉"; + tempMap["打钉"]["en-US"] = "Nailing"; + tempMap["打钉"]["ms-MY"] = "Pemakuan"; + + tempMap["满焊"]["zh-CN"] = "满焊"; + tempMap["满焊"]["en-US"] = "Full Welding"; + tempMap["满焊"]["ms-MY"] = "Kimpalan Penuh"; + + tempMap["放钉"]["zh-CN"] = "放钉"; + tempMap["放钉"]["en-US"] = "Place Nail"; + tempMap["放钉"]["ms-MY"] = "Letak Paku"; + + tempMap["气泡"]["zh-CN"] = "气泡"; + tempMap["气泡"]["en-US"] = "Bubble"; + tempMap["气泡"]["ms-MY"] = "Gelembung"; + + tempMap["上钉"]["zh-CN"] = "上钉"; + tempMap["上钉"]["en-US"] = "Install Nail"; + tempMap["上钉"]["ms-MY"] = "Pasang Paku"; + + tempMap["残液"]["zh-CN"] = "残液"; + tempMap["残液"]["en-US"] = "Residual Liquid"; + tempMap["残液"]["ms-MY"] = "Cecair Sisa"; + + tempMap["检测"]["zh-CN"] = "检测"; + tempMap["检测"]["en-US"] = "Inspection"; + tempMap["检测"]["ms-MY"] = "Pemeriksaan"; + + tempMap["最大"]["zh-CN"] = "最大"; + tempMap["最大"]["en-US"] = "Maximum"; + tempMap["最大"]["ms-MY"] = "Maksimum"; + + tempMap["最小"]["zh-CN"] = "最小"; + tempMap["最小"]["en-US"] = "Minimum"; + tempMap["最小"]["ms-MY"] = "Minimum"; + + tempMap["上限"]["zh-CN"] = "上限"; + tempMap["上限"]["en-US"] = "Upper Limit"; + tempMap["上限"]["ms-MY"] = "Had Atas"; + + tempMap["下限"]["zh-CN"] = "下限"; + tempMap["下限"]["en-US"] = "Lower Limit"; + tempMap["下限"]["ms-MY"] = "Had Bawah"; + + tempMap["极性"]["zh-CN"] = "极性"; + tempMap["极性"]["en-US"] = "Polarity"; + tempMap["极性"]["ms-MY"] = "Kekutuban"; + + tempMap["顶部"]["zh-CN"] = "顶部"; + tempMap["顶部"]["en-US"] = "Top"; + tempMap["顶部"]["ms-MY"] = "Atas"; + + tempMap["底部"]["zh-CN"] = "底部"; + tempMap["底部"]["en-US"] = "Bottom"; + tempMap["底部"]["ms-MY"] = "Bawah"; + + tempMap["大面"]["zh-CN"] = "大面"; + tempMap["大面"]["en-US"] = "Large Surface"; + tempMap["大面"]["ms-MY"] = "Permukaan Besar"; + + tempMap["放钉"]["zh-CN"] = "放钉"; + tempMap["放钉"]["en-US"] = "Place Nail"; + tempMap["放钉"]["ms-MY"] = "Letak Paku"; + + tempMap["入壳"]["zh-CN"] = "入壳"; + tempMap["入壳"]["en-US"] = "Casing"; + tempMap["入壳"]["ms-MY"] = "Pemasangan Sarung"; + + tempMap["机台"]["zh-CN"] = "机台"; + tempMap["机台"]["en-US"] = "Machine"; + tempMap["机台"]["ms-MY"] = "Mesin"; + + tempMap["离线"]["zh-CN"] = "离线"; + tempMap["离线"]["en-US"] = "Offline"; + tempMap["离线"]["ms-MY"] = "Luar Talian"; + + tempMap["在线"]["zh-CN"] = "在线"; + tempMap["在线"]["en-US"] = "Online"; + tempMap["在线"]["ms-MY"] = "Dalam Talian"; + + tempMap["密封钉"]["zh-CN"] = "密封钉"; + tempMap["密封钉"]["en-US"] = "Sealing Nail"; + tempMap["密封钉"]["ms-MY"] = "Paku Pengedap"; + + tempMap["刻码"]["zh-CN"] = "刻码"; + tempMap["刻码"]["en-US"] = "Marking"; + tempMap["刻码"]["ms-MY"] = "Penandaan"; + + tempMap["热熔"]["zh-CN"] = "热熔"; + tempMap["热熔"]["en-US"] = "Hot Melt"; + tempMap["热熔"]["ms-MY"] = "Cairan Panas"; + + tempMap["马甲热熔"]["zh-CN"] = "马甲热熔"; + tempMap["马甲热熔"]["en-US"] = "Jacket Hot Melt"; + tempMap["马甲热熔"]["ms-MY"] = "Cairan Panas Jaket"; + + tempMap["触发"]["zh-CN"] = "触发"; + tempMap["触发"]["en-US"] = "Trigger"; + tempMap["触发"]["ms-MY"] = "Pencetus"; + + tempMap["结束"]["zh-CN"] = "结束"; + tempMap["结束"]["en-US"] = "End"; + tempMap["结束"]["ms-MY"] = "Tamat"; + + tempMap["完成"]["zh-CN"] = "完成"; + tempMap["完成"]["en-US"] = "Complete"; + tempMap["完成"]["ms-MY"] = "Selesai"; + + tempMap["信号"]["zh-CN"] = "信号"; + tempMap["信号"]["en-US"] = "Signal"; + tempMap["信号"]["ms-MY"] = "Isyarat"; + + tempMap["长度"]["zh-CN"] = "长度"; + tempMap["长度"]["en-US"] = "Length"; + tempMap["长度"]["ms-MY"] = "Panjang"; + + tempMap["宽度"]["zh-CN"] = "宽度"; + tempMap["宽度"]["en-US"] = "Width"; + tempMap["宽度"]["ms-MY"] = "Lebar"; + + tempMap["翻折"]["zh-CN"] = "翻折"; + tempMap["翻折"]["en-US"] = "Folding"; + tempMap["翻折"]["ms-MY"] = "Lipatan"; + + tempMap["电解液"]["zh-CN"] = "电解液"; + tempMap["电解液"]["en-US"] = "Electrolyte"; + tempMap["电解液"]["ms-MY"] = "Elektrolit"; + + tempMap["底托"]["zh-CN"] = "底托"; + tempMap["底托"]["en-US"] = "Bottom Tray"; + tempMap["底托"]["ms-MY"] = "Dulang Bawah"; + + tempMap["位置"]["zh-CN"] = "位置"; + tempMap["位置"]["en-US"] = "Position"; + tempMap["位置"]["ms-MY"] = "Kedudukan"; + + tempMap["正面"]["zh-CN"] = "正面"; + tempMap["正面"]["en-US"] = "Front"; + tempMap["正面"]["ms-MY"] = "Depan"; + + tempMap["侧面"]["zh-CN"] = "侧面"; + tempMap["侧面"]["en-US"] = "Side"; + tempMap["侧面"]["ms-MY"] = "Sisi"; + + tempMap["反面"]["zh-CN"] = "反面"; + tempMap["反面"]["en-US"] = "Back"; + tempMap["反面"]["ms-MY"] = "Belakang"; + + tempMap["焊印"]["zh-CN"] = "焊印"; + tempMap["焊印"]["en-US"] = "Weld Mark"; + tempMap["焊印"]["ms-MY"] = "Tanda Kimpalan"; + + tempMap["残液"]["zh-CN"] = "残液"; + tempMap["残液"]["en-US"] = "Residual Liquid"; + tempMap["残液"]["ms-MY"] = "Cecair Sisa"; + + tempMap["面积"]["zh-CN"] = "面积"; + tempMap["面积"]["en-US"] = "Area"; + tempMap["面积"]["ms-MY"] = "Luas"; + + tempMap["总"]["zh-CN"] = "总"; + tempMap["总"]["en-US"] = "Total"; + tempMap["总"]["ms-MY"] = "Jumlah"; + + tempMap["引导"]["zh-CN"] = "引导"; + tempMap["引导"]["en-US"] = "Guide"; + tempMap["引导"]["ms-MY"] = "Panduan"; + + tempMap["上钉"]["zh-CN"] = "上钉"; + tempMap["上钉"]["en-US"] = "Install Nail"; + tempMap["上钉"]["ms-MY"] = "Pasang Paku"; + + tempMap["算法"]["zh-CN"] = "算法"; + tempMap["算法"]["en-US"] = "Algorithm"; + tempMap["算法"]["ms-MY"] = "Algoritma"; + + tempMap["异常"]["zh-CN"] = "异常"; + tempMap["异常"]["en-US"] = "Exception"; + tempMap["异常"]["ms-MY"] = "Pengecualian"; + + tempMap["偏移"]["zh-CN"] = "偏移"; + tempMap["偏移"]["en-US"] = "Offset"; + tempMap["偏移"]["ms-MY"] = "Ofset"; + + tempMap["纠偏"]["zh-CN"] = "纠偏"; + tempMap["纠偏"]["en-US"] = "Correction"; + tempMap["纠偏"]["ms-MY"] = "Pembetulan"; + + tempMap["一次注液"]["zh-CN"] = "一次注液"; + tempMap["一次注液"]["en-US"] = "Primary Injection"; + tempMap["一次注液"]["ms-MY"] = "Suntikan Pertama"; + + tempMap["一注"]["zh-CN"] = "一注"; + tempMap["一注"]["en-US"] = "Primary Injection"; + tempMap["一注"]["ms-MY"] = "Suntikan Pertama"; + + tempMap["二次注液"]["zh-CN"] = "二次注液"; + tempMap["二次注液"]["en-US"] = "Secondary Injection"; + tempMap["二次注液"]["ms-MY"] = "Suntikan Sekunder"; + + tempMap["二注"]["zh-CN"] = "二注"; + tempMap["二注"]["en-US"] = "Secondary Injection"; + tempMap["二注"]["ms-MY"] = "Suntikan Sekunder"; + + tempMap["获取"]["zh-CN"] = "获取"; + tempMap["获取"]["en-US"] = "Acquire"; + tempMap["获取"]["ms-MY"] = "Perolehi"; + + tempMap["图像"]["zh-CN"] = "图像"; + tempMap["图像"]["en-US"] = "Image"; + tempMap["图像"]["ms-MY"] = "Imej"; + + tempMap["时间"]["zh-CN"] = "时间"; + tempMap["时间"]["en-US"] = "Time"; + tempMap["时间"]["ms-MY"] = "Masa"; + + tempMap["产品"]["zh-CN"] = "产品"; + tempMap["产品"]["en-US"] = "Product"; + tempMap["产品"]["ms-MY"] = "Produk"; + + tempMap["条码"]["zh-CN"] = "条码"; + tempMap["条码"]["en-US"] = "Barcode"; + tempMap["条码"]["ms-MY"] = "Kod Bar"; + + tempMap["边缘"]["zh-CN"] = "边缘"; + tempMap["边缘"]["en-US"] = "Edge"; + tempMap["边缘"]["ms-MY"] = "Tepi"; + + tempMap["上"]["zh-CN"] = "上"; + tempMap["上"]["en-US"] = "Up"; + tempMap["上"]["ms-MY"] = "Atas"; + + tempMap["中"]["zh-CN"] = "中"; + tempMap["中"]["en-US"] = "Middle"; + tempMap["中"]["ms-MY"] = "Tengah"; + + tempMap["下"]["zh-CN"] = "下"; + tempMap["下"]["en-US"] = "Down"; + tempMap["下"]["ms-MY"] = "Bawah"; + + tempMap["侧"]["zh-CN"] = "侧"; + tempMap["侧"]["en-US"] = "Side"; + tempMap["侧"]["ms-MY"] = "Sisi"; + + tempMap["大面"]["zh-CN"] = "大面"; + tempMap["大面"]["en-US"] = "Large Surface"; + tempMap["大面"]["ms-MY"] = "Permukaan Besar"; + + tempMap["度"]["zh-CN"] = "度"; + tempMap["度"]["en-US"] = "Degree"; + tempMap["度"]["ms-MY"] = "Darjah"; + + tempMap["外观"]["zh-CN"] = "外观"; + tempMap["外观"]["en-US"] = "Appearance"; + tempMap["外观"]["ms-MY"] = "Penampilan"; + + tempMap["电芯"]["zh-CN"] = "电芯"; + tempMap["电芯"]["en-US"] = "Battery Cell"; + tempMap["电芯"]["ms-MY"] = "Sel Bateri"; + + tempMap["端盖"]["zh-CN"] = "端盖"; + tempMap["端盖"]["en-US"] = "End Cover"; + tempMap["端盖"]["ms-MY"] = "Penutup Hujung"; + + tempMap["四角"]["zh-CN"] = "四角"; + tempMap["四角"]["en-US"] = "Four Corners"; + tempMap["四角"]["ms-MY"] = "Empat Penjuru"; + + tempMap["破碎"]["zh-CN"] = "破碎"; + tempMap["破碎"]["en-US"] = "Crushed"; + tempMap["破碎"]["ms-MY"] = "Hancur"; + + tempMap["长边"]["zh-CN"] = "长边"; + tempMap["长边"]["en-US"] = "Long Side"; + tempMap["长边"]["ms-MY"] = "Sisi Panjang"; + + tempMap["短边"]["zh-CN"] = "短边"; + tempMap["短边"]["en-US"] = "Short Side"; + tempMap["短边"]["ms-MY"] = "Sisi Pendek"; + + tempMap["辊压"]["zh-CN"] = "辊压"; + tempMap["辊压"]["en-US"] = "Roller Pressing"; + tempMap["辊压"]["ms-MY"] = "Tekanan Penggelek"; + + tempMap["凸高"]["zh-CN"] = "凸高"; + tempMap["凸高"]["en-US"] = "Protrusion Height"; + tempMap["凸高"]["ms-MY"] = "Ketinggian Tonjolan"; + + tempMap["侧面"]["zh-CN"] = "侧面"; + tempMap["侧面"]["en-US"] = "Side"; + tempMap["侧面"]["ms-MY"] = "Sisi"; + + tempMap["顶面"]["zh-CN"] = "顶面"; + tempMap["顶面"]["en-US"] = "Top Surface"; + tempMap["顶面"]["ms-MY"] = "Permukaan Atas"; + + tempMap["内侧"]["zh-CN"] = "内侧"; + tempMap["内侧"]["en-US"] = "Inner Side"; + tempMap["内侧"]["ms-MY"] = "Sisi Dalam"; + + tempMap["外侧"]["zh-CN"] = "外侧"; + tempMap["外侧"]["en-US"] = "Outer Side"; + tempMap["外侧"]["ms-MY"] = "Sisi Luar"; + + tempMap["模型"]["zh-CN"] = "模型"; + tempMap["模型"]["en-US"] = "Model"; + tempMap["模型"]["ms-MY"] = "Model"; + + tempMap["台阶"]["zh-CN"] = "台阶"; + tempMap["台阶"]["en-US"] = "Step"; + tempMap["台阶"]["ms-MY"] = "Langkah"; + + tempMap["台阶差"]["zh-CN"] = "台阶差"; + tempMap["台阶差"]["en-US"] = "Step Difference"; + tempMap["台阶差"]["ms-MY"] = "Perbezaan Langkah"; + + tempMap["间隙"]["zh-CN"] = "间隙"; + tempMap["间隙"]["en-US"] = "Gap"; + tempMap["间隙"]["ms-MY"] = "Jurang"; + + tempMap["缝隙"]["zh-CN"] = "缝隙"; + tempMap["缝隙"]["en-US"] = "Slit"; + tempMap["缝隙"]["ms-MY"] = "Celah"; + + tempMap["不良"]["zh-CN"] = "不良"; + tempMap["不良"]["en-US"] = "Defect"; + tempMap["不良"]["ms-MY"] = "Kecacatan"; + + tempMap["失败"]["zh-CN"] = "失败"; + tempMap["失败"]["en-US"] = "Failure"; + tempMap["失败"]["ms-MY"] = "Kegagalan"; + + tempMap["高度"]["zh-CN"] = "高度"; + tempMap["高度"]["en-US"] = "Height"; + tempMap["高度"]["ms-MY"] = "Ketinggian"; + + tempMap["区域"]["zh-CN"] = "区域"; + tempMap["区域"]["en-US"] = "Region"; + tempMap["区域"]["ms-MY"] = "Kawasan"; + + tempMap["管理"]["zh-CN"] = "管理"; + tempMap["管理"]["en-US"] = "Management"; + tempMap["管理"]["ms-MY"] = "Pengurusan"; + + tempMap["创建"]["zh-CN"] = "创建"; + tempMap["创建"]["en-US"] = "Create"; + tempMap["创建"]["ms-MY"] = "Cipta"; + + tempMap["修改"]["zh-CN"] = "修改"; + tempMap["修改"]["en-US"] = "Modify"; + tempMap["修改"]["ms-MY"] = "Ubah Suai"; + + tempMap["结果"]["zh-CN"] = "结果"; + tempMap["结果"]["en-US"] = "Result"; + tempMap["结果"]["ms-MY"] = "Hasil"; + + tempMap["耗时"]["zh-CN"] = "耗时"; + tempMap["耗时"]["en-US"] = "Time Consumed"; + tempMap["耗时"]["ms-MY"] = "Masa Digunakan"; + + tempMap["流程"]["zh-CN"] = "流程"; + tempMap["流程"]["en-US"] = "Process"; + tempMap["流程"]["ms-MY"] = "Proses"; + + tempMap["判定"]["zh-CN"] = "判定"; + tempMap["判定"]["en-US"] = "Judgment"; + tempMap["判定"]["ms-MY"] = "Penghakiman"; + + tempMap["启用"]["zh-CN"] = "启用"; + tempMap["启用"]["en-US"] = "Enable"; + tempMap["启用"]["ms-MY"] = "Dayakan"; + + tempMap["置信度"]["zh-CN"] = "置信度"; + tempMap["置信度"]["en-US"] = "Confidence"; + tempMap["置信度"]["ms-MY"] = "Keyakinan"; + + tempMap["本地读图"]["zh-CN"] = "本地读图"; + tempMap["本地读图"]["en-US"] = "Local Image Reading"; + tempMap["本地读图"]["ms-MY"] = "Pembacaan Imej Tempatan"; + + tempMap["通用设置"]["zh-CN"] = "通用设置"; + tempMap["通用设置"]["en-US"] = "General Settings"; + tempMap["通用设置"]["ms-MY"] = "Tetapan Umum"; + + tempMap["仅在NG时"]["zh-CN"] = "仅在NG时"; + tempMap["仅在NG时"]["en-US"] = "Only When NG"; + tempMap["仅在NG时"]["ms-MY"] = "Hanya Apabila NG"; + + tempMap["上限"]["zh-CN"] = "上限"; + tempMap["上限"]["en-US"] = "Upper Limit"; + tempMap["上限"]["ms-MY"] = "Had Atas"; + + tempMap["存储"]["zh-CN"] = "存储"; + tempMap["存储"]["en-US"] = "Storage"; + tempMap["存储"]["ms-MY"] = "Penyimpanan"; + + tempMap["原图"]["zh-CN"] = "原图"; + tempMap["原图"]["en-US"] = "Original Image"; + tempMap["原图"]["ms-MY"] = "Imej Asal"; + + tempMap["结果图"]["zh-CN"] = "结果图"; + tempMap["结果图"]["en-US"] = "Result Image"; + tempMap["结果图"]["ms-MY"] = "Imej Hasil"; + + tempMap["图片"]["zh-CN"] = "图片"; + tempMap["图片"]["en-US"] = "Image"; + tempMap["图片"]["ms-MY"] = "Imej"; + + tempMap["图"]["zh-CN"] = "图"; + tempMap["图"]["en-US"] = "Image"; + tempMap["图"]["ms-MY"] = "Imej"; + + tempMap["额外"]["zh-CN"] = "额外"; + tempMap["额外"]["en-US"] = "Extra"; + tempMap["额外"]["ms-MY"] = "Tambahan"; + + tempMap["等待"]["zh-CN"] = "等待"; + tempMap["等待"]["en-US"] = "Wait"; + tempMap["等待"]["ms-MY"] = "Tunggu"; + + tempMap["汇总"]["zh-CN"] = "汇总"; + tempMap["汇总"]["en-US"] = "Summary"; + tempMap["汇总"]["ms-MY"] = "Ringkasan"; + + tempMap["精度"]["zh-CN"] = "精度"; + tempMap["精度"]["en-US"] = "Precision"; + tempMap["精度"]["ms-MY"] = "Ketepatan"; + + tempMap["未登录"]["zh-CN"] = "未登录"; + tempMap["未登录"]["en-US"] = "Not logged in"; + tempMap["未登录"]["ms-MY"] = "Tidak log masuk"; + + tempMap["仅"]["zh-CN"] = "仅"; + tempMap["仅"]["en-US"] = "Only"; + tempMap["仅"]["ms-MY"] = "Hanya"; + + tempMap["不"]["zh-CN"] = "不"; + tempMap["不"]["en-US"] = "No"; + tempMap["不"]["ms-MY"] = "Tidak"; + + tempMap["强制"]["zh-CN"] = "强制"; + tempMap["强制"]["en-US"] = "Force"; + tempMap["强制"]["ms-MY"] = "Paksa"; + + tempMap["屏蔽"]["zh-CN"] = "屏蔽"; + tempMap["屏蔽"]["en-US"] = "Block"; + tempMap["屏蔽"]["ms-MY"] = "Sekat"; + + tempMap["任何"]["zh-CN"] = "任何"; + tempMap["任何"]["en-US"] = "Any"; + tempMap["任何"]["ms-MY"] = "Mana-mana"; + + tempMap["存图"]["zh-CN"] = "存图"; + tempMap["存图"]["en-US"] = "Save Image"; + tempMap["存图"]["ms-MY"] = "Simpan Imej"; + + tempMap["的"]["zh-CN"] = "的"; + tempMap["的"]["en-US"] = "of"; + tempMap["的"]["ms-MY"] = "daripada"; + + tempMap["内存"]["zh-CN"] = "内存"; + tempMap["内存"]["en-US"] = "Memory"; + tempMap["内存"]["ms-MY"] = "Memori"; + + tempMap["路径"]["zh-CN"] = "路径"; + tempMap["路径"]["en-US"] = "Path"; + tempMap["路径"]["ms-MY"] = "Laluan"; + + tempMap["多个"]["zh-CN"] = "多个"; + tempMap["多个"]["en-US"] = "Multiple"; + tempMap["多个"]["ms-MY"] = "Pelbagai"; + + tempMap["使用"]["zh-CN"] = "使用"; + tempMap["使用"]["en-US"] = "Use"; + tempMap["使用"]["ms-MY"] = "Guna"; + + tempMap["用"]["zh-CN"] = "用"; + tempMap["用"]["en-US"] = "Use"; + tempMap["用"]["ms-MY"] = "Guna"; + + tempMap["分割"]["zh-CN"] = "分割"; + tempMap["分割"]["en-US"] = "Split"; + tempMap["分割"]["ms-MY"] = "Bahagi"; + + tempMap["数量"]["zh-CN"] = "数量"; + tempMap["数量"]["en-US"] = "Quantity"; + tempMap["数量"]["ms-MY"] = "Kuantiti"; + + tempMap["补充"]["zh-CN"] = "补充"; + tempMap["补充"]["en-US"] = "Supplement"; + tempMap["补充"]["ms-MY"] = "Tambahan"; + + tempMap["黑图"]["zh-CN"] = "黑图"; + tempMap["黑图"]["en-US"] = "Black Image"; + tempMap["黑图"]["ms-MY"] = "Imej Hitam"; + + tempMap["参数"]["zh-CN"] = "参数"; + tempMap["参数"]["en-US"] = "Parameter"; + tempMap["参数"]["ms-MY"] = "Parameter"; + + tempMap["名"]["zh-CN"] = "名"; + tempMap["名"]["en-US"] = "Name"; + tempMap["名"]["ms-MY"] = "Nama"; + + tempMap["分组"]["zh-CN"] = "分组"; + tempMap["分组"]["en-US"] = "Group"; + tempMap["分组"]["ms-MY"] = "Kumpulan"; + + tempMap["掉线"]["zh-CN"] = "掉线"; + tempMap["掉线"]["en-US"] = "Disconnect"; + tempMap["掉线"]["ms-MY"] = "Terputus"; + + tempMap["连接"]["zh-CN"] = "连接"; + tempMap["连接"]["en-US"] = "Connect"; + tempMap["连接"]["ms-MY"] = "Sambung"; + + tempMap["类型"]["zh-CN"] = "类型"; + tempMap["类型"]["en-US"] = "Type"; + tempMap["类型"]["ms-MY"] = "Jenis"; + + tempMap["留白"]["zh-CN"] = "留白"; + tempMap["留白"]["en-US"] = "White Space"; + tempMap["留白"]["ms-MY"] = "Ruang Putih"; + + tempMap["占用"]["zh-CN"] = "占用"; + tempMap["占用"]["en-US"] = "Occupied"; + tempMap["占用"]["ms-MY"] = "Diduduki"; + + tempMap["秒"]["zh-CN"] = "秒"; + tempMap["秒"]["en-US"] = "Second"; + tempMap["秒"]["ms-MY"] = "Saat"; + + tempMap["不足"]["zh-CN"] = "不足"; + tempMap["不足"]["en-US"] = "Insufficient"; + tempMap["不足"]["ms-MY"] = "Tidak Mencukupi"; + + tempMap["存在"]["zh-CN"] = "存在"; + tempMap["存在"]["en-US"] = "Exists"; + tempMap["存在"]["ms-MY"] = "Wujud"; + + tempMap["内部"]["zh-CN"] = "内部"; + tempMap["内部"]["en-US"] = "Internal"; + tempMap["内部"]["ms-MY"] = "Dalam"; + + tempMap["外部"]["zh-CN"] = "外部"; + tempMap["外部"]["en-US"] = "External"; + tempMap["外部"]["ms-MY"] = "Luar"; + + tempMap["状态"]["zh-CN"] = "状态"; + tempMap["状态"]["en-US"] = "Status"; + tempMap["状态"]["ms-MY"] = "Status"; + + tempMap["变更"]["zh-CN"] = "变更"; + tempMap["变更"]["en-US"] = "Change"; + tempMap["变更"]["ms-MY"] = "Perubahan"; + + tempMap["铜极"]["zh-CN"] = "铜极"; + tempMap["铜极"]["en-US"] = "Copper Electrode"; + tempMap["铜极"]["ms-MY"] = "Elektrod Kuprum"; + + tempMap["铝极"]["zh-CN"] = "铝极"; + tempMap["铝极"]["en-US"] = "Aluminum Electrode"; + tempMap["铝极"]["ms-MY"] = "Elektrod Aluminium"; + + tempMap["输出"]["zh-CN"] = "输出"; + tempMap["输出"]["en-US"] = "Output"; + tempMap["输出"]["ms-MY"] = "Output"; + + tempMap["输入"]["zh-CN"] = "输入"; + tempMap["输入"]["en-US"] = "Input"; + tempMap["输入"]["ms-MY"] = "Input"; + + tempMap["未"]["zh-CN"] = "未"; + tempMap["未"]["en-US"] = "Not"; + tempMap["未"]["ms-MY"] = "Tidak"; + + tempMap["取用"]["zh-CN"] = "取用"; + tempMap["取用"]["en-US"] = "Take"; + tempMap["取用"]["ms-MY"] = "Ambil"; + + tempMap["已"]["zh-CN"] = "已"; + tempMap["已"]["en-US"] = "Already"; + tempMap["已"]["ms-MY"] = "Sudah"; + + tempMap["多余"]["zh-CN"] = "多余"; + tempMap["多余"]["en-US"] = "Redundant"; + tempMap["多余"]["ms-MY"] = "Berlebihan"; + + tempMap["通过"]["zh-CN"] = "通过"; + tempMap["通过"]["en-US"] = "Pass"; + tempMap["通过"]["ms-MY"] = "Lulus"; + + tempMap["自检"]["zh-CN"] = "自检"; + tempMap["自检"]["en-US"] = "Self-check"; + tempMap["自检"]["ms-MY"] = "Pemeriksaan Sendiri"; + + tempMap["地址"]["zh-CN"] = "地址"; + tempMap["地址"]["en-US"] = "Address"; + tempMap["地址"]["ms-MY"] = "Alamat"; + + tempMap["超出限制"]["zh-CN"] = "超出限制"; + tempMap["超出限制"]["en-US"] = "Exceeds Limit"; + tempMap["超出限制"]["ms-MY"] = "Melebihi Had"; + + tempMap["断开"]["zh-CN"] = "断开"; + tempMap["断开"]["en-US"] = "Disconnect"; + tempMap["断开"]["ms-MY"] = "Putuskan sambungan"; + + tempMap["正在"]["zh-CN"] = "正在"; + tempMap["正在"]["en-US"] = "In progress"; + tempMap["正在"]["ms-MY"] = "Sedang"; + + tempMap["尝试"]["zh-CN"] = "尝试"; + tempMap["尝试"]["en-US"] = "Try"; + tempMap["尝试"]["ms-MY"] = "Cuba"; + + tempMap["重连"]["zh-CN"] = "重连"; + tempMap["重连"]["en-US"] = "Reconnect"; + tempMap["重连"]["ms-MY"] = "Sambung semula"; + + tempMap["加载"]["zh-CN"] = "加载"; + tempMap["加载"]["en-US"] = "Load"; + tempMap["加载"]["ms-MY"] = "Muat"; + + tempMap["文件"]["zh-CN"] = "文件"; + tempMap["文件"]["en-US"] = "File"; + tempMap["文件"]["ms-MY"] = "Fail"; + + tempMap["大小"]["zh-CN"] = "大小"; + tempMap["大小"]["en-US"] = "Size"; + tempMap["大小"]["ms-MY"] = "Saiz"; + + tempMap["匹配"]["zh-CN"] = "匹配"; + tempMap["匹配"]["en-US"] = "Match"; + tempMap["匹配"]["ms-MY"] = "Padan"; + + tempMap["读取"]["zh-CN"] = "读取"; + tempMap["读取"]["en-US"] = "Read"; + tempMap["读取"]["ms-MY"] = "Baca"; + + tempMap["字节"]["zh-CN"] = "字节"; + tempMap["字节"]["en-US"] = "Byte"; + tempMap["字节"]["ms-MY"] = "Bait"; + + tempMap["与"]["zh-CN"] = "与"; + tempMap["与"]["en-US"] = "And"; + tempMap["与"]["ms-MY"] = "Dan"; + + tempMap["连接片"]["zh-CN"] = "连接片"; + tempMap["连接片"]["en-US"] = "Connecting Piece"; + tempMap["连接片"]["ms-MY"] = "Penyambung"; + + tempMap["胶纸"]["zh-CN"] = "胶纸"; + tempMap["胶纸"]["en-US"] = "Adhesive Tape"; + tempMap["胶纸"]["ms-MY"] = "Pita Pelekat"; + + tempMap["芯包"]["zh-CN"] = "芯包"; + tempMap["芯包"]["en-US"] = "Battery Cell"; + tempMap["芯包"]["ms-MY"] = "Sel Bateri"; + + tempMap["注液孔"]["zh-CN"] = "注液孔"; + tempMap["注液孔"]["en-US"] = "Injection Hole"; + tempMap["注液孔"]["ms-MY"] = "Lubang Suntikan"; + + tempMap["距离"]["zh-CN"] = "距离"; + tempMap["距离"]["en-US"] = "Distance"; + tempMap["距离"]["ms-MY"] = "Jarak"; + + tempMap["圆心"]["zh-CN"] = "圆心"; + tempMap["圆心"]["en-US"] = "Circle Center"; + tempMap["圆心"]["ms-MY"] = "Pusat Bulatan"; + + tempMap["盖板"]["zh-CN"] = "盖板"; + tempMap["盖板"]["en-US"] = "Cover Plate"; + tempMap["盖板"]["ms-MY"] = "Plat Penutup"; + + tempMap["左侧"]["zh-CN"] = "左侧"; + tempMap["左侧"]["en-US"] = "Left Side"; + tempMap["左侧"]["ms-MY"] = "Sebelah Kiri"; + + tempMap["右侧"]["zh-CN"] = "右侧"; + tempMap["右侧"]["en-US"] = "Right Side"; + tempMap["右侧"]["ms-MY"] = "Sebelah Kanan"; + + tempMap["塑胶"]["zh-CN"] = "塑胶"; + tempMap["塑胶"]["en-US"] = "Plastic"; + tempMap["塑胶"]["ms-MY"] = "Plastik"; + + tempMap["防爆阀"]["zh-CN"] = "防爆阀"; + tempMap["防爆阀"]["en-US"] = "Explosion-proof Valve"; + tempMap["防爆阀"]["ms-MY"] = "Injap Kalis Letupan"; + + tempMap["焊接"]["zh-CN"] = "焊接"; + tempMap["焊接"]["en-US"] = "Welding"; + tempMap["焊接"]["ms-MY"] = "Kimpalan"; + + tempMap["段"]["zh-CN"] = "段"; + tempMap["段"]["en-US"] = "Segment"; + tempMap["段"]["ms-MY"] = "Segmen"; + + tempMap["软连接"]["zh-CN"] = "软连接"; + tempMap["软连接"]["en-US"] = "Flexible Connection"; + tempMap["软连接"]["ms-MY"] = "Sambungan Fleksibel"; + + tempMap["中心"]["zh-CN"] = "中心"; + tempMap["中心"]["en-US"] = "Center"; + tempMap["中心"]["ms-MY"] = "Pusat"; + + tempMap["线段"]["zh-CN"] = "线段"; + tempMap["线段"]["en-US"] = "Line Segment"; + tempMap["线段"]["ms-MY"] = "Segmen Garis"; + + tempMap["夹角"]["zh-CN"] = "夹角"; + tempMap["夹角"]["en-US"] = "Included Angle"; + tempMap["夹角"]["ms-MY"] = "Sudut Sertaan"; + + tempMap["绿"]["zh-CN"] = "绿"; + tempMap["绿"]["en-US"] = "Green"; + tempMap["绿"]["ms-MY"] = "Hijau"; + + tempMap["绿色"]["zh-CN"] = "绿色"; + tempMap["绿色"]["en-US"] = "Green"; + tempMap["绿色"]["ms-MY"] = "Hijau"; + + tempMap["黄"]["zh-CN"] = "黄"; + tempMap["黄"]["en-US"] = "Yellow"; + tempMap["黄"]["ms-MY"] = "Kuning"; + + tempMap["黄色"]["zh-CN"] = "黄色"; + tempMap["黄色"]["en-US"] = "Yellow"; + tempMap["黄色"]["ms-MY"] = "Kuning"; + + tempMap["蓝"]["zh-CN"] = "蓝"; + tempMap["蓝"]["en-US"] = "Blue"; + tempMap["蓝"]["ms-MY"] = "Biru"; + + tempMap["蓝色"]["zh-CN"] = "蓝色"; + tempMap["蓝色"]["en-US"] = "Blue"; + tempMap["蓝色"]["ms-MY"] = "Biru"; + + tempMap["隔膜"]["zh-CN"] = "隔膜"; + tempMap["隔膜"]["en-US"] = "Separator"; + tempMap["隔膜"]["ms-MY"] = "Pemisah"; + + tempMap["的"]["zh-CN"] = "的"; + tempMap["的"]["en-US"] = "of"; + tempMap["的"]["ms-MY"] = "daripada"; + + tempMap["底座"]["zh-CN"] = "底座"; + tempMap["底座"]["en-US"] = "Base"; + tempMap["底座"]["ms-MY"] = "Tapak"; + + tempMap["焊盘"]["zh-CN"] = "焊盘"; + tempMap["焊盘"]["en-US"] = "Solder Pad"; + tempMap["焊盘"]["ms-MY"] = "Pad Pateri"; + + tempMap["热熔点"]["zh-CN"] = "热熔点"; + tempMap["热熔点"]["en-US"] = "Hot Melt Point"; + tempMap["热熔点"]["ms-MY"] = "Titik Cairan Panas"; + + tempMap["热熔点数"]["zh-CN"] = "热熔点数"; + tempMap["热熔点数"]["en-US"] = "Number of Hot Melt Points"; + tempMap["热熔点数"]["ms-MY"] = "Bilangan Titik Cairan Panas"; + + tempMap["同心度"]["zh-CN"] = "同心度"; + tempMap["同心度"]["en-US"] = "Concentricity"; + tempMap["同心度"]["ms-MY"] = "Keserapatan"; + + tempMap["明码"]["zh-CN"] = "明码"; + tempMap["明码"]["en-US"] = "Plain Code"; + tempMap["明码"]["ms-MY"] = "Kod Biasa"; + + tempMap["二维码"]["zh-CN"] = "二维码"; + tempMap["二维码"]["en-US"] = "QR Code"; + tempMap["二维码"]["ms-MY"] = "Kod QR"; + + tempMap["右竖直边"]["zh-CN"] = "右竖直边"; + tempMap["右竖直边"]["en-US"] = "Right Vertical Edge"; + tempMap["右竖直边"]["ms-MY"] = "Tepi Menegak Kanan"; + + tempMap["水平"]["zh-CN"] = "水平"; + tempMap["水平"]["en-US"] = "Horizontal"; + tempMap["水平"]["ms-MY"] = "Mendatar"; + + tempMap["垂直"]["zh-CN"] = "垂直"; + tempMap["垂直"]["en-US"] = "Vertical"; + tempMap["垂直"]["ms-MY"] = "Menegak"; + + tempMap["字符"]["zh-CN"] = "字符"; + tempMap["字符"]["en-US"] = "Character"; + tempMap["字符"]["ms-MY"] = "Aksara"; + + tempMap["字体"]["zh-CN"] = "字体"; + tempMap["字体"]["en-US"] = "Font"; + tempMap["字体"]["ms-MY"] = "Fon"; + + tempMap["打印"]["zh-CN"] = "打印"; + tempMap["打印"]["en-US"] = "Print"; + tempMap["打印"]["ms-MY"] = "Cetak"; + + tempMap["厚度"]["zh-CN"] = "厚度"; + tempMap["厚度"]["en-US"] = "Thickness"; + tempMap["厚度"]["ms-MY"] = "Ketebalan"; + + tempMap["胶体"]["zh-CN"] = "胶体"; + tempMap["胶体"]["en-US"] = "Gel"; + tempMap["胶体"]["ms-MY"] = "Gel"; + + tempMap["比例"]["zh-CN"] = "比例"; + tempMap["比例"]["en-US"] = "Ratio"; + tempMap["比例"]["ms-MY"] = "Nisbah"; + + tempMap["内圆"]["zh-CN"] = "内圆"; + tempMap["内圆"]["en-US"] = "Inner Circle"; + tempMap["内圆"]["ms-MY"] = "Bulatan Dalam"; + + tempMap["外圆"]["zh-CN"] = "外圆"; + tempMap["外圆"]["en-US"] = "Outer Circle"; + tempMap["外圆"]["ms-MY"] = "Bulatan Luar"; + + tempMap["蓝膜"]["zh-CN"] = "蓝膜"; + tempMap["蓝膜"]["en-US"] = "Blue Film"; + tempMap["蓝膜"]["ms-MY"] = "Filem Biru"; + + tempMap["重叠区"]["zh-CN"] = "重叠区"; + tempMap["重叠区"]["en-US"] = "Overlap Area"; + tempMap["重叠区"]["ms-MY"] = "Kawasan Tindih"; + + tempMap["最大值"]["zh-CN"] = "最大值"; + tempMap["最大值"]["en-US"] = "Maximum"; + tempMap["最大值"]["ms-MY"] = "Maksimum"; + + tempMap["最小值"]["zh-CN"] = "最小值"; + tempMap["最小值"]["en-US"] = "Minimum"; + tempMap["最小值"]["ms-MY"] = "Minimum"; + + tempMap["膜"]["zh-CN"] = "膜"; + tempMap["膜"]["en-US"] = "Film"; + tempMap["膜"]["ms-MY"] = "Filem"; + + tempMap["监控"]["zh-CN"] = "监控"; + tempMap["监控"]["en-US"] = "Monitoring"; + tempMap["监控"]["ms-MY"] = "Pemantauan"; + + tempMap["工位"]["zh-CN"] = "工位"; + tempMap["工位"]["en-US"] = "Workstation"; + tempMap["工位"]["ms-MY"] = "Stesen Kerja"; + + tempMap["头部"]["zh-CN"] = "头部"; + tempMap["头部"]["en-US"] = "Head"; + tempMap["头部"]["ms-MY"] = "Kepala"; + + tempMap["尾部"]["zh-CN"] = "尾部"; + tempMap["尾部"]["en-US"] = "Tail"; + tempMap["尾部"]["ms-MY"] = "Ekor"; + + tempMap["边"]["zh-CN"] = "边"; + tempMap["边"]["en-US"] = "Edge"; + tempMap["边"]["ms-MY"] = "Tepi"; + + tempMap["请稍后"]["zh-CN"] = "请稍后"; + tempMap["请稍后"]["en-US"] = "Please wait"; + tempMap["请稍后"]["ms-MY"] = "Sila tunggu"; + + tempMap["程序"]["zh-CN"] = "程序"; + tempMap["程序"]["en-US"] = "Program"; + tempMap["程序"]["ms-MY"] = "Program"; + + tempMap["正在"]["zh-CN"] = "正在"; + tempMap["正在"]["en-US"] = "In progress"; + tempMap["正在"]["ms-MY"] = "Sedang"; + + tempMap["数据"]["zh-CN"] = "数据"; + tempMap["数据"]["en-US"] = "Data"; + tempMap["数据"]["ms-MY"] = "Data"; + + tempMap["请勿"]["zh-CN"] = "请勿"; + tempMap["请勿"]["en-US"] = "Do not"; + tempMap["请勿"]["ms-MY"] = "Jangan"; + + tempMap["超时"]["zh-CN"] = "超时"; + tempMap["超时"]["en-US"] = "Timeout"; + tempMap["超时"]["ms-MY"] = "Tamat masa"; + + tempMap["取图"]["zh-CN"] = "取图"; + tempMap["取图"]["en-US"] = "Capture Image"; + tempMap["取图"]["ms-MY"] = "Tangkap Imej"; + + tempMap["请"]["zh-CN"] = "请"; + tempMap["请"]["en-US"] = "Please"; + tempMap["请"]["ms-MY"] = "Sila"; + + tempMap["稍等"]["zh-CN"] = "稍等"; + tempMap["稍等"]["en-US"] = "Wait a moment"; + tempMap["稍等"]["ms-MY"] = "Tunggu sebentar"; + + tempMap["检查"]["zh-CN"] = "检查"; + tempMap["检查"]["en-US"] = "Check"; + tempMap["检查"]["ms-MY"] = "Periksa"; + + tempMap["跳过"]["zh-CN"] = "跳过"; + tempMap["跳过"]["en-US"] = "Skip"; + tempMap["跳过"]["ms-MY"] = "Langkau"; + + tempMap["当前"]["zh-CN"] = "当前"; + tempMap["当前"]["en-US"] = "Current"; + tempMap["当前"]["ms-MY"] = "Semasa"; + + tempMap["治具"]["zh-CN"] = "治具"; + tempMap["治具"]["en-US"] = "Jig"; + tempMap["治具"]["ms-MY"] = "Jig"; + + tempMap["补偿值"]["zh-CN"] = "补偿值"; + tempMap["补偿值"]["en-US"] = "Compensation Value"; + tempMap["补偿值"]["ms-MY"] = "Nilai Pampasan"; + + tempMap["固定"]["zh-CN"] = "固定"; + tempMap["固定"]["en-US"] = "Fixed"; + tempMap["固定"]["ms-MY"] = "Tetap"; + + tempMap["到"]["zh-CN"] = "到"; + tempMap["到"]["en-US"] = "To"; + tempMap["到"]["ms-MY"] = "Ke"; + + tempMap["间距"]["zh-CN"] = "间距"; + tempMap["间距"]["en-US"] = "Spacing"; + tempMap["间距"]["ms-MY"] = "Jarak"; + + tempMap["同心距"]["zh-CN"] = "同心距"; + tempMap["同心距"]["en-US"] = "Concentric Distance"; + tempMap["同心距"]["ms-MY"] = "Jarak Sepusat"; + + tempMap["翘钉"]["zh-CN"] = "翘钉"; + tempMap["翘钉"]["en-US"] = "Lifted Nail"; + tempMap["翘钉"]["ms-MY"] = "Paku Terangkat"; + + tempMap["平行度"]["zh-CN"] = "平行度"; + tempMap["平行度"]["en-US"] = "Parallelism"; + tempMap["平行度"]["ms-MY"] = "Keselarian"; + + tempMap["焊渣"]["zh-CN"] = "焊渣"; + tempMap["焊渣"]["en-US"] = "Weld Spatter"; + tempMap["焊渣"]["ms-MY"] = "Percikan Kimpalan"; + + tempMap["裂纹"]["zh-CN"] = "裂纹"; + tempMap["裂纹"]["en-US"] = "Crack"; + tempMap["裂纹"]["ms-MY"] = "Retak"; + + tempMap["炸焊"]["zh-CN"] = "炸焊"; + tempMap["炸焊"]["en-US"] = "Weld Explosion"; + tempMap["炸焊"]["ms-MY"] = "Letupan Kimpalan"; + + tempMap["焊烟"]["zh-CN"] = "焊烟"; + tempMap["焊烟"]["en-US"] = "Weld Fume"; + tempMap["焊烟"]["ms-MY"] = "Asap Kimpalan"; + + tempMap["沙眼"]["zh-CN"] = "沙眼"; + tempMap["沙眼"]["en-US"] = "Pinhole"; + tempMap["沙眼"]["ms-MY"] = "Lubang Jarum"; + + tempMap["标识"]["zh-CN"] = "标识"; + tempMap["标识"]["en-US"] = "Mark"; + tempMap["标识"]["ms-MY"] = "Tanda"; + + tempMap["标准"]["zh-CN"] = "标准"; + tempMap["标准"]["en-US"] = "Standard"; + tempMap["标准"]["ms-MY"] = "Standard"; + + tempMap["胶带"]["zh-CN"] = "胶带"; + tempMap["胶带"]["en-US"] = "Tape"; + tempMap["胶带"]["ms-MY"] = "Pita"; + + tempMap["脏污"]["zh-CN"] = "脏污"; + tempMap["脏污"]["en-US"] = "Dirt"; + tempMap["脏污"]["ms-MY"] = "Kotor"; + + tempMap["油污"]["zh-CN"] = "油污"; + tempMap["油污"]["en-US"] = "Oil Stain"; + tempMap["油污"]["ms-MY"] = "Noda Minyak"; + + tempMap["划伤"]["zh-CN"] = "划伤"; + tempMap["划伤"]["en-US"] = "Scratch"; + tempMap["划伤"]["ms-MY"] = "Calar"; + + tempMap["面"]["zh-CN"] = "面"; + tempMap["面"]["en-US"] = "Surface"; + tempMap["面"]["ms-MY"] = "Permukaan"; + + tempMap["筛选"]["zh-CN"] = "筛选"; + tempMap["筛选"]["en-US"] = "Filter"; + tempMap["筛选"]["ms-MY"] = "Tapisan"; + + tempMap["缩放"]["zh-CN"] = "缩放"; + tempMap["缩放"]["en-US"] = "Zoom"; + tempMap["缩放"]["ms-MY"] = "Zum"; + + tempMap["倍率"]["zh-CN"] = "倍率"; + tempMap["倍率"]["en-US"] = "Magnification"; + tempMap["倍率"]["ms-MY"] = "Pembesaran"; + + tempMap["方向"]["zh-CN"] = "方向"; + tempMap["方向"]["en-US"] = "Direction"; + tempMap["方向"]["ms-MY"] = "Arah"; + + tempMap["灰度值"]["zh-CN"] = "灰度值"; + tempMap["灰度值"]["en-US"] = "Gray Value"; + tempMap["灰度值"]["ms-MY"] = "Nilai Kelabu"; + + tempMap["缺陷"]["zh-CN"] = "缺陷"; + tempMap["缺陷"]["en-US"] = "Defect"; + tempMap["缺陷"]["ms-MY"] = "Kecacatan"; + + tempMap["定位"]["zh-CN"] = "定位"; + tempMap["定位"]["en-US"] = "Positioning"; + tempMap["定位"]["ms-MY"] = "Kedudukan"; + + tempMap["定位网"]["zh-CN"] = "定位网"; + tempMap["定位网"]["en-US"] = "Positioning Network"; + tempMap["定位网"]["ms-MY"] = "Rangkaian Kedudukan"; + + tempMap["缺陷网"]["zh-CN"] = "缺陷网"; + tempMap["缺陷网"]["en-US"] = "Defect Network"; + tempMap["缺陷网"]["ms-MY"] = "Rangkaian Kecacatan"; + + tempMap["平均"]["zh-CN"] = "平均"; + tempMap["平均"]["en-US"] = "Average"; + tempMap["平均"]["ms-MY"] = "Purata"; + + tempMap["外扩"]["zh-CN"] = "外扩"; + tempMap["外扩"]["en-US"] = "Outward Expansion"; + tempMap["外扩"]["ms-MY"] = "Pengembangan Luar"; + + tempMap["测试"]["zh-CN"] = "测试"; + tempMap["测试"]["en-US"] = "Test"; + tempMap["测试"]["ms-MY"] = "Ujian"; + + tempMap["查看器"]["zh-CN"] = "查看器"; + tempMap["查看器"]["en-US"] = "Viewer"; + tempMap["查看器"]["ms-MY"] = "Pemapar"; + + tempMap["隐藏"]["zh-CN"] = "隐藏"; + tempMap["隐藏"]["en-US"] = "Hide"; + tempMap["隐藏"]["ms-MY"] = "Sembunyi"; + + tempMap["显示"]["zh-CN"] = "显示"; + tempMap["显示"]["en-US"] = "Show"; + tempMap["显示"]["ms-MY"] = "Tunjukkan"; + + tempMap["过滤"]["zh-CN"] = "过滤"; + tempMap["过滤"]["en-US"] = "Filter"; + tempMap["过滤"]["ms-MY"] = "Tapis"; + + tempMap["训练用"]["zh-CN"] = "训练用"; + tempMap["训练用"]["en-US"] = "For Training"; + tempMap["训练用"]["ms-MY"] = "Untuk Latihan"; + + tempMap["直接"]["zh-CN"] = "直接"; + tempMap["直接"]["en-US"] = "Direct"; + tempMap["直接"]["ms-MY"] = "Langsung"; + + tempMap["模式"]["zh-CN"] = "模式"; + tempMap["模式"]["en-US"] = "Mode"; + tempMap["模式"]["ms-MY"] = "Mod"; + + tempMap["通用"]["zh-CN"] = "通用"; + tempMap["通用"]["en-US"] = "General"; + tempMap["通用"]["ms-MY"] = "Umum"; + + tempMap["仍然"]["zh-CN"] = "仍然"; + tempMap["仍然"]["en-US"] = "Still"; + tempMap["仍然"]["ms-MY"] = "Masih"; + + tempMap["进行"]["zh-CN"] = "进行"; + tempMap["进行"]["en-US"] = "Proceed"; + tempMap["进行"]["ms-MY"] = "Teruskan"; + + tempMap["尺寸"]["zh-CN"] = "尺寸"; + tempMap["尺寸"]["en-US"] = "Dimension"; + tempMap["尺寸"]["ms-MY"] = "Dimensi"; + + tempMap["过短"]["zh-CN"] = "过短"; + tempMap["过短"]["en-US"] = "Too Short"; + tempMap["过短"]["ms-MY"] = "Terlalu Pendek"; + + tempMap["过长"]["zh-CN"] = "过长"; + tempMap["过长"]["en-US"] = "Too Long"; + tempMap["过长"]["ms-MY"] = "Terlalu Panjang"; + + tempMap["过大"]["zh-CN"] = "过大"; + tempMap["过大"]["en-US"] = "Too Large"; + tempMap["过大"]["ms-MY"] = "Terlalu Besar"; + + tempMap["过小"]["zh-CN"] = "过小"; + tempMap["过小"]["en-US"] = "Too Small"; + tempMap["过小"]["ms-MY"] = "Terlalu Kecil"; + + tempMap["单次"]["zh-CN"] = "单次"; + tempMap["单次"]["en-US"] = "Single"; + tempMap["单次"]["ms-MY"] = "Tunggal"; + + tempMap["多次"]["zh-CN"] = "多次"; + tempMap["多次"]["en-US"] = "Multiple"; + tempMap["多次"]["ms-MY"] = "Berganda"; + + tempMap["编辑器"]["zh-CN"] = "编辑器"; + tempMap["编辑器"]["en-US"] = "Editor"; + tempMap["编辑器"]["ms-MY"] = "Editor"; + + tempMap["选择"]["zh-CN"] = "选择"; + tempMap["选择"]["en-US"] = "Select"; + tempMap["选择"]["ms-MY"] = "Pilih"; + + tempMap["写入"]["zh-CN"] = "写入"; + tempMap["写入"]["en-US"] = "Write"; + tempMap["写入"]["ms-MY"] = "Tulis"; + + tempMap["全部"]["zh-CN"] = "全部"; + tempMap["全部"]["en-US"] = "All"; + tempMap["全部"]["ms-MY"] = "Semua"; + + tempMap["模拟"]["zh-CN"] = "模拟"; + tempMap["模拟"]["en-US"] = "Simulate"; + tempMap["模拟"]["ms-MY"] = "Simulasi"; + + tempMap["重新"]["zh-CN"] = "重新"; + tempMap["重新"]["en-US"] = "Re-"; + tempMap["重新"]["ms-MY"] = "Ulang"; + + tempMap["监控"]["zh-CN"] = "监控"; + tempMap["监控"]["en-US"] = "Monitoring"; + tempMap["监控"]["ms-MY"] = "Pemantauan"; + + tempMap["铜极耳"]["zh-CN"] = "铜极耳"; + tempMap["铜极耳"]["en-US"] = "Copper Tab"; + tempMap["铜极耳"]["ms-MY"] = "Tab Kuprum"; + + tempMap["铝极耳"]["zh-CN"] = "铝极耳"; + tempMap["铝极耳"]["en-US"] = "Aluminum Tab"; + tempMap["铝极耳"]["ms-MY"] = "Tab Aluminium"; + + tempMap["像素"]["zh-CN"] = "像素"; + tempMap["像素"]["en-US"] = "Pixel"; + tempMap["像素"]["ms-MY"] = "Piksel"; + + tempMap["测量"]["zh-CN"] = "测量"; + tempMap["测量"]["en-US"] = "Measure"; + tempMap["测量"]["ms-MY"] = "Ukur"; + + tempMap["补偿"]["zh-CN"] = "补偿"; + tempMap["补偿"]["en-US"] = "Compensation"; + tempMap["补偿"]["ms-MY"] = "Pampasan"; + + tempMap["裁切"]["zh-CN"] = "裁切"; + tempMap["裁切"]["en-US"] = "Crop"; + tempMap["裁切"]["ms-MY"] = "Potong"; + + tempMap["缩小"]["zh-CN"] = "缩小"; + tempMap["缩小"]["en-US"] = "Shrink"; + tempMap["缩小"]["ms-MY"] = "Kecilkan"; + + tempMap["长"]["zh-CN"] = "长"; + tempMap["长"]["en-US"] = "Length"; + tempMap["长"]["ms-MY"] = "Panjang"; + + tempMap["宽"]["zh-CN"] = "宽"; + tempMap["宽"]["en-US"] = "Width"; + tempMap["宽"]["ms-MY"] = "Lebar"; + + tempMap["高"]["zh-CN"] = "高"; + tempMap["高"]["en-US"] = "High"; + tempMap["高"]["ms-MY"] = "Tinggi"; + + tempMap["短"]["zh-CN"] = "短"; + tempMap["短"]["en-US"] = "Short"; + tempMap["短"]["ms-MY"] = "Pendek"; + + tempMap["预焊印"]["zh-CN"] = "预焊印"; + tempMap["预焊印"]["en-US"] = "Pre-weld Mark"; + tempMap["预焊印"]["ms-MY"] = "Tanda Pra-kimpalan"; + + tempMap["起点"]["zh-CN"] = "起点"; + tempMap["起点"]["en-US"] = "Start Point"; + tempMap["起点"]["ms-MY"] = "Titik Mula"; + + tempMap["终点"]["zh-CN"] = "终点"; + tempMap["终点"]["en-US"] = "End Point"; + tempMap["终点"]["ms-MY"] = "Titik Tamat"; + + tempMap["线体号"]["zh-CN"] = "线体号"; + tempMap["线体号"]["en-US"] = "Line Number"; + tempMap["线体号"]["ms-MY"] = "Nombor Talian"; + + tempMap["抓取"]["zh-CN"] = "抓取"; + tempMap["抓取"]["en-US"] = "Grab"; + tempMap["抓取"]["ms-MY"] = "Tangkap"; + + tempMap["抓边"]["zh-CN"] = "抓边"; + tempMap["抓边"]["en-US"] = "Grab Edge"; + tempMap["抓边"]["ms-MY"] = "Tangkap Tepi"; + + tempMap["初始化"]["zh-CN"] = "初始化"; + tempMap["初始化"]["en-US"] = "Initialize"; + tempMap["初始化"]["ms-MY"] = "Mulakan"; + + tempMap["初始化中"]["zh-CN"] = "初始化中"; + tempMap["初始化中"]["en-US"] = "Initializing"; + tempMap["初始化中"]["ms-MY"] = "Sedang Memulakan"; + + tempMap["周一"]["zh-CN"] = "周一"; + tempMap["周一"]["en-US"] = "Monday"; + tempMap["周一"]["ms-MY"] = "Isnin"; + + tempMap["周二"]["zh-CN"] = "周二"; + tempMap["周二"]["en-US"] = "Tuesday"; + tempMap["周二"]["ms-MY"] = "Selasa"; + + tempMap["周三"]["zh-CN"] = "周三"; + tempMap["周三"]["en-US"] = "Wednesday"; + tempMap["周三"]["ms-MY"] = "Rabu"; + + tempMap["周四"]["zh-CN"] = "周四"; + tempMap["周四"]["en-US"] = "Thursday"; + tempMap["周四"]["ms-MY"] = "Khamis"; + + tempMap["周五"]["zh-CN"] = "周五"; + tempMap["周五"]["en-US"] = "Friday"; + tempMap["周五"]["ms-MY"] = "Jumaat"; + + tempMap["周六"]["zh-CN"] = "周六"; + tempMap["周六"]["en-US"] = "Saturday"; + tempMap["周六"]["ms-MY"] = "Sabtu"; + + tempMap["周日"]["zh-CN"] = "周日"; + tempMap["周日"]["en-US"] = "Sunday"; + tempMap["周日"]["ms-MY"] = "Ahad"; + + tempMap["一键"]["zh-CN"] = "一键"; + tempMap["一键"]["en-US"] = "One-Click"; + tempMap["一键"]["ms-MY"] = "Satu-Klik"; + + tempMap["替换"]["zh-CN"] = "替换"; + tempMap["替换"]["en-US"] = "Replace"; + tempMap["替换"]["ms-MY"] = "Ganti"; + + tempMap["虚拟"]["zh-CN"] = "虚拟"; + tempMap["虚拟"]["en-US"] = "Virtual"; + tempMap["虚拟"]["ms-MY"] = "Maya"; + + tempMap["物理"]["zh-CN"] = "物理"; + tempMap["物理"]["en-US"] = "Physical"; + tempMap["物理"]["ms-MY"] = "Fizikal"; + + tempMap["重合"]["zh-CN"] = "重合"; + tempMap["重合"]["en-US"] = "Overlap"; + tempMap["重合"]["ms-MY"] = "Tindih"; + + tempMap["上移"]["zh-CN"] = "上移"; + tempMap["上移"]["en-US"] = "Move Up"; + tempMap["上移"]["ms-MY"] = "Alih ke Atas"; + + tempMap["下移"]["zh-CN"] = "下移"; + tempMap["下移"]["en-US"] = "Move Down"; + tempMap["下移"]["ms-MY"] = "Alih ke Bawah"; + + tempMap["裂痕"]["zh-CN"] = "裂痕"; + tempMap["裂痕"]["en-US"] = "Crack"; + tempMap["裂痕"]["ms-MY"] = "Retak"; + + tempMap["断焊"]["zh-CN"] = "断焊"; + tempMap["断焊"]["en-US"] = "Weld Break"; + tempMap["断焊"]["ms-MY"] = "Kimpalan Putus"; + + tempMap["向"]["zh-CN"] = "向"; + tempMap["向"]["en-US"] = "Direction"; + tempMap["向"]["ms-MY"] = "Arah"; + + tempMap["正负极"]["zh-CN"] = "正负极"; + tempMap["正负极"]["en-US"] = "Positive and Negative Poles"; + tempMap["正负极"]["ms-MY"] = "Kutub Positif dan Negatif"; + + tempMap["角度"]["zh-CN"] = "角度"; + tempMap["角度"]["en-US"] = "Angle"; + tempMap["角度"]["ms-MY"] = "Sudut"; + + tempMap["连线"]["zh-CN"] = "连线"; + tempMap["连线"]["en-US"] = "Connect"; + tempMap["连线"]["ms-MY"] = "Sambung"; + + tempMap["和"]["zh-CN"] = "和"; + tempMap["和"]["en-US"] = "And"; + tempMap["和"]["ms-MY"] = "Dan"; + + tempMap["是否"]["zh-CN"] = "是否"; + tempMap["是否"]["en-US"] = "Whether"; + tempMap["是否"]["ms-MY"] = "Sama ada"; + + tempMap["先拍"]["zh-CN"] = "先拍"; + tempMap["先拍"]["en-US"] = "Capture First"; + tempMap["先拍"]["ms-MY"] = "Tangkap Dahulu"; + + tempMap["严重"]["zh-CN"] = "严重"; + tempMap["严重"]["en-US"] = "Severe"; + tempMap["严重"]["ms-MY"] = "Teruk"; + + tempMap["丢点"]["zh-CN"] = "丢点"; + tempMap["丢点"]["en-US"] = "Missing Point"; + tempMap["丢点"]["ms-MY"] = "Titik Hilang"; + + tempMap["存在"]["zh-CN"] = "存在"; + tempMap["存在"]["en-US"] = "Exists"; + tempMap["存在"]["ms-MY"] = "Wujud"; + + tempMap["竖直边"]["zh-CN"] = "竖直边"; + tempMap["竖直边"]["en-US"] = "Vertical Edge"; + tempMap["竖直边"]["ms-MY"] = "Tepi Menegak"; + + tempMap["垂直边"]["zh-CN"] = "垂直边"; + tempMap["垂直边"]["en-US"] = "Vertical Edge"; + tempMap["垂直边"]["ms-MY"] = "Tepi Menegak"; + + tempMap["水平边"]["zh-CN"] = "水平边"; + tempMap["水平边"]["en-US"] = "Horizontal Edge"; + tempMap["水平边"]["ms-MY"] = "Tepi Mendatar"; + + tempMap["极柱"]["zh-CN"] = "极柱"; + tempMap["极柱"]["en-US"] = "Terminal Post"; + tempMap["极柱"]["ms-MY"] = "Tiang Terminal"; + + tempMap["圆"]["zh-CN"] = "圆"; + tempMap["圆"]["en-US"] = "Circle"; + tempMap["圆"]["ms-MY"] = "Bulatan"; + + tempMap["须与"]["zh-CN"] = "须与"; + tempMap["须与"]["en-US"] = "Must be with"; + tempMap["须与"]["ms-MY"] = "Mesti dengan"; + + tempMap["覆盖"]["zh-CN"] = "覆盖"; + tempMap["覆盖"]["en-US"] = "Cover"; + tempMap["覆盖"]["ms-MY"] = "Tutup"; + + tempMap["沟通"]["zh-CN"] = "沟通"; + tempMap["沟通"]["en-US"] = "Communication"; + tempMap["沟通"]["ms-MY"] = "Komunikasi"; + + tempMap["设备"]["zh-CN"] = "设备"; + tempMap["设备"]["en-US"] = "Equipment"; + tempMap["设备"]["ms-MY"] = "Peralatan"; + + tempMap["破损"]["zh-CN"] = "破损"; + tempMap["破损"]["en-US"] = "Breakage"; + tempMap["破损"]["ms-MY"] = "Keretakan"; + + tempMap["褶皱"]["zh-CN"] = "褶皱"; + tempMap["褶皱"]["en-US"] = "Wrinkle"; + tempMap["褶皱"]["ms-MY"] = "Kedut"; + + tempMap["其他"]["zh-CN"] = "其他"; + tempMap["其他"]["en-US"] = "Other"; + tempMap["其他"]["ms-MY"] = "Lain-lain"; + + tempMap["未知缺陷"]["zh-CN"] = "未知缺陷"; + tempMap["未知缺陷"]["en-US"] = "Unknown Defect"; + tempMap["未知缺陷"]["ms-MY"] = "Kecacatan Tidak Diketahui"; + + tempMap["露白"]["zh-CN"] = "露白"; + tempMap["露白"]["en-US"] = "Exposed White"; + tempMap["露白"]["ms-MY"] = "Putih Terdedah"; + + tempMap["等比"]["zh-CN"] = "等比"; + tempMap["等比"]["en-US"] = "Equal Ratio"; + tempMap["等比"]["ms-MY"] = "Nisbah Sama"; + + tempMap["缩放"]["zh-CN"] = "缩放"; + tempMap["缩放"]["en-US"] = "Zoom"; + tempMap["缩放"]["ms-MY"] = "Zum"; + + tempMap["或"]["zh-CN"] = "或"; + tempMap["或"]["en-US"] = "Or"; + tempMap["或"]["ms-MY"] = "Atau"; + + tempMap["百分比"]["zh-CN"] = "百分比"; + tempMap["百分比"]["en-US"] = "Percentage"; + tempMap["百分比"]["ms-MY"] = "Peratusan"; + + tempMap["拍摄"]["zh-CN"] = "拍摄"; + tempMap["拍摄"]["en-US"] = "Capture"; + tempMap["拍摄"]["ms-MY"] = "Tangkap"; + + tempMap["有效"]["zh-CN"] = "有效"; + tempMap["有效"]["en-US"] = "Valid"; + tempMap["有效"]["ms-MY"] = "Sah"; + + tempMap["无效"]["zh-CN"] = "无效"; + tempMap["无效"]["en-US"] = "Invalid"; + tempMap["无效"]["ms-MY"] = "Tidak Sah"; + + tempMap["R角"]["zh-CN"] = "R角"; + tempMap["R角"]["en-US"] = "R Corner"; + tempMap["R角"]["ms-MY"] = "Sudut R"; + + tempMap["开启"]["zh-CN"] = "开启"; + tempMap["开启"]["en-US"] = "Turn On"; + tempMap["开启"]["ms-MY"] = "Hidupkan"; + + tempMap["关闭"]["zh-CN"] = "关闭"; + tempMap["关闭"]["en-US"] = "Turn Off"; + tempMap["关闭"]["ms-MY"] = "Matikan"; + + tempMap["结束"]["zh-CN"] = "结束"; + tempMap["结束"]["en-US"] = "End"; + tempMap["结束"]["ms-MY"] = "Tamat"; + + tempMap["起始"]["zh-CN"] = "起始"; + tempMap["起始"]["en-US"] = "Start"; + tempMap["起始"]["ms-MY"] = "Mula"; + + tempMap["正"]["zh-CN"] = "正"; + tempMap["正"]["en-US"] = "Positive"; + tempMap["正"]["ms-MY"] = "Positif"; + + tempMap["负"]["zh-CN"] = "负"; + tempMap["负"]["en-US"] = "Negative"; + tempMap["负"]["ms-MY"] = "Negatif"; + + tempMap["系数"]["zh-CN"] = "系数"; + tempMap["系数"]["en-US"] = "Coefficient"; + tempMap["系数"]["ms-MY"] = "Pekali"; + + tempMap["测量点"]["zh-CN"] = "测量点"; + tempMap["测量点"]["en-US"] = "Measurement Point"; + tempMap["测量点"]["ms-MY"] = "Titik Ukuran"; + + tempMap["来料"]["zh-CN"] = "来料"; + tempMap["来料"]["en-US"] = "Incoming Material"; + tempMap["来料"]["ms-MY"] = "Bahan Masuk"; + + tempMap["扫描"]["zh-CN"] = "扫描"; + tempMap["扫描"]["en-US"] = "Scan"; + tempMap["扫描"]["ms-MY"] = "Imbas"; + + tempMap["顺序"]["zh-CN"] = "顺序"; + tempMap["顺序"]["en-US"] = "Order"; + tempMap["顺序"]["ms-MY"] = "Susunan"; + + tempMap["壳体"]["zh-CN"] = "壳体"; + tempMap["壳体"]["en-US"] = "Housing"; + tempMap["壳体"]["ms-MY"] = "Rumah"; + + tempMap["压装"]["zh-CN"] = "压装"; + tempMap["压装"]["en-US"] = "Press Fit"; + tempMap["压装"]["ms-MY"] = "Pemasukan Tekan"; + + tempMap["凸高"]["zh-CN"] = "凸高"; + tempMap["凸高"]["en-US"] = "Protrusion Height"; + tempMap["凸高"]["ms-MY"] = "Ketinggian Tonjolan"; + + tempMap["中..."]["zh-CN"] = "中..."; + tempMap["中..."]["en-US"] = "In progress..."; + tempMap["中..."]["ms-MY"] = "Sedang berlangsung..."; + + tempMap["一次"]["zh-CN"] = "一次"; + tempMap["一次"]["en-US"] = "Primary"; + tempMap["一次"]["ms-MY"] = "Pertama"; + + tempMap["二次"]["zh-CN"] = "二次"; + tempMap["二次"]["en-US"] = "Secondary"; + tempMap["二次"]["ms-MY"] = "Kedua"; + + tempMap["非缺陷"]["zh-CN"] = "非缺陷"; + tempMap["非缺陷"]["en-US"] = "Non-defect"; + tempMap["非缺陷"]["ms-MY"] = "Bukan Kecacatan"; + + tempMap["退出中"]["zh-CN"] = "退出中"; + tempMap["退出中"]["en-US"] = "Exiting"; + tempMap["退出中"]["ms-MY"] = "Sedang Keluar"; + + tempMap["焊点"]["zh-CN"] = "焊点"; + tempMap["焊点"]["en-US"] = "Weld Spot"; + tempMap["焊点"]["ms-MY"] = "Titik Kimpalan"; + + tempMap["平钉"]["zh-CN"] = "平钉"; + tempMap["平钉"]["en-US"] = "Flat Nail"; + tempMap["平钉"]["ms-MY"] = "Paku Rata"; + + tempMap["凹钉"]["zh-CN"] = "凹钉"; + tempMap["凹钉"]["en-US"] = "Concave Nail"; + tempMap["凹钉"]["ms-MY"] = "Paku Cekung"; + + tempMap["标定"]["zh-CN"] = "标定"; + tempMap["标定"]["en-US"] = "Calibration"; + tempMap["标定"]["ms-MY"] = "Penentukuran"; + + tempMap["生产"]["zh-CN"] = "生产"; + tempMap["生产"]["en-US"] = "Production"; + tempMap["生产"]["ms-MY"] = "Pengeluaran"; + + tempMap["钉子"]["zh-CN"] = "钉子"; + tempMap["钉子"]["en-US"] = "Nail"; + tempMap["钉子"]["ms-MY"] = "Paku"; + + tempMap["轴"]["zh-CN"] = "轴"; + tempMap["轴"]["en-US"] = "Axis"; + tempMap["轴"]["ms-MY"] = "Paksi"; + + tempMap["设定"]["zh-CN"] = "设定"; + tempMap["设定"]["en-US"] = "Setting"; + tempMap["设定"]["ms-MY"] = "Tetapan"; + + tempMap["相似"]["zh-CN"] = "相似"; + tempMap["相似"]["en-US"] = "Similar"; + tempMap["相似"]["ms-MY"] = "Serupa"; + //基准标定模式 +#pragma endregion +#pragma region 处理翻译字典 + for (const auto pair : tempMap) { + if (pair.first.size() > basicTranslations.size()) + basicTranslations.resize(pair.first.size()); + basicTranslations.at(pair.first.size() - 1).insert(pair); + } +#pragma endregion +} \ No newline at end of file diff --git a/include/translation.h b/include/translation.h new file mode 100644 index 0000000..a804129 --- /dev/null +++ b/include/translation.h @@ -0,0 +1,401 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define translationLRUCacheCapacity 3000 //LRU缓存容量,建议设置为1000-5000,根据实际情况调整 +using json = nlohmann::json; + +/** + * 单头文件翻译类 - 单例模式 + * 支持可扩展的语言section + * 文本建议:建议翻译固定文本,像文本中带有数值之类会改变的建议拆分出固定文本进行翻译 + */ +class translationLRUCache { +public: + explicit translationLRUCache(int capacity) : maxCapacity(capacity) { + if (capacity <= 0) { + throw std::invalid_argument("LRU缓存容量必须大于0"); + } + } + + // 检查字符串是否在缓存中 + bool contains(const std::string& key, std::string& value) { + QMutexLocker locker(&mutex); + int index = cacheKeyList.indexOf(QString::fromStdString(key)); + if (index != -1) { + // 移动到列表头部(最近使用) + cacheKeyList.move(index, 0); + value = cacheMap[key]; + return true; + } + return false; + } + + // 添加字符串到缓存 + void put(const std::string& key, const std::string& value) { + QMutexLocker locker(&mutex); + std::pairpairData = { key,value }; + if (key.size() == 0 || value.size() == 0) { + return; // 不缓存空字符串 + } + + int index = cacheKeyList.indexOf(QString::fromStdString(key)); + if (index != -1) { + // 已存在,移动到头部 + cacheKeyList.move(index, 0); + cacheMap[key] = value; // 更新值 + return; + } + + // 不存在,需要添加 + if (cacheKeyList.size() >= maxCapacity) { + // 缓存已满,移除最久未使用的元素(尾部) + cacheMap.remove(cacheKeyList.last().toStdString()); + cacheKeyList.removeLast(); + } + + // 添加新元素到头部 + cacheKeyList.prepend(QString::fromStdString(key)); + cacheMap.insert(key, value); + } + + // 移除指定元素 + bool remove(const std::string& key) { + QMutexLocker locker(&mutex); + int index = cacheKeyList.indexOf(QString::fromStdString(key)); + if (index != -1) { + cacheKeyList.removeAt(index); + cacheMap.remove(key); + return true; + } + return false; + } + + // 获取缓存大小 + int size() { + QMutexLocker locker(&mutex); + return cacheKeyList.size(); + } + + // 获取最大容量 + int capacity() { + QMutexLocker locker(&mutex); + return maxCapacity; + } + + // 检查是否为空 + bool isEmpty() { + QMutexLocker locker(&mutex); + return cacheKeyList.isEmpty(); + } + + // 清空缓存 + void clear() { + QMutexLocker locker(&mutex); + cacheKeyList.clear(); + } + + +private: + QMutex mutex; + int maxCapacity; + QStringList cacheKeyList; // QStringList,头部是最近使用的,尾部是最久未使用的 + QMap cacheMap; +}; +class Translation{ +private: + translationLRUCache translatedCache{ translationLRUCacheCapacity };//缓存最近翻译的文本进行提速 + std::vector sections; // 可扩展的语言列表 + std::vector, std::less<>>> basicTranslations; //内置字典 [文本长度][文本][语言] std::less<> 启用透明查找,支持 string_view 零拷贝查询 + std::string currentLanguage = "zh-CN"; // 默认语言 + QMutex mutex;//线程安全锁 + // 私有构造函数 + Translation(){ + QMutexLocker locker(&mutex);//线程安全锁 + //语言选项 + addSection_unsafe("zh-CN"); + addSection_unsafe("en-US"); + addSection_unsafe("ms-MY"); + if (sections.size() > 0)//默认为第一个语言 + currentLanguage = sections[0]; + loadFromFile("./config/translation.json"); + initBuiltInDict(basicTranslations);//初始化默认词库 + + } + + // 禁用拷贝构造函数和赋值运算符 + Translation(const Translation&) = delete; + Translation& operator=(const Translation&) = delete; + +public: + // 获取单例实例 + static Translation& getInstance() { + static Translation instance; + return instance; + } + + // 从JSON文件加载配置 + bool loadFromFile(const std::string& filePath) { + try { + std::ifstream file(filePath); + if (!file.is_open()) { + return false; + } + + originalJson.clear(); + file >> originalJson; + file.close(); + + return parseJson_unsafe(originalJson); + } catch (const std::exception& e) { + std::cerr << "Error loading translation file: " << e.what() << std::endl; + return false; + } + } + + // 从JSON字符串加载配置 + bool loadFromString(const std::string& jsonString) { + try { + json j = json::parse(jsonString); + return parseJson_unsafe(j); + } catch (const std::exception& e) { + std::cerr << "Error parsing JSON string: " << e.what() << std::endl; + return false; + } + } + + // 从JSON对象加载配置 + bool loadFromJson(const json& j) { + return parseJson_unsafe(j); + } + bool setLanguage(const std::string& lang) { + if (currentLanguage == lang)// + return false; + for (const auto& section : sections) { + if (section == lang) { + currentLanguage = lang; + return true; + } + } + // 如果语言不在sections中,也允许设置(可能是新添加的语言) + currentLanguage = lang; + return false; + } + + // 获取当前语言 + std::string getCurrentLanguage() const { + return currentLanguage; + } + + // 获取翻译文本 + std::string translate(const std::string& key) { + std::string cacheResult; + if (translatedCache.contains(key + currentLanguage, cacheResult)) + return cacheResult; + QMutexLocker locker(&mutex);//线程安全锁 + auto result = translate_unsafe(key); + translatedCache.put(key + currentLanguage, result); + return result; // 如果找不到翻译,返回原始key + } + + // 获取指定语言的翻译 + std::string translate(const std::string& key, const std::string& lang) { + QMutexLocker locker(&mutex);//线程安全锁 + {//先从全字匹配字典中获取 + if (key.length() <= basicTranslations.size()) { + auto it = basicTranslations.at(key.length() - 1).find(key); + if (it != basicTranslations.at(key.length() - 1).end()) { + auto langIt = it->second.find(lang); + if (langIt != it->second.end()) { + return langIt->second; + } + } + } + } + return key; + } + + //获取所有语言的翻译结果 + std::vector < std::pair < std::string, std::string>> getAllTranslateResult(const std::string& key) { + QMutexLocker locker(&mutex);//线程安全锁 + std::vector < std::pair < std::string, std::string>> Result; + for (auto& section : sections) { + Result.push_back({ section,translate_unsafe(key,section) }); + } + return Result; + } + + // 添加语言section + void addSection(const std::string& lang) { + QMutexLocker locker(&mutex);//线程安全锁 + if (lang == "us-EN") return;//老代码中大量存在的错误编码 + for (const auto& section : sections) { + if (section == lang) return; // 已存在 + } + sections.push_back(lang); + } + + // 获取所有支持的语言 + const std::vector& getSections() const { + return sections; + } + + // 检查是否有指定key的翻译 + bool hasTranslation(const std::string& key) const { + return basicTranslations.at(key.length() - 1).find(key) != basicTranslations.at(key.length() - 1).end(); + } + + // 获取所有翻译key + std::vector getAllKeys() { + QMutexLocker locker(&mutex);//线程安全锁 + std::vector keys; + for (const auto& vec : basicTranslations) { + for(const auto& pair : vec) + keys.push_back(pair.first); + } + return keys; + } + + //保存到JSON文件 + bool saveToFile(const std::string& filePath) { + QMutexLocker locker(&mutex);//线程安全锁 + try { + originalJson["current_language"] = currentLanguage; + originalJson["section"] = sections; + + + std::ofstream file(filePath); + file << originalJson.dump(4); // 格式化输出,缩进4个空格 + file.close(); + return true; + } catch (const std::exception& e) { + std::cerr << "Error saving translation file: " << e.what() << std::endl; + return false; + } + } + +private: + json originalJson; + + // 使用nlohmann/json解析 + bool parseJson_unsafe(const json& j) { + try { + // 解析current_language + if (j.contains("current_language") && j["current_language"].is_string()) { + currentLanguage = j["current_language"].get(); + } + + // 解析sections + if (j.contains("section") && j["section"].is_array()) { + for (const auto& section : j["section"]) { + if (section.is_string()) { + addSection_unsafe(section.get()); + } + } + } + + // 解析translations + if (j.contains("translate") && j["translate"].is_object()) { + for (const auto& [key, langObj] : j["translate"].items()) { + if (langObj.is_object()) { + for (const auto& [lang, text] : langObj.items()) { + if (text.is_string()) { + if (text.size() > basicTranslations.size()) + basicTranslations.resize(text.size()); + basicTranslations.at(text.size() - 1)[key][lang] = text.get(); + } + } + } + } + } + + return true; + } catch (const std::exception& e) { + std::cerr << "Error parsing JSON: " << e.what() << std::endl; + return false; + } + } + + std::string translate_unsafe(const std::string& key) { + if (key == "OK" || key == "NG")//部分简写短字不翻译 + return key; + if (key.length() <= basicTranslations.size()){//先从全字匹配字典中获取 + auto it = basicTranslations.at(key.length() - 1).find(key); + if (it != basicTranslations.at(key.length() - 1).end()) { + auto langIt = it->second.find(currentLanguage); + if (langIt != it->second.end()) { + return langIt->second; + } + } + } + //均无法找到 逐字翻译 仅适用于中文翻译到其他文字 + for (int length = std::min(basicTranslations.size() - 1, key.length()); length > 1; length--) { + if (basicTranslations.at(length - 1).size() == 0) + continue; + auto& translationMap = basicTranslations.at(length - 1); + for (int startPos = 0; startPos <= key.length() - length; startPos++) { + { + std::string_view sv(key.data() + startPos, length); + auto it = translationMap.find(sv); + if (it != translationMap.end()) { + auto langIt = it->second.find(currentLanguage); + if (langIt != it->second.end()) {//成功翻译时 + std::string result = langIt->second, frontStr, backStr; + if (startPos != 0) {//查询翻译成功之前的一段是否翻译成功 + if (currentLanguage != "zh-CN")//不为中文时在词间添加空格 + result = translate_unsafe(key.substr(0, startPos)) + " " + result; + else + result = translate_unsafe(key.substr(0, startPos)) + result; + } + if (startPos + length < key.length()) {//查询翻译成功之后的一段是否翻译成功 + if (currentLanguage != "zh-CN")//不为中文时在词间添加空格 + result += " " + translate_unsafe(key.substr(startPos + length)); + else + result += translate_unsafe(key.substr(startPos + length)); + } + return result; + } + } + } + } + } + return key; // 如果找不到翻译,返回原始key + } + + std::string translate_unsafe(const std::string& key, const std::string& lang) { + {//先从全字匹配字典中获取 + auto it = basicTranslations.at(key.length() - 1).find(key); + if (it != basicTranslations.at(key.length() - 1).end()) { + auto langIt = it->second.find(lang); + if (langIt != it->second.end()) { + return langIt->second; + } + } + } + return key; + } + // 添加语言section + void addSection_unsafe(const std::string& lang) { + if (lang == "us-EN") return;//老代码中大量存在的错误编码 + for (const auto& section : sections) { + if (section == lang) return; // 已存在 + } + sections.push_back(lang); + } + +}; + +#define TR(key) QString::fromStdString(Translation::getInstance().translate(key)) + diff --git a/src/core/backendInterface.h b/src/core/backendInterface.h index 58a9369..5c4604c 100644 --- a/src/core/backendInterface.h +++ b/src/core/backendInterface.h @@ -106,6 +106,9 @@ public slots: } return; } + void launguageChanged(const std::string& language){ + _serviceManager.translateManager->setLanguage(language); + } private: bool initOnce = false; QMutex backendJsonMutex; diff --git a/src/core/service/CLIManager.h b/src/core/service/CLIManager.h index 5f0d785..39c9348 100644 --- a/src/core/service/CLIManager.h +++ b/src/core/service/CLIManager.h @@ -86,7 +86,7 @@ public: continue; } #pragma region 注册地址写入模式的 - { + if(callbacks.createCliBtn){ QString uuid = QUuid::createUuid().toString();; auto commands = basicTriggerPresetGenerate(callbacks.triggerAddress, callbacks.triggerValue); QString tips; @@ -99,7 +99,7 @@ public: } #pragma endregion #pragma region 注册直接触发模式的 - { + if (callbacks.createCliBtn) { QString uuid = QUuid::createUuid().toString();; QStringList commands = { "DirectTrigger#"+ QString::fromStdString(callbacks.funcName)}; QString tips; @@ -120,7 +120,7 @@ public: continue; } #pragma region 注册地址写入模式的 - { + if (callbacks.createCliBtn) { QString uuid = QUuid::createUuid().toString();; auto commands = basicUnionTriggerPresetGenerate(callbacks.triggerAddressAndValue); QString tips; @@ -133,7 +133,7 @@ public: } #pragma endregion #pragma region 注册直接触发模式的 - { + if (callbacks.createCliBtn) { QString uuid = QUuid::createUuid().toString();; QStringList commands = { "DirectTrigger#" + QString::fromStdString(callbacks.funcName) }; QString tips; @@ -165,7 +165,7 @@ public: QString setZeroTips; for (auto& data : _serviceManager->_triggerManager->triggerCallbackFuncs) { for (auto& callbacks : data.second) { - if (callbacks.funcName.find(avoid) != std::string::npos) { + if (callbacks.funcName.find(avoid) != std::string::npos && callbacks.createCliBtn == false) { continue; } commands.append("fins#write_short_D" + QString::number(callbacks.triggerAddress) + "_" + QString::number(callbacks.triggerValue)); @@ -176,7 +176,7 @@ public: } for (auto& data : _serviceManager->_triggerManager->unionTriggerCallbackFuncs) { for (auto& unionCallbacks : data.second) { - if (unionCallbacks.funcName.find(avoid) != std::string::npos) { + if (unionCallbacks.funcName.find(avoid) != std::string::npos && unionCallbacks.createCliBtn == false) { continue; } for (auto& callbacks : unionCallbacks.triggerAddressAndValue) { diff --git a/src/core/service/cameraManager.cpp b/src/core/service/cameraManager.cpp index 5fdb43e..74f6bd6 100644 --- a/src/core/service/cameraManager.cpp +++ b/src/core/service/cameraManager.cpp @@ -176,14 +176,15 @@ void cameraManager::unloadAllCameras(){ module.destory_ptr = nullptr; } - for (auto* lib : lib_list) { - if (lib != nullptr) { - if (lib->isLoaded()) - lib->unload(); - delete lib; - } - } - lib_list.clear(); + //for (auto& lib : lib_list) { + // if (lib != nullptr) { + // if (lib->isLoaded()) + // lib->unload(); + // delete lib; + // lib = nullptr; + // } + //} + //lib_list.clear(); m_usedDllPath.clear(); onlineStatusMap.clear(); initFlag = false; @@ -284,7 +285,11 @@ void cameraManager::reloadAllCameraAsVirtual(){ bool cameraManager::loadModule(cameraStruct& _cameraStruct){ try{ QString keyName = QString::fromStdString(_cameraStruct.key); +#if offlineMode == 0 QString dllPath = QString::fromStdString(_cameraStruct.dllPath);// 相机模块名 +#else + QString dllPath = "Hd_VirtualCamera"; +#endif QString module_path = "./" + dllPath; qDebug() << "[INFO] " << " module_path:" << module_path; diff --git a/src/core/service/imgSaveThreadManager.h b/src/core/service/imgSaveThreadManager.h index 594f381..4461e9a 100644 --- a/src/core/service/imgSaveThreadManager.h +++ b/src/core/service/imgSaveThreadManager.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include @@ -475,6 +476,13 @@ public: } } } + + // 每天检查一次,自动删除超出保留天数的旧表 + QDate currentDate = QDate::currentDate(); + if (lastCleanupDate.isNull() || lastCleanupDate != currentDate) { + lastCleanupDate = currentDate; + cleanupOldTables(); + } } catch (std::exception& e) { qCritical() << "[DB存储线程] 异常:" << e.what(); @@ -529,11 +537,50 @@ private: return false; } } - + + // 自动删除超出保留天数的旧表 + void cleanupOldTables() { + try { + int saveDays = pathDataBaseSaveDays; + if (saveDays <= 0) { + return; + } + + auto tables = sqlDB.getTables(); + QDate deadline = QDate::currentDate().addDays(-saveDays); + int deleteCount = 0; + + for (const auto& tableName : tables) { + // 表名格式: yyyy-MM-dd-HH,提取日期部分 + QStringList parts = tableName.split("-"); + if (parts.size() >= 3) { + QDate tableDate(parts[0].toInt(), parts[1].toInt(), parts[2].toInt()); + if (tableDate.isValid() && tableDate < deadline) { + qDebug() << "[DB存储线程] 删除旧表:" << tableName; + if (sqlDB.dropTable(tableName)) { + deleteCount++; + } + } + } + } + + if (deleteCount > 0) { + qDebug() << "[DB存储线程] 清理完成,共删除" << deleteCount << "个旧表"; + } + } + catch (std::exception& e) { + qCritical() << "[DB存储线程] 清理旧表异常:" << e.what(); + } + catch (...) { + qCritical() << "[DB存储线程] 清理旧表未知异常"; + } + } + SQLiteDB sqlDB; QQueue pathQueue; QMutex queueMutex; std::atomic pendingCount = 0; + QDate lastCleanupDate; // 上次清理日期,用于每天只清理一次 }; class imgSaveThread : public QThread { @@ -592,12 +639,11 @@ public: } void addJob(std::shared_ptr job, type type_ = normal) { - + QMutexLocker locker(&queueMutex); for (auto& img : job->imgQueue) { threadBufferSize += img.second->size(); } - - QMutexLocker locker(&queueMutex); + switch (type_) { case normal: defaultQueue.append(job); @@ -735,7 +781,7 @@ public: QString resSavePath = _ImageSavePathFormatter->genPath(data->SNcode, data->cameraKeyName, data->saveObjectName, "结果图", data->customPath, ngSummaryResult, data->customImageSaveTemplateParams); if (saveRes == true && //保存结果图按钮为启用 - _memUsage.load().usedMemPercent < notSaveAnyImgThreshold) {//内存占用不超过限制 + notSaveAnyImg.load() == false) {//内存占用不超过限制 createDirIfNotExistsWithCache(resSavePath);//带LRUCache缓存校验的文件夹创建,并将保存路径加入数据库 @@ -750,11 +796,11 @@ public: QString oriSavePath = _ImageSavePathFormatter->genPath(data->SNcode, data->cameraKeyName, data->saveObjectName, "原图", data->customPath, ngSummaryResult ,data->customImageSaveTemplateParams); if ((saveOri == true || saveSeg == true || saveCls == true) && //保存SEG图/CLS图/原图按钮为启用 - _memUsage.load().usedMemPercent < notSaveOriImgThreshold) {//内存占用不超过限制 + notSaveAnyOriImg.load() == false) {//内存占用不超过限制 createDirIfNotExistsWithCache(oriSavePath);//带LRUCache缓存校验的文件夹创建,并将保存路径加入数据库 #pragma region 原图存储及判断 - if (_memUsage.load().usedMemPercent > notSaveOkOriImgThreshold && //当内存占用超过上限 + if (notSaveOkImg.load() == true && //当内存占用超过上限 ngSummaryResult.aiDetOK == true && ngSummaryResult.halconOK == true) {//且结果为OK时不保存原图 cv::Mat blankImg(300, 300, CV_8UC1, cv::Scalar(0)); @@ -828,7 +874,6 @@ public: private: bSignalHub* bridge; std::atomic savingImgCount = 0; - std::atomic _memUsage;//内存占用 ngSummary* _ngSummary;//用于汇总NG存图结果 LRUCache createPathCache{ 100 };//用于缓存已经创建过的文件夹路径,防止重复创建 std::unique_ptr dbThread; // 数据库存储线程 @@ -910,6 +955,7 @@ private: } //刷新存图参数 + std::atomic notSaveAnyImg, notSaveAnyOriImg, notSaveOkImg; void refreshParam() { if (_paramSyncManager != nullptr) { saveExtraNgImg = _paramSyncManager->get("通用设置", "额外存储NG图片", false).toBool(); @@ -922,19 +968,21 @@ private: saveCls = _paramSyncManager->get("通用设置", "存储Cls图", true).toBool(); notSaveOkOriImgThreshold = _paramSyncManager->get("通用设置", "仅存储NG图的内存占用上限", 70.0).toDouble(); notSaveOriImgThreshold = _paramSyncManager->get("通用设置", "仅存储结果图的内存占用上限", 80.0).toDouble(); - notSaveAnyImgThreshold = _paramSyncManager->get("通用设置", "不存储任何图片的内存占用上限", 90.0).toDouble(); + notSaveAnyImgThreshold = _paramSyncManager->get("通用设置", "不存储任何图片的内存占用上限", 95.0).toDouble(); _ngSummary->setWaitTimeSec(_paramSyncManager->get("通用设置", "存图汇总NG结果的等待时间(秒)", 6.0).toDouble()); enableSummurayNgResult = _paramSyncManager->get("通用设置", "启用等待NG汇总存图", false).toBool(); - _memUsage = getMemUsage(); - auto mem = _memUsage.load(); - if (mem.usedMemPercent > notSaveAnyImgThreshold) { + auto mem = getMemUsage();; + if (mem.usedMemPercent > notSaveAnyImgThreshold && mem.usedPhysPercent > notSaveAnyImgThreshold) { qDebug() << "内存占用超过" << notSaveAnyImgThreshold << "%,将不储存任何图片"; + notSaveAnyImg = true; notSaveAnyOriImg = true; notSaveOkImg = true; } - else if (mem.usedMemPercent > notSaveOriImgThreshold) { + else if (mem.usedMemPercent > notSaveOriImgThreshold && mem.usedPhysPercent > notSaveOriImgThreshold) { qDebug() << "内存占用超过" << notSaveOriImgThreshold << "%,将不储存原图"; + notSaveAnyOriImg = true; notSaveOkImg = true; } - else if (mem.usedMemPercent > notSaveOkOriImgThreshold) { + else if (mem.usedMemPercent > notSaveOkOriImgThreshold && mem.usedPhysPercent > notSaveOkOriImgThreshold) { qDebug() << "内存占用超过" << notSaveOkOriImgThreshold << "%,将不储存OK原图"; + notSaveOkImg = true; } } } @@ -953,4 +1001,3 @@ private: } }; -#pragma once \ No newline at end of file diff --git a/src/core/service/serviceManager.h b/src/core/service/serviceManager.h index 5cddfc2..5d03cef 100644 --- a/src/core/service/serviceManager.h +++ b/src/core/service/serviceManager.h @@ -7,6 +7,7 @@ #include #include #include +#include class ServiceManager { public: detDataManager* _detDataManager = nullptr;// 检测数据管理器 需要初始化 @@ -18,6 +19,7 @@ public: missionResultHandle* _missionResultHandle = nullptr;//处理算法线程的数据采集 paramSyncManager* _paramSyncManager = nullptr;//前后端参数实时同步器 handleAiManager* _handleAiManager = nullptr;;//模型管理器 + Translation* translateManager = &Translation::getInstance(); }; #pragma once \ No newline at end of file diff --git a/src/core/service/triggerManager.cpp b/src/core/service/triggerManager.cpp index e497832..b2a6508 100644 --- a/src/core/service/triggerManager.cpp +++ b/src/core/service/triggerManager.cpp @@ -60,6 +60,7 @@ bool triggerManager::connectHost(){ if (init == true) return true; status = NotInit; +#if offlineMode == 0 m_lib = new QLibrary(triggerFileName); libLoadedflag = m_lib->load(); if (!m_lib->isLoaded()){ @@ -97,10 +98,15 @@ bool triggerManager::connectHost(){ return true; } } +#else + status = InitOK; + init = true; + emit bridge->loadingWindow_appendInitLog("离线模式创建成功", "green"); +#endif return false; } void triggerManager::receiveCommand() { - +#if offlineMode == 0 for (auto& _struct : readAllCmds) { QByteArray readByte = _struct.readAllCmd; //接收数据 @@ -113,7 +119,7 @@ void triggerManager::receiveCommand() { //解析数据 decodeCameraCMD(_struct,readByte); } - +#endif } void triggerManager::decodeCameraCMD(readAllStruct& _struct, QByteArray byte) diff --git a/src/core/service/triggerManager.h b/src/core/service/triggerManager.h index 1a85c8b..94aab30 100644 --- a/src/core/service/triggerManager.h +++ b/src/core/service/triggerManager.h @@ -9,7 +9,6 @@ #include #include -#define debugTesting 0 using triggerCallback = std::function; using uniontriggerCallback = std::function>, QByteArray& byte)>; class cameraManager; @@ -131,17 +130,21 @@ public: #pragma region 发送数据 //直接发送数据到模块的方法 bool sendFinsMsg(const QString& cmdx){ +#if offlineMode == 0 if (trigger == nullptr) return false; + if (!trigger->writeData(vec_mat, cmdx.toUtf8())) { qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << cmdx; return false; } +#endif return true; } //直接发送数据到模块的方法 bool sendFinsMsg(const QByteArray& write_byte){ +#if offlineMode == 0 if (trigger == nullptr) return false; QByteArray dataSend = write_byte; @@ -150,6 +153,7 @@ public: qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << write_byte; return false; } +#endif return true; } @@ -157,6 +161,7 @@ public: //useage "D9200_1" bool writeShort(const QByteArray& write_byte) { +#if offlineMode == 0 if (trigger == nullptr) return false; QByteArray array("write_short_" + write_byte); @@ -165,10 +170,12 @@ public: qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << write_byte; return false; } +#endif return true; } //useage {"D9200_1","D9201_1"} bool writeShort(const std::vector& write_byte) { +#if offlineMode == 0 if (trigger == nullptr || write_byte.size() == 0) return false; for (auto& byteArray : write_byte) { @@ -178,11 +185,12 @@ public: return false; } } - +#endif return true; } //useage {"D9200_1","D9201_1"} bool writeShort(const std::vector& write_byte) { +#if offlineMode == 0 if (trigger == nullptr || write_byte.size() == 0) return false; for (auto& byteArray : write_byte) { @@ -192,12 +200,13 @@ public: return false; } } - +#endif return true; } //useage "D9200_1" bool writeFloat(const QByteArray& write_byte) { +#if offlineMode == 0 if (trigger == nullptr) return false; QByteArray array = "write_float_" + write_byte; @@ -205,11 +214,12 @@ public: qCritical() << "[TCP Error] " << QString::fromUtf8("Fins数据发送失败!") << array; return false; } - +#endif return true; } //useage {"D9200_1","D9201_1"} bool writeFloat(const std::vector& write_byte) { +#if offlineMode == 0 if (trigger == nullptr || write_byte.size() == 0) return false; for (auto& byteArray : write_byte) { @@ -219,11 +229,12 @@ public: return false; } } - +#endif return true; } //useage {"D9200_1","D9201_1"} bool writeFloat(const std::vector& write_byte) { +#if offlineMode == 0 if (trigger == nullptr || write_byte.size() == 0) return false; for (auto& byteArray : write_byte) { @@ -233,7 +244,7 @@ public: return false; } } - +#endif return true; } #pragma endregion @@ -246,12 +257,14 @@ public: int triggerAddress;//触发信号 int triggerValue;//触发的值 std::string funcName;//函数名 + bool createCliBtn;//是否在故障排查界面创建按钮 triggerCallback func;//函数 }; struct unionTriggerCallbackStruct { std::vector> triggerAddressAndValue;//联合触发用于判断的地址 conditionMode mode;//联合判断模式 std::string funcName;//函数名 + bool createCliBtn;//是否在故障排查界面创建按钮 uniontriggerCallback func;//函数 }; @@ -306,7 +319,7 @@ public: } //单条件的触发器注册 - bool registerCallback(int triggerAddress, int triggerValue, triggerCallback func, std::string funcName) { + bool registerCallback(int triggerAddress, int triggerValue, triggerCallback func, std::string funcName, bool createCliBtn = true) { QMutexLocker locer(&mutex); triggerCallbackStruct _triggerCallbackStruct; _triggerCallbackStruct.triggerAddress = triggerAddress; @@ -326,7 +339,7 @@ public: std::map> triggerCallbackFuncs;//单触发回调函数表 //联合条件的触发器注册 - bool registerUnionCallback(std::vector> triggerAddressAndValue, conditionMode mode, uniontriggerCallback func, std::string funcName) { + bool registerUnionCallback(std::vector> triggerAddressAndValue, conditionMode mode, uniontriggerCallback func, std::string funcName, bool createCliBtn = true) { QMutexLocker locer(&mutex); if (triggerAddressAndValue.size() < 2) { qCritical() << "联合触发器至少需要两个条件"; @@ -353,6 +366,7 @@ public: cb.func = std::move(func); cb.mode = mode; cb.funcName = funcName.empty() ? QString("%1~%2联合触发").arg(cb.triggerAddressAndValue[0].first).arg(cb.triggerAddressAndValue[cb.triggerAddressAndValue.size() - 1].first).toStdString() : funcName; + cb.createCliBtn = createCliBtn; unionTriggerCallbackFuncs[ownerStruct->readAllCmd].push_back(std::move(cb)); qInfo() << "注册联合触发器成功:" << ownerStruct->readAllCmd << ", 条件数=" << unionTriggerCallbackFuncs[ownerStruct->readAllCmd].back().triggerAddressAndValue.size(); return true; diff --git a/src/launcher/CMakeLists.txt b/src/launcher/CMakeLists.txt index 1059325..b54fc45 100644 --- a/src/launcher/CMakeLists.txt +++ b/src/launcher/CMakeLists.txt @@ -25,7 +25,6 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/GUI/halconAlgo ${CMAKE_CURRENT_SOURCE_DIR}/GUI/uiModule ) - link_directories ( ${ENV_LIB} ) diff --git a/src/launcher/GUI/pages/displayPageWidget.h b/src/launcher/GUI/pages/displayPageWidget.h index eb24c55..ce85f3a 100644 --- a/src/launcher/GUI/pages/displayPageWidget.h +++ b/src/launcher/GUI/pages/displayPageWidget.h @@ -26,6 +26,7 @@ #include #include #include +#include class toolBarWidget : public QWidget { Q_OBJECT public: @@ -80,7 +81,7 @@ public: }) } // 通用的创建工具按钮函数实现 - QToolButton* createToolButton(QIcon icon, const QString& text, + MarqueeToolButton* createToolButton(QIcon icon, const QString& text, std::function clickHandler, Auth::UserLevel level = Auth::UserLevel::GUEST, const QSize& buttonSize = QSize(110, 60), const QSize& iconSize = QSize(32, 32)) { @@ -99,7 +100,7 @@ public: btnLayout->setContentsMargins(0, 0, 0, 0); // 使用 QToolButton 来实现图标在上文字在下的效果 - QToolButton* btn = new QToolButton(this); + MarqueeToolButton* btn = new MarqueeToolButton(this); if (!btn) { delete btnLayout; return nullptr; @@ -133,7 +134,7 @@ public: btnLayout->setAlignment(Qt::AlignCenter); // 连接点击事件 - if (!connect(btn, &QToolButton::clicked, [this, level,clickHandler]() { + if (!connect(btn, &MarqueeToolButton::clicked, [this, level,clickHandler]() { m_config->Authorization.executeWithPermission(level, [this, clickHandler]() { clickHandler(); }); @@ -374,7 +375,7 @@ public: std::string fileName = fileManager::getFileName(lnkPath); auto exePath = getShortcutTarget(QString::fromLocal8Bit(lnkPath.c_str())); auto icon = getFileIcon(exePath, QSize(32, 32)); - _toolBarWidget->createToolButton(icon, QString::fromLocal8Bit(fileName.c_str()), [exePath]() { + _toolBarWidget->createToolButton(icon, TR(QString::fromLocal8Bit(fileName.c_str()).toStdString()), [exePath]() { QProcess::startDetached(exePath); }); } diff --git a/src/launcher/GUI/pages/logPageWidget.h b/src/launcher/GUI/pages/logPageWidget.h index 78b63c2..5d0c522 100644 --- a/src/launcher/GUI/pages/logPageWidget.h +++ b/src/launcher/GUI/pages/logPageWidget.h @@ -103,9 +103,12 @@ public: stdConsoleOutput.setStyleSheet(textEditStyle); qtConsoleOutput.setStyleSheet(textEditStyle); + QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged, this, [this]() { + Title->setText(TR("日志分析")); + }); - addLogWidget(TR("控制台"), &stdConsoleOutput, logType::stdConsle); - addLogWidget(TR("系统日志"), &qtConsoleOutput, logType::qtConsle); + addLogWidget("控制台", &stdConsoleOutput, logType::stdConsle); + addLogWidget("系统日志", &qtConsoleOutput, logType::qtConsle); btns[0]->pressed(); Layout->addWidget(widgets); @@ -118,10 +121,10 @@ public: void addLogWidget(QString btnText, QPlainTextEdit* textWidget, logType type) { QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); - QFont font2("Microsoft YaHei", 8); + QFont font2("Microsoft YaHei", 8); int index = btns.size(); - gradientButton* btn = new gradientButton(160, 50, btnText, ""); + gradientButton* btn = new gradientButton(160, 50, TR(btnText.toStdString()), ""); btnLayout->addWidget(btn); btns.push_back(btn); connect(btn, &QPushButton::clicked, [=]() { @@ -131,7 +134,9 @@ public: widgets->setCurrentIndex(index); processCacheLog(index); }); - + QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged, this, [btn, btnText]() { + btn->setText(TR(btnText.toStdString())); + }); QWidget* widget = new QWidget(); widgets->addWidget(widget); widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); diff --git a/src/launcher/GUI/pages/settingWidget.h b/src/launcher/GUI/pages/settingWidget.h index 01189c9..c27aed7 100644 --- a/src/launcher/GUI/pages/settingWidget.h +++ b/src/launcher/GUI/pages/settingWidget.h @@ -23,7 +23,7 @@ #include #include #include -//#include +#include class settingWidget :public QWidget{ Q_OBJECT @@ -214,12 +214,14 @@ public: connect(languageSelect, &QComboBox::currentTextChanged, [=](const QString& str) { Translation::getInstance().setLanguage(str.toStdString()); - auto languageSelectTipTexts = Translation::getInstance().getAllTranslateResult("重启后将会更改"); - QString languageSelectTipText; - for (auto& text : languageSelectTipTexts) - languageSelectTipText += QString::fromStdString(text.second) + "/"; - languageSelectTipText.right(1); - languageSelectTip->setText(languageSelectTipText); + emit fSignalHub::getInstance()->languageChanged(str.toStdString()); + //auto languageSelectTipTexts = Translation::getInstance().getAllTranslateResult("重启后将会更改"); + //QString languageSelectTipText; + //for (auto& text : languageSelectTipTexts) + // languageSelectTipText += QString::fromStdString(text.second) + "/"; + //languageSelectTipText.right(1); + //languageSelectTip->setText(languageSelectTipText); + }); m_layout->addWidget(languageGroupBox); @@ -392,7 +394,7 @@ public: const auto reply = QMessageBox::question( this, TR("确认"), - TR("确定要替换吗,在调试结束后哦请重启软件"), + TR("确定要替换吗,在调试结束后请重启软件"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (reply == QMessageBox::Yes) { diff --git a/src/launcher/GUI/pages/sqlControlWidget.h b/src/launcher/GUI/pages/sqlControlWidget.h index 4378205..99f1aac 100644 --- a/src/launcher/GUI/pages/sqlControlWidget.h +++ b/src/launcher/GUI/pages/sqlControlWidget.h @@ -15,7 +15,7 @@ class sqliteReader : public QWidget{ public: sqliteReader(SQLiteDB* dbIn):db(dbIn) { - QFont font("Microsoft YaHei", 12, QFont::Bold); + QFont font("Microsoft YaHei", 12, QFont::Bold); QPalette palette; palette.setColor(QPalette::WindowText, Qt::white); @@ -28,13 +28,12 @@ public: showLabel->setFont(font); showLabel->setPalette(palette); vLayout->addWidget(showLabel); - tableSelectComboBox->setFixedWidth(200); vLayout->addWidget(tableSelectComboBox); connect(tableSelectComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=]() { if(tableSelectComboBox->currentText() != "") - switchWidget(tableSelectComboBox->currentText()); + switchWidget(tableKeyPair[tableSelectComboBox->currentText()]); }); refreshBtn->setFont(font); @@ -58,15 +57,26 @@ public: connect(dumpToCsvBtn, &QPushButton::clicked, this, [=]() {dumpToCsv(tableSelectComboBox->currentText()); }); //1-2 layout->addWidget(tableWidget); + QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged, this, [this, showLabel, showLabel2]() { + showLabel->setText(TR("班次")); + showLabel2->setText(TR("SN查询")); + refreshBtn->setText(TR("刷新")); + searchSnBtn->setText(TR("查询")); + dumpToCsvBtn->setText(TR("导出")); + }); } //QTableView* view = new QTableView; void refreshTable() { + tableKeyPair.clear(); tableSelectComboBox->clear(); auto tables = db->getTables(); for (int i = tables.size() - 1; i > 0 ; i--){ - if (!tables[i].contains("set") && !tables[i].contains("hide")) - tableSelectComboBox->addItem(tables[i]); + if (!tables[i].contains("set") && !tables[i].contains("hide")) { + auto translatedStr = TR(tables[i].toStdString()); + tableKeyPair[translatedStr] = tables[i]; + tableSelectComboBox->addItem(translatedStr); + } } } void switchWidget(QString tableName) { @@ -77,6 +87,20 @@ public: qDebug() << "查询失败:" << model->lastError().text(); return; } + for (int col = 0; col < model->columnCount(); ++col){ + QString header = + model->headerData( + col, + Qt::Horizontal + ).toString(); + + model->setHeaderData( + col, + Qt::Horizontal, + TR(header.toStdString()) + ); + + } tableWidget->setModel(model); } void searchSN(QString tableName, QString SN) { @@ -130,9 +154,10 @@ private: QComboBox* tableSelectComboBox = new QComboBox(); QVBoxLayout* layout = new QVBoxLayout(this); QTableView* tableWidget = new QTableView(); - fancyButtonText* refreshBtn = new fancyButtonText(TR("刷新"), 80, 25, ""); - fancyButtonText* searchSnBtn = new fancyButtonText(TR("查询"), 80, 25, ""); - fancyButtonText* dumpToCsvBtn = new fancyButtonText(TR("导出"), 80, 25, ""); + fancyButtonText* refreshBtn = new fancyButtonText(TR("刷新"), 140, 25, ""); + fancyButtonText* searchSnBtn = new fancyButtonText(TR("查询"), 120, 25, ""); + fancyButtonText* dumpToCsvBtn = new fancyButtonText(TR("导出"), 120, 25, ""); + QMap tableKeyPair;//展示文本与原始文本的对应 protected: void showEvent(QShowEvent* event) override { QWidget::showEvent(event); @@ -144,7 +169,7 @@ public: QVBoxLayout* Layout = new QVBoxLayout(this); QHBoxLayout* btnLayout = new QHBoxLayout(this); std::vectorbtns; - QLabel* icon, * Title; + QLabel* icon, *Title; QStackedWidget* widgets = new QStackedWidget(); sqliteReader _sqliteReader; QTableWidget* sqlWidget = new QTableWidget(); @@ -191,7 +216,9 @@ public: Layout->addLayout(btnLayout); Layout->addWidget(&_sqliteReader); - + QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged, this, [this]() { + Title->setText(TR("数据库操作界面")); + }); } }; #pragma once \ No newline at end of file diff --git a/src/launcher/GUI/paramEditorDialog.h b/src/launcher/GUI/paramEditorDialog.h index f8d893c..fd835e1 100644 --- a/src/launcher/GUI/paramEditorDialog.h +++ b/src/launcher/GUI/paramEditorDialog.h @@ -1,5 +1,5 @@ #pragma once - +#include #include #include #include @@ -26,6 +26,11 @@ #include #include #include +#include +struct paramName { + QString originName;//原始名字 键 + QString showName;//展示用的名字 可能会经过翻译 +}; class WheelBlocker : public QObject { Q_OBJECT public: @@ -45,9 +50,8 @@ class paramTableEditor : public QDialog { public: explicit paramTableEditor(QWidget* parent = nullptr,bool viewOnlyModeIN = false) : QDialog(parent), viewOnlyMode(viewOnlyModeIN){ - this->setWindowTitle("参数编辑器"); + this->setWindowTitle(TR("参数编辑器")); this->resize(1400, 600); - setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint); this->setObjectName("paramTableEditor"); this->setStyleSheet(QString("QDialog#paramTableEditor {background-color: rgb(%1);border: 2px solid #000000;border-radius: 6px;}").arg(sColor_Blue)); @@ -74,7 +78,8 @@ public: mainLayout->addWidget(m_sidebarWidget); mainLayout->addWidget(m_dividerLine); mainLayout->addWidget(m_contentWidget,1); - mainLayout->addWidget(m_imageTipWidget,1); + // mainLayout->addWidget(m_imageTipWidget,1);//无人员配合 暂时屏蔽 + imageTipLabel->hide(); } void setParams(std::vector> params) { @@ -126,7 +131,10 @@ public: if (viewOnlyMode && (group == "hide" || (!m_allParams["hide." + group].toBool()))) { continue; } - m_sidebarList->addItem(group); + auto translateResult = TR(group.toStdString()); + m_sidebarKeyPair[translateResult] = group; + m_sidebarList->addItem(translateResult); + } //保存分组参数 @@ -135,7 +143,7 @@ public: //默认显示第一个分组 if (m_sidebarList->count() > 0) { m_sidebarList->setCurrentRow(0); - displayGroupParams(m_sidebarList->item(0)->text()); + displayGroupParams(m_sidebarKeyPair[m_sidebarList->item(0)->text()]); } } @@ -180,7 +188,7 @@ private slots: void onSidebarItemClicked(QListWidgetItem* item) { if (!item) return; - QString groupName = item->text(); + QString groupName = m_sidebarKeyPair[item->text()]; displayGroupParams(groupName); switchImageTipArea(groupName); } @@ -191,11 +199,12 @@ private: QTableView* m_tableView; QStandardItemModel* m_tableModel; nlohmann::json m_originalJson; - std::map m_originalTypes; - std::map m_editorWidgets; + std::map m_originalTypes;//参数原始的类型,类似浮点型 整型 + std::map m_editorWidgets;//参数对应的控件 //左侧边栏相关成员 QWidget* m_sidebarWidget; + QMap m_sidebarKeyPair;//侧边栏的展示值与原始值的对应 QWidget* m_contentWidget; QListWidget* m_sidebarList; QFrame* m_dividerLine; @@ -224,10 +233,10 @@ private: sidebarLayout->setContentsMargins(8, 8, 8, 8); sidebarLayout->setSpacing(10); - //左侧边栏标题 - QLabel* sidebarTitle = new QLabel("参数分组"); - sidebarTitle->setStyleSheet("color: white; font-weight: bold; font-size: 14px; padding: 5px;"); - sidebarTitle->setAlignment(Qt::AlignCenter); + ////左侧边栏标题 + //QLabel* sidebarTitle = new QLabel(TR("参数分组")); + //sidebarTitle->setStyleSheet("color: white; font-weight: bold; font-size: 14px; padding: 5px;"); + //sidebarTitle->setAlignment(Qt::AlignCenter); //侧边栏列表样式 m_sidebarList = new QListWidget(); @@ -257,7 +266,7 @@ private: )"); connect(m_sidebarList, &QListWidget::itemClicked, this, ¶mTableEditor::onSidebarItemClicked); - sidebarLayout->addWidget(sidebarTitle); + //sidebarLayout->addWidget(sidebarTitle); sidebarLayout->addWidget(m_sidebarList); } void createImageTipArea() { @@ -277,7 +286,7 @@ private: imgaeTipLayout->setSpacing(10); //左侧边栏标题 - imageTipLabel = new QLabel("参数分组"); + imageTipLabel = new QLabel(TR("参数分组")); imageTipLabel->setStyleSheet("color: white; font-weight: bold; font-size: 14px; padding: 5px;"); imageTipLabel->setAlignment(Qt::AlignCenter); @@ -306,7 +315,8 @@ private: contentLayout->setSpacing(10); // 当前分组标签 - m_currentGroupLabel = new QLabel("所有参数" + viewOnlyMode == false ? "":"当前无法修改(权限不足,请登录后重新打开此界面)"); + QString text = TR("所有参数") + viewOnlyMode == false ? "" : TR("当前无法修改(权限不足,请登录后重新打开此界面)"); + m_currentGroupLabel = new QLabel(text); m_currentGroupLabel->setStyleSheet("color: white; font-weight: bold; font-size: 16px; padding: 5px;"); contentLayout->addWidget(m_currentGroupLabel); @@ -332,26 +342,26 @@ private: m_tableView->setItemDelegateForColumn(0, new QStyledItemDelegate(m_tableView)); m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_tableView->setSelectionMode(QAbstractItemView::SingleSelection); - m_tableView->setColumnWidth(0, 320); + m_tableView->setColumnWidth(0, 600); // 禁止第一列选中 m_tableView->setColumnHidden(0, false); m_tableView->setFocusPolicy(Qt::NoFocus); // 设置表头 - m_tableModel->setHorizontalHeaderLabels({ "参数名", "值" }); + m_tableModel->setHorizontalHeaderLabels({ TR("参数名"), TR("值") }); // 设置表格属性 m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_tableView->setAlternatingRowColors(true); m_tableView->horizontalHeader()->setStretchLastSection(true); - m_tableView->setColumnWidth(1, 140); + m_tableView->setColumnWidth(1, 150); - fancyButtonText* okBtn = new fancyButtonText("保存", 70, 22, ""); + fancyButtonText* okBtn = new fancyButtonText(TR("保存"), 140, 22, ""); okBtn->setDisabled(viewOnlyMode); okBtn->setVisible(!viewOnlyMode); - fancyButtonText* cancelBtn = new fancyButtonText("取消", 70, 22, ""); + fancyButtonText* cancelBtn = new fancyButtonText(TR("取消"), 70, 22, ""); connect(okBtn, &QPushButton::clicked, this, ¶mTableEditor::onAccept); connect(cancelBtn, &QPushButton::clicked, this, &QDialog::reject); @@ -420,7 +430,7 @@ private: void displayGroupParams(const QString& groupName) { //更新当前分组标签 - m_currentGroupLabel->setText(groupName); + m_currentGroupLabel->setText(TR(groupName.toStdString())); // 清空表格 m_tableModel->setRowCount(0); @@ -460,12 +470,12 @@ private: } // 设置键名(不可编辑) - QStandardItem* keyItem = new QStandardItem(displayName); + QStandardItem* keyItem = new QStandardItem(TR(displayName.toStdString())); keyItem->setEditable(false); keyItem->setBackground(QColor(60, 60, 60)); keyItem->setForeground(QColor(255, 255, 255)); keyItem->setData(fullKey, Qt::UserRole);//存储完整键名 - keyItem->setToolTip(fullKey);//提示显示完整键名 + keyItem->setToolTip(TR(fullKey.toStdString()));//提示显示完整键名 m_tableModel->setItem(row, 0, keyItem); //确定类型(内部使用,不显示) diff --git a/src/launcher/GUI/uiModule/components/dayShiftTimer.h b/src/launcher/GUI/uiModule/components/dayShiftTimer.h index 2cd5161..6c152c5 100644 --- a/src/launcher/GUI/uiModule/components/dayShiftTimer.h +++ b/src/launcher/GUI/uiModule/components/dayShiftTimer.h @@ -20,7 +20,7 @@ public: timeCacheTimer.start(); const QTime now = cachedDateTime.time(); const int minutes = now.hour() * 60 + now.minute(); - bool isDay = (minutes >= (8 * 60 + 30) && minutes < (20 * 60 + 30)); + bool isDay = (minutes >= (dayShiftHour * 60 + dayShiftMin) && minutes < (nightShiftHour * 60 + nightShiftMin)); QString shiftDate = calcShiftDate(cachedDateTime, isDay); lastIsDayState = isDay; lastDayShiftDate = shiftDate; @@ -39,7 +39,7 @@ public: const QTime now = cachedDateTime.time(); const int minutes = now.hour() * 60 + now.minute(); - bool isDay = (minutes >= (8 * 60 + 30) && minutes < (20 * 60 + 30)); + bool isDay = (minutes >= (dayShiftHour * 60 + dayShiftMin) && minutes < (nightShiftHour * 60 + nightShiftMin)); QString shiftDate = calcShiftDate(cachedDateTime, isDay); @@ -62,10 +62,10 @@ private: QString calcShiftDate(const QDateTime& dt, bool isDay) { QDate date = dt.date(); - //夜班0.00~8.30为前一天的夜班 + //例如夜班0.00~8.30为前一天的夜班 if (!isDay) { - if (dt.time().hour() < 8 || - (dt.time().hour() == 8 && dt.time().minute() < 30)) { + if (dt.time().hour() < dayShiftHour || + (dt.time().hour() == dayShiftHour && dt.time().minute() < dayShiftMin)) { date = date.addDays(-1); } } diff --git a/src/launcher/GUI/uiModule/components/marqueeToolButton.h b/src/launcher/GUI/uiModule/components/marqueeToolButton.h new file mode 100644 index 0000000..b37b959 --- /dev/null +++ b/src/launcher/GUI/uiModule/components/marqueeToolButton.h @@ -0,0 +1,190 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +class MarqueeToolButton : public QToolButton +{ + Q_OBJECT + +public: + + explicit MarqueeToolButton(QWidget* parent = nullptr) + : QToolButton(parent) + { + setMouseTracking(true); + + connect(&m_timer, &QTimer::timeout, this, [this]() { + + m_offset += 1; + + QFontMetrics fm(font()); + + int textWidth = fm.horizontalAdvance(text()); + + if (m_offset > textWidth + m_spacing) { + m_offset = 0; + } + + update(); + }); + + m_timer.setInterval(30); + } + +protected: + + // Qt5 使用 QEvent* + void enterEvent(QEvent* event) override + { + QToolButton::enterEvent(event); + + updateScrollState(); + + if (m_needScroll) { + + m_offset = 0; + + m_timer.start(); + } + } + + void leaveEvent(QEvent* event) override + { + QToolButton::leaveEvent(event); + + m_timer.stop(); + + m_offset = 0; + + update(); + } + + void resizeEvent(QResizeEvent* event) override + { + QToolButton::resizeEvent(event); + + updateScrollState(); + } + + void paintEvent(QPaintEvent* event) override + { + Q_UNUSED(event); + + QStyleOptionToolButton opt; + + initStyleOption(&opt); + + QPainter painter(this); + + // 绘制按钮背景 + style()->drawPrimitive( + QStyle::PE_PanelButtonTool, + &opt, + &painter, + this); + + QRect rect = this->rect(); + + // 图标大小 + int iconSize = iconSizeValue(); + + QRect iconRect( + (rect.width() - iconSize) / 2, + 5, + iconSize, + iconSize + ); + + // 绘制图标 + opt.icon.paint(&painter, iconRect); + + // 文本区域 + QRect textRect( + 5, + iconRect.bottom() + 5, + rect.width() - 10, + rect.height() - iconRect.bottom() - 10 + ); + + painter.setPen(palette().buttonText().color()); + + QFontMetrics fm(font()); + + int textWidth = fm.horizontalAdvance(text()); + + // 不需要滚动 + if (!m_needScroll || !underMouse()) { + + QString elided = + fm.elidedText( + text(), + Qt::ElideRight, + textRect.width()); + + painter.drawText( + textRect, + Qt::AlignCenter, + elided); + + return; + } + + // 裁剪文本区域 + painter.setClipRect(textRect); + + int y = + textRect.center().y() + + fm.ascent() / 2; + + // 第一段文字 + painter.drawText( + textRect.left() - m_offset, + y, + text()); + + // 第二段文字(循环衔接) + painter.drawText( + textRect.left() + - m_offset + + textWidth + + m_spacing, + y, + text()); + } + +private: + + QTimer m_timer; + + int m_offset = 0; + + bool m_needScroll = false; + + int m_spacing = 30; + + void updateScrollState() + { + QFontMetrics fm(font()); + + int textWidth = + fm.horizontalAdvance(text()); + + m_needScroll = + textWidth > width() - 10; + } + + int iconSizeValue() const + { + QSize s = iconSize(); + + if (s.width() <= 0) + return 32; + + return s.width(); + } +}; \ No newline at end of file diff --git a/src/launcher/GUI/uiModule/components/valueViewer.h b/src/launcher/GUI/uiModule/components/valueViewer.h index 7263ee7..ac2670b 100644 --- a/src/launcher/GUI/uiModule/components/valueViewer.h +++ b/src/launcher/GUI/uiModule/components/valueViewer.h @@ -23,7 +23,7 @@ public: QMap>& plcViwerLineedits) : groupName(groupNameIN) { - QLabel* groupNameLabel = new QLabel(groupNameIN); + groupNameLabel = new QLabel(groupNameIN); groupNameLabel->setFont(font1); groupNameLabel->setStyleSheet("color: white;"); @@ -38,7 +38,7 @@ public: QMap>& plcViwerLineedits) : groupName(groupNameIN) { - QLabel* groupNameLabel = new QLabel(groupNameIN); + groupNameLabel = new QLabel(groupNameIN); groupNameLabel->setFont(font1); groupNameLabel->setStyleSheet("color: white;"); @@ -71,4 +71,5 @@ public: QWidget* widget = new QWidget(); QHBoxLayout* layout = new QHBoxLayout(widget); QMap map; + QLabel* groupNameLabel = nullptr; }; diff --git a/src/launcher/GUI/uiModule/uiChart_WaveForm.h b/src/launcher/GUI/uiModule/uiChart_WaveForm.h index f239915..6407f54 100644 --- a/src/launcher/GUI/uiModule/uiChart_WaveForm.h +++ b/src/launcher/GUI/uiModule/uiChart_WaveForm.h @@ -170,7 +170,7 @@ protected: m_plot->replot(); QWidget::leaveEvent(event); } -#if switchToTongYongUi == 1 + void paintEvent(QPaintEvent* event) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); @@ -183,7 +183,7 @@ protected: painter.setPen(Qt::NoPen); painter.drawRoundedRect(r, radius, radius); } -#endif + private slots: void editJsonParameters() { JsonParamTableEditor* dlg = new JsonParamTableEditor(this); diff --git a/src/launcher/GUI/uiModule/uiChart_histogramWidget.h b/src/launcher/GUI/uiModule/uiChart_histogramWidget.h index d89650a..cbddb14 100644 --- a/src/launcher/GUI/uiModule/uiChart_histogramWidget.h +++ b/src/launcher/GUI/uiModule/uiChart_histogramWidget.h @@ -179,7 +179,7 @@ private: } void initChart() { - barSet = new QBarSet(QString::fromUtf8("数量")); + barSet = new QBarSet(TR("数量")); barSet->setColor(QColor(255, 0, 0)); // 红色柱体 barSet->setBorderColor(QColor(255, 255, 255)); // 白色边框 @@ -191,8 +191,9 @@ private: } if (index < 0 || index >= categories.size()) return; - const QString text = QString::fromUtf8("* %1 数量: %2") + const QString text = QString::fromUtf8("* %1 %2 %3") .arg(categories.at(index)) + .arg(TR("数量")) .arg(barSet->at(index)); buttomBarSetTipLabel.setText(text); }); @@ -314,8 +315,13 @@ public: histogramWidget* nightHistogramWidget; dayNightShiftHistogramWidget() { QString ymd = QDate::currentDate().toString("yyyy-MM-dd"); - dayHistogramWidget = new histogramWidget(ymd + TR("白班") + "(08:30-20:30)"); - nightHistogramWidget = new histogramWidget(ymd + TR("夜班") + "(20:30-08:30)"); + dayHistogramWidget = new histogramWidget(ymd + TR("白班") + + "(" + QString("%1:%2").arg(dayShiftHour, 2, 10, QChar('0')).arg(dayShiftMin, 2, 10, QChar('0')) + + "-" + QString("%1:%2").arg(nightShiftHour, 2, 10, QChar('0')).arg(nightShiftMin, 2, 10, QChar('0')) + ")"); + + nightHistogramWidget = new histogramWidget(ymd + TR("夜班") + + "(" + QString("%1:%2").arg(nightShiftHour, 2, 10, QChar('0')).arg(nightShiftMin, 2, 10, QChar('0')) + + "-" + QString("%1:%2").arg(dayShiftHour, 2, 10, QChar('0')).arg(dayShiftMin, 2, 10, QChar('0')) + ")"); QVBoxLayout* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); @@ -324,8 +330,13 @@ public: BindTRLambda([this]() { QString ymd = QDate::currentDate().toString("yyyy-MM-dd"); - dayHistogramWidget->setTitle(ymd + TR("白班") + "(08:30-20:30)"); - nightHistogramWidget->setTitle(ymd + TR("夜班") + "(20:30-08:30)"); + dayHistogramWidget->setTitle(ymd + TR("白班") + + "(" + QString("%1:%2").arg(dayShiftHour, 2, 10, QChar('0')).arg(dayShiftMin, 2, 10, QChar('0')) + + "-" + QString("%1:%2").arg(nightShiftHour, 2, 10, QChar('0')).arg(nightShiftMin, 2, 10, QChar('0')) + ")"); + + nightHistogramWidget->setTitle(ymd + TR("夜班") + + "(" + QString("%1:%2").arg(nightShiftHour, 2, 10, QChar('0')).arg(nightShiftMin, 2, 10, QChar('0')) + + "-" + QString("%1:%2").arg(dayShiftHour, 2, 10, QChar('0')).arg(dayShiftMin, 2, 10, QChar('0')) + ")"); }); } //defects为空 输入为修改量 @@ -336,11 +347,15 @@ public: if (dayShiftResult.isShiftChanged) { if (dayShiftResult.isDay == true) { dayHistogramWidget->clearAllData(); - dayHistogramWidget->setTitle(dayShiftResult.shiftDate + TR("白班") + "(08:30-20:30)"); + dayHistogramWidget->setTitle(dayShiftResult.shiftDate + TR("白班") + + "(" + QString("%1:%2").arg(dayShiftHour, 2, 10, QChar('0')).arg(dayShiftMin, 2, 10, QChar('0')) + + "-" + QString("%1:%2").arg(nightShiftHour, 2, 10, QChar('0')).arg(nightShiftMin, 2, 10, QChar('0')) + ")"); } else { nightHistogramWidget->clearAllData(); - nightHistogramWidget->setTitle(dayShiftResult.shiftDate + TR("夜班") + "(20:30-08:30)"); + nightHistogramWidget->setTitle(dayShiftResult.shiftDate + TR("夜班") + + "(" + QString("%1:%2").arg(nightShiftHour, 2, 10, QChar('0')).arg(nightShiftMin, 2, 10, QChar('0')) + + "-" + QString("%1:%2").arg(dayShiftHour, 2, 10, QChar('0')).arg(dayShiftMin, 2, 10, QChar('0')) + ")"); } } diff --git a/src/launcher/GUI/uiModule/uiModule_dsStatsWidget.h b/src/launcher/GUI/uiModule/uiModule_dsStatsWidget.h index 4e2ab32..e6f17a9 100644 --- a/src/launcher/GUI/uiModule/uiModule_dsStatsWidget.h +++ b/src/launcher/GUI/uiModule/uiModule_dsStatsWidget.h @@ -126,9 +126,9 @@ private: totalEdit->setText(QString::number(total)); okEdit->setText(QString::number(good)); ngEdit->setText(QString::number(ng)); - double rate = total > 0 ? (double)good / total : 0.0; - rateEdit->setText(QString::number(rate * 100, 'f', 1) + "%"); - pie->setGoodRate(rate, total > 0); + double goodRate = total > 0 ? (double)good / total : 0.0; + rateEdit->setText(QString::number(goodRate * 100, 'f', 3) + "%"); + pie->setGoodRate(goodRate, total > 0); } void clearAllData() { QMutexLocker locker(&mutex); @@ -242,7 +242,8 @@ private: if (GlobalMemoryStatusEx(&memInfo)) { - return ((double)(memInfo.ullTotalPageFile - memInfo.ullAvailPageFile) / (double)memInfo.ullTotalPageFile) * 100; + return std::min(((double)(memInfo.ullTotalPageFile - memInfo.ullAvailPageFile) / (double)memInfo.ullTotalPageFile) * 100, + ((double)(memInfo.ullTotalPhys - memInfo.ullAvailPhys) / (double)memInfo.ullTotalPhys) * 100); } return -1.0; } diff --git a/src/launcher/GUI/uiModule/uiModule_imageView.h b/src/launcher/GUI/uiModule/uiModule_imageView.h index 4f6f80c..44a6428 100644 --- a/src/launcher/GUI/uiModule/uiModule_imageView.h +++ b/src/launcher/GUI/uiModule/uiModule_imageView.h @@ -52,7 +52,7 @@ public: //scene->addItem(rectGroup); setScene(scene); -#if switchToTongYongUi == true + setStyleSheet(R"( QGraphicsView#SonGraphicsView { background: rgb(32, 36, 40); @@ -62,15 +62,6 @@ public: } )"); -#else - setStyleSheet(R"( - QGraphicsView#SonGraphicsView { - background: transparent; - background-image: url(:/icon/icon/waitting.png); - background-repeat: no-repeat; - background-position: center center; - })"); -#endif } void setImg(const QPixmap& pixmap) { @@ -588,15 +579,7 @@ protected: } } private: -#if switchToTongYongUi == 0 - void paintEvent(QPaintEvent* event) override { - QWidget::paintEvent(event); - QPainter painter(this); - painter.setPen(QPen(Qt::white, 1)); - painter.drawRect(rect().adjusted(1, 1, -2, -2)); - } -#else void paintEvent(QPaintEvent* event) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); @@ -609,7 +592,7 @@ private: painter.setPen(Qt::NoPen); painter.drawRoundedRect(r, radius, radius); } -#endif + int in = 0; QLabel* label; SonGraphicsView* viewer; @@ -656,7 +639,7 @@ class ImageWidgetManager :public QWidget Q_OBJECT public: ImageWidget* createViewer(QString windowName, std::vector viewers, int xPos = -1, int yPos = -1){ - ImageWidget* ImageView = new ImageWidget(this,TR(windowName.toStdString())); + ImageWidget* ImageView = new ImageWidget(this,windowName); ImageWidgetList.push_back(ImageView); map.insert({ windowName,ImageView }); if (xPos < 0 || yPos < 0){ diff --git a/src/launcher/GUI/uiModule/uiModule_runCommand.h b/src/launcher/GUI/uiModule/uiModule_runCommand.h index c7d24ed..5b29e5d 100644 --- a/src/launcher/GUI/uiModule/uiModule_runCommand.h +++ b/src/launcher/GUI/uiModule/uiModule_runCommand.h @@ -56,7 +56,7 @@ public: QHBoxLayout* topLayout = new QHBoxLayout(); topLayout->setAlignment(Qt::AlignLeft); - QLabel* modeSwitchTitle = new QLabel(TR("模式选择:")); + modeSwitchTitle = new QLabel(TR("模式选择:")); modeSwitchTitle->setStyleSheet( "QLabel {" "font-family: 'Microsoft YaHei';" @@ -92,6 +92,10 @@ public: } }); layout->addLayout(topLayout, 0, 0); + BindTRLambda([this]() { + this->setWindowTitle(TR("执行命令")); + modeSwitchTitle->setText(TR("模式选择:")); + }); } signals: void excuteCommandPreset(QString uuid); @@ -101,7 +105,10 @@ public slots: if (type == runCommandWidgetType::PlcSim) { QListWidgetItem* item = new QListWidgetItem(btnWidgetsPlcSim); btnWidgetsPlcSim->addItem(item); - fancyButtonText* funcBtn = new fancyButtonText(btnName, 0, 0, tip); + fancyButtonText* funcBtn = new fancyButtonText(TR(btnName.toStdString()), 0, 0, tip); + QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged, this, [funcBtn, btnName, tip]() { + funcBtn->setText(TR(btnName.toStdString())); + }); btnWidgetsPlcSim->setItemWidget(item, funcBtn); connect(funcBtn, &fancyButtonText::clicked, this, [this, uuid]() { QMessageBox::StandardButton reply; @@ -120,6 +127,9 @@ public slots: QListWidgetItem* item = new QListWidgetItem(btnWidgetsDirect); btnWidgetsDirect->addItem(item); fancyButtonText* funcBtn = new fancyButtonText(btnName, 0, 0, tip); + QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged, this, [funcBtn, btnName, tip]() { + funcBtn->setText(TR(btnName.toStdString())); + }); btnWidgetsDirect->setItemWidget(item, funcBtn); connect(funcBtn, &fancyButtonText::clicked, this, [this, uuid]() { QMessageBox::StandardButton reply; @@ -136,7 +146,7 @@ public slots: } } void addPlcValueViewer(const QString& groupName, const std::vector>& viewerNameAndAddress) { - auto viewer = new valueViewer(groupName, viewerNameAndAddress, plcViwerLineedits); + auto viewer = new valueViewer(TR(groupName.toStdString()), viewerNameAndAddress, plcViwerLineedits); // 添加到 QListView 中 QStandardItem* item = new QStandardItem(); // 根据内部 widget 的 sizeHint 设置行高 @@ -146,6 +156,9 @@ public slots: plcValueViewerList->setIndexWidget(index, viewer->widget); xExtraSize = std::max(groupName.size() * 20, xExtraSize); this->setFixedSize(sizeX + xExtraSize, sizeY); + QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged, this, [viewer, groupName]() { + viewer->groupNameLabel->setText(TR(groupName.toStdString())); + }); } void refreshPlcValueViewer(const int& address, const QString& value) { for (auto& lineedit : plcViwerLineedits[address]) { @@ -167,6 +180,7 @@ protected: } private: + QLabel* modeSwitchTitle; CircularSwitch modeSwitch; int sizeX = 1100, sizeY = 720,xExtraSize = 0; QListWidget* btnWidgetsPlcSim, * btnWidgetsDirect; diff --git a/src/launcher/GUI/uiModule/uiModule_userSwitch.h b/src/launcher/GUI/uiModule/uiModule_userSwitch.h index 62523c0..9d3915e 100644 --- a/src/launcher/GUI/uiModule/uiModule_userSwitch.h +++ b/src/launcher/GUI/uiModule/uiModule_userSwitch.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include @@ -36,14 +36,14 @@ public: this->config = config; } - void startAutoLogout() { + void startAutoLogout(int duration = 180) { loginTime = QDateTime::currentDateTime(); - + lastDurationSec = duration; if (!autoLogoutTimer) { autoLogoutTimer = new QTimer(this); connect(autoLogoutTimer, &QTimer::timeout, this, &AutoLogoutManager::onAutoLogout); } - autoLogoutTimer->start(180000); // 3分钟 + autoLogoutTimer->start(duration * 1000); if (!remainingTimeTimer) { remainingTimeTimer = new QTimer(this); @@ -77,7 +77,7 @@ private slots: if (loginTime.isValid()) { QDateTime currentTime = QDateTime::currentDateTime(); qint64 elapsedSeconds = loginTime.secsTo(currentTime); - qint64 remainingSeconds = 180 - elapsedSeconds; + qint64 remainingSeconds = lastDurationSec - elapsedSeconds; if (remainingSeconds > 0) { int minutes = remainingSeconds / 60; @@ -95,6 +95,7 @@ signals: void userLoggedOut(); private: + std::atomic lastDurationSec; QTimer* autoLogoutTimer = nullptr; QTimer* remainingTimeTimer = nullptr; QDateTime loginTime; @@ -108,7 +109,7 @@ class UserManagerDialog : public QDialog { public: explicit UserManagerDialog(appConfig* configIN, AutoLogoutManager* autoLogoutMgr, QTimer* updateTimer, QWidget* parent = nullptr) : QDialog(parent), config(configIN), autoLogoutManager(autoLogoutMgr), globalUpdateTimer(updateTimer) { - setWindowTitle(TR("User Management")); + setWindowTitle(TR("用户管理")); setFixedSize(400, 500); setModal(true); @@ -609,6 +610,13 @@ public: } } + // 临时权限提升方法 + void useTemporaryPermission(const QString& accountName, int durationSeconds, int level) { + config->Authorization.useTemporaryPermission(accountName, durationSeconds, level); + autoLogoutManager->startAutoLogout(durationSeconds); + updateUserDisplay(); + } + private slots: void showUserManagerDialog() { UserManagerDialog* dialog = new UserManagerDialog(config, autoLogoutManager, globalUpdateTimer, this); diff --git a/src/launcher/appConfig/appConfig.h b/src/launcher/appConfig/appConfig.h index dabf7bb..46abc65 100644 --- a/src/launcher/appConfig/appConfig.h +++ b/src/launcher/appConfig/appConfig.h @@ -30,7 +30,7 @@ public: saveJsonFromPath("./config/setting.json", settingJson); saveOrderedJsonFromPath("./config/"+ objectSelect +".json", missionJson); auto trans = &Translation::getInstance(); - trans->saveToFile("./config/translation.json"); + Translation::getInstance().saveToFile("./config/translation.json"); } runtimeDataCacheStore* cacheStore;//配置缓存 将部分界面数据缓存到数据库中 std::atomic exitWithRestart = false;//是否重启后退出 diff --git a/src/launcher/appConfig/auth.hpp b/src/launcher/appConfig/auth.hpp index aa84812..53f2d8e 100644 --- a/src/launcher/appConfig/auth.hpp +++ b/src/launcher/appConfig/auth.hpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace Auth { @@ -569,6 +570,29 @@ namespace Auth { int getUserCount() const { return static_cast(users.size()); } + + // 临时权限提升方法(即使账号不存在也允许临时使用,结束后恢复到GUEST权限) + void useTemporaryPermission(const QString& accountName, int durationSeconds, int level) { + std::string username = accountName.toStdString(); + + // 临时提升权限 + UserLevel targetLevel = static_cast(level); + currentLoggedUser = username; + currentUserLevel = targetLevel; + isLoggedIn = true; + + std::cout << "Temporary permission granted to " << username + << " at level " << userLevelToString(targetLevel) + << " for " << durationSeconds << " seconds." << std::endl; + + // 定时恢复为GUEST权限 + QTimer::singleShot(durationSeconds * 1000, [this]() { + currentLoggedUser = ""; + currentUserLevel = UserLevel::GUEST; + isLoggedIn = false; + std::cout << "Temporary permission has expired, restored to GUEST." << std::endl; + }); + } }; // 权限验证辅助函数 diff --git a/src/launcher/appConfig/translation.h b/src/launcher/appConfig/translation.h deleted file mode 100644 index bda95f6..0000000 --- a/src/launcher/appConfig/translation.h +++ /dev/null @@ -1,1401 +0,0 @@ -#ifndef TRANSLATION_H -#define TRANSLATION_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -using json = nlohmann::json; - -/** - * 单头文件翻译类 - 单例模式 - * 支持可扩展的语言section - */ -class Translation : public QObject { - Q_OBJECT -private: - std::vector sections; // 可扩展的语言列表 - std::map> translations; // [key][language] = text - std::map> basicTranslations; // [key][language] = text - std::string currentLanguage = "zh-CN"; // 默认语言 - QRecursiveMutex mutex;//线程安全锁 - // 私有构造函数 - Translation(){ - initBasicLib();//初始化默认词库 - if(sections.size() > 0)//默认为第一个语言 - currentLanguage = sections[0]; - loadFromFile("./config/translation.json"); - } - - // 禁用拷贝构造函数和赋值运算符 - Translation(const Translation&) = delete; - Translation& operator=(const Translation&) = delete; - -public: - // 获取单例实例 - static Translation& getInstance() { - static Translation instance; - return instance; - } - - // 从JSON文件加载配置 - bool loadFromFile(const std::string& filePath) { - try { - std::ifstream file(filePath); - if (!file.is_open()) { - return false; - } - - json j; - file >> j; - file.close(); - - return parseJson(j); - } catch (const std::exception& e) { - std::cerr << "Error loading translation file: " << e.what() << std::endl; - return false; - } - } - - // 从JSON字符串加载配置 - bool loadFromString(const std::string& jsonString) { - try { - json j = json::parse(jsonString); - return parseJson(j); - } catch (const std::exception& e) { - std::cerr << "Error parsing JSON string: " << e.what() << std::endl; - return false; - } - } - - // 从JSON对象加载配置 - bool loadFromJson(const json& j) { - return parseJson(j); - } - void setLanguage(const std::string& lang) { - if (currentLanguage == lang)// - return; - for (const auto& section : sections) { - if (section == lang) { - currentLanguage = lang; - emit languageChanged(); - return; - } - } - // 如果语言不在sections中,也允许设置(可能是新添加的语言) - currentLanguage = lang; - } - - // 获取当前语言 - std::string getCurrentLanguage() const { - return currentLanguage; - } - - // 获取翻译文本 - std::string translate(const std::string& key) { - QMutexLocker locker(&mutex);//线程安全锁 - {//先从基础字典中获取 - auto it = basicTranslations.find(key); - if (it != basicTranslations.end()) { - auto langIt = it->second.find(currentLanguage); - if (langIt != it->second.end()) { - return langIt->second; - } - } - } - {//再从额外字典中获取 - auto it = translations.find(key); - if (it != translations.end()) { - auto langIt = it->second.find(currentLanguage); - if (langIt != it->second.end()) { - return langIt->second; - } - } - } - //均无法找到 逐字翻译 仅适用于中文翻译到其他文字 - for (int length = key.length() - 1; length > 1; length--) { - for (int startPos = 0; startPos < key.length() - length; startPos++) { - { - auto it = basicTranslations.find(key.substr(startPos, length)); - if (it != basicTranslations.end()) { - auto langIt = it->second.find(currentLanguage); - if (langIt != it->second.end()) { - std::string result = langIt->second, frontStr, backStr; - if (startPos != 0) { - if(currentLanguage != "zh-CN")//不为中文时在词间添加空格 - result = translate(key.substr(0, startPos)) + " " + result; - else - result = translate(key.substr(0, startPos)) + result; - } - if (startPos + length < key.length()) { - if (currentLanguage != "zh-CN")//不为中文时在词间添加空格 - result += " " + translate(key.substr(startPos + length)); - else - result += translate(key.substr(startPos + length)); - } - return result; - } - } - } - { - auto it = translations.find(key.substr(startPos, length)); - if (it != translations.end()) { - auto langIt = it->second.find(currentLanguage); - if (langIt != it->second.end()) { - std::string result = langIt->second, frontStr, backStr; - if (startPos != 0) { - if (currentLanguage != "zh-CN")//不为中文时在词间添加空格 - result = translate(key.substr(0, startPos)) + " " + result; - else - result = translate(key.substr(0, startPos)) + result; - } - if (startPos + length < key.length()) { - if (currentLanguage != "zh-CN")//不为中文时在词间添加空格 - result += " " + translate(key.substr(startPos + length)); - else - result += translate(key.substr(startPos + length)); - } - return result; - } - } - } - } - } - return key; // 如果找不到翻译,返回原始key - } - - // 获取指定语言的翻译 - std::string translate(const std::string& key, const std::string& lang) { - QMutexLocker locker(&mutex);//线程安全锁 - {//先从基础字典中获取 - auto it = basicTranslations.find(key); - if (it != basicTranslations.end()) { - auto langIt = it->second.find(lang); - if (langIt != it->second.end()) { - return langIt->second; - } - } - } - {//再从额外字典中获取 - auto it = translations.find(key); - if (it != translations.end()) { - auto langIt = it->second.find(lang); - if (langIt != it->second.end()) { - return langIt->second; - } - } - } - return key; - } - - //获取所有语言的翻译结果 - std::vector < std::pair < std::string, std::string>> getAllTranslateResult(const std::string& key) { - QMutexLocker locker(&mutex);//线程安全锁 - std::vector < std::pair < std::string, std::string>> Result; - for (auto& section : sections) { - Result.push_back({ section,translate(key,section) }); - } - return Result; - } - - // 添加翻译项 - void addTranslation(const std::string& key, const std::string& lang, const std::string& text) { - QMutexLocker locker(&mutex);//线程安全锁 - translations[key][lang] = text; - } - - // 添加语言section - void addSection(const std::string& lang) { - QMutexLocker locker(&mutex);//线程安全锁 - if (lang == "us-EN") return;//老代码中大量存在的错误编码 - for (const auto& section : sections) { - if (section == lang) return; // 已存在 - } - sections.push_back(lang); - } - - // 获取所有支持的语言 - const std::vector& getSections() const { - return sections; - } - - // 检查是否有指定key的翻译 - bool hasTranslation(const std::string& key) const { - return translations.find(key) != translations.end() || basicTranslations.find(key) != basicTranslations.end(); - } - - // 获取所有翻译key - std::vector getAllKeys() { - QMutexLocker locker(&mutex);//线程安全锁 - std::vector keys; - for (const auto& pair : basicTranslations) { - keys.push_back(pair.first); - } - for (const auto& pair : translations) { - keys.push_back(pair.first); - } - return keys; - } - - //保存到JSON文件 - bool saveToFile(const std::string& filePath) const { - try { - json j; - j["current_language"] = currentLanguage; - j["section"] = sections; - - json translateObj; - for (const auto& [key, langMap] : translations) { - json keyObj; - for (const auto& [lang, text] : langMap) { - keyObj[lang] = text; - } - translateObj[key] = keyObj; - } - j["translate"] = translateObj; - - std::ofstream file(filePath); - file << j.dump(4); // 格式化输出,缩进4个空格 - file.close(); - return true; - } catch (const std::exception& e) { - std::cerr << "Error saving translation file: " << e.what() << std::endl; - return false; - } - } - - // 转换为JSON字符串 - std::string toJsonString() const { - try { - json j; - j["current_language"] = currentLanguage; - j["section"] = sections; - - json translateObj; - for (const auto& [key, langMap] : translations) { - json keyObj; - for (const auto& [lang, text] : langMap) { - keyObj[lang] = text; - } - translateObj[key] = keyObj; - } - j["translate"] = translateObj; - - return j.dump(4); - } catch (const std::exception& e) { - std::cerr << "Error converting to JSON string: " << e.what() << std::endl; - return "{}"; - } - } - -private: - //初始化默认词库 - void initBasicLib() { - //语言选项 - addSection("zh-CN"); - addSection("en-US"); - addSection("ms-MY"); - - //KEY 对应语言 翻译(返回值) -#pragma region 强对应字典 - basicTranslations["AI检测系统"]["zh-CN"] = "AI检测系统"; - basicTranslations["AI检测系统"]["en-US"] = "AI Detection System"; - basicTranslations["AI检测系统"]["ms-MY"] = "Sistem Pengesanan AI"; - - basicTranslations["权限不足"]["zh-CN"] = "权限不足"; - basicTranslations["权限不足"]["en-US"] = "Insufficient permissions"; - basicTranslations["权限不足"]["ms-MY"] = "Kebenaran tidak mencukupi"; - - basicTranslations["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["zh-CN"] = "您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"; - basicTranslations["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["en-US"] = "You do not have sufficient permissions to perform this action.\n\nRequired level: %1\nCurrent level: %2"; - basicTranslations["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["ms-MY"] = "Anda tidak mempunyai kebenaran yang mencukupi untuk melaksanakan tindakan ini.\n\nTahap diperlukan: %1\nTahap semasa: %2"; - - basicTranslations["JSON 表格编辑器"]["zh-CN"] = "JSON 表格编辑器"; - basicTranslations["JSON 表格编辑器"]["en-US"] = "JSON Table Editor"; - basicTranslations["JSON 表格编辑器"]["ms-MY"] = "Editor Jadual JSONI"; - - basicTranslations["通用 JSON 编辑"]["zh-CN"] = "通用 JSON 编辑"; - basicTranslations["通用 JSON 编辑"]["en-US"] = "General JSON Editor"; - basicTranslations["通用 JSON 编辑"]["ms-MY"] = "Penyunting JSON Am"; - - basicTranslations["导出失败"]["zh-CN"] = "导出失败"; - basicTranslations["导出失败"]["en-US"] = "Export Failed"; - basicTranslations["导出失败"]["ms-MY"] = "Eksport Gagal"; - - basicTranslations["权限不足"]["zh-CN"] = "权限不足"; - basicTranslations["权限不足"]["en-US"] = "Insufficient permissions"; - basicTranslations["权限不足"]["ms-MY"] = "Kebenaran tidak mencukupi"; - - basicTranslations["售后"]["zh-CN"] = "售后"; - basicTranslations["售后"]["en-US"] = "After-sales"; - basicTranslations["售后"]["ms-MY"] = "Perkhidmatan Selepas Jualan"; - - basicTranslations["所有密码字段都不能为空"]["zh-CN"] = "所有密码字段都不能为空"; - basicTranslations["所有密码字段都不能为空"]["en-US"] = "All password fields cannot be empty"; - basicTranslations["所有密码字段都不能为空"]["ms-MY"] = "Semua medan kata laluan tidak boleh kosong"; - - basicTranslations["确定要执行此操作吗?"]["zh-CN"] = "确定要执行此操作吗?"; - basicTranslations["确定要执行此操作吗?"]["en-US"] = "Are you sure you want to execute this action?"; - basicTranslations["确定要执行此操作吗?"]["ms-MY"] = "Adakah anda pasti mahu melaksanakan tindakan ini?"; - - basicTranslations["自动滚动"]["zh-CN"] = "自动滚动"; - basicTranslations["自动滚动"]["en-US"] = "Auto Scroll"; - basicTranslations["自动滚动"]["ms-MY"] = "Tatal Automatik"; - - basicTranslations["返回目录"]["zh-CN"] = "返回目录"; - basicTranslations["返回目录"]["en-US"] = "Back to Menu"; - basicTranslations["返回目录"]["ms-MY"] = "Kembali ke Menu"; - - basicTranslations["布尔值控件类型错误"]["zh-CN"] = "布尔值控件类型错误"; - basicTranslations["布尔值控件类型错误"]["en-US"] = "Boolean control type mismatch"; - basicTranslations["布尔值控件类型错误"]["ms-MY"] = "Jenis kawalan boolean tidak sepadan"; - - basicTranslations["布尔值只能是 true 或 false"]["zh-CN"] = "布尔值只能是 true 或 false"; - basicTranslations["布尔值只能是 true 或 false"]["en-US"] = "Boolean must be true or false"; - basicTranslations["布尔值只能是 true 或 false"]["ms-MY"] = "Boolean mesti true atau false"; - - basicTranslations["相机标签"]["zh-CN"] = "相机标签"; - basicTranslations["相机标签"]["en-US"] = "Camera Label"; - basicTranslations["相机标签"]["ms-MY"] = "Label Kamera"; - - basicTranslations["取消"]["zh-CN"] = "取消"; - basicTranslations["取消"]["en-US"] = "Cancel"; - basicTranslations["取消"]["ms-MY"] = "Batal"; - - basicTranslations["修改密码"]["zh-CN"] = "修改密码"; - basicTranslations["修改密码"]["en-US"] = "Change Password"; - basicTranslations["修改密码"]["ms-MY"] = "Tukar Kata Laluan"; - - basicTranslations["关闭"]["zh-CN"] = "关闭"; - basicTranslations["关闭"]["en-US"] = "Close"; - basicTranslations["关闭"]["ms-MY"] = "Tutup"; - - basicTranslations["提示"]["zh-CN"] = "提示"; - basicTranslations["提示"]["en-US"] = "Confirm"; - basicTranslations["提示"]["ms-MY"] = "Sahkan"; - - basicTranslations["确认密码:"]["zh-CN"] = "确认密码:"; - basicTranslations["确认密码:"]["en-US"] = "Confirm Password:"; - basicTranslations["确认密码:"]["ms-MY"] = "Sahkan Kata Laluan:"; - - basicTranslations["控制台"]["zh-CN"] = "控制台"; - basicTranslations["控制台"]["en-US"] = "Console"; - basicTranslations["控制台"]["ms-MY"] = "Konsol"; - - basicTranslations["控制台日志..."]["zh-CN"] = "控制台日志..."; - basicTranslations["控制台日志..."]["en-US"] = "Console Log..."; - basicTranslations["控制台日志..."]["ms-MY"] = "Log Konsol..."; - - basicTranslations["控制台设置"]["zh-CN"] = "控制台设置"; - basicTranslations["控制台设置"]["en-US"] = "Console Settings"; - basicTranslations["控制台设置"]["ms-MY"] = "Tetapan Konsol"; - - basicTranslations["转换错误: %1"]["zh-CN"] = "转换错误: %1"; - basicTranslations["转换错误: %1"]["en-US"] = "Conversion error: %1"; - basicTranslations["转换错误: %1"]["ms-MY"] = "Ralat penukaran: %1"; - - basicTranslations["创建用户"]["zh-CN"] = "创建用户"; - basicTranslations["创建用户"]["en-US"] = "Create User"; - basicTranslations["创建用户"]["ms-MY"] = "Cipta Pengguna"; - - basicTranslations["当前密码:"]["zh-CN"] = "当前密码:"; - basicTranslations["当前密码:"]["en-US"] = "Current Password:"; - basicTranslations["当前密码:"]["ms-MY"] = "Kata Laluan Semasa:"; - - basicTranslations["本次运行数据"]["zh-CN"] = "本次运行数据"; - basicTranslations["本次运行数据"]["en-US"] = "Current Run Data"; - basicTranslations["本次运行数据"]["ms-MY"] = "Data Larian Semasa"; - - basicTranslations["当前用户信息"]["zh-CN"] = "当前用户信息"; - basicTranslations["当前用户信息"]["en-US"] = "Current User Information"; - basicTranslations["当前用户信息"]["ms-MY"] = "Maklumat Pengguna Semasa"; - - basicTranslations["当前用户: "]["zh-CN"] = "当前用户: "; - basicTranslations["当前用户: "]["en-US"] = "Current User: "; - basicTranslations["当前用户: "]["ms-MY"] = "Pengguna Semasa: "; - - basicTranslations["当前用户: 未登录"]["zh-CN"] = "当前用户: 未登录"; - basicTranslations["当前用户: 未登录"]["en-US"] = "Current User: Not logged in"; - basicTranslations["当前用户: 未登录"]["ms-MY"] = "Pengguna Semasa: Tidak log masuk"; - - basicTranslations["已注销当前用户"]["zh-CN"] = "已注销当前用户"; - basicTranslations["已注销当前用户"]["en-US"] = "Current user logged out"; - basicTranslations["已注销当前用户"]["ms-MY"] = "Pengguna semasa telah log keluar"; - - basicTranslations["当前版本: v%1"]["zh-CN"] = "当前版本: v%1"; - basicTranslations["当前版本: v%1"]["en-US"] = "Current version: v%1"; - basicTranslations["当前版本: v%1"]["ms-MY"] = "Versi semasa: v%1"; - - basicTranslations["数据已成功导出到:\n"]["zh-CN"] = "数据已成功导出到:\n"; - basicTranslations["数据已成功导出到:\n"]["en-US"] = "Data successfully exported to:\n"; - basicTranslations["数据已成功导出到:\n"]["ms-MY"] = "Data berjaya dieksport ke:\n"; - - basicTranslations["数据库操作界面"]["zh-CN"] = "数据库操作界面"; - basicTranslations["数据库操作界面"]["en-US"] = "Database Operations"; - basicTranslations["数据库操作界面"]["ms-MY"] = "Operasi Pangkalan Data"; - - basicTranslations["故障排查"]["zh-CN"] = "故障排查"; - basicTranslations["故障排查"]["en-US"] = "Debug"; - basicTranslations["故障排查"]["ms-MY"] = "Penyelesaian Masalah"; - - basicTranslations["默认标题"]["zh-CN"] = "默认标题"; - basicTranslations["默认标题"]["en-US"] = "Default Title"; - basicTranslations["默认标题"]["ms-MY"] = "Tajuk Lalai"; - - basicTranslations["正在检测..."]["zh-CN"] = "正在检测..."; - basicTranslations["正在检测..."]["en-US"] = "Detecting..."; - basicTranslations["正在检测..."]["ms-MY"] = "Mengesan..."; - - basicTranslations["是否退出程序?"]["zh-CN"] = "是否退出程序?"; - basicTranslations["是否退出程序?"]["en-US"] = "Do you want to exit the application?"; - basicTranslations["是否退出程序?"]["ms-MY"] = "Adakah anda mahu keluar daripada aplikasi?"; - - basicTranslations["编辑参数"]["zh-CN"] = "编辑参数"; - basicTranslations["编辑参数"]["en-US"] = "Edit Parameters"; - basicTranslations["编辑参数"]["ms-MY"] = "Sunting Parameter"; - - basicTranslations["工程师"]["zh-CN"] = "工程师"; - basicTranslations["工程师"]["en-US"] = "Engineer"; - basicTranslations["工程师"]["ms-MY"] = "Jurutera"; - - basicTranslations["输入 Y 或 y"]["zh-CN"] = "输入 Y 或 y"; - basicTranslations["输入 Y 或 y"]["en-US"] = "Enter Y or y"; - basicTranslations["输入 Y 或 y"]["ms-MY"] = "Masukkan Y atau y"; - - basicTranslations["输入布尔值(true 或 false)"]["zh-CN"] = "输入布尔值(true 或 false)"; - basicTranslations["输入布尔值(true 或 false)"]["en-US"] = "Enter a boolean value (true or false)"; - basicTranslations["输入布尔值(true 或 false)"]["ms-MY"] = "Masukkan nilai boolean (true atau false)"; - - basicTranslations["输入数字值(小数)"]["zh-CN"] = "输入数字值(小数)"; - basicTranslations["输入数字值(小数)"]["en-US"] = "Enter a decimal value"; - basicTranslations["输入数字值(小数)"]["ms-MY"] = "Masukkan nilai perpuluhan"; - - basicTranslations["输入数字值(整数或小数)"]["zh-CN"] = "输入数字值(整数或小数)"; - basicTranslations["输入数字值(整数或小数)"]["en-US"] = "Enter a numeric value (integer or decimal)"; - basicTranslations["输入数字值(整数或小数)"]["ms-MY"] = "Masukkan nilai nombor (integer atau perpuluhan)"; - - basicTranslations["输入字符串值(不需要引号)"]["zh-CN"] = "输入字符串值(不需要引号)"; - basicTranslations["输入字符串值(不需要引号)"]["en-US"] = "Enter a string value (no quotes required)"; - basicTranslations["输入字符串值(不需要引号)"]["ms-MY"] = "Masukkan nilai rentetan (tidak perlu tanda petik)"; - - basicTranslations["输入数字值(整数)"]["zh-CN"] = "输入数字值(整数)"; - basicTranslations["输入数字值(整数)"]["en-US"] = "Enter an integer value"; - basicTranslations["输入数字值(整数)"]["ms-MY"] = "Masukkan nilai integer"; - - basicTranslations["错误"]["zh-CN"] = "错误"; - basicTranslations["错误"]["en-US"] = "Error"; - basicTranslations["错误"]["ms-MY"] = "Ralat"; - - basicTranslations["执行命令"]["zh-CN"] = "执行命令"; - basicTranslations["执行命令"]["en-US"] = "Execute Command"; - basicTranslations["执行命令"]["ms-MY"] = "Jalankan Perintah"; - - basicTranslations["退出"]["zh-CN"] = "退出"; - basicTranslations["退出"]["en-US"] = "Exit"; - basicTranslations["退出"]["ms-MY"] = "Keluar"; - - basicTranslations["退出确认"]["zh-CN"] = "退出确认"; - basicTranslations["退出确认"]["en-US"] = "Exit Confirmation"; - basicTranslations["退出确认"]["ms-MY"] = "Pengesahan Keluar"; - - basicTranslations["退出中,请稍后"]["zh-CN"] = "退出中,请稍后"; - basicTranslations["退出中,请稍后"]["en-US"] = "Exiting, please wait"; - basicTranslations["退出中,请稍后"]["ms-MY"] = "Keluar, sila tunggu sebentar"; - - basicTranslations["正在退出..."]["zh-CN"] = "正在退出..."; - basicTranslations["正在退出..."]["en-US"] = "Exiting..."; - basicTranslations["正在退出..."]["ms-MY"] = "Keluar..."; - - basicTranslations["导出"]["zh-CN"] = "导出"; - basicTranslations["导出"]["en-US"] = "Export"; - basicTranslations["导出"]["ms-MY"] = "Eksport"; - - basicTranslations["导出失败"]["zh-CN"] = "导出失败"; - basicTranslations["导出失败"]["en-US"] = "Export Failed"; - basicTranslations["导出失败"]["ms-MY"] = "Eksport Gagal"; - - basicTranslations["导出成功"]["zh-CN"] = "导出成功"; - basicTranslations["导出成功"]["en-US"] = "Export Successful"; - basicTranslations["导出成功"]["ms-MY"] = "Eksport Berjaya"; - - basicTranslations["导出为CSV"]["zh-CN"] = "导出为CSV"; - basicTranslations["导出为CSV"]["en-US"] = "Export as CSV"; - basicTranslations["导出为CSV"]["ms-MY"] = "Eksport sebagai CSV"; - - basicTranslations["导出CSV文件失败,请检查路径或数据库状态。"]["zh-CN"] = "导出CSV文件失败,请检查路径或数据库状态。"; - basicTranslations["导出CSV文件失败,请检查路径或数据库状态。"]["en-US"] = "Failed to export CSV. Please check the path or database status."; - basicTranslations["导出CSV文件失败,请检查路径或数据库状态。"]["ms-MY"] = "Gagal mengeksport CSV. Sila semak laluan atau status pangkalan data."; - - basicTranslations["通用 JSON 编辑"]["zh-CN"] = "通用 JSON 编辑"; - basicTranslations["通用 JSON 编辑"]["en-US"] = "General JSON Editor"; - basicTranslations["通用 JSON 编辑"]["ms-MY"] = "Penyunting JSON Am"; - - basicTranslations["获取值错误: %1"]["zh-CN"] = "获取值错误: %1"; - basicTranslations["获取值错误: %1"]["en-US"] = "Get value error: %1"; - basicTranslations["获取值错误: %1"]["ms-MY"] = "Ralat mendapat nilai: %1"; - - basicTranslations["返回上一级"]["zh-CN"] = "返回上一级"; - basicTranslations["返回上一级"]["en-US"] = "Go Back"; - basicTranslations["返回上一级"]["ms-MY"] = "Kembali"; - - basicTranslations["访客"]["zh-CN"] = "访客"; - basicTranslations["访客"]["en-US"] = "Guest"; - basicTranslations["访客"]["ms-MY"] = "Tetamu"; - - basicTranslations["硬件信息"]["zh-CN"] = "硬件信息"; - basicTranslations["硬件信息"]["en-US"] = "Hardware Information"; - basicTranslations["硬件信息"]["ms-MY"] = "Maklumat Perkakasan"; - - basicTranslations["历史记录"]["zh-CN"] = "历史记录"; - basicTranslations["历史记录"]["en-US"] = "History"; - basicTranslations["历史记录"]["ms-MY"] = "Sejarah"; - - basicTranslations["正在初始化..."]["zh-CN"] = "正在初始化..."; - basicTranslations["正在初始化..."]["en-US"] = "Initializing..."; - basicTranslations["正在初始化..."]["ms-MY"] = "Memulakan..."; - - basicTranslations["输入值过大(超过10240字符)"]["zh-CN"] = "输入值过大(超过10240字符)"; - basicTranslations["输入值过大(超过10240字符)"]["en-US"] = "Input value too large (exceeds 10240 characters)"; - basicTranslations["输入值过大(超过10240字符)"]["ms-MY"] = "Nilai input terlalu besar (melebihi 10240 aksara)"; - - basicTranslations["权限不足"]["zh-CN"] = "权限不足"; - basicTranslations["权限不足"]["en-US"] = "Insufficient permissions"; - basicTranslations["权限不足"]["ms-MY"] = "Kebenaran tidak mencukupi"; - - basicTranslations["数字控件INT类型错误"]["zh-CN"] = "数字控件INT类型错误"; - basicTranslations["数字控件INT类型错误"]["en-US"] = "Integer number control type mismatch"; - basicTranslations["数字控件INT类型错误"]["ms-MY"] = "Jenis kawalan nombor integer tidak sepadan"; - - basicTranslations["无效的数字格式"]["zh-CN"] = "无效的数字格式"; - basicTranslations["无效的数字格式"]["en-US"] = "Invalid numeric format"; - basicTranslations["无效的数字格式"]["ms-MY"] = "Format nombor tidak sah"; - - basicTranslations["JSON 表格编辑器"]["zh-CN"] = "JSON 表格编辑器"; - basicTranslations["JSON 表格编辑器"]["en-US"] = "JSON Table Editor"; - basicTranslations["JSON 表格编辑器"]["ms-MY"] = "Editor Jadual JSON"; - - basicTranslations["JSON 内容不能为空"]["zh-CN"] = "JSON 内容不能为空"; - basicTranslations["JSON 内容不能为空"]["en-US"] = "JSON content cannot be empty"; - basicTranslations["JSON 内容不能为空"]["ms-MY"] = "Kandungan JSON tidak boleh kosong"; - - basicTranslations["JSON 内容过大,可能导致崩溃"]["zh-CN"] = "JSON 内容过大,可能导致崩溃"; - basicTranslations["JSON 内容过大,可能导致崩溃"]["en-US"] = "JSON content is too large and may cause a crash"; - basicTranslations["JSON 内容过大,可能导致崩溃"]["ms-MY"] = "Kandungan JSON terlalu besar dan mungkin menyebabkan kerosakan"; - - basicTranslations["JSON解析错误: %1"]["zh-CN"] = "JSON解析错误: %1"; - basicTranslations["JSON解析错误: %1"]["en-US"] = "JSON parse error: %1"; - basicTranslations["JSON解析错误: %1"]["ms-MY"] = "Ralat parse JSON: %1"; - - basicTranslations["JSON 解析失败:\n%1"]["zh-CN"] = "JSON 解析失败:\n%1"; - basicTranslations["JSON 解析失败:\n%1"]["en-US"] = "JSON parse failed:\n%1"; - basicTranslations["JSON 解析失败:\n%1"]["ms-MY"] = "Parse JSON gagal:\n%1"; - - basicTranslations["语言设置"]["zh-CN"] = "语言设置"; - basicTranslations["语言设置"]["en-US"] = "Language Settings"; - basicTranslations["语言设置"]["ms-MY"] = "Tetapan Bahasa"; - - basicTranslations["长度"]["zh-CN"] = "长度"; - basicTranslations["长度"]["en-US"] = "Length"; - basicTranslations["长度"]["ms-MY"] = "Panjang"; - - basicTranslations["日志分析"]["zh-CN"] = "日志分析"; - basicTranslations["日志分析"]["en-US"] = "Log"; - basicTranslations["日志分析"]["ms-MY"] = "Analisis Log"; - - basicTranslations["登录"]["zh-CN"] = "登录"; - basicTranslations["登录"]["en-US"] = "Login"; - basicTranslations["登录"]["ms-MY"] = "Log Masuk"; - - basicTranslations["登录失败,请检查用户名和密码"]["zh-CN"] = "登录失败,请检查用户名和密码"; - basicTranslations["登录失败,请检查用户名和密码"]["en-US"] = "Login failed, please check username and password"; - basicTranslations["登录失败,请检查用户名和密码"]["ms-MY"] = "Log masuk gagal, sila periksa nama pengguna dan kata laluan"; - - basicTranslations["登录成功!系统将在3分钟后自动注销"]["zh-CN"] = "登录成功!系统将在3分钟后自动注销"; - basicTranslations["登录成功!系统将在3分钟后自动注销"]["en-US"] = "Login successful! System will auto logout in 3 minutes"; - basicTranslations["登录成功!系统将在3分钟后自动注销"]["ms-MY"] = "Log masuk berjaya! Sistem akan auto log keluar dalam 3 minit"; - - basicTranslations["登录/注销"]["zh-CN"] = "登录/注销"; - basicTranslations["登录/注销"]["en-US"] = "Login/Logout"; - basicTranslations["登录/注销"]["ms-MY"] = "Log Masuk/Log Keluar"; - - basicTranslations["注销"]["zh-CN"] = "注销"; - basicTranslations["注销"]["en-US"] = "Logout"; - basicTranslations["注销"]["ms-MY"] = "Log Keluar"; - - basicTranslations["监控错误: %1"]["zh-CN"] = "监控错误: %1"; - basicTranslations["监控错误: %1"]["en-US"] = "Monitor error: %1"; - basicTranslations["监控错误: %1"]["ms-MY"] = "Ralat pemantauan: %1"; - - basicTranslations["监控异常"]["zh-CN"] = "监控异常"; - basicTranslations["监控异常"]["en-US"] = "Monitoring Error"; - basicTranslations["监控异常"]["ms-MY"] = "Ralat Pemantauan"; - - basicTranslations["NG数量"]["zh-CN"] = "NG数量"; - basicTranslations["NG数量"]["en-US"] = "NG Count"; - basicTranslations["NG数量"]["ms-MY"] = "Kiraan NG"; - - basicTranslations["新密码:"]["zh-CN"] = "新密码:"; - basicTranslations["新密码:"]["en-US"] = "New Password:"; - basicTranslations["新密码:"]["ms-MY"] = "Kata Laluan Baru:"; - - basicTranslations["新密码和确认密码不匹配"]["zh-CN"] = "新密码和确认密码不匹配"; - basicTranslations["新密码和确认密码不匹配"]["en-US"] = "New password and confirm password do not match"; - basicTranslations["新密码和确认密码不匹配"]["ms-MY"] = "Kata laluan baru dan pengesahan kata laluan tidak sepadan"; - - basicTranslations["新密码长度至少为4位"]["zh-CN"] = "新密码长度至少为4位"; - basicTranslations["新密码长度至少为4位"]["en-US"] = "New password must be at least 4 characters"; - basicTranslations["新密码长度至少为4位"]["ms-MY"] = "Kata laluan baru mestilah sekurang-kurangnya 4 aksara"; - - basicTranslations["空值(输入 null)"]["zh-CN"] = "空值(输入 null)"; - basicTranslations["空值(输入 null)"]["en-US"] = "Null (enter null)"; - basicTranslations["空值(输入 null)"]["ms-MY"] = "Null (masukkan null)"; - - basicTranslations["空值只能是 null"]["zh-CN"] = "空值只能是 null"; - basicTranslations["空值只能是 null"]["en-US"] = "Null value must be null"; - basicTranslations["空值只能是 null"]["ms-MY"] = "Nilai null mesti null"; - - basicTranslations["数字控件类型错误"]["zh-CN"] = "数字控件类型错误"; - basicTranslations["数字控件类型错误"]["en-US"] = "Number control type mismatch"; - basicTranslations["数字控件类型错误"]["ms-MY"] = "Jenis kawalan nombor tidak sepadan"; - - basicTranslations["确定"]["zh-CN"] = "确定"; - basicTranslations["确定"]["en-US"] = "OK"; - basicTranslations["确定"]["ms-MY"] = "OK"; - - basicTranslations["OK数量"]["zh-CN"] = "OK数量"; - basicTranslations["OK数量"]["en-US"] = "OK Count"; - basicTranslations["OK数量"]["ms-MY"] = "Kiraan OK"; - - basicTranslations["离线模式"]["zh-CN"] = "离线模式"; - basicTranslations["离线模式"]["en-US"] = "Offline Mode"; - basicTranslations["离线模式"]["ms-MY"] = "Mod Luar Talian"; - - basicTranslations["打开日志文件夹"]["zh-CN"] = "打开日志文件夹"; - basicTranslations["打开日志文件夹"]["en-US"] = "Open Log Folder"; - basicTranslations["打开日志文件夹"]["ms-MY"] = "Buka Folder Log"; - - basicTranslations["选项"]["zh-CN"] = "选项"; - basicTranslations["选项"]["en-US"] = "Option"; - basicTranslations["选项"]["ms-MY"] = "Pilihan"; - - basicTranslations["第 %1 行找不到原始类型信息"]["zh-CN"] = "第 %1 行找不到原始类型信息"; - basicTranslations["第 %1 行找不到原始类型信息"]["en-US"] = "Original type information not found for row %1"; - basicTranslations["第 %1 行找不到原始类型信息"]["ms-MY"] = "Maklumat jenis asal tidak ditemui untuk baris %1"; - - basicTranslations["参数设置"]["zh-CN"] = "参数设置"; - basicTranslations["参数设置"]["en-US"] = "Param"; - basicTranslations["参数设置"]["ms-MY"] = "Tetapan Parameter"; - - basicTranslations["编辑参数"]["zh-CN"] = "编辑参数"; - basicTranslations["编辑参数"]["en-US"] = "Param Edit"; - basicTranslations["编辑参数"]["ms-MY"] = "Sunting Parameter"; - - basicTranslations["解析错误"]["zh-CN"] = "解析错误"; - basicTranslations["解析错误"]["en-US"] = "Parse Error"; - basicTranslations["解析错误"]["ms-MY"] = "Ralat Parse"; - - basicTranslations["密码修改失败,请检查当前密码"]["zh-CN"] = "密码修改失败,请检查当前密码"; - basicTranslations["密码修改失败,请检查当前密码"]["en-US"] = "Password change failed, please check current password"; - basicTranslations["密码修改失败,请检查当前密码"]["ms-MY"] = "Penukaran kata laluan gagal, sila periksa kata laluan semasa"; - - basicTranslations["密码修改成功!"]["zh-CN"] = "密码修改成功!"; - basicTranslations["密码修改成功!"]["en-US"] = "Password changed successfully!"; - basicTranslations["密码修改成功!"]["ms-MY"] = "Kata laluan berjaya ditukar!"; - - basicTranslations["密码长度至少为4位"]["zh-CN"] = "密码长度至少为4位"; - basicTranslations["密码长度至少为4位"]["en-US"] = "Password must be at least 4 characters"; - basicTranslations["密码长度至少为4位"]["ms-MY"] = "Kata laluan mestilah sekurang-kurangnya 4 aksara"; - - basicTranslations["密码:"]["zh-CN"] = "密码:"; - basicTranslations["密码:"]["en-US"] = "Password:"; - basicTranslations["密码:"]["ms-MY"] = "Kata Laluan:"; - - basicTranslations["待读取"]["zh-CN"] = "待读取"; - basicTranslations["待读取"]["en-US"] = "Pending"; - basicTranslations["待读取"]["ms-MY"] = "Tertunda"; - - basicTranslations["权限等级:"]["zh-CN"] = "权限等级:"; - basicTranslations["权限等级:"]["en-US"] = "Permission Level:"; - basicTranslations["权限等级:"]["ms-MY"] = "Tahap Kebenaran:"; - - basicTranslations["权限等级: "]["zh-CN"] = "权限等级: "; - basicTranslations["权限等级: "]["en-US"] = "Permission Level: "; - basicTranslations["权限等级: "]["ms-MY"] = "Tahap Kebenaran: "; - - basicTranslations["权限等级: 访客"]["zh-CN"] = "权限等级: 访客"; - basicTranslations["权限等级: 访客"]["en-US"] = "Permission Level: Guest"; - basicTranslations["权限等级: 访客"]["ms-MY"] = "Tahap Kebenaran: Tetamu"; - - basicTranslations["请先创建用户"]["zh-CN"] = "请先创建用户"; - basicTranslations["请先创建用户"]["en-US"] = "Please create user first"; - basicTranslations["请先创建用户"]["ms-MY"] = "Sila cipta pengguna dahulu"; - - basicTranslations["请输入 JSON:"]["zh-CN"] = "请输入 JSON:"; - basicTranslations["请输入 JSON:"]["en-US"] = "Please enter JSON:"; - basicTranslations["请输入 JSON:"]["ms-MY"] = "Sila masukkan JSON:"; - - basicTranslations["请输入 Y 或 y 以退出(%1 秒后取消)"]["zh-CN"] = "请输入 Y 或 y 以退出(%1 秒后取消)"; - basicTranslations["请输入 Y 或 y 以退出(%1 秒后取消)"]["en-US"] = "Please enter Y or y to exit (will cancel after %1 sec)"; - basicTranslations["请输入 Y 或 y 以退出(%1 秒后取消)"]["ms-MY"] = "Sila masukkan Y atau y untuk keluar (akan batal selepas %1 saat)"; - - basicTranslations["请输入有效的JSON值"]["zh-CN"] = "请输入有效的JSON值"; - basicTranslations["请输入有效的JSON值"]["en-US"] = "Please enter a valid JSON value"; - basicTranslations["请输入有效的JSON值"]["ms-MY"] = "Sila masukkan nilai JSON yang sah"; - - basicTranslations["生产数据采集"]["zh-CN"] = "生产数据采集"; - basicTranslations["生产数据采集"]["en-US"] = "Production Data Collection"; - basicTranslations["生产数据采集"]["ms-MY"] = "Pengumpulan Data Pengeluaran"; - - basicTranslations["刷新"]["zh-CN"] = "刷新"; - basicTranslations["刷新"]["en-US"] = "Refresh"; - basicTranslations["刷新"]["ms-MY"] = "Segarkan"; - - basicTranslations["重新进行初始化"]["zh-CN"] = "重新进行初始化"; - basicTranslations["重新进行初始化"]["en-US"] = "Reinitialize"; - basicTranslations["重新进行初始化"]["ms-MY"] = "Inisialisasi Semula"; - - basicTranslations["剩余: "]["zh-CN"] = "剩余: "; - basicTranslations["剩余: "]["en-US"] = "Remaining: "; - basicTranslations["剩余: "]["ms-MY"] = "Baki: "; - - basicTranslations["重试"]["zh-CN"] = "重试"; - basicTranslations["重试"]["en-US"] = "Retry"; - basicTranslations["重试"]["ms-MY"] = "Cuba Semula"; - - basicTranslations["第 %1 行数据不完整"]["zh-CN"] = "第 %1 行数据不完整"; - basicTranslations["第 %1 行数据不完整"]["en-US"] = "Row %1 data is incomplete"; - basicTranslations["第 %1 行数据不完整"]["ms-MY"] = "Data baris %1 tidak lengkap"; - - basicTranslations["第 %1 行 key 为空"]["zh-CN"] = "第 %1 行 key 为空"; - basicTranslations["第 %1 行 key 为空"]["en-US"] = "Row %1 key is empty"; - basicTranslations["第 %1 行 key 为空"]["ms-MY"] = "Kekunci baris %1 kosong"; - - basicTranslations["第 %1 行值验证失败:\n%2"]["zh-CN"] = "第 %1 行值验证失败:\n%2"; - basicTranslations["第 %1 行值验证失败:\n%2"]["en-US"] = "Row %1 value validation failed:\n%2"; - basicTranslations["第 %1 行值验证失败:\n%2"]["ms-MY"] = "Pengesahan nilai baris %1 gagal:\n%2"; - - basicTranslations["运行数据"]["zh-CN"] = "运行数据"; - basicTranslations["运行数据"]["en-US"] = "Run Data"; - basicTranslations["运行数据"]["ms-MY"] = "Data Larian"; - - basicTranslations["SN查询"]["zh-CN"] = "SN查询"; - basicTranslations["SN查询"]["en-US"] = "SN Search"; - basicTranslations["SN查询"]["ms-MY"] = "Carian SN"; - - basicTranslations["保存"]["zh-CN"] = "保存"; - basicTranslations["保存"]["en-US"] = "Save"; - basicTranslations["保存"]["ms-MY"] = "Simpan"; - - basicTranslations["查询"]["zh-CN"] = "查询"; - basicTranslations["查询"]["en-US"] = "Search"; - basicTranslations["查询"]["ms-MY"] = "Carian"; - - basicTranslations["服务已离线"]["zh-CN"] = "服务已离线"; - basicTranslations["服务已离线"]["en-US"] = "Service is offline"; - basicTranslations["服务已离线"]["ms-MY"] = "Perkhidmatan luar talian"; - - basicTranslations["设置"]["zh-CN"] = "设置"; - basicTranslations["设置"]["en-US"] = "Setting"; - basicTranslations["设置"]["ms-MY"] = "Tetapan"; - - basicTranslations["班次"]["zh-CN"] = "班次"; - basicTranslations["班次"]["en-US"] = "Shift"; - basicTranslations["班次"]["ms-MY"] = "Syif"; - - basicTranslations["字符串控件类型错误"]["zh-CN"] = "字符串控件类型错误"; - basicTranslations["字符串控件类型错误"]["en-US"] = "String control type mismatch"; - basicTranslations["字符串控件类型错误"]["ms-MY"] = "Jenis kawalan rentetan tidak sepadan"; - - basicTranslations["成功"]["zh-CN"] = "成功"; - basicTranslations["成功"]["en-US"] = "Success"; - basicTranslations["成功"]["ms-MY"] = "Berjaya"; - - basicTranslations["系统日志"]["zh-CN"] = "系统日志"; - basicTranslations["系统日志"]["en-US"] = "System Log"; - basicTranslations["系统日志"]["ms-MY"] = "Log Sistem"; - - basicTranslations["系统状态: %1\n"]["zh-CN"] = "系统状态: %1\n"; - basicTranslations["系统状态: %1\n"]["en-US"] = "System status: %1\n"; - basicTranslations["系统状态: %1\n"]["ms-MY"] = "Status sistem: %1\n"; - - basicTranslations["工具"]["zh-CN"] = "工具"; - basicTranslations["工具"]["en-US"] = "TOOLS"; - basicTranslations["工具"]["ms-MY"] = "Alat"; - - basicTranslations["已超时"]["zh-CN"] = "已超时"; - basicTranslations["已超时"]["en-US"] = "Timed out"; - basicTranslations["已超时"]["ms-MY"] = "Masa tamat"; - - basicTranslations["总数量"]["zh-CN"] = "总数量"; - basicTranslations["总数量"]["en-US"] = "Total Count"; - basicTranslations["总数量"]["ms-MY"] = "Jumlah Kiraan"; - - basicTranslations["类型验证失败"]["zh-CN"] = "类型验证失败"; - basicTranslations["类型验证失败"]["en-US"] = "Type Validation Failed"; - basicTranslations["类型验证失败"]["ms-MY"] = "Pengesahan Jenis Gagal"; - - basicTranslations["未知的数据类型"]["zh-CN"] = "未知的数据类型"; - basicTranslations["未知的数据类型"]["en-US"] = "Unknown data type"; - basicTranslations["未知的数据类型"]["ms-MY"] = "Jenis data tidak diketahui"; - - basicTranslations["用户管理"]["zh-CN"] = "用户管理"; - basicTranslations["用户管理"]["en-US"] = "User Management"; - basicTranslations["用户管理"]["ms-MY"] = "Pengurusan Pengguna"; - - basicTranslations["用户创建成功!"]["zh-CN"] = "用户创建成功!"; - basicTranslations["用户创建成功!"]["en-US"] = "User created successfully!"; - basicTranslations["用户创建成功!"]["ms-MY"] = "Pengguna berjaya dicipta!"; - - basicTranslations["用户创建失败,用户名可能已存在"]["zh-CN"] = "用户创建失败,用户名可能已存在"; - basicTranslations["用户创建失败,用户名可能已存在"]["en-US"] = "User creation failed, username may already exist"; - basicTranslations["用户创建失败,用户名可能已存在"]["ms-MY"] = "Penciptaan pengguna gagal, nama pengguna mungkin sudah wujud"; - - basicTranslations["用户名和密码不能为空"]["zh-CN"] = "用户名和密码不能为空"; - basicTranslations["用户名和密码不能为空"]["en-US"] = "Username and password cannot be empty"; - basicTranslations["用户名和密码不能为空"]["ms-MY"] = "Nama pengguna dan kata laluan tidak boleh kosong"; - - basicTranslations["用户名:"]["zh-CN"] = "用户名:"; - basicTranslations["用户名:"]["en-US"] = "Username:"; - basicTranslations["用户名:"]["ms-MY"] = "Nama Pengguna:"; - - basicTranslations["值"]["zh-CN"] = "值"; - basicTranslations["值"]["en-US"] = "Value"; - basicTranslations["值"]["ms-MY"] = "Nilai"; - - basicTranslations["值:"]["zh-CN"] = "值:"; - basicTranslations["值:"]["en-US"] = "Value:"; - basicTranslations["值:"]["ms-MY"] = "Nilai:"; - - basicTranslations["预览参数"]["zh-CN"] = "预览参数"; - basicTranslations["预览参数"]["en-US"] = "View Param"; - basicTranslations["预览参数"]["ms-MY"] = "Lihat Parameter"; - - basicTranslations["查看图片"]["zh-CN"] = "查看图片"; - basicTranslations["查看图片"]["en-US"] = "View Image"; - basicTranslations["查看图片"]["ms-MY"] = "Lihat Imej"; - - basicTranslations["警告"]["zh-CN"] = "警告"; - basicTranslations["警告"]["en-US"] = "Warning"; - basicTranslations["警告"]["ms-MY"] = "Amaran"; - - basicTranslations["欢迎!"]["zh-CN"] = "欢迎!"; - basicTranslations["欢迎!"]["en-US"] = "Welcome!"; - basicTranslations["欢迎!"]["ms-MY"] = "Selamat Datang!"; - - basicTranslations["宽度:"]["zh-CN"] = "宽度:"; - basicTranslations["宽度:"]["en-US"] = "Width:"; - basicTranslations["宽度:"]["ms-MY"] = "Lebar:"; - - basicTranslations["窗口设置"]["zh-CN"] = "窗口设置"; - basicTranslations["窗口设置"]["en-US"] = "Window Settings"; - basicTranslations["窗口设置"]["ms-MY"] = "Tetapan Tetingkap"; - - basicTranslations["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["zh-CN"] = "您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"; - basicTranslations["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["en-US"] = "You do not have sufficient permissions to perform this action.\n\nRequired level: %1\nCurrent level: %2"; - basicTranslations["您没有足够的权限执行此操作。\n\n所需等级: %1\n当前等级: %2"]["ms-MY"] = "Anda tidak mempunyai kebenaran yang mencukupi untuk melaksanakan tindakan ini.\n\nTahap diperlukan: %1\nTahap semasa: %2"; - - basicTranslations["您需要管理员权限才能创建用户"]["zh-CN"] = "您需要管理员权限才能创建用户"; - basicTranslations["您需要管理员权限才能创建用户"]["en-US"] = "You need administrator permissions to create users"; - basicTranslations["您需要管理员权限才能创建用户"]["ms-MY"] = "Anda memerlukan kebenaran pentadbir untuk mencipta pengguna"; - - basicTranslations["放大窗口"]["zh-CN"] = "放大窗口"; - basicTranslations["放大窗口"]["en-US"] = "Zoom In"; - basicTranslations["放大窗口"]["ms-MY"] = "Zum Masuk"; - - basicTranslations["缩小窗口"]["zh-CN"] = "缩小窗口"; - basicTranslations["缩小窗口"]["en-US"] = "Zoom Out"; - basicTranslations["缩小窗口"]["ms-MY"] = "Zum Keluar"; - - basicTranslations["隐藏控制台"]["zh-CN"] = "隐藏控制台"; - basicTranslations["隐藏控制台"]["en-US"] = "Hide Console"; - basicTranslations["隐藏控制台"]["ms-MY"] = "Sembunyikan Konsol"; - - basicTranslations["刷新"]["zh-CN"] = "刷新"; - basicTranslations["刷新"]["en-US"] = "Refresh"; - basicTranslations["刷新"]["ms-MY"] = "Segarkan"; - - basicTranslations["显示控制台"]["zh-CN"] = "显示控制台"; - basicTranslations["显示控制台"]["en-US"] = "Show Console"; - basicTranslations["显示控制台"]["ms-MY"] = "Tunjukkan Konsol"; - - basicTranslations["重启后将会更改"]["zh-CN"] = "重启后将会更改"; - basicTranslations["重启后将会更改"]["en-US"] = "will change after restart"; - basicTranslations["重启后将会更改"]["ms-MY"] = "Akan berubah selepas restart"; - - basicTranslations["退出确认"]["zh-CN"] = "退出确认"; - basicTranslations["退出确认"]["en-US"] = "Exit Confirmation"; - basicTranslations["退出确认"]["ms-MY"] = "Pengesahan Keluar"; - - basicTranslations["选择语言"]["zh-CN"] = "选择语言:"; - basicTranslations["选择语言"]["en-US"] = "Language:"; - basicTranslations["选择语言"]["ms-MY"] = "Bahasa"; - - basicTranslations["打开日志目录"]["zh-CN"] = "打开日志目录"; - basicTranslations["打开日志目录"]["en-US"] = "Open Log Directory"; - basicTranslations["打开日志目录"]["ms-MY"] = "Buka Direktori Log"; - - basicTranslations["控制调试控制台窗口的可见性"]["zh-CN"] = "控制调试控制台窗口的可见性"; - basicTranslations["控制调试控制台窗口的可见性"]["en-US"] = "Control the visibility of the debug console window"; - basicTranslations["控制调试控制台窗口的可见性"]["ms-MY"] = "Kawal keterlihatan tetingkap konsol debug"; - - basicTranslations["工具箱"]["zh-CN"] = "工具箱"; - basicTranslations["工具箱"]["en-US"] = "Toolbox"; - basicTranslations["工具箱"]["ms-MY"] = "Kotak Alat"; - - basicTranslations["设置"]["zh-CN"] = "设置"; - basicTranslations["设置"]["en-US"] = "Settings"; - basicTranslations["设置"]["ms-MY"] = "Tetapan"; - - basicTranslations["打开配置文件"]["zh-CN"] = "打开配置文件"; - basicTranslations["打开配置文件"]["en-US"] = "Open Config File"; - basicTranslations["打开配置文件"]["ms-MY"] = "Buka Fail Konfigurasi"; - - basicTranslations["摄像头实时捕获(仅软触发)"]["zh-CN"] = "摄像头实时捕获(仅软触发)"; - basicTranslations["摄像头实时捕获(仅软触发)"]["en-US"] = "Camera Real-time Capture (soft-trigger only)"; - basicTranslations["摄像头实时捕获(仅软触发)"]["ms-MY"] = "Tangkapan Masa Nyata Kamera (hanya pencetus lembut)"; - - basicTranslations["九点校准"]["zh-CN"] = "九点校准"; - basicTranslations["九点校准"]["en-US"] = "Nine-Point Calibration"; - basicTranslations["九点校准"]["ms-MY"] = "Penentukuran Sembilan Titik"; - - basicTranslations["CSV 文件 (*.csv)"]["zh-CN"] = "CSV 文件 (*.csv)"; - basicTranslations["CSV 文件 (*.csv)"]["en-US"] = "CSV File (*.csv)"; - basicTranslations["CSV 文件 (*.csv)"]["ms-MY"] = ""; - - basicTranslations["停止取流"]["zh-CN"] = "停止取流"; - basicTranslations["停止取流"]["en-US"] = "Stop Grabbing"; - basicTranslations["停止取流"]["ms-MY"] = "Hentikan Tangkapan"; - - basicTranslations["开始取流"]["zh-CN"] = "开始取流"; - basicTranslations["开始取流"]["en-US"] = "Start Grabbing"; - basicTranslations["开始取流"]["ms-MY"] = "Mulakan Tangkapan"; - - basicTranslations["提示"]["zh-CN"] = "提示"; - basicTranslations["提示"]["en-US"] = "Notice"; - basicTranslations["提示"]["ms-MY"] = "Notis"; - - basicTranslations["没有可保存的图像"]["zh-CN"] = "没有可保存的图像"; - basicTranslations["没有可保存的图像"]["en-US"] = "No image available to save"; - basicTranslations["没有可保存的图像"]["ms-MY"] = "Tiada imej untuk disimpan"; - - basicTranslations["保存失败"]["zh-CN"] = "保存失败"; - basicTranslations["保存失败"]["en-US"] = "Save Failed"; - basicTranslations["保存失败"]["ms-MY"] = "Gagal Menyimpan"; - - basicTranslations["无法将图像保存到所选位置"]["zh-CN"] = "无法将图像保存到所选位置"; - basicTranslations["无法将图像保存到所选位置"]["en-US"] = "Unable to save image to selected location"; - basicTranslations["无法将图像保存到所选位置"]["ms-MY"] = "Tidak dapat menyimpan imej ke lokasi yang dipilih"; - - basicTranslations["刷新相机"]["zh-CN"] = "刷新相机"; - basicTranslations["刷新相机"]["en-US"] = "Refresh Cameras"; - basicTranslations["刷新相机"]["ms-MY"] = "Muat Semula Kamera"; - - basicTranslations["保存图片"]["zh-CN"] = "保存图片"; - basicTranslations["保存图片"]["en-US"] = "Save Image"; - basicTranslations["保存图片"]["ms-MY"] = "Simpan Imej"; - - basicTranslations["实时取流"]["zh-CN"] = "实时取流"; - basicTranslations["实时取流"]["en-US"] = "Real-time Grabbing"; - basicTranslations["实时取流"]["ms-MY"] = "Tangkapan Masa Nyata"; - - basicTranslations["导出数据到CSV"]["zh-CN"] = "导出数据到CSV"; - basicTranslations["导出数据到CSV"]["en-US"] = "Export data to CSV"; - basicTranslations["导出数据到CSV"]["ms-MY"] = "Eksport data ke CSV"; - - basicTranslations["生产统计:"]["zh-CN"] = "生产统计:"; - basicTranslations["生产统计:"]["en-US"] = "Production Statistics:"; - basicTranslations["生产统计:"]["ms-MY"] = "Statistik Pengeluaran:"; - - basicTranslations["清零"]["zh-CN"] = "清零"; - basicTranslations["清零"]["en-US"] = "Reset"; - basicTranslations["清零"]["ms-MY"] = "Tetapkan Semula"; - - basicTranslations["确认清零"]["zh-CN"] = "确认清零"; - basicTranslations["确认清零"]["en-US"] = "Confirm Reset"; - basicTranslations["确认清零"]["ms-MY"] = "Sahkan Tetapan Semula"; - - basicTranslations["确定要清零当前统计数据吗?"]["zh-CN"] = "确定要清零当前统计数据吗?"; - basicTranslations["确定要清零当前统计数据吗?"]["en-US"] = "Are you sure you want to reset the current statistics?"; - basicTranslations["确定要清零当前统计数据吗?"]["ms-MY"] = "Adakah anda pasti mahu menetapkan semula statistik semasa?"; - - basicTranslations["检测总数"]["zh-CN"] = "检测总数"; - basicTranslations["检测总数"]["en-US"] = "Total Inspections"; - basicTranslations["检测总数"]["ms-MY"] = "Jumlah Pemeriksaan"; - - basicTranslations["不良数"]["zh-CN"] = "不良数"; - basicTranslations["不良数"]["en-US"] = "Defect Count"; - basicTranslations["不良数"]["ms-MY"] = "Kiraan Kecacatan"; - - basicTranslations["良品数"]["zh-CN"] = "良品数"; - basicTranslations["良品数"]["en-US"] = "Good Count"; - basicTranslations["良品数"]["ms-MY"] = "Kiraan Baik"; - - basicTranslations["良品率"]["zh-CN"] = "良品率"; - basicTranslations["良品率"]["en-US"] = "Yield Rate"; - basicTranslations["良品率"]["ms-MY"] = "Kadar Hasil"; - - basicTranslations["白班"]["zh-CN"] = "白班"; - basicTranslations["白班"]["en-US"] = "Day Shift"; - basicTranslations["白班"]["ms-MY"] = "Syif Siang"; - - basicTranslations["夜班"]["zh-CN"] = "夜班"; - basicTranslations["夜班"]["en-US"] = "Night Shift"; - basicTranslations["夜班"]["ms-MY"] = "Syif Malam"; - ///////// - basicTranslations["主界面"]["zh-CN"] = "主界面"; - basicTranslations["主界面"]["en-US"] = "Main Interface"; - basicTranslations["主界面"]["ms-MY"] = "Antaramuka Utama"; - - basicTranslations["生产数据"]["zh-CN"] = "生产数据"; - basicTranslations["生产数据"]["en-US"] = "Production Data"; - basicTranslations["生产数据"]["ms-MY"] = "Data Pengeluaran"; - - basicTranslations["数据库"]["zh-CN"] = "数据库"; - basicTranslations["数据库"]["en-US"] = "Database"; - basicTranslations["数据库"]["ms-MY"] = "Pangkalan Data"; - - basicTranslations["数据库"]["zh-CN"] = "数据库"; - basicTranslations["数据库"]["en-US"] = "Database"; - basicTranslations["数据库"]["ms-MY"] = "Pangkalan Data"; - - basicTranslations["查看图片"]["zh-CN"] = "查看图片"; - basicTranslations["查看图片"]["en-US"] = "View Image"; - basicTranslations["查看图片"]["ms-MY"] = "Lihat Imej"; - - basicTranslations["输入布尔值(true or false)"]["zh-CN"] = "输入布尔值(true or false)"; - basicTranslations["输入布尔值(true or false)"]["en-US"] = "Enter a boolean value (true or false)"; - basicTranslations["输入布尔值(true or false)"]["ms-MY"] = "Masukkan nilai boolean (benar atau palsu)"; - -#pragma endregion -#pragma region 逐字翻译字典 - basicTranslations["预焊"]["zh-CN"] = "预焊"; - basicTranslations["预焊"]["en-US"] = "Pre-welding"; - basicTranslations["预焊"]["ms-MY"] = "Pra-kimpalan"; - - basicTranslations["机"]["zh-CN"] = "机"; - basicTranslations["机"]["en-US"] = "Station"; - basicTranslations["机"]["ms-MY"] = "Stesen"; - - basicTranslations["查看器"]["zh-CN"] = "查看器"; - basicTranslations["查看器"]["en-US"] = "Viewer"; - basicTranslations["查看器"]["ms-MY"] = "Pemapar"; - - basicTranslations["极耳"]["zh-CN"] = "极耳"; - basicTranslations["极耳"]["en-US"] = "Tab"; - basicTranslations["极耳"]["ms-MY"] = "Tab"; - - basicTranslations["撕裂"]["zh-CN"] = "撕裂"; - basicTranslations["撕裂"]["en-US"] = "Tearing"; - basicTranslations["撕裂"]["ms-MY"] = "Koyak"; - - basicTranslations["翻折"]["zh-CN"] = "翻折"; - basicTranslations["翻折"]["en-US"] = "Folding"; - basicTranslations["翻折"]["ms-MY"] = "Lipatan"; - - basicTranslations["铜"]["zh-CN"] = "铜"; - basicTranslations["铜"]["en-US"] = "Copper"; - basicTranslations["铜"]["ms-MY"] = "Kuprum"; - - basicTranslations["铝"]["zh-CN"] = "铝"; - basicTranslations["铝"]["en-US"] = "Aluminum"; - basicTranslations["铝"]["ms-MY"] = "Aluminium"; - - basicTranslations["包膜"]["zh-CN"] = "包膜"; - basicTranslations["包膜"]["en-US"] = "Wrapping"; - basicTranslations["包膜"]["ms-MY"] = "Pembalut"; - - basicTranslations["前"]["zh-CN"] = "前"; - basicTranslations["前"]["en-US"] = "Front"; - basicTranslations["前"]["ms-MY"] = "Depan"; - - basicTranslations["后"]["zh-CN"] = "后"; - basicTranslations["后"]["en-US"] = "Rear"; - basicTranslations["后"]["ms-MY"] = "Belakang"; - - basicTranslations["内"]["zh-CN"] = "内"; - basicTranslations["内"]["en-US"] = "Inner"; - basicTranslations["内"]["ms-MY"] = "Dalam"; - - basicTranslations["外"]["zh-CN"] = "外"; - basicTranslations["外"]["en-US"] = "Outer"; - basicTranslations["外"]["ms-MY"] = "Luar"; - - basicTranslations["左"]["zh-CN"] = "左"; - basicTranslations["左"]["en-US"] = "Left"; - basicTranslations["左"]["ms-MY"] = "Kiri"; - - basicTranslations["右"]["zh-CN"] = "右"; - basicTranslations["右"]["en-US"] = "Right"; - basicTranslations["右"]["ms-MY"] = "Kanan"; - - basicTranslations["通道"]["zh-CN"] = "通道"; - basicTranslations["通道"]["en-US"] = "Channel"; - basicTranslations["通道"]["ms-MY"] = "Saluran"; - - basicTranslations["线"]["zh-CN"] = "线"; - basicTranslations["线"]["en-US"] = "Line"; - basicTranslations["线"]["ms-MY"] = "Talian"; - - basicTranslations["终焊"]["zh-CN"] = "终焊"; - basicTranslations["终焊"]["en-US"] = "Final Welding"; - basicTranslations["终焊"]["ms-MY"] = "Kimpalan Akhir"; - - basicTranslations["焊前"]["zh-CN"] = "焊前"; - basicTranslations["焊前"]["en-US"] = "Pre-welding"; - basicTranslations["焊前"]["ms-MY"] = "Pra-kimpalan"; - - basicTranslations["焊前定位"]["zh-CN"] = "焊前定位"; - basicTranslations["焊前定位"]["en-US"] = "Pre-welding Positioning"; - basicTranslations["焊前定位"]["ms-MY"] = "Penentududukan Pra-kimpalan"; - - basicTranslations["焊后"]["zh-CN"] = "焊后"; - basicTranslations["焊后"]["en-US"] = "Post-welding"; - basicTranslations["焊后"]["ms-MY"] = "Pasca-kimpalan"; - - basicTranslations["终焊"]["zh-CN"] = "终焊"; - basicTranslations["终焊"]["en-US"] = "Final Welding"; - basicTranslations["终焊"]["ms-MY"] = "Kimpalan Akhir"; - - basicTranslations["点胶"]["zh-CN"] = "点胶"; - basicTranslations["点胶"]["en-US"] = "Dispensing"; - basicTranslations["点胶"]["ms-MY"] = "Penyuntikan"; - - basicTranslations["贴胶"]["zh-CN"] = "贴胶"; - basicTranslations["贴胶"]["en-US"] = "Taping"; - basicTranslations["贴胶"]["ms-MY"] = "Pelekatan"; - - basicTranslations["阈值"]["zh-CN"] = "阈值"; - basicTranslations["阈值"]["en-US"] = "Threshold"; - basicTranslations["阈值"]["ms-MY"] = "Ambang"; - - basicTranslations["包膜前"]["zh-CN"] = "包膜前"; - basicTranslations["包膜前"]["en-US"] = "Pre-wrapping"; - basicTranslations["包膜前"]["ms-MY"] = "Pra-pembalut"; - - basicTranslations["包膜后"]["zh-CN"] = "包膜后"; - basicTranslations["包膜后"]["en-US"] = "Post-wrapping"; - basicTranslations["包膜后"]["ms-MY"] = "Pasca-pembalut"; - - basicTranslations["马甲"]["zh-CN"] = "马甲"; - basicTranslations["马甲"]["en-US"] = "Jacket"; - basicTranslations["马甲"]["ms-MY"] = "Jaket"; - - basicTranslations["相机"]["zh-CN"] = "相机"; - basicTranslations["相机"]["en-US"] = "Camera"; - basicTranslations["相机"]["ms-MY"] = "Kamera"; - - basicTranslations["顶盖"]["zh-CN"] = "顶盖"; - basicTranslations["顶盖"]["en-US"] = "Top Cover"; - basicTranslations["顶盖"]["ms-MY"] = "Penutup Atas"; - - basicTranslations["焊"]["zh-CN"] = "焊"; - basicTranslations["焊"]["en-US"] = "Welding"; - basicTranslations["焊"]["ms-MY"] = "Kimpalan"; - - basicTranslations["打钉"]["zh-CN"] = "打钉"; - basicTranslations["打钉"]["en-US"] = "Nailing"; - basicTranslations["打钉"]["ms-MY"] = "Pemakuan"; - - basicTranslations["满焊"]["zh-CN"] = "满焊"; - basicTranslations["满焊"]["en-US"] = "Full Welding"; - basicTranslations["满焊"]["ms-MY"] = "Kimpalan Penuh"; - - basicTranslations["放钉"]["zh-CN"] = "放钉"; - basicTranslations["放钉"]["en-US"] = "Place Nail"; - basicTranslations["放钉"]["ms-MY"] = "Letak Paku"; - - basicTranslations["气泡"]["zh-CN"] = "气泡"; - basicTranslations["气泡"]["en-US"] = "Bubble"; - basicTranslations["气泡"]["ms-MY"] = "Gelembung"; - - basicTranslations["上钉"]["zh-CN"] = "上钉"; - basicTranslations["上钉"]["en-US"] = "Install Nail"; - basicTranslations["上钉"]["ms-MY"] = "Pasang Paku"; - - basicTranslations["残液"]["zh-CN"] = "残液"; - basicTranslations["残液"]["en-US"] = "Residual Liquid"; - basicTranslations["残液"]["ms-MY"] = "Cecair Sisa"; - - basicTranslations["检测"]["zh-CN"] = "检测"; - basicTranslations["检测"]["en-US"] = "Inspection"; - basicTranslations["检测"]["ms-MY"] = "Pemeriksaan"; - - basicTranslations["最大"]["zh-CN"] = "最大"; - basicTranslations["最大"]["en-US"] = "Maximum"; - basicTranslations["最大"]["ms-MY"] = "Maksimum"; - - basicTranslations["最小"]["zh-CN"] = "最小"; - basicTranslations["最小"]["en-US"] = "Minimum"; - basicTranslations["最小"]["ms-MY"] = "Minimum"; - - basicTranslations["上限"]["zh-CN"] = "上限"; - basicTranslations["上限"]["en-US"] = "Upper Limit"; - basicTranslations["上限"]["ms-MY"] = "Had Atas"; - - basicTranslations["下限"]["zh-CN"] = "下限"; - basicTranslations["下限"]["en-US"] = "Lower Limit"; - basicTranslations["下限"]["ms-MY"] = "Had Bawah"; - - basicTranslations["极性"]["zh-CN"] = "极性"; - basicTranslations["极性"]["en-US"] = "Polarity"; - basicTranslations["极性"]["ms-MY"] = "Kekutuban"; - - basicTranslations["顶部"]["zh-CN"] = "顶部"; - basicTranslations["顶部"]["en-US"] = "Top"; - basicTranslations["顶部"]["ms-MY"] = "Atas"; - - basicTranslations["底部"]["zh-CN"] = "底部"; - basicTranslations["底部"]["en-US"] = "Bottom"; - basicTranslations["底部"]["ms-MY"] = "Bawah"; - - basicTranslations["大面"]["zh-CN"] = "大面"; - basicTranslations["大面"]["en-US"] = "Large Surface"; - basicTranslations["大面"]["ms-MY"] = "Permukaan Besar"; - - basicTranslations["放钉"]["zh-CN"] = "放钉"; - basicTranslations["放钉"]["en-US"] = "Place Nail"; - basicTranslations["放钉"]["ms-MY"] = "Letak Paku"; - - basicTranslations["入壳"]["zh-CN"] = "入壳"; - basicTranslations["入壳"]["en-US"] = "Casing"; - basicTranslations["入壳"]["ms-MY"] = "Pemasangan Sarung"; - - basicTranslations["机台"]["zh-CN"] = "机台"; - basicTranslations["机台"]["en-US"] = "Machine"; - basicTranslations["机台"]["ms-MY"] = "Mesin"; - - basicTranslations["离线"]["zh-CN"] = "离线"; - basicTranslations["离线"]["en-US"] = "Offline"; - basicTranslations["离线"]["ms-MY"] = "Luar Talian"; - - basicTranslations["在线"]["zh-CN"] = "在线"; - basicTranslations["在线"]["en-US"] = "Online"; - basicTranslations["在线"]["ms-MY"] = "Dalam Talian"; - - basicTranslations["密封钉"]["zh-CN"] = "密封钉"; - basicTranslations["密封钉"]["en-US"] = "Sealing Nail"; - basicTranslations["密封钉"]["ms-MY"] = "Paku Pengedap"; - - basicTranslations["刻码"]["zh-CN"] = "刻码"; - basicTranslations["刻码"]["en-US"] = "Marking"; - basicTranslations["刻码"]["ms-MY"] = "Penandaan"; - - basicTranslations["热熔"]["zh-CN"] = "热熔"; - basicTranslations["热熔"]["en-US"] = "Hot Melt"; - basicTranslations["热熔"]["ms-MY"] = "Cairan Panas"; - - basicTranslations["马甲热熔"]["zh-CN"] = "马甲热熔"; - basicTranslations["马甲热熔"]["en-US"] = "Jacket Hot Melt"; - basicTranslations["马甲热熔"]["ms-MY"] = "Cairan Panas Jaket"; - - basicTranslations["触发"]["zh-CN"] = "触发"; - basicTranslations["触发"]["en-US"] = "Trigger"; - basicTranslations["触发"]["ms-MY"] = "Pencetus"; - - basicTranslations["结束"]["zh-CN"] = "结束"; - basicTranslations["结束"]["en-US"] = "End"; - basicTranslations["结束"]["ms-MY"] = "Tamat"; - - basicTranslations["完成"]["zh-CN"] = "完成"; - basicTranslations["完成"]["en-US"] = "Complete"; - basicTranslations["完成"]["ms-MY"] = "Selesai"; - - basicTranslations["信号"]["zh-CN"] = "信号"; - basicTranslations["信号"]["en-US"] = "Signal"; - basicTranslations["信号"]["ms-MY"] = "Isyarat"; - - basicTranslations["长度"]["zh-CN"] = "长度"; - basicTranslations["长度"]["en-US"] = "Length"; - basicTranslations["长度"]["ms-MY"] = "Panjang"; - - basicTranslations["宽度"]["zh-CN"] = "宽度"; - basicTranslations["宽度"]["en-US"] = "Width"; - basicTranslations["宽度"]["ms-MY"] = "Lebar"; - - basicTranslations["翻折"]["zh-CN"] = "翻折"; - basicTranslations["翻折"]["en-US"] = "Folding"; - basicTranslations["翻折"]["ms-MY"] = "Lipatan"; - - basicTranslations["电解液"]["zh-CN"] = "电解液"; - basicTranslations["电解液"]["en-US"] = "Electrolyte"; - basicTranslations["电解液"]["ms-MY"] = "Elektrolit"; - - basicTranslations["底托"]["zh-CN"] = "底托"; - basicTranslations["底托"]["en-US"] = "Bottom Tray"; - basicTranslations["底托"]["ms-MY"] = "Dulang Bawah"; - - basicTranslations["位置"]["zh-CN"] = "位置"; - basicTranslations["位置"]["en-US"] = "Position"; - basicTranslations["位置"]["ms-MY"] = "Kedudukan"; - - basicTranslations["正面"]["zh-CN"] = "正面"; - basicTranslations["正面"]["en-US"] = "Front"; - basicTranslations["正面"]["ms-MY"] = "Depan"; - - basicTranslations["侧面"]["zh-CN"] = "侧面"; - basicTranslations["侧面"]["en-US"] = "Side"; - basicTranslations["侧面"]["ms-MY"] = "Sisi"; - - basicTranslations["反面"]["zh-CN"] = "反面"; - basicTranslations["反面"]["en-US"] = "Back"; - basicTranslations["反面"]["ms-MY"] = "Belakang"; - - basicTranslations["焊印"]["zh-CN"] = "焊印"; - basicTranslations["焊印"]["en-US"] = "Weld Mark"; - basicTranslations["焊印"]["ms-MY"] = "Tanda Kimpalan"; -#pragma endregion - - - } - - // 使用nlohmann/json解析 - bool parseJson(const json& j) { - try { - // 解析current_language - if (j.contains("current_language") && j["current_language"].is_string()) { - currentLanguage = j["current_language"].get(); - } - - // 解析sections - if (j.contains("section") && j["section"].is_array()) { - for (const auto& section : j["section"]) { - if (section.is_string()) { - addSection(section.get()); - } - } - } - - // 解析translations - if (j.contains("translate") && j["translate"].is_object()) { - for (const auto& [key, langObj] : j["translate"].items()) { - if (langObj.is_object()) { - for (const auto& [lang, text] : langObj.items()) { - if (text.is_string()) { - addTranslation(key, lang, text.get()); - } - } - } - } - } - - return true; - } catch (const std::exception& e) { - std::cerr << "Error parsing JSON: " << e.what() << std::endl; - return false; - } - } - -signals: - void languageChanged(); -}; - -#define BindTR(languageChangedFunc) QObject::connect(&Translation::getInstance(), &Translation::languageChanged,this, &languageChangedFunc); -#define BindTRLambda(languageChangedFunc) QObject::connect(&Translation::getInstance(), &Translation::languageChanged,this, languageChangedFunc); -#define TR(key) QString::fromStdString(Translation::getInstance().translate(key)) - -#endif // TRANSLATION_H \ No newline at end of file diff --git a/src/launcher/frontendSignalHub.h b/src/launcher/frontendSignalHub.h index 7affa1d..b64d8c1 100644 --- a/src/launcher/frontendSignalHub.h +++ b/src/launcher/frontendSignalHub.h @@ -59,5 +59,8 @@ signals: void getAllParams(std::vector>* params); void editParam(QString group, QString name, QVariant value); void saveMissionJson(); + void languageChanged(const std::string& language); +}; -}; \ No newline at end of file +#define BindTR(languageChangedFunc) QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged,this, &languageChangedFunc); +#define BindTRLambda(languageChangedFunc) QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged,this, languageChangedFunc); \ No newline at end of file diff --git a/src/launcher/logger/logService.cpp b/src/launcher/logger/logService.cpp index 0003750..02fa17d 100644 --- a/src/launcher/logger/logService.cpp +++ b/src/launcher/logger/logService.cpp @@ -1,6 +1,11 @@ #include "logService.h" #include +#include +#include +#include +#include #include +#include logService* logService::_instance = nullptr; std::mutex logService::_instanceMutex; @@ -67,10 +72,53 @@ logService::logService(){ } }); + // 清理超出保留天数的旧日志文件 + cleanupOldLogs(); + } catch (const std::exception& e) { qDebug() << "Failed to initialize logService:" << e.what(); } } +// 删除超出保留天数的旧日志文件 +void logService::cleanupOldLogs() { + try { + int saveDays = logSaveDays; + if (saveDays <= 0) { + return; + } + + QDir logDir(QString::fromStdString(logBasePath)); + if (!logDir.exists()) { + return; + } + + QDateTime deadline = QDateTime::currentDateTime().addDays(-saveDays); + const QFileInfoList fileList = logDir.entryInfoList(QStringList() << "*.log" << "*_*-*-*.log", QDir::Files, QDir::Name); + int deleteCount = 0; + + for (const auto& fileInfo : fileList) { + if (fileInfo.lastModified() < deadline) { + if (QFile::remove(fileInfo.absoluteFilePath())) { + deleteCount++; + qDebug() << "[日志清理] 删除旧日志文件:" << fileInfo.fileName(); + } else { + qWarning() << "[日志清理] 删除失败:" << fileInfo.absoluteFilePath(); + } + } + } + + if (deleteCount > 0) { + qDebug() << "[日志清理] 完成,共删除" << deleteCount << "个旧日志文件"; + } + } + catch (const std::exception& e) { + qCritical() << "[日志清理] 异常:" << e.what(); + } + catch (...) { + qCritical() << "[日志清理] 未知异常"; + } +} + logService::~logService() { try { _stdConsoleRedirector.reset(); diff --git a/src/launcher/logger/logService.h b/src/launcher/logger/logService.h index 86c1606..7dc596b 100644 --- a/src/launcher/logger/logService.h +++ b/src/launcher/logger/logService.h @@ -13,7 +13,7 @@ #include "spdLogSupport.hpp" #include "stdLogRediretor.hpp" #include "qtLogRediretor.h" - +#include static const std::string logBasePath = "./Log/"; class logToQtWidget : public QObject { @@ -65,6 +65,9 @@ public: // 获取日志组件 logToQtWidget* getLogWidget() const { return _logToQtWidget.get(); } + // 删除超出保留天数的旧日志文件 + void cleanupOldLogs(); + private: std::unique_ptr _qtRediretor; std::unique_ptr _stdConsoleRedirector; diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index feec134..f7280e2 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -267,7 +267,6 @@ void connectFrontSignals(appCore* _core, MainWindow* _MainWindow, fSignalHub* br //BackEnd To Front //等待界面 - //波形图 QObject::connect(bridge, &fSignalHub::triggerAndCaptureImage, _core->_backEnd.backendPtr, &IBackend::triggerAndCaptureImage,Qt::DirectConnection); QObject::connect(bridge, &fSignalHub::getCameraNames, @@ -292,7 +291,9 @@ void connectFrontSignals(appCore* _core, MainWindow* _MainWindow, fSignalHub* br void connectBackSignals(appCore* _core, MainWindow* _MainWindow, bSignalHub* bridge) { //等待界面 QObject::connect(bridge, &bSignalHub::loadingWindow_appendInitLog, - _MainWindow, [=](const QString& text, const QColor& color) {_MainWindow->_loadingWidget.appendInitLog(text, color); }); + _MainWindow, [=](const QString& text, const QColor& color) { + _MainWindow->_loadingWidget.appendInitLog(TR(text.toStdString()), color); + }); QObject::connect(bridge, &bSignalHub::loadingWindow_modifyLog, _MainWindow, [=](int col, const QString& text, const QColor& color) {_MainWindow->_loadingWidget.modifyLog(col, text, color); }); QObject::connect(bridge, &bSignalHub::loadingWindow_clearLog, @@ -376,10 +377,13 @@ void connectBackSignals(appCore* _core, MainWindow* _MainWindow, bSignalHub* bri QObject::connect(bridge, &bSignalHub::waitForFrontendInitComfirm, _core, [=](const QString& message,const std::vector& options, std::shared_ptr> recivedResult, std::shared_ptr> Result) { - std::vector optionsCopy = options; - optionsCopy.push_back("退出程序"); + std::vector optionsCopy; + for (auto& option : options) { + optionsCopy.push_back(TR(option.toStdString())); + } + optionsCopy.push_back(TR("退出程序")); QMessageBox msgBox(_MainWindow); - msgBox.setWindowTitle(QObject::tr("确认")); + msgBox.setWindowTitle(TR("确认")); msgBox.setIcon(QMessageBox::Question); msgBox.setText(message); @@ -392,16 +396,16 @@ void connectBackSignals(appCore* _core, MainWindow* _MainWindow, bSignalHub* bri // options 为空时兜底,避免弹窗无按钮无法关闭 if (optionButtons.empty()) { - optionButtons.push_back(msgBox.addButton(QObject::tr("确定"), QMessageBox::AcceptRole)); + optionButtons.push_back(msgBox.addButton(TR("确定"), QMessageBox::AcceptRole)); } msgBox.exec(); - + int selectedOptionId = -1; QAbstractButton* clicked = msgBox.clickedButton(); for (int i = 0; i < static_cast(optionButtons.size()); ++i) { if (optionButtons[i] == clicked) { - if (optionButtons[i]->text() == "退出程序") + if (optionButtons[i]->text() == TR("退出程序")) exit(999); selectedOptionId = i; break; @@ -443,6 +447,12 @@ void connectBackSignals(appCore* _core, MainWindow* _MainWindow, bSignalHub* bri [=]() { emit bridge->reloadAllCameraAsVirtual(); }); + + QObject::connect(fSignalHub::getInstance(), &fSignalHub::languageChanged, + _core->_backEnd.backendPtr, &IBackend::launguageChanged); + + QObject::connect(bridge, &bSignalHub::updateUserPermission, + _MainWindow->_displayWidget->_userSwitch, &userSwitch::useTemporaryPermission); } std::unique_ptr initBreakPad() { std::wstring dumpPath = L"./dumps"; @@ -470,10 +480,11 @@ int main(int argc, char* argv[]) QApplication a(argc, argv); //如果有同名文件则判断是否要启动软件 +#if offlineMode == 0 if (!handleSameNameProcessOnStartup(nullptr)) { return 0; } - +#endif appCore _core; auto& config = appConfig::getInstance(); config.consoleHandle = hWnd; @@ -533,12 +544,5 @@ int main(int argc, char* argv[]) qCritical() << "=============================="; return -3; } - catch (...) { - // 捕获所有其他异常 - qCritical() << "========== 未知异常捕获 =========="; - qCritical() << "捕获到未知类型的异常"; - qCritical() << "=============================="; - return -2; - } return -99; } \ No newline at end of file diff --git a/src/mission/604/CMakeLists - 副本.txt b/src/mission/604/CMakeLists - 副本.txt deleted file mode 100644 index f9a95fd..0000000 --- a/src/mission/604/CMakeLists - 副本.txt +++ /dev/null @@ -1,11 +0,0 @@ -# CMakeList.txt: 遍历文件夹 添加子项目 - -set(OUR_LIBS "") -SUBDIRENAMES(OUR_LIBS ${CMAKE_CURRENT_SOURCE_DIR} "" OFF) -message("OUR_LIBS :" ${OUR_LIBS}) - - -# 遍历子库 -foreach(dll ${OUR_LIBS}) - add_subdirectory(${dll}) -endforeach(dll ${}) diff --git a/src/mission/old/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp b/src/mission/old/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp index be9ec5b..ea3530b 100644 --- a/src/mission/old/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp +++ b/src/mission/old/581-BaoMo-Cam1213/581-BaoMo-Cam1213.cpp @@ -248,8 +248,8 @@ bool ALGO_BaoMoHouDiBu(std::shared_ptr data, baoMoHouDiBuDetParams* _d } int Rate = (Paint.rows > Paint.cols ? Paint.cols : Paint.rows) / 20; TextRendererZH textPainter1(Paint.cols, Paint.rows, Rate); - textPainter1.putText(Paint, "产品条码:" + data->SNcode, cv::Point(50, Paint.rows - Rate), cv::Scalar(0, 255, 255)); - textPainter1.putText(Paint, "获取图像时间:" + createTime.toString("yyyy/MM/dd hh:mm:ss").toStdString(), cv::Point(50, Paint.rows - (Rate * 2)), cv::Scalar(0, 255, 255)); + textPainter1.putText(Paint, data->service->translateManager->translate("产品条码:") + data->SNcode, cv::Point(50, Paint.rows - Rate), cv::Scalar(0, 255, 255)); + textPainter1.putText(Paint, data->service->translateManager->translate("获取图像时间:") + createTime.toString("yyyy/MM/dd hh:mm:ss").toStdString(), cv::Point(50, Paint.rows - (Rate * 2)), cv::Scalar(0, 255, 255)); data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr) + "_" + QByteArray::number(hResult1.resultX));//发送结果 data->service->_triggerManager->writeFloat("D" + QByteArray::number(address.valueOffsetAddr + 2) + "_" + QByteArray::number(hResult1.resultY));//发送结果 diff --git a/src/mission/old/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h b/src/mission/old/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h index e84734b..ea91ad9 100644 --- a/src/mission/old/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h +++ b/src/mission/old/581-BaoMo-Cam1213/581-BaoMo-Cam1213.h @@ -27,7 +27,7 @@ public: [](std::map& inputHObj, std::map& inputHTuple, const input& in) { - inputHObj["in_Image"] = in.in_Image; + inputHObj["in_ImageX"] = in.in_Image; inputHTuple["in_Par"] = in.in_Par; inputHTuple["in_FilePath"] = in.in_FilePath; inputHTuple["in_Resolution"] = in.in_Resolution; @@ -56,13 +56,12 @@ public: //handleAiModelWithGuard testModel; void onConfigReloaded() { halconEngineManager::instance().loadAlgoFile("./halconAlgo/AlgoLibrary_581.hdpl", bridge); - //_serviceManager->_handleAiManager->loadSegModel("./handleAiModel/Seg_2026-3-25_1-05-47_2.130355.BHD", 16, 0, "铜Seg90度极耳定位网"); - //_serviceManager->_handleAiManager->loadSegModel("./handleAiModel/Seg_2026-3-25_1-05-47_2.130355.BHD", 16, 0, "铜Seg90度焊印定位网"); + _serviceManager->_handleAiManager->loadSegModel("./handleAiModel/Seg_2026-3-25_1-05-47_2.130355.BHD", 16, 0, "铜Seg90度极耳定位网"); + _serviceManager->_handleAiManager->loadSegModel("./handleAiModel/Seg_2026-3-25_1-05-47_2.130355.BHD", 16, 0, "铜Seg90度焊印定位网"); } bool initCustom() { #pragma region 注册触发器回调 - _station_1.init("Camera1","包膜后底托位置度检测-左-相机12",20400,1,2, &_baoMoHouDiBuDetParams,_serviceManager,bridge, ALGO_BaoMoHouDiBu); _station_2.init("Camera2", "包膜后底托位置度检测-右-相机13",20200,1,2,&_baoMoHouDiBuDetParams, _serviceManager, bridge, ALGO_BaoMoHouDiBu); #pragma endregion diff --git a/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.cpp b/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.cpp index fa75a98..e209d98 100644 --- a/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.cpp +++ b/subModule/Hd_CameraModule_HIK_PCIE/Hd_CameraModule_HIK_PCIE.cpp @@ -305,6 +305,8 @@ Hd_CameraModule_HIK_hard_PCIE::Hd_CameraModule_HIK_hard_PCIE() { } Hd_CameraModule_HIK_hard_PCIE::~Hd_CameraModule_HIK_hard_PCIE() { + runFlag = false; + callbackCollectTimeoutTimer.stop(); CloseDevice(); if (n_mutex)