diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..90d0fa5 --- /dev/null +++ b/config.ini @@ -0,0 +1,2 @@ +[generic] +lang=zh_CN \ No newline at end of file diff --git a/core/file_save.py b/core/file_save.py index ed64010..2bc4662 100644 --- a/core/file_save.py +++ b/core/file_save.py @@ -1,6 +1,7 @@ import os from PySide6.QtWidgets import (QMessageBox) from modules.UML import GameMakerLib as gml +import loc class FileSave(): def __init__(self): super().__init__() @@ -11,13 +12,13 @@ def save_file_raw(self, path, content): os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, 'w', encoding='utf-8') as f: f.write(content) - QMessageBox.information(self, "成功", "文件保存成功!") + QMessageBox.information(self, loc.translate("locSuccess"), loc.translate("locProjectSaved")) except Exception as e: - QMessageBox.critical(self, "错误", f"保存失败:{str(e)}") + QMessageBox.critical(self, loc.translate("locError"), loc.translate("locProjectLoadFailed")+str(e)) def save_file_gm(self, path, content): try: gml.Write(path, content) - QMessageBox.information(self, "成功", "文件保存成功!") + QMessageBox.information(self, loc.translate("locSuccess"), loc.translate("locProjectSaved")) except Exception as e: - QMessageBox.critical(self, "错误", f"保存失败:{str(e)}") \ No newline at end of file + QMessageBox.critical(self, loc.translate("locError"), loc.translate("locProjectLoadFailed")+str(e)) \ No newline at end of file diff --git a/core/project_manager.py b/core/project_manager.py index d3b1027..d3a71de 100644 --- a/core/project_manager.py +++ b/core/project_manager.py @@ -4,6 +4,7 @@ import datetime from PySide6.QtCore import QObject, Signal from PySide6.QtWidgets import QFileDialog +import loc class ProjectManager(QObject): project_loaded = Signal(dict) # 工程加载成功信号 project_saved = Signal() # 工程保存成功信号 @@ -15,10 +16,10 @@ def __init__(self): def new_project(self, parent_window): """创建新工程""" - src_folder = self._get_directory(parent_window, "选择源文件夹") + src_folder = self._get_directory(parent_window, loc.translate("locSelectSrcFolder")) if not src_folder: return - project_folder = self._get_directory(parent_window, "选择工程文件夹") + project_folder = self._get_directory(parent_window, loc.translate("locSelectProjFolder")) if not project_folder: return try: @@ -26,16 +27,16 @@ def new_project(self, parent_window): self.current_project = project_data self.project_loaded.emit(project_data) except Exception as e: - self.error_occurred.emit(f"创建工程失败:{str(e)}") + self.error_occurred.emit(loc.translate("locProjectCreateFailed")+str(e)) def open_project(self, parent_window): """打开已有工程""" - project_folder = self._get_directory(parent_window, "选择工程文件夹") + project_folder = self._get_directory(parent_window, loc.translate("locSelectProjFolder")) if not project_folder: return project_file = os.path.join(project_folder, 'project.json') if not os.path.exists(project_file): - self.error_occurred.emit("无效的工程目录") + self.error_occurred.emit(loc.translate("locInvalidProjDir")) return try: @@ -47,12 +48,12 @@ def open_project(self, parent_window): self.current_project = project_data self.project_loaded.emit(project_data) except Exception as e: - self.error_occurred.emit(f"加载工程失败:{str(e)}") + self.error_occurred.emit(loc.translate("locProjectLoadFailed")+str(e)) def save_project(self): """保存当前工程""" if not self.current_project: - self.error_occurred.emit("没有正在编辑的工程") + self.error_occurred.emit(loc.translate("locNoProjEditing")) return try: @@ -64,7 +65,7 @@ def save_project(self): self.project_saved.emit() except Exception as e: - self.error_occurred.emit(f"保存失败:{str(e)}") + self.error_occurred.emit(loc.translate("locProjectLoadFailed")+str(e)) def _create_project_structure(self, src_folder, project_folder): """创建工程目录结构""" @@ -98,4 +99,4 @@ def _validate_project(self, project_data): required_dirs = ['source', 'target'] for d in required_dirs: if not os.path.isdir(os.path.join(project_data['project_path'], d)): - raise ValueError(f"缺失必需目录: {d}") \ No newline at end of file + raise ValueError(loc.translate("locNecessaryDirMissing")+d) \ No newline at end of file diff --git a/editors/base_editor.py b/editors/base_editor.py index d01b9f5..815e150 100644 --- a/editors/base_editor.py +++ b/editors/base_editor.py @@ -10,7 +10,7 @@ def __init__(self, source_path, target_path): self.init_ui() def init_ui(self): - raise NotImplementedError("必须实现init_ui方法") + raise NotImplementedError("Method init_ui need to be implement") def get_content(self): - raise NotImplementedError("必须实现get_content方法") \ No newline at end of file + raise NotImplementedError("Method get_content need to be implement") \ No newline at end of file diff --git a/editors/csv_editor.py b/editors/csv_editor.py index 1b9fd78..0aae6b2 100644 --- a/editors/csv_editor.py +++ b/editors/csv_editor.py @@ -3,6 +3,7 @@ from .base_editor import BaseEditor from PySide6.QtCore import Qt from utils import detect_encoding +import loc class CSVEditor(BaseEditor): def init_ui(self): @@ -46,8 +47,8 @@ def _create_table(self, source_data, target_data): # 设置表头 headers = [] for i in range(col_count): - headers.append(f"源列 {i+1}") - headers.append(f"目标列 {i+1}") + headers.append(f"{loc.translate("locSourceColumn")} {i+1}") + headers.append(f"{loc.translate("locTargetColumn")} {i+1}") self.table.setHorizontalHeaderLabels(headers) # 填充数据 diff --git a/editors/gm/gm_base_editor.py b/editors/gm/gm_base_editor.py index 97c8299..81e0010 100644 --- a/editors/gm/gm_base_editor.py +++ b/editors/gm/gm_base_editor.py @@ -11,7 +11,7 @@ def __init__(self, source_data, target_data, id): self.init_ui() def init_ui(self): - raise NotImplementedError("必须实现init_ui方法") + raise NotImplementedError("Method init_ui need to be implement") def save(self): - raise NotImplementedError("必须实现save方法") \ No newline at end of file + raise NotImplementedError("Method save need to be implement") \ No newline at end of file diff --git a/editors/gm/gm_strings_editor.py b/editors/gm/gm_strings_editor.py index b3a72e0..7de8c1d 100644 --- a/editors/gm/gm_strings_editor.py +++ b/editors/gm/gm_strings_editor.py @@ -1,6 +1,7 @@ from PySide6.QtWidgets import QHBoxLayout, QPlainTextEdit, QVBoxLayout, QLabel from .gm_base_editor import GMBaseEditor from modules.UML import GameMakerLib as gml +import loc class GMStringsEditor(GMBaseEditor): def _handle_modify(self): @@ -12,18 +13,18 @@ def init_ui(self): # 源文本侧布局 source_layout = QVBoxLayout() - source_layout.addWidget(QLabel("源文本")) + source_layout.addWidget(QLabel(loc.translate("locSrcTxt"))) self.source_editor = QPlainTextEdit() try: self.source_editor.setPlainText(self.source_data.Strings[int(self.id)].Content) except: - self.source_editor.setPlainText("无法读取源文本") + self.source_editor.setPlainText(loc.translate("locUnable2LoadSrcTxt")) self.source_editor.setReadOnly(True) source_layout.addWidget(self.source_editor) # 目标文本侧布局 target_layout = QVBoxLayout() - target_layout.addWidget(QLabel("目标文本")) + target_layout.addWidget(QLabel(loc.translate("locTarTxt"))) self.target_editor = QPlainTextEdit() try: self.target_editor.setPlainText(self.target_data.Strings[int(self.id)].Content) diff --git a/editors/json_editor.py b/editors/json_editor.py index b869da1..37f08c9 100644 --- a/editors/json_editor.py +++ b/editors/json_editor.py @@ -1,6 +1,7 @@ import json from PySide6.QtWidgets import QHBoxLayout, QTableWidget, QTableWidgetItem from .base_editor import BaseEditor +import loc class JSONEditor(BaseEditor): def init_ui(self): @@ -14,7 +15,7 @@ def init_ui(self): target_data = source_data.copy() self.table.setColumnCount(3) - self.table.setHorizontalHeaderLabels(["键", "源文本", "目标文本"]) + self.table.setHorizontalHeaderLabels([loc.translate("locKey"), loc.translate("locSrcTxt"), loc.translate("locTarTxt")]) self.table.setRowCount(len(source_data)) for row, (key, value) in enumerate(source_data.items()): diff --git a/editors/text_editor.py b/editors/text_editor.py index 6ebf1f9..ce01adb 100644 --- a/editors/text_editor.py +++ b/editors/text_editor.py @@ -1,5 +1,6 @@ from PySide6.QtWidgets import QHBoxLayout, QPlainTextEdit from .base_editor import BaseEditor +import loc class TextEditor(BaseEditor): def _handle_modify(self): @@ -13,7 +14,7 @@ def init_ui(self): with open(self.source_path, 'r', encoding='utf-8') as f: self.source_editor.setPlainText(f.read()) except: - self.source_editor.setPlainText("无法读取源文件") + self.source_editor.setPlainText(loc.translate("locUnable2LoadSrcFile")) self.source_editor.setReadOnly(True) self.target_editor = QPlainTextEdit() diff --git a/loc.csv b/loc.csv new file mode 100644 index 0000000..944337b --- /dev/null +++ b/loc.csv @@ -0,0 +1,105 @@ +keys,en,zh_CN,zh_TW +locLangName,English,中文(简体),中文(繁體) + +locAppName,TianjiHanTools,天机汉化工具,天機漢化工具 +locLoadingCore,Loading Core Component...,正在加载核心组件...,正在加載核心組件 +locReady,Ready to go,准备就绪,準備就緒 +locConfirmQuit,Confirm to quit,确认退出,確認退出 +locConfirmQuitDiag,Are you sure to quit?,确定要退出程序吗?,確定要退出程式嗎? + +locSuccess,Success,成功,成功 +locProjectSaved,Project saved!,工程保存成功!,工程儲存成功! +locProjectSaveFailed,Project saving failed: ,工程保存失败:,工程儲存失敗: +locProjectLoaded,Project loaded!,工程加载成功!,工程加載成功! +locProjectLoadFailed,Project loading failed: ,工程加载失败:,工程加載失敗: +locProjectCreateFailed,Project creating failed: ,创建工程失败:,創建工程失敗: +locError,Error,错误,錯誤 + +locSelectProjFolder,Select project folder,选择工程文件夹,選擇工程資料夾 +locSelectSrcFolder,Select source folder,选择源文件夹,選擇源資料夾 +locInvalidProjDir,Invalid project directory.,无效的工程目录,無效的工程目錄 + +locMainToolbar,Main toolbar,主工具栏,主工具欄 +locFile,File,文件,檔案 +locQuit,Quit,退出,退出 +locAdd,Add,添加,添加 +locEdit,Edit,编辑,編輯 +locDelete,Delete,删除,刪除 +locBuild,Build,构建,構建 +locView,View,视图,試圖 +locTool,Tool,工具,工具 +locScript,Script,脚本,脚本 +locHelp,Help,帮助,幫助 + +locFileExplorer,File Explorer,文件浏览器,檔案瀏覽器 +locExport,Export,导出,匯出 +locNew,New,新建,新建 +locOpen,Open,打开,打開 +locSave,Save,保存,儲存 +locRun,Run,运行,運行 +locNewInfo,New project,新建工程,新建工程 +locOpenInfo,Open project,打开工程,打開工程 +locSaveInfo,Save project,保存工程,儲存工程 +locRunInfo,Run project,运行工程,運行工程 +locNewInfoKey,New project (Ctrl+N),新建工程 (Ctrl+N),新建工程 (Ctrl+N) +locOpenInfoKey,Open project (Ctrl+O),打开工程 (Ctrl+O),打開工程 (Ctrl+O) +locSaveInfoKey,Save project (Ctrl+S),保存工程 (Ctrl+S),儲存工程 (Ctrl+S) +locRunInfoKey,Run project (F5),运行工程 (F5),運行工程 (F5) +locWriteIntoData,Write into data,写入 data,寫入 data +locNoProjEditing,There is no project editing.,没有正在编辑的工程,沒有正在編輯的工程 +locNecessaryDirMissing,Neccessary directory is missing: ,缺失必需目录:,缺失必須目錄: + +locKey,Key,键,鍵 +locSrcTxt,Source text,源文本,源文本 +locTarTxt,Target text,目标文本,目標文本 +locUnable2LoadSrcTxt,Unable to load source text.,无法读取源文本,無法讀取源文本 +locUnable2LoadSrcFile,Unable to load source file.,无法读取源文件,無法讀取源檔案 +locSourceColumn,Source column,源列,源列 +locTargetColumn,Target column,目标列,目標列 +locPreferences,Preferences,首选项,首選項 +locLocalizedStrStandardization,Localized Strings Standardization,本地化文本规范化,在地化文本規範化 +locSearch,Search...,搜索...,搜尋... +locRegEx,RegEx,正则表达式,規則運算式 +locProjectFile,Project file,项目文件,專案檔案 + +locConvert,Convert,转换,轉換 +locMerge,Merge,合并,合并 +locUpgrade,Upgrade,升级,升級 +locClassification,Classification,分类管理,分類管理 + +locConvertTxt2Json,Convert TXT to JSON,转换 TXT 到 JSON,轉換 TXT 到 JSON +locMergeJson2Txt,Merge JSON to TXT,合并 JSON 到 TXT,合并 JSON 到 TXT +locSelectDir,Select directory,选择目录,選擇目錄 +locSelectFile,Select file,选择文件,選擇檔案 +locSaveFile,Save file,保存文件,儲存檔案 +locSelectInputFile,Select input file,选择输入文件,選擇輸入檔案 +locSelectOutputDir,Select output directory,选择输出目录,選擇輸出目錄 +locInputFile,Input file: ,输入文件,輸入檔案: +locOutputDir,Output directory: ,输出目录,輸出目錄: +locSelectInputDir,Select input directory,选择输入目录,選擇輸入目錄 +locSelectOutputFile,Select output file,选择输出文件,選擇輸出檔案 +locInputDir,Input directory: ,输入目录:,輸入目錄: +locOutputFile,Output file: ,输出文件:,輸出檔案: + +locUpgradeTxt,Upgrade Texts,升级文本,升級文本 +locSelectOldTxt,Select old TXT file,选择旧 TXT 文件,選擇舊 TXT 檔案 +locSelectOldJson,Select old JSON file,选择旧 JSON 文件,選擇舊 JSON 檔案 +locSelectNewTxt,Select new TXT file,选择新 TXT 文件,選擇新 TXT 檔案 +locOldTxt,Old TXT file: ,旧 TXT 文件:,舊 TXT 檔案: +locOldJson,Old JSON file: ,旧 JSON 文件:,舊 JSON 檔案: +locNewTxt,New TXT file: ,新 TXT 文件:,新 TXT 檔案: + +locMoveUp,Move up,上移,上移 +locMoveDn,Move down,下移,下移 +locName,Name,名称,名稱 +locNameInfo,Classification name,分类名称,分類名稱 +locType,Type,类型,類型 +locTypeInfo,Condition type,条件类型,條件類型 +locParam,Param,参数,參數 +locRuleEditor,Rule editor,规则编辑器,規則編輯器 +locAddRule,Add rule,添加规则,添加規則 + +locFinished,Finished,完成,完成 +locConvertFinished,Convert finished.,转换完成,轉換完成 +locMergeFinished,Merge finished.,合并完成,合并完成 +locUpgradeFinished,Upgrade finished.,升级完成,升級完成 \ No newline at end of file diff --git a/loc.py b/loc.py new file mode 100644 index 0000000..7febed9 --- /dev/null +++ b/loc.py @@ -0,0 +1,36 @@ +import csv +import configparser + +config = configparser.ConfigParser() + +global lang +global langs +global keys +lang = "en" +langs = [] +keys = {} +with open("loc.csv",encoding="utf-8") as f: + reader = csv.reader(f) + for line in reader: + if (line): + if (line[0] == "keys"): + for langi in line: + if (langi != "keys"): + langs.append(langi) + keys[langi] = {} + else: + for stri in line: + if (line.index(stri) != 0): + keys[langs[line.index(stri)-1]][line[0]] = stri +# print(keys) +config.read("config.ini") +lang = config.get("generic","lang",fallback="en") + +def translate(key): + if (key in keys[lang]): + return keys[lang][key] + elif (key in keys["en"]): + return keys["en"][key] + else: + print("Error: Undefined key: "+key) + return key \ No newline at end of file diff --git a/main_window.py b/main_window.py index dfc6d73..cb1bb0e 100644 --- a/main_window.py +++ b/main_window.py @@ -9,6 +9,7 @@ from editors.text_editor import TextEditor from tools.tools_register import ToolsRegister from core.file_save import FileSave as fs +import loc class LocalizationIDE(QMainWindow): def __init__(self): @@ -18,7 +19,7 @@ def __init__(self): def _init_basic_ui(self): # 极简初始化 - self.setWindowTitle("天机汉化工具 | TianjiHanTools") + self.setWindowTitle(loc.translate("locAppName")) self.resize(1200, 800) self.setCentralWidget(QWidget()) self.setWindowState(Qt.WindowActive) @@ -35,7 +36,7 @@ def _stage1_init(self): self.menu_bar = ProjectMenuBar() self.setMenuBar(self.menu_bar) # 立即显示进度 - self.statusBar().showMessage("正在加载核心组件...") + self.statusBar().showMessage(loc.translate("locLoadingCore")) def _stage2_init(self): from editors.json_editor import JSONEditor @@ -99,13 +100,13 @@ def init_ui(self): self.tabs.setMovable(True) self.setCentralWidget(self.tabs) - self.statusBar().showMessage("准备就绪", 3000) + self.statusBar().showMessage(loc.translate("locReady"), 3000) def exit(self): reply = QMessageBox.question( self, - '确认退出', - '确定要退出程序吗?', + loc.translate("locConfirmQuit"), + loc.translate("locConfirmQuitDialg"), QMessageBox.Yes | QMessageBox.No, QMessageBox.No ) @@ -118,24 +119,24 @@ def exit(self): def on_project_loaded(self, project_data): """处理工程加载完成""" self.file_explorer.load_project(project_data) - QMessageBox.information(self, "成功", "工程加载成功!") + QMessageBox.information(self, loc.translate("locSuccess"), loc.translate("locProjectLoaded")) def on_project_saved(self): """处理工程保存完成""" - QMessageBox.information(self, "成功", "工程保存成功!") + QMessageBox.information(self, loc.translate("locSuccess"), loc.translate("locProjectSaved")) def show_error(self, message): """显示错误信息""" - QMessageBox.critical(self, "错误", message) + QMessageBox.critical(self, loc.translate("locError"), message) def open_project(self): - project_folder = QFileDialog.getExistingDirectory(self, "选择工程文件夹") + project_folder = QFileDialog.getExistingDirectory(self, loc.translate("locSelectProjFolder")) if not project_folder: return project_file = os.path.join(project_folder, 'project.json') if not os.path.exists(project_file): - QMessageBox.critical(self, "错误", "无效的工程目录") + QMessageBox.critical(self, loc.translate("locError"), loc.translate("locInvalidProjDir")) return try: @@ -143,10 +144,10 @@ def open_project(self): self.project_data = json.load(f) self.file_explorer.load_project(self.project_data) - QMessageBox.information(self, "成功", "工程加载成功!") + QMessageBox.information(self, loc.translate("locSuccess"), loc.translate("locProjectLoaded")) except Exception as e: - QMessageBox.critical(self, "错误", f"加载工程失败:{str(e)}") + QMessageBox.critical(self, loc.translate("locError"), loc.translate("locProjectLoadFailed")+str(e)) def save_project(self): if not self.project_data: @@ -159,10 +160,10 @@ def save_project(self): with open(project_file, 'w') as f: json.dump(self.project_data, f, indent=4) - QMessageBox.information(self, "成功", "工程保存成功!") + QMessageBox.information(self, loc.translate("locSuccess"), loc.translate("locProjectSaved")) except Exception as e: - QMessageBox.critical(self, "错误", f"保存失败:{str(e)}") + QMessageBox.critical(self, loc.translate("locError"), loc.translate("locProjectSaveFailed")+str(e)) def _populate_tree(self, parent, path): if os.path.isdir(path): @@ -191,7 +192,7 @@ def open_file(self, rel_path): tab.rel_path = rel_path # 存储关联文件路径 layout = QVBoxLayout(tab) layout.addWidget(editor) - save_btn = QPushButton("保存") + save_btn = QPushButton(loc.translate("locSave")) save_btn.clicked.connect(lambda: fs.save_file_raw(self, target_path, editor.get_content())) layout.addWidget(save_btn) self.tabs.addTab(tab, os.path.basename(rel_path)) @@ -216,7 +217,7 @@ def open_file(self, rel_path): tab.rel_path = rel_path layout = QVBoxLayout(tab) layout.addWidget(editor) - save_btn = QPushButton("写入 data") + save_btn = QPushButton(loc.translate("locWriteIntoData")) target_path = os.path.join(self.project_manager.current_project['target'], data_path) save_btn.clicked.connect(lambda: fs.save_file_gm(self, target_path, self.file_explorer.data[1][data_path])) layout.addWidget(save_btn) diff --git a/tools/txt_format_late.py b/tools/txt_format_late.py index b562118..706bc1a 100644 --- a/tools/txt_format_late.py +++ b/tools/txt_format_late.py @@ -8,27 +8,28 @@ import os import re from collections import defaultdict +import loc jap = re.compile(r'[\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7A3]') class RuleDialog(QDialog): def __init__(self, rule=None, parent=None): super().__init__(parent) - self.setWindowTitle('规则编辑器' if rule else '添加规则') + self.setWindowTitle(loc.translate("locRuleEditor") if rule else loc.translate("locAddRule")) layout = QVBoxLayout(self) - self.name_label = QLabel("分类名称:") + self.name_label = QLabel(loc.translate("locNameInfo")+":") self.name_edit = QLineEdit() layout.addWidget(self.name_label) layout.addWidget(self.name_edit) - self.type_label = QLabel("条件类型:") + self.type_label = QLabel(loc.translate("locTypeInfo")+":") self.type_combo = QComboBox() self.type_combo.addItems(["start_with", "regex", "contains_space", "default"]) layout.addWidget(self.type_label) layout.addWidget(self.type_combo) - self.param_label = QLabel("参数:") + self.param_label = QLabel(loc.translate("locParam")+":") self.param_edit = QLineEdit() layout.addWidget(self.param_label) layout.addWidget(self.param_edit) @@ -56,7 +57,7 @@ class ToolTxTFormatLate(QDockWidget): file_double_clicked = Signal(str) def __init__(self, parent=None): - super().__init__("本地化文本规范化", parent) + super().__init__(loc.translate("locLocalizedStrStandardization"), parent) self.classification_rules = [ {'name': 'starred', 'type': 'start_with', 'param': '*'}, {'name': 'spaced', 'type': 'regex', 'param': r'[\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7A3 ]'}, @@ -66,10 +67,10 @@ def __init__(self, parent=None): self.tabs = QTabWidget() self.classification_tab = QWidget() self.create_classification_tab() - self.tabs.addTab(self.create_convert_tab(), "转换") - self.tabs.addTab(self.create_merge_tab(), "合并") - self.tabs.addTab(self.create_upgrade_tab(), "升级") - self.tabs.addTab(self.classification_tab, "分类管理") + self.tabs.addTab(self.create_convert_tab(), loc.translate("locConvert")) + self.tabs.addTab(self.create_merge_tab(), loc.translate("locMerge")) + self.tabs.addTab(self.create_upgrade_tab(), loc.translate("locUpgrade")) + self.tabs.addTab(self.classification_tab, loc.translate("locClassification")) self.setWidget(self.tabs) self.update_rules_tree() @@ -78,19 +79,19 @@ def create_convert_tab(self): tab = QWidget() layout = QVBoxLayout(tab) - group = QGroupBox("转换 TXT 到 JSON") + group = QGroupBox(loc.translate("locConvertTxt2Json")) group_layout = QVBoxLayout() self.convert_input_edit = QLineEdit() - self.convert_input_btn = QPushButton("选择输入文件") + self.convert_input_btn = QPushButton(loc.translate("locSelectInputFile")) self.convert_output_edit = QLineEdit() - self.convert_output_btn = QPushButton("选择输出目录") - self.convert_btn = QPushButton("执行转换") + self.convert_output_btn = QPushButton(loc.translate("locSelectOutputDir")) + self.convert_btn = QPushButton(loc.translate("locConvert")) - group_layout.addWidget(QLabel("输入 TXT 文件:")) + group_layout.addWidget(QLabel(loc.translate("locInputFile"))) group_layout.addWidget(self.convert_input_edit) group_layout.addWidget(self.convert_input_btn) - group_layout.addWidget(QLabel("输出目录:")) + group_layout.addWidget(QLabel(loc.translate("locOutputDir"))) group_layout.addWidget(self.convert_output_edit) group_layout.addWidget(self.convert_output_btn) group_layout.addWidget(self.convert_btn) @@ -110,19 +111,19 @@ def create_merge_tab(self): tab = QWidget() layout = QVBoxLayout(tab) - group = QGroupBox("合并 JSON 到 TXT") + group = QGroupBox(loc.translate("locMergeJson2Txt")) group_layout = QVBoxLayout() self.merge_input_edit = QLineEdit() - self.merge_input_btn = QPushButton("选择输入目录") + self.merge_input_btn = QPushButton(loc.translate("locSelectInputDir")) self.merge_output_edit = QLineEdit() - self.merge_output_btn = QPushButton("选择输出文件") - self.merge_btn = QPushButton("执行合并") + self.merge_output_btn = QPushButton(loc.translate("locSelectOutputFile")) + self.merge_btn = QPushButton(loc.translate("locMerge")) - group_layout.addWidget(QLabel("输入 JSON 目录:")) + group_layout.addWidget(QLabel(loc.translate("locInputDir"))) group_layout.addWidget(self.merge_input_edit) group_layout.addWidget(self.merge_input_btn) - group_layout.addWidget(QLabel("输出 TXT 文件:")) + group_layout.addWidget(QLabel(loc.translate("locOutputFile"))) group_layout.addWidget(self.merge_output_edit) group_layout.addWidget(self.merge_output_btn) group_layout.addWidget(self.merge_btn) @@ -142,29 +143,29 @@ def create_upgrade_tab(self): tab = QWidget() layout = QVBoxLayout(tab) - group = QGroupBox("版本升级") + group = QGroupBox(loc.translate("locUpgradeTxt")) group_layout = QVBoxLayout() self.upgrade_old_txt_edit = QLineEdit() - self.upgrade_old_txt_btn = QPushButton("选择旧TXT") + self.upgrade_old_txt_btn = QPushButton(loc.translate("locSelectOldTxt")) self.upgrade_old_json_edit = QLineEdit() - self.upgrade_old_json_btn = QPushButton("选择旧JSON目录") + self.upgrade_old_json_btn = QPushButton(loc.translate("locSelectOldJson")) self.upgrade_new_txt_edit = QLineEdit() - self.upgrade_new_txt_btn = QPushButton("选择新TXT") + self.upgrade_new_txt_btn = QPushButton(loc.translate("locSelectNewTxt")) self.upgrade_output_edit = QLineEdit() - self.upgrade_output_btn = QPushButton("选择输出目录") - self.upgrade_btn = QPushButton("执行升级") + self.upgrade_output_btn = QPushButton(loc.translate("locSelectOutputDir")) + self.upgrade_btn = QPushButton(loc.translate("locUpgrade")) - group_layout.addWidget(QLabel("旧 TXT 文件:")) + group_layout.addWidget(QLabel(loc.translate("locOldTxt"))) group_layout.addWidget(self.upgrade_old_txt_edit) group_layout.addWidget(self.upgrade_old_txt_btn) - group_layout.addWidget(QLabel("旧 JSON 目录:")) + group_layout.addWidget(QLabel(loc.translate("locNewTxt"))) group_layout.addWidget(self.upgrade_old_json_edit) group_layout.addWidget(self.upgrade_old_json_btn) - group_layout.addWidget(QLabel("新 TXT 文件:")) + group_layout.addWidget(QLabel(loc.translate("locOutputDir"))) group_layout.addWidget(self.upgrade_new_txt_edit) group_layout.addWidget(self.upgrade_new_txt_btn) - group_layout.addWidget(QLabel("输出目录:")) + group_layout.addWidget(QLabel(loc.translate("locOutputDir"))) group_layout.addWidget(self.upgrade_output_edit) group_layout.addWidget(self.upgrade_output_btn) group_layout.addWidget(self.upgrade_btn) @@ -185,15 +186,15 @@ def create_upgrade_tab(self): def create_classification_tab(self): layout = QVBoxLayout(self.classification_tab) self.rules_tree = QTreeWidget() - self.rules_tree.setHeaderLabels(["名称", "类型", "参数"]) + self.rules_tree.setHeaderLabels([loc.translate("locName"), loc.translate("locType"), loc.translate("locParam")]) layout.addWidget(self.rules_tree) btn_layout = QHBoxLayout() - self.add_btn = QPushButton("添加") - self.edit_btn = QPushButton("编辑") - self.delete_btn = QPushButton("删除") - self.up_btn = QPushButton("上移") - self.down_btn = QPushButton("下移") + self.add_btn = QPushButton(loc.translate("locAdd")) + self.edit_btn = QPushButton(loc.translate("locEdit")) + self.delete_btn = QPushButton(loc.translate("locDelete")) + self.up_btn = QPushButton(loc.translate("locMoveUp")) + self.down_btn = QPushButton(loc.translate("locMoveDn")) btn_layout.addWidget(self.add_btn) btn_layout.addWidget(self.edit_btn) @@ -260,17 +261,17 @@ def move_rule_down(self): self.classification_rules.insert(index+1, self.classification_rules.pop(index)) self.update_rules_tree() def select_file(self, edit_widget): - path, _ = QFileDialog.getOpenFileName(self, "选择文件") + path, _ = QFileDialog.getOpenFileName(self, loc.translate("locSelectFile")) if path: edit_widget.setText(path) def select_directory(self, edit_widget): - path = QFileDialog.getExistingDirectory(self, "选择目录") + path = QFileDialog.getExistingDirectory(self, loc.translate("locSelectDir")) if path: edit_widget.setText(path) def save_file(self, edit_widget): - path, _ = QFileDialog.getSaveFileName(self, "保存文件") + path, _ = QFileDialog.getSaveFileName(self, loc.translate("locSaveFile")) if path: edit_widget.setText(path) @@ -295,7 +296,7 @@ def do_convert(self): output_dir = self.convert_output_edit.text() if not os.path.exists(input_txt): - raise ValueError("输入文件不存在") + raise ValueError("Input file not exists: "+input_txt) os.makedirs(output_dir, exist_ok=True) @@ -307,7 +308,7 @@ def do_convert(self): for line_num, line in enumerate(lines): category = self.categorize_line(line) if not category: - raise ValueError(f"无法分类第 {line_num} 行: {line}") + raise ValueError(f"Can't categorize line {line_num}: {line}") categories[category][str(line_num)] = line for name, data in categories.items(): @@ -315,9 +316,9 @@ def do_convert(self): with open(output_path, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) - QMessageBox.information(self, "完成", "转换完成") + QMessageBox.information(self, loc.translate("locFinished"), loc.translate("locConvertFinished")) except Exception as e: - QMessageBox.critical(self, "错误", str(e)) + QMessageBox.critical(self, loc.translate("locError"), str(e)) def do_merge(self): try: @@ -349,9 +350,9 @@ def do_merge(self): with open(output_txt, 'w', encoding='utf-8') as f: f.write('\n'.join(merged)) - QMessageBox.information(self, "完成", "合并完成") + QMessageBox.information(self, loc.translate("locFinished"), loc.translate("locMergeFinished")) except Exception as e: - QMessageBox.critical(self, "错误", str(e)) + QMessageBox.critical(self, loc.translate("locError"), str(e)) def do_upgrade(self): try: @@ -406,6 +407,6 @@ def do_upgrade(self): with open(path, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) - QMessageBox.information(self, "完成", "升级完成") + QMessageBox.information(self, loc.translate("locFinished"), loc.translate("locUpgradeFinished")) except Exception as e: - QMessageBox.critical(self, "错误", str(e)) \ No newline at end of file + QMessageBox.critical(self, loc.translate("locError"), str(e)) \ No newline at end of file diff --git a/widgets/file_explorer.py b/widgets/file_explorer.py index 4494e3b..1f0080e 100644 --- a/widgets/file_explorer.py +++ b/widgets/file_explorer.py @@ -3,18 +3,19 @@ from PySide6.QtCore import Qt, Signal import os import re +import loc class FileExplorer(QDockWidget): file_double_clicked = Signal(str) # 发送相对路径 def __init__(self, parent=None): - super().__init__("文件浏览器", parent) + super().__init__(loc.translate("locFileExplorer"), parent) self.data = [{},{}] # 创建搜索组件 self.search_line = QLineEdit() - self.search_line.setPlaceholderText("搜索...") - self.regex_checkbox = QCheckBox("正则表达式") + self.search_line.setPlaceholderText(loc.translate("locSearch")) + self.regex_checkbox = QCheckBox(loc.translate("locRegEx")) # 创建布局 search_layout = QHBoxLayout() @@ -23,7 +24,7 @@ def __init__(self, parent=None): # 创建树部件 self.tree = QTreeWidget() - self.tree.setHeaderLabel("项目文件") + self.tree.setHeaderLabel(loc.translate("locProjectFile")) self.tree.itemDoubleClicked.connect(self.on_item_double_clicked) # 主容器布局 diff --git a/widgets/menu_bar.py b/widgets/menu_bar.py index e97e943..a6ac209 100644 --- a/widgets/menu_bar.py +++ b/widgets/menu_bar.py @@ -1,6 +1,7 @@ from PySide6.QtWidgets import QMenuBar from PySide6.QtCore import Signal from PySide6.QtGui import QKeySequence, QAction +import loc class ProjectMenuBar(QMenuBar): new_project = Signal(object) @@ -15,16 +16,16 @@ def __init__(self, parent=None): self.init_ui() def init_ui(self): - file_menu = self.addMenu('文件') + file_menu = self.addMenu(loc.translate("locFile")) # 新建工程 - new_action = QAction('新建工程', self) + new_action = QAction(loc.translate("locNewInfo"), self) new_action.triggered.connect(lambda: self.new_project.emit(self.parent())) new_action.setShortcut(QKeySequence.StandardKey.New) file_menu.addAction(new_action) # 打开工程 - open_action = QAction('打开工程', self) + open_action = QAction(loc.translate("locOpenInfo"), self) open_action.triggered.connect(lambda: self.open_project.emit(self.parent())) open_action.setShortcut(QKeySequence.StandardKey.Open) file_menu.addAction(open_action) @@ -32,41 +33,41 @@ def init_ui(self): file_menu.addSeparator() # 保存工程 - save_action = QAction('保存工程', self) + save_action = QAction(loc.translate("locSaveInfo"), self) save_action.triggered.connect(self.save_project.emit) save_action.setShortcut(QKeySequence.StandardKey.Save) file_menu.addAction(save_action) - export_menu = file_menu.addMenu("导出") - save_zip_action = QAction('通用压缩格式 (.zip)', self) + export_menu = file_menu.addMenu(loc.translate("locExport")) + save_zip_action = QAction('.zip', self) export_menu.addAction(save_zip_action) - preferences_action = QAction('首选项', self) + preferences_action = QAction(loc.translate("locPreferences"), self) preferences_action.setShortcut(QKeySequence.StandardKey.Preferences) file_menu.addAction(preferences_action) file_menu.addSeparator() - exit_action = QAction('退出', self) + exit_action = QAction(loc.translate("locQuit"), self) exit_action.setShortcut(QKeySequence.StandardKey.Quit) exit_action.triggered.connect(self.exit_action.emit) file_menu.addAction(exit_action) - edit_menu = self.addMenu('编辑') - build_menu = self.addMenu('构建') + edit_menu = self.addMenu(loc.translate("locEdit")) + build_menu = self.addMenu(loc.translate("locBuild")) - view_menu = self.addMenu('视图') + view_menu = self.addMenu(loc.translate("locView")) - file_explorer_action = QAction('文件浏览器', self) + file_explorer_action = QAction(loc.translate("locFileExplorer"), self) file_explorer_action.triggered.connect(self.file_explorer_action.emit) view_menu.addAction(file_explorer_action) - tools_menu = self.addMenu('工具') - txt_split_action = QAction('本地化文本规范化', self) + tools_menu = self.addMenu(loc.translate("locTool")) + txt_split_action = QAction(loc.translate("locLocalizedStrStandardization"), self) txt_split_action.triggered.connect(lambda: self.txt_split_action.emit(self.parent())) tools_menu.addAction(txt_split_action) - scripts_menu = self.addMenu('脚本') - help_menu = self.addMenu('帮助') \ No newline at end of file + scripts_menu = self.addMenu(loc.translate("locScript")) + help_menu = self.addMenu(loc.translate("locHelp")) \ No newline at end of file diff --git a/widgets/toolbar.py b/widgets/toolbar.py index c2cd47d..68b965f 100644 --- a/widgets/toolbar.py +++ b/widgets/toolbar.py @@ -1,6 +1,7 @@ from PySide6.QtWidgets import QToolBar from PySide6.QtGui import QIcon, QAction from PySide6.QtCore import Signal, QSize +import loc class MainToolBar(QToolBar): new_project = Signal(object) @@ -9,34 +10,34 @@ class MainToolBar(QToolBar): run_action = Signal() def __init__(self, parent=None): - super().__init__("主工具栏", parent) + super().__init__(loc.translate("locMainToolbar"), parent) self.init_ui() self.setMovable(False) self.setIconSize(QSize(24, 24)) def init_ui(self): # 新建按钮 - new_action = QAction(QIcon("assets/icons/new.png"), "新建", self) + new_action = QAction(QIcon("assets/icons/new.png"), loc.translate("locNew"), self) new_action.triggered.connect(lambda: self.new_project.emit(self.parent())) - new_action.setToolTip("新建工程 (Ctrl+N)") + new_action.setToolTip(loc.translate("locNewInfoKey")) self.addAction(new_action) # 打开按钮 - open_action = QAction(QIcon("assets/icons/open.png"), "打开", self) + open_action = QAction(QIcon("assets/icons/open.png"), loc.translate("locOpen"), self) open_action.triggered.connect(lambda: self.open_project.emit(self.parent())) - open_action.setToolTip("打开工程 (Ctrl+O)") + open_action.setToolTip(loc.translate("locOpenInfoKey")) self.addAction(open_action) # 保存按钮 - save_action = QAction(QIcon("assets/icons/save.png"), "保存", self) + save_action = QAction(QIcon("assets/icons/save.png"), loc.translate("locSave"), self) save_action.triggered.connect(self.save_project.emit) - save_action.setToolTip("保存工程 (Ctrl+S)") + save_action.setToolTip(loc.translate("locSaveInfoKey")) self.addAction(save_action) self.addSeparator() # 运行按钮 - run_action = QAction(QIcon("assets/icons/run.png"), "运行", self) + run_action = QAction(QIcon("assets/icons/run.png"), loc.translate("locRun"), self) run_action.triggered.connect(self.run_action.emit) - run_action.setToolTip("运行工程 (F5)") + run_action.setToolTip(loc.translate("locRunInfoKey")) self.addAction(run_action) \ No newline at end of file