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