je-editor 0.0.202__py3-none-any.whl → 0.0.228__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. je_editor/__init__.py +2 -2
  2. je_editor/code_scan/__init__.py +0 -0
  3. je_editor/code_scan/ruff_thread.py +58 -0
  4. je_editor/code_scan/watchdog_implement.py +56 -0
  5. je_editor/code_scan/watchdog_thread.py +78 -0
  6. je_editor/git_client/__init__.py +0 -0
  7. je_editor/git_client/commit_graph.py +77 -0
  8. je_editor/git_client/git_action.py +175 -0
  9. je_editor/git_client/git_cli.py +66 -0
  10. je_editor/pyside_ui/browser/browser_download_window.py +40 -4
  11. je_editor/pyside_ui/browser/browser_serach_lineedit.py +24 -0
  12. je_editor/pyside_ui/browser/browser_view.py +55 -6
  13. je_editor/pyside_ui/browser/browser_widget.py +62 -19
  14. je_editor/pyside_ui/browser/main_browser_widget.py +85 -0
  15. je_editor/pyside_ui/code/auto_save/auto_save_manager.py +33 -1
  16. je_editor/pyside_ui/code/auto_save/auto_save_thread.py +18 -5
  17. je_editor/pyside_ui/code/code_format/pep8_format.py +52 -7
  18. je_editor/pyside_ui/code/code_process/code_exec.py +118 -64
  19. je_editor/pyside_ui/code/plaintext_code_edit/code_edit_plaintext.py +115 -53
  20. je_editor/pyside_ui/code/running_process_manager.py +18 -0
  21. je_editor/pyside_ui/code/shell_process/shell_exec.py +99 -60
  22. je_editor/pyside_ui/code/syntax/python_syntax.py +44 -9
  23. je_editor/pyside_ui/code/syntax/syntax_setting.py +39 -11
  24. je_editor/pyside_ui/code/textedit_code_result/code_record.py +33 -11
  25. je_editor/pyside_ui/code/variable_inspector/__init__.py +0 -0
  26. je_editor/pyside_ui/code/variable_inspector/inspector_gui.py +172 -0
  27. je_editor/pyside_ui/dialog/ai_dialog/__init__.py +0 -0
  28. je_editor/pyside_ui/dialog/ai_dialog/set_ai_dialog.py +71 -0
  29. je_editor/pyside_ui/dialog/file_dialog/create_file_dialog.py +38 -4
  30. je_editor/pyside_ui/dialog/file_dialog/open_file_dialog.py +32 -4
  31. je_editor/pyside_ui/dialog/file_dialog/save_file_dialog.py +25 -2
  32. je_editor/pyside_ui/dialog/search_ui/search_error_box.py +27 -2
  33. je_editor/pyside_ui/dialog/search_ui/search_text_box.py +28 -3
  34. je_editor/pyside_ui/git_ui/__init__.py +0 -0
  35. je_editor/pyside_ui/git_ui/code_diff_compare/__init__.py +0 -0
  36. je_editor/pyside_ui/git_ui/code_diff_compare/code_diff_viewer_widget.py +90 -0
  37. je_editor/pyside_ui/git_ui/code_diff_compare/line_number_code_viewer.py +141 -0
  38. je_editor/pyside_ui/git_ui/code_diff_compare/multi_file_diff_viewer.py +88 -0
  39. je_editor/pyside_ui/git_ui/code_diff_compare/side_by_side_diff_widget.py +284 -0
  40. je_editor/pyside_ui/git_ui/git_client/__init__.py +0 -0
  41. je_editor/pyside_ui/git_ui/git_client/commit_table.py +65 -0
  42. je_editor/pyside_ui/git_ui/git_client/git_branch_tree_widget.py +156 -0
  43. je_editor/pyside_ui/git_ui/git_client/git_client_gui.py +799 -0
  44. je_editor/pyside_ui/git_ui/git_client/graph_view.py +218 -0
  45. je_editor/pyside_ui/main_ui/ai_widget/__init__.py +0 -0
  46. je_editor/pyside_ui/main_ui/ai_widget/ai_config.py +34 -0
  47. je_editor/pyside_ui/main_ui/ai_widget/ask_thread.py +36 -0
  48. je_editor/pyside_ui/main_ui/ai_widget/chat_ui.py +147 -0
  49. je_editor/pyside_ui/main_ui/ai_widget/langchain_interface.py +84 -0
  50. je_editor/pyside_ui/main_ui/console_widget/__init__.py +0 -0
  51. je_editor/pyside_ui/main_ui/console_widget/console_gui.py +162 -0
  52. je_editor/pyside_ui/main_ui/console_widget/qprocess_adapter.py +84 -0
  53. je_editor/pyside_ui/main_ui/dock/destroy_dock.py +32 -1
  54. je_editor/pyside_ui/main_ui/editor/editor_widget.py +113 -23
  55. je_editor/pyside_ui/main_ui/editor/editor_widget_dock.py +33 -6
  56. je_editor/pyside_ui/main_ui/editor/process_input.py +42 -10
  57. je_editor/pyside_ui/main_ui/ipython_widget/rich_jupyter.py +45 -10
  58. je_editor/pyside_ui/main_ui/main_editor.py +189 -49
  59. je_editor/pyside_ui/main_ui/menu/check_style_menu/build_check_style_menu.py +50 -27
  60. je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py +141 -30
  61. je_editor/pyside_ui/main_ui/menu/file_menu/build_file_menu.py +67 -17
  62. je_editor/pyside_ui/main_ui/menu/help_menu/build_help_menu.py +33 -3
  63. je_editor/pyside_ui/main_ui/menu/language_menu/build_language_server.py +39 -0
  64. je_editor/pyside_ui/main_ui/menu/python_env_menu/build_venv_menu.py +102 -40
  65. je_editor/pyside_ui/main_ui/menu/run_menu/build_run_menu.py +53 -6
  66. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_debug_menu.py +47 -3
  67. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_program_menu.py +45 -5
  68. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/build_shell_menu.py +41 -3
  69. je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/utils.py +21 -0
  70. je_editor/pyside_ui/main_ui/menu/set_menu_bar.py +37 -11
  71. je_editor/pyside_ui/main_ui/menu/style_menu/build_style_menu.py +42 -6
  72. je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py +202 -27
  73. je_editor/pyside_ui/main_ui/menu/text_menu/build_text_menu.py +66 -0
  74. je_editor/pyside_ui/main_ui/save_settings/setting_utils.py +18 -1
  75. je_editor/pyside_ui/main_ui/save_settings/user_color_setting_file.py +32 -2
  76. je_editor/pyside_ui/main_ui/save_settings/user_setting_file.py +37 -10
  77. je_editor/pyside_ui/main_ui/system_tray/extend_system_tray.py +39 -0
  78. je_editor/start_editor.py +25 -0
  79. je_editor/utils/encodings/python_encodings.py +100 -97
  80. je_editor/utils/exception/exception_tags.py +11 -11
  81. je_editor/utils/file/open/open_file.py +35 -19
  82. je_editor/utils/file/save/save_file.py +34 -13
  83. je_editor/utils/json/json_file.py +29 -14
  84. je_editor/utils/json_format/json_process.py +32 -1
  85. je_editor/utils/logging/loggin_instance.py +37 -7
  86. je_editor/utils/multi_language/english.py +102 -6
  87. je_editor/utils/multi_language/multi_language_wrapper.py +28 -3
  88. je_editor/utils/multi_language/traditional_chinese.py +101 -10
  89. je_editor/utils/redirect_manager/redirect_manager_class.py +49 -11
  90. je_editor/utils/venv_check/check_venv.py +37 -14
  91. {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info}/METADATA +12 -6
  92. je_editor-0.0.228.dist-info/RECORD +140 -0
  93. {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info}/WHEEL +1 -1
  94. je_editor-0.0.202.dist-info/RECORD +0 -108
  95. {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info/licenses}/LICENSE +0 -0
  96. {je_editor-0.0.202.dist-info → je_editor-0.0.228.dist-info}/top_level.txt +0 -0
@@ -1,36 +1,64 @@
1
+ # 匯入未來功能,允許延遲型別註解 (Python 3.7+ 常用)
2
+ # Import future feature: postponed evaluation of type annotations
1
3
  from __future__ import annotations
2
4
 
5
+ # 僅用於型別檢查,避免循環匯入
6
+ # For type checking only (avoids circular imports)
3
7
  from typing import TYPE_CHECKING
4
8
 
9
+ # 匯入 Qt 動作與訊息框
10
+ # Import QAction and QMessageBox from PySide6
5
11
  from PySide6.QtGui import QAction
6
12
  from PySide6.QtWidgets import QMessageBox
7
13
 
14
+ # 匯入使用者設定字典,用來保存語言設定
15
+ # Import user settings dictionary for saving language preferences
8
16
  from je_editor.pyside_ui.main_ui.save_settings.user_setting_file import user_setting_dict
17
+ # 匯入日誌紀錄器
18
+ # Import logger instance
9
19
  from je_editor.utils.logging.loggin_instance import jeditor_logger
10
20
 
21
+ # 僅在型別檢查時匯入 EditorMain,避免循環依賴
22
+ # Import EditorMain only for type checking (avoids circular dependency)
11
23
  if TYPE_CHECKING:
12
24
  from je_editor.pyside_ui.main_ui.main_editor import EditorMain
13
25
 
26
+ # 匯入多語言包裝器,用於 UI 多語言顯示
27
+ # Import multi-language wrapper for UI localization
14
28
  from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
15
29
 
16
30
 
31
+ # 設定語言選單
32
+ # Set up the Language menu
17
33
  def set_language_menu(ui_we_want_to_set: EditorMain) -> None:
18
34
  jeditor_logger.info(f"build_language_server.py set_language_menu ui_we_want_to_set: {ui_we_want_to_set}")
35
+
36
+ # 建立 Language 選單
37
+ # Create Language menu
19
38
  ui_we_want_to_set.language_menu = ui_we_want_to_set.menu.addMenu(
20
39
  language_wrapper.language_word_dict.get("language_menu_label")
21
40
  )
41
+
42
+ # 建立「切換到英文」動作
43
+ # Add "Switch to English" action
22
44
  ui_we_want_to_set.language_menu.change_to_english_language_action = QAction(
23
45
  language_wrapper.language_word_dict.get("language_menu_bar_english")
24
46
  )
25
47
  ui_we_want_to_set.language_menu.change_to_english_language_action.triggered.connect(
26
48
  lambda: set_language("English", ui_we_want_to_set)
27
49
  )
50
+
51
+ # 建立「切換到繁體中文」動作
52
+ # Add "Switch to Traditional Chinese" action
28
53
  ui_we_want_to_set.language_menu.change_to_traditional_chinese_language_action = QAction(
29
54
  language_wrapper.language_word_dict.get("language_menu_bar_traditional_chinese")
30
55
  )
31
56
  ui_we_want_to_set.language_menu.change_to_traditional_chinese_language_action.triggered.connect(
32
57
  lambda: set_language("Traditional_Chinese", ui_we_want_to_set)
33
58
  )
59
+
60
+ # 將動作加入選單
61
+ # Add actions to the menu
34
62
  ui_we_want_to_set.language_menu.addAction(
35
63
  ui_we_want_to_set.language_menu.change_to_english_language_action
36
64
  )
@@ -39,12 +67,23 @@ def set_language_menu(ui_we_want_to_set: EditorMain) -> None:
39
67
  )
40
68
 
41
69
 
70
+ # 設定語言
71
+ # Set the application language
42
72
  def set_language(language: str, ui_we_want_to_set: EditorMain) -> None:
43
73
  jeditor_logger.info("build_language_server.py set_language "
44
74
  f"language: {language} "
45
75
  f"ui_we_want_to_set: {ui_we_want_to_set}")
76
+
77
+ # 重設語言 (更新多語言字典)
78
+ # Reset language (update multi-language dictionary)
46
79
  language_wrapper.reset_language(language)
80
+
81
+ # 更新使用者設定,保存語言偏好
82
+ # Update user settings dictionary to persist language preference
47
83
  user_setting_dict.update({"language": language})
84
+
85
+ # 顯示提示訊息,提醒使用者需要重新啟動程式
86
+ # Show a message box to remind user to restart the application
48
87
  message_box = QMessageBox(ui_we_want_to_set)
49
88
  message_box.setText(language_wrapper.language_word_dict.get("language_menu_bar_please_restart_messagebox"))
50
89
  message_box.show()
@@ -1,68 +1,91 @@
1
+ # 匯入未來功能,允許延遲型別註解 (Python 3.7+ 常用)
2
+ # Import future feature: postponed evaluation of type annotations
1
3
  from __future__ import annotations
2
4
 
5
+ # 僅用於型別檢查,避免循環匯入
6
+ # For type checking only (avoids circular imports)
3
7
  from typing import TYPE_CHECKING
4
8
 
9
+ # 匯入編輯器元件
10
+ # Import EditorWidget
5
11
  from je_editor.pyside_ui.main_ui.editor.editor_widget import EditorWidget
12
+ # 匯入顏色設定,用於輸出訊息時的字體顏色
13
+ # Import color settings for console/text output
14
+ from je_editor.pyside_ui.main_ui.save_settings.user_color_setting_file import actually_color_dict
15
+ # 匯入使用者設定字典,用來保存 Python 解譯器與環境設定
16
+ # Import user settings dictionary for saving Python interpreter and environment settings
6
17
  from je_editor.pyside_ui.main_ui.save_settings.user_setting_file import user_setting_dict
18
+ # 匯入日誌紀錄器
19
+ # Import logger instance
7
20
  from je_editor.utils.logging.loggin_instance import jeditor_logger
8
21
 
22
+ # 僅在型別檢查時匯入 EditorMain,避免循環依賴
23
+ # Import EditorMain only for type checking (avoids circular dependency)
9
24
  if TYPE_CHECKING:
10
25
  from je_editor.pyside_ui.main_ui.main_editor import EditorMain
26
+
11
27
  import os
12
28
  from pathlib import Path
13
29
 
14
- from PySide6.QtGui import QAction, QKeySequence
30
+ # 匯入 Qt 動作、快捷鍵、文字格式、訊息框、輸入框、檔案對話框
31
+ # Import QAction, QKeySequence, QTextCharFormat, QMessageBox, QInputDialog, QFileDialog
32
+ from PySide6.QtGui import QAction, QKeySequence, QTextCharFormat
15
33
  from PySide6.QtWidgets import QMessageBox, QInputDialog, QFileDialog
16
34
 
35
+ # 匯入 ShellManager,用於執行系統命令 (建立 venv、pip install 等)
36
+ # Import ShellManager for executing shell commands (create venv, pip install, etc.)
17
37
  from je_editor.pyside_ui.code.shell_process.shell_exec import ShellManager
18
38
 
39
+ # 匯入多語言包裝器,用於 UI 多語言顯示
40
+ # Import multi-language wrapper for UI localization
19
41
  from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
20
42
 
21
43
 
44
+ # 設定 Python 環境選單 (venv menu)
45
+ # Set up the Python Environment (venv) menu
22
46
  def set_venv_menu(ui_we_want_to_set: EditorMain) -> None:
23
47
  jeditor_logger.info(f"build_venv_menu.py set_venv_menu ui_we_want_to_set: {ui_we_want_to_set}")
24
48
  ui_we_want_to_set.venv_menu = ui_we_want_to_set.menu.addMenu(
25
49
  language_wrapper.language_word_dict.get("python_env_menu_label"))
26
- # Create an venv
50
+
51
+ # 建立虛擬環境 (Ctrl+Shift+V)
52
+ # Create virtual environment
27
53
  ui_we_want_to_set.venv_menu.change_language_menu = QAction(
28
54
  language_wrapper.language_word_dict.get("python_env_menu_create_venv_label"))
29
- ui_we_want_to_set.venv_menu.change_language_menu.setShortcut(
30
- QKeySequence("Ctrl+Shift+V")
31
- )
55
+ ui_we_want_to_set.venv_menu.change_language_menu.setShortcut(QKeySequence("Ctrl+Shift+V"))
32
56
  ui_we_want_to_set.venv_menu.change_language_menu.triggered.connect(
33
- lambda: create_venv(ui_we_want_to_set)
34
- )
57
+ lambda: create_venv(ui_we_want_to_set))
35
58
  ui_we_want_to_set.venv_menu.addAction(ui_we_want_to_set.venv_menu.change_language_menu)
59
+
60
+ # pip 升級套件 (Ctrl+Shift+U)
36
61
  # pip upgrade package
37
62
  ui_we_want_to_set.venv_menu.pip_upgrade_action = QAction(
38
- language_wrapper.language_word_dict.get("python_env_menu_pip_upgrade_label")
39
- )
40
- ui_we_want_to_set.venv_menu.pip_upgrade_action.setShortcut(
41
- QKeySequence("Ctrl+Shift+U")
42
- )
63
+ language_wrapper.language_word_dict.get("python_env_menu_pip_upgrade_label"))
64
+ ui_we_want_to_set.venv_menu.pip_upgrade_action.setShortcut(QKeySequence("Ctrl+Shift+U"))
43
65
  ui_we_want_to_set.venv_menu.pip_upgrade_action.triggered.connect(
44
- lambda: pip_install_package_update(ui_we_want_to_set)
45
- )
66
+ lambda: pip_install_package_update(ui_we_want_to_set))
46
67
  ui_we_want_to_set.venv_menu.addAction(ui_we_want_to_set.venv_menu.pip_upgrade_action)
47
- # pip package
68
+
69
+ # pip 安裝套件 (Ctrl+Shift+P)
70
+ # pip install package
48
71
  ui_we_want_to_set.venv_menu.pip_action = QAction(
49
72
  language_wrapper.language_word_dict.get("python_env_menu_pip_label"))
50
- ui_we_want_to_set.venv_menu.pip_action.setShortcut(
51
- QKeySequence("Ctrl+Shift+P")
52
- )
73
+ ui_we_want_to_set.venv_menu.pip_action.setShortcut(QKeySequence("Ctrl+Shift+P"))
53
74
  ui_we_want_to_set.venv_menu.pip_action.triggered.connect(
54
- lambda: pip_install_package(ui_we_want_to_set)
55
- )
75
+ lambda: pip_install_package(ui_we_want_to_set))
56
76
  ui_we_want_to_set.venv_menu.addAction(ui_we_want_to_set.venv_menu.pip_action)
57
- # choose python interpreter
77
+
78
+ # 選擇 Python 解譯器
79
+ # Choose Python interpreter
58
80
  ui_we_want_to_set.venv_menu.choose_interpreter_action = QAction(
59
81
  language_wrapper.language_word_dict.get("python_env_menu_choose_interpreter_label"))
60
82
  ui_we_want_to_set.venv_menu.choose_interpreter_action.triggered.connect(
61
- lambda: chose_python_interpreter(ui_we_want_to_set)
62
- )
83
+ lambda: chose_python_interpreter(ui_we_want_to_set))
63
84
  ui_we_want_to_set.venv_menu.addAction(ui_we_want_to_set.venv_menu.choose_interpreter_action)
64
85
 
65
86
 
87
+ # 建立虛擬環境
88
+ # Create virtual environment
66
89
  def create_venv(ui_we_want_to_set: EditorMain) -> None:
67
90
  jeditor_logger.info(f"build_venv_menu.py create_venv ui_we_want_to_set: {ui_we_want_to_set}")
68
91
  widget = ui_we_want_to_set.tab_widget.currentWidget()
@@ -70,21 +93,31 @@ def create_venv(ui_we_want_to_set: EditorMain) -> None:
70
93
  widget.python_compiler = ui_we_want_to_set.python_compiler
71
94
  venv_path = Path(os.getcwd() + "/venv")
72
95
  if not venv_path.exists():
96
+ # 使用 ShellManager 執行 python -m venv venv
97
+ # Use ShellManager to run python -m venv venv
73
98
  create_venv_shell = ShellManager(main_window=widget, after_done_function=widget.code_edit.check_env,
74
99
  shell_encoding=ui_we_want_to_set.encoding)
75
100
  create_venv_shell.later_init()
76
- create_venv_shell.exec_shell(
77
- [f"{create_venv_shell.compiler_path}", "-m", "venv", "venv"]
78
- )
79
- widget.code_result.append(
80
- language_wrapper.language_word_dict.get("python_env_menu_creating_venv_message"))
101
+ create_venv_shell.exec_shell([f"{create_venv_shell.compiler_path}", "-m", "venv", "venv"])
102
+
103
+ # 在編輯器輸出區顯示訊息
104
+ # Show message in editor output area
105
+ text_cursor = widget.code_result.textCursor()
106
+ text_format = QTextCharFormat()
107
+ text_format.setForeground(actually_color_dict.get("normal_output_color"))
108
+ text_cursor.insertText(language_wrapper.language_word_dict.get("python_env_menu_creating_venv_message"),
109
+ text_format)
110
+ text_cursor.insertBlock()
81
111
  else:
112
+ # 如果 venv 已存在,顯示提示訊息
113
+ # If venv exists, show message
82
114
  message_box = QMessageBox()
83
- message_box.setText(
84
- language_wrapper.language_word_dict.get("python_env_menu_venv_exists"))
115
+ message_box.setText(language_wrapper.language_word_dict.get("python_env_menu_venv_exists"))
85
116
  message_box.exec()
86
117
 
87
118
 
119
+ # 使用 pip 安裝套件 (通用函式)
120
+ # Run pip install command (general function)
88
121
  def shell_pip_install(ui_we_want_to_set: EditorMain, pip_install_command_list: list):
89
122
  jeditor_logger.info("build_venv_menu.py create_venv "
90
123
  f"ui_we_want_to_set: {ui_we_want_to_set} "
@@ -94,10 +127,14 @@ def shell_pip_install(ui_we_want_to_set: EditorMain, pip_install_command_list: l
94
127
  widget.python_compiler = ui_we_want_to_set.python_compiler
95
128
  venv_path = Path(os.getcwd() + "/venv")
96
129
  if not venv_path.exists():
130
+ # 如果 venv 不存在,提醒使用者先建立
131
+ # If venv does not exist, remind user to create it first
97
132
  message_box = QMessageBox()
98
133
  message_box.setText(language_wrapper.language_word_dict.get("python_env_menu_please_create_venv"))
99
134
  message_box.exec()
100
135
  else:
136
+ # 彈出輸入框,讓使用者輸入套件名稱
137
+ # Ask user to input package name
101
138
  ask_package_dialog = QInputDialog()
102
139
  package_text, press_ok = ask_package_dialog.getText(
103
140
  ui_we_want_to_set,
@@ -107,11 +144,11 @@ def shell_pip_install(ui_we_want_to_set: EditorMain, pip_install_command_list: l
107
144
  if press_ok:
108
145
  pip_install_shell = ShellManager(main_window=widget, shell_encoding=ui_we_want_to_set.encoding)
109
146
  pip_install_shell.later_init()
110
- pip_install_shell.exec_shell(
111
- pip_install_command_list
112
- )
147
+ pip_install_shell.exec_shell(pip_install_command_list)
113
148
 
114
149
 
150
+ # 偵測 venv 是否存在
151
+ # Detect if venv exists
115
152
  def detect_venv() -> bool:
116
153
  jeditor_logger.info("build_venv_menu.py detect_venv")
117
154
  venv_path = Path(os.getcwd() + "/venv")
@@ -120,15 +157,20 @@ def detect_venv() -> bool:
120
157
  message_box.setText(language_wrapper.language_word_dict.get("python_env_menu_please_create_venv"))
121
158
  message_box.exec()
122
159
  return False
123
- return True
160
+ else:
161
+ return True
124
162
 
125
163
 
164
+ # pip 安裝或更新套件
165
+ # pip install or update package
126
166
  def pip_install_package_update(ui_we_want_to_set: EditorMain) -> None:
127
167
  jeditor_logger.info(f"build_venv_menu.py pip_install_package_update ui_we_want_to_set: {ui_we_want_to_set}")
128
168
  widget = ui_we_want_to_set.tab_widget.currentWidget()
129
169
  if isinstance(widget, EditorWidget):
130
170
  widget.python_compiler = ui_we_want_to_set.python_compiler
131
- if detect_venv:
171
+ if detect_venv():
172
+ # 彈出輸入框,讓使用者輸入要安裝或更新的套件名稱
173
+ # Ask user to input package name to install or update
132
174
  ask_package_dialog = QInputDialog()
133
175
  package_text, press_ok = ask_package_dialog.getText(
134
176
  ui_we_want_to_set,
@@ -136,20 +178,29 @@ def pip_install_package_update(ui_we_want_to_set: EditorMain) -> None:
136
178
  language_wrapper.language_word_dict.get("python_env_menu_install_or_update_package_messagebox_label")
137
179
  )
138
180
  if press_ok:
139
- pip_install_shell = ShellManager(main_window=widget, after_done_function=widget.code_edit.check_env,
140
- shell_encoding=ui_we_want_to_set.encoding)
181
+ # 使用 ShellManager 執行 pip install -U
182
+ # Use ShellManager to run pip install -U
183
+ pip_install_shell = ShellManager(
184
+ main_window=widget,
185
+ after_done_function=widget.code_edit.check_env,
186
+ shell_encoding=ui_we_want_to_set.encoding
187
+ )
141
188
  pip_install_shell.later_init()
142
189
  pip_install_shell.exec_shell(
143
190
  [f"{pip_install_shell.compiler_path}", "-m", "pip", "install", f"{package_text}", "-U"]
144
191
  )
145
192
 
146
193
 
194
+ # pip 安裝套件 (不加 -U)
195
+ # pip install package (without -U)
147
196
  def pip_install_package(ui_we_want_to_set: EditorMain) -> None:
148
197
  jeditor_logger.info(f"build_venv_menu.py pip_install_package ui_we_want_to_set: {ui_we_want_to_set}")
149
198
  widget = ui_we_want_to_set.tab_widget.currentWidget()
150
199
  if isinstance(widget, EditorWidget):
151
200
  widget.python_compiler = ui_we_want_to_set.python_compiler
152
- if detect_venv:
201
+ if detect_venv():
202
+ # 彈出輸入框,讓使用者輸入要安裝的套件名稱
203
+ # Ask user to input package name
153
204
  ask_package_dialog = QInputDialog()
154
205
  package_text, press_ok = ask_package_dialog.getText(
155
206
  ui_we_want_to_set,
@@ -157,14 +208,21 @@ def pip_install_package(ui_we_want_to_set: EditorMain) -> None:
157
208
  language_wrapper.language_word_dict.get("python_env_menu_install_package_messagebox_label")
158
209
  )
159
210
  if press_ok:
160
- pip_install_shell = ShellManager(main_window=widget, after_done_function=widget.code_edit.check_env,
161
- shell_encoding=ui_we_want_to_set.encoding)
211
+ # 使用 ShellManager 執行 pip install
212
+ # Use ShellManager to run pip install
213
+ pip_install_shell = ShellManager(
214
+ main_window=widget,
215
+ after_done_function=widget.code_edit.check_env,
216
+ shell_encoding=ui_we_want_to_set.encoding
217
+ )
162
218
  pip_install_shell.later_init()
163
219
  pip_install_shell.exec_shell(
164
220
  [f"{pip_install_shell.compiler_path}", "-m", "pip", "install", f"{package_text}"]
165
221
  )
166
222
 
167
223
 
224
+ # 選擇 Python 解譯器
225
+ # Choose Python interpreter
168
226
  def chose_python_interpreter(ui_we_want_to_set: EditorMain):
169
227
  jeditor_logger.info(f"build_venv_menu.py chose_python_interpreter ui_we_want_to_set: {ui_we_want_to_set}")
170
228
  file_path = QFileDialog().getOpenFileName(
@@ -172,5 +230,9 @@ def chose_python_interpreter(ui_we_want_to_set: EditorMain):
172
230
  dir=str(Path.cwd())
173
231
  )[0]
174
232
  if file_path is not None and file_path != "":
233
+ # 更新主程式的 Python 解譯器路徑
234
+ # Update main editor's Python interpreter path
175
235
  ui_we_want_to_set.python_compiler = file_path
236
+ # 同時更新使用者設定,讓下次啟動時能記住
237
+ # Update user settings so it persists across sessions
176
238
  user_setting_dict.update({"python_compiler": file_path})
@@ -2,61 +2,95 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
+ # 匯入 Qt 訊息框
6
+ # Import QMessageBox for showing dialogs
5
7
  from PySide6.QtWidgets import QMessageBox
6
8
 
9
+ # 匯入執行中程序管理器,用於統一管理所有程式/除錯器/Shell 執行實例
10
+ # Import run_instance_manager for managing all running processes
7
11
  from je_editor.pyside_ui.code.running_process_manager import run_instance_manager
12
+ # 匯入編輯器元件
13
+ # Import EditorWidget
8
14
  from je_editor.pyside_ui.main_ui.editor.editor_widget import EditorWidget
15
+ # 匯入子選單建構函式 (Program / Debug / Shell)
16
+ # Import submenu builders (Program / Debug / Shell)
9
17
  from je_editor.pyside_ui.main_ui.menu.run_menu.under_run_menu.build_debug_menu import set_debug_menu
10
18
  from je_editor.pyside_ui.main_ui.menu.run_menu.under_run_menu.build_program_menu import set_program_menu
11
19
  from je_editor.pyside_ui.main_ui.menu.run_menu.under_run_menu.build_shell_menu import set_shell_menu
20
+ # 匯入日誌紀錄器
21
+ # Import logger instance
12
22
  from je_editor.utils.logging.loggin_instance import jeditor_logger
13
23
 
14
24
  if TYPE_CHECKING:
15
25
  from je_editor.pyside_ui.main_ui.main_editor import EditorMain
26
+
27
+ # 匯入 Qt 動作
28
+ # Import QAction
16
29
  from PySide6.QtGui import QAction
17
30
 
31
+ # 匯入多語言包裝器
32
+ # Import multi-language wrapper for UI localization
18
33
  from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
19
34
 
20
35
 
36
+ # 設定 Run 選單
37
+ # Set up the Run menu
21
38
  def set_run_menu(ui_we_want_to_set: EditorMain) -> None:
22
39
  jeditor_logger.info(f"build_run_menu.py set_run_menu ui_we_want_to_set: {ui_we_want_to_set}")
40
+ # 建立 Run 選單
41
+ # Create Run menu
23
42
  ui_we_want_to_set.run_menu = ui_we_want_to_set.menu.addMenu(
24
43
  language_wrapper.language_word_dict.get("run_menu_label"))
44
+
45
+ # 加入子選單:Program / Shell / Debug
46
+ # Add submenus: Program / Shell / Debug
25
47
  set_program_menu(ui_we_want_to_set)
26
48
  set_shell_menu(ui_we_want_to_set)
27
49
  set_debug_menu(ui_we_want_to_set)
28
- # Clean result
50
+
51
+ # 清除結果
52
+ # Clear execution result
29
53
  ui_we_want_to_set.run_menu.clean_result_action = QAction(
30
54
  language_wrapper.language_word_dict.get("run_menu_clear_result_label"))
31
55
  ui_we_want_to_set.run_menu.clean_result_action.triggered.connect(
32
56
  lambda: clean_result(ui_we_want_to_set)
33
57
  )
34
58
  ui_we_want_to_set.run_menu.addAction(ui_we_want_to_set.run_menu.clean_result_action)
35
- # Close program
59
+
60
+ # 停止目前程式
61
+ # Stop current program
36
62
  ui_we_want_to_set.run_menu.stop_program_action = QAction(
37
63
  language_wrapper.language_word_dict.get("run_menu_stop_program_label"))
38
64
  ui_we_want_to_set.run_menu.stop_program_action.triggered.connect(
39
65
  lambda: stop_program(ui_we_want_to_set)
40
66
  )
41
67
  ui_we_want_to_set.run_menu.addAction(ui_we_want_to_set.run_menu.stop_program_action)
42
- # Close all program
68
+
69
+ # 停止所有程式
70
+ # Stop all programs
43
71
  ui_we_want_to_set.run_menu.stop_all_program_action = QAction(
44
72
  language_wrapper.language_word_dict.get("run_menu_stop_all_program_label"))
45
73
  ui_we_want_to_set.run_menu.stop_all_program_action.triggered.connect(
46
74
  stop_all_program
47
75
  )
48
76
  ui_we_want_to_set.run_menu.addAction(ui_we_want_to_set.run_menu.stop_all_program_action)
49
- # Run help menu
77
+
78
+ # Run 說明子選單
79
+ # Run Help submenu
50
80
  ui_we_want_to_set.run_menu.run_help_menu = ui_we_want_to_set.run_menu.addMenu(
51
81
  language_wrapper.language_word_dict.get("run_menu_run_help_label"))
52
- # Run help action
82
+
83
+ # Run 說明動作
84
+ # Run Help action
53
85
  ui_we_want_to_set.run_menu.run_help_menu.run_help_action = QAction(
54
86
  language_wrapper.language_word_dict.get("run_menu_run_help_label"))
55
87
  ui_we_want_to_set.run_menu.run_help_menu.run_help_action.triggered.connect(
56
88
  show_run_help
57
89
  )
58
90
  ui_we_want_to_set.run_menu.run_help_menu.addAction(ui_we_want_to_set.run_menu.run_help_menu.run_help_action)
59
- # Shell help action
91
+
92
+ # Shell 說明動作
93
+ # Shell Help action
60
94
  ui_we_want_to_set.run_menu.run_help_menu.shell_help_action = QAction(
61
95
  language_wrapper.language_word_dict.get("run_menu_shell_help_label"))
62
96
  ui_we_want_to_set.run_menu.run_help_menu.shell_help_action.triggered.connect(
@@ -65,29 +99,38 @@ def set_run_menu(ui_we_want_to_set: EditorMain) -> None:
65
99
  ui_we_want_to_set.run_menu.run_help_menu.addAction(ui_we_want_to_set.run_menu.run_help_menu.shell_help_action)
66
100
 
67
101
 
102
+ # 停止目前分頁的程式 / Shell / 除錯器
103
+ # Stop current tab's program / shell / debugger
68
104
  def stop_program(ui_we_want_to_set: EditorMain) -> None:
69
105
  jeditor_logger.info(f"build_run_menu.py stop_program ui_we_want_to_set: {ui_we_want_to_set}")
70
106
  widget = ui_we_want_to_set.tab_widget.currentWidget()
71
107
  if isinstance(widget, EditorWidget):
108
+ # 停止程式
72
109
  if widget.exec_program is not None:
73
110
  if widget.exec_program.process is not None:
74
111
  widget.exec_program.process.terminate()
75
112
  widget.exec_program = None
113
+ # 停止 Shell
76
114
  if widget.exec_shell is not None:
77
115
  if widget.exec_shell.process is not None:
78
116
  widget.exec_shell.process.terminate()
79
117
  widget.exec_shell = None
118
+ # 停止除錯器
80
119
  if widget.exec_python_debugger is not None:
81
120
  if widget.exec_python_debugger.process is not None:
82
121
  widget.exec_python_debugger.process.terminate()
83
122
  widget.exec_python_debugger = None
84
123
 
85
124
 
125
+ # 停止所有執行中的程式
126
+ # Stop all running programs
86
127
  def stop_all_program() -> None:
87
128
  jeditor_logger.info("build_run_menu.py stop_all_program")
88
129
  run_instance_manager.close_all_instance()
89
130
 
90
131
 
132
+ # 清除目前分頁的輸出結果
133
+ # Clear current tab's output result
91
134
  def clean_result(ui_we_want_to_set: EditorMain) -> None:
92
135
  jeditor_logger.info(f"build_run_menu.py clean_result ui_we_want_to_set: {ui_we_want_to_set}")
93
136
  widget = ui_we_want_to_set.tab_widget.currentWidget()
@@ -95,6 +138,8 @@ def clean_result(ui_we_want_to_set: EditorMain) -> None:
95
138
  widget.code_result.setPlainText("")
96
139
 
97
140
 
141
+ # 顯示 Run 說明
142
+ # Show Run help
98
143
  def show_run_help() -> None:
99
144
  jeditor_logger.info("build_run_menu.py show_run_help")
100
145
  message_box = QMessageBox()
@@ -104,6 +149,8 @@ def show_run_help() -> None:
104
149
  message_box.exec()
105
150
 
106
151
 
152
+ # 顯示 Shell 說明
153
+ # Show Shell help
107
154
  def show_shell_help() -> None:
108
155
  jeditor_logger.info("build_run_menu.py show_shell_help")
109
156
  message_box = QMessageBox()
@@ -1,34 +1,64 @@
1
+ # 匯入未來功能,允許延遲型別註解 (Python 3.7+ 常用)
2
+ # Import future feature: postponed evaluation of type annotations
1
3
  from __future__ import annotations
2
4
 
5
+ # 僅用於型別檢查,避免循環匯入
6
+ # For type checking only (avoids circular imports)
3
7
  from typing import TYPE_CHECKING
4
8
 
9
+ # 匯入編輯器元件與輸入處理
10
+ # Import EditorWidget and ProcessInput
5
11
  from je_editor.pyside_ui.main_ui.editor.editor_widget import EditorWidget
6
12
  from je_editor.pyside_ui.main_ui.editor.process_input import ProcessInput
13
+ # 匯入工具函式:顯示「請先關閉目前執行中的程式」訊息框
14
+ # Import utility: show message box if a program is already running
7
15
  from je_editor.pyside_ui.main_ui.menu.run_menu.under_run_menu.utils import please_close_current_running_messagebox
16
+ # 匯入日誌紀錄器
17
+ # Import logger instance
8
18
  from je_editor.utils.logging.loggin_instance import jeditor_logger
9
19
 
20
+ # 僅在型別檢查時匯入 EditorMain,避免循環依賴
21
+ # Import EditorMain only for type checking (avoids circular dependency)
10
22
  if TYPE_CHECKING:
11
23
  from je_editor.pyside_ui.main_ui.main_editor import EditorMain
24
+
25
+ # 匯入 Qt 動作
26
+ # Import QAction
12
27
  from PySide6.QtGui import QAction
13
28
 
29
+ # 匯入程式執行管理器 (ExecManager)
30
+ # Import ExecManager for running/debugging code
14
31
  from je_editor.pyside_ui.code.code_process.code_exec import ExecManager
32
+
33
+ # 匯入檔案儲存對話框
34
+ # Import file save dialog
15
35
  from je_editor.pyside_ui.dialog.file_dialog.save_file_dialog import choose_file_get_save_file_path
36
+
37
+ # 匯入多語言包裝器
38
+ # Import multi-language wrapper for UI localization
16
39
  from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
17
40
 
18
41
 
42
+ # 設定 Debug 選單
43
+ # Set up the Debug menu
19
44
  def set_debug_menu(ui_we_want_to_set: EditorMain) -> None:
20
45
  jeditor_logger.info(f"build_debug_menu.py set_debug_menu ui_we_want_to_set: {ui_we_want_to_set}")
21
- # Debug menu inside run menu
46
+ # Run 選單下建立 Debug 子選單
47
+ # Create Debug submenu under Run menu
22
48
  ui_we_want_to_set.debug_menu = ui_we_want_to_set.run_menu.addMenu(
23
49
  language_wrapper.language_word_dict.get("editor_debugger_input_title_label"))
24
- # Run debugger
50
+
51
+ # 建立「執行除錯器」動作
52
+ # Add "Run Debugger" action
25
53
  ui_we_want_to_set.debug_menu.run_debugger_action = QAction(
26
54
  language_wrapper.language_word_dict.get("run_menu_run_debugger"))
27
55
  ui_we_want_to_set.debug_menu.run_debugger_action.triggered.connect(
28
56
  lambda: run_debugger(ui_we_want_to_set)
29
57
  )
30
58
  ui_we_want_to_set.debug_menu.addAction(ui_we_want_to_set.debug_menu.run_debugger_action)
31
- # Show debugger input
59
+
60
+ # 建立「顯示除錯輸入」動作
61
+ # Add "Show Debugger Input" action
32
62
  ui_we_want_to_set.debug_menu.show_shell_input = QAction(
33
63
  language_wrapper.language_word_dict.get("show_debugger_input"))
34
64
  ui_we_want_to_set.debug_menu.show_shell_input.triggered.connect(
@@ -37,26 +67,40 @@ def set_debug_menu(ui_we_want_to_set: EditorMain) -> None:
37
67
  ui_we_want_to_set.debug_menu.addAction(ui_we_want_to_set.debug_menu.show_shell_input)
38
68
 
39
69
 
70
+ # 執行除錯器 (pdb)
71
+ # Run debugger (pdb)
40
72
  def run_debugger(ui_we_want_to_set: EditorMain) -> None:
41
73
  jeditor_logger.info(f"build_debug_menu.py run_debugger ui_we_want_to_set: {ui_we_want_to_set}")
42
74
  widget = ui_we_want_to_set.tab_widget.currentWidget()
43
75
  if isinstance(widget, EditorWidget):
76
+ # 確保沒有正在執行的除錯器
77
+ # Ensure no debugger is already running
44
78
  if widget.exec_python_debugger is None:
45
79
  widget.python_compiler = ui_we_want_to_set.python_compiler
80
+ # 要求使用者選擇儲存檔案路徑
81
+ # Ask user to choose save file path
46
82
  if choose_file_get_save_file_path(ui_we_want_to_set):
83
+ # 建立程式執行管理器,並以 pdb 模式執行
84
+ # Create ExecManager and run with pdb
47
85
  code_exec = ExecManager(widget, program_encoding=ui_we_want_to_set.encoding)
48
86
  code_exec.later_init()
49
87
  code_exec.code_result = widget.debugger_result
50
88
  code_exec.exec_code(
51
89
  widget.current_file, exec_prefix=["-m", "pdb"]
52
90
  )
91
+ # 綁定除錯器與輸入介面
92
+ # Bind debugger and input interface
53
93
  widget.exec_python_debugger = code_exec
54
94
  widget.debugger_input = ProcessInput(widget)
55
95
  widget.debugger_input.show()
56
96
  else:
97
+ # 如果已有程式在執行,顯示提示訊息
98
+ # If a program is already running, show message
57
99
  please_close_current_running_messagebox(ui_we_want_to_set)
58
100
 
59
101
 
102
+ # 顯示除錯輸入介面
103
+ # Show debugger input interface
60
104
  def show_debugger_input(ui_we_want_to_set: EditorMain) -> None:
61
105
  jeditor_logger.info(f"build_debug_menu.py show_debugger_input ui_we_want_to_set: {ui_we_want_to_set}")
62
106
  widget = ui_we_want_to_set.tab_widget.currentWidget()