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,80 +1,103 @@
1
- from __future__ import annotations
1
+ from __future__ import annotations # 啟用未來版本的型別註解功能 / Enable postponed evaluation of type annotations
2
2
 
3
- from typing import TYPE_CHECKING
3
+ from typing import TYPE_CHECKING # 僅在型別檢查時使用,避免循環匯入 / Used only for type checking to avoid circular imports
4
4
 
5
- from je_editor.pyside_ui.main_ui.editor.editor_widget import EditorWidget
6
- from je_editor.utils.logging.loggin_instance import jeditor_logger
7
- from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
5
+ from je_editor.pyside_ui.main_ui.editor.editor_widget import EditorWidget # 編輯器分頁元件 / Editor tab widget
6
+ from je_editor.utils.logging.loggin_instance import jeditor_logger # 專案內的日誌紀錄器 / Project logger
7
+ from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper # 多語系支援 / Multi-language wrapper
8
8
 
9
9
  if TYPE_CHECKING:
10
- from je_editor.pyside_ui.main_ui.main_editor import EditorMain
11
- from PySide6.QtGui import QAction, QKeySequence
12
- from yapf.yapflib.yapf_api import FormatCode
10
+ from je_editor.pyside_ui.main_ui.main_editor import EditorMain # 僅在型別檢查時匯入 / Import only for type checking
13
11
 
14
- from je_editor.utils.json_format.json_process import reformat_json
12
+ from PySide6.QtGui import QAction, QKeySequence # Qt 動作與快捷鍵 / Qt actions and shortcuts
13
+ from yapf.yapflib.yapf_api import FormatCode # YAPF 程式碼格式化工具 / YAPF code formatter
14
+
15
+ from je_editor.utils.json_format.json_process import reformat_json # JSON 格式化工具 / JSON reformatter
15
16
 
16
17
 
17
18
  def set_check_menu(ui_we_want_to_set: EditorMain) -> None:
19
+ """
20
+ 建立「程式碼檢查/格式化」選單,並加入三個功能:
21
+ - 使用 YAPF 重新格式化 Python 程式碼
22
+ - 重新格式化 JSON
23
+ - 檢查 Python 檔案格式
24
+
25
+ Create "Check/Format Code" menu with three actions:
26
+ - Reformat Python code with YAPF
27
+ - Reformat JSON
28
+ - Check Python file format
29
+ """
18
30
  jeditor_logger.info(f"build_check_style_menu.py set_check_menu ui_we_want_to_set: {ui_we_want_to_set}")
31
+
32
+ # 在主選單中新增一個子選單 / Add submenu to main menu
19
33
  ui_we_want_to_set.check_menu = ui_we_want_to_set.menu.addMenu(
20
34
  language_wrapper.language_word_dict.get("check_code_style_menu_label"))
21
- # Yapf code check
35
+
36
+ # === 1. Yapf Python 程式碼格式化 / Yapf Python code reformat ===
22
37
  ui_we_want_to_set.check_menu.yapf_check_python_action = QAction(
23
38
  language_wrapper.language_word_dict.get("yapf_reformat_label"))
24
39
  ui_we_want_to_set.check_menu.yapf_check_python_action.setShortcut(
25
- QKeySequence("Ctrl+Shift+Y"))
40
+ QKeySequence("Ctrl+Shift+Y")) # 設定快捷鍵 / Set shortcut
26
41
  ui_we_want_to_set.check_menu.yapf_check_python_action.triggered.connect(
27
- lambda: yapf_check_python_code(
28
- ui_we_want_to_set
29
- )
42
+ lambda: yapf_check_python_code(ui_we_want_to_set)
30
43
  )
31
44
  ui_we_want_to_set.check_menu.addAction(ui_we_want_to_set.check_menu.yapf_check_python_action)
32
- # Reformat JSON
45
+
46
+ # === 2. JSON 重新格式化 / Reformat JSON ===
33
47
  ui_we_want_to_set.check_menu.reformat_json_action = QAction(
34
48
  language_wrapper.language_word_dict.get("reformat_json_label"))
35
49
  ui_we_want_to_set.check_menu.reformat_json_action.setShortcut("Ctrl+j")
36
50
  ui_we_want_to_set.check_menu.reformat_json_action.triggered.connect(
37
- lambda: reformat_json_text(
38
- ui_we_want_to_set
39
- )
51
+ lambda: reformat_json_text(ui_we_want_to_set)
40
52
  )
41
53
  ui_we_want_to_set.check_menu.addAction(ui_we_want_to_set.check_menu.reformat_json_action)
42
- # Python formate check
54
+
55
+ # === 3. Python 格式檢查 / Python format check ===
43
56
  ui_we_want_to_set.check_menu.check_python_format = QAction(
44
57
  language_wrapper.language_word_dict.get("python_format_checker"))
45
58
  ui_we_want_to_set.check_menu.check_python_format.setShortcut("Ctrl+Alt+p")
46
59
  ui_we_want_to_set.check_menu.check_python_format.triggered.connect(
47
- lambda: check_python_format(
48
- ui_we_want_to_set
49
- )
60
+ lambda: check_python_format(ui_we_want_to_set)
50
61
  )
51
62
  ui_we_want_to_set.check_menu.addAction(ui_we_want_to_set.check_menu.check_python_format)
52
63
 
53
64
 
54
65
  def yapf_check_python_code(ui_we_want_to_set: EditorMain) -> None:
66
+ """
67
+ 使用 YAPF 重新格式化目前分頁中的 Python 程式碼
68
+ Reformat current tab's Python code using YAPF
69
+ """
55
70
  jeditor_logger.info(f"build_check_style_menu.py yapf_check_python_code ui_we_want_to_set: {ui_we_want_to_set}")
56
71
  widget = ui_we_want_to_set.tab_widget.currentWidget()
57
72
  if isinstance(widget, EditorWidget):
58
- code_text = widget.code_edit.toPlainText()
59
- widget.code_result.setPlainText("")
73
+ code_text = widget.code_edit.toPlainText() # 取得編輯器文字 / Get code text
74
+ widget.code_result.setPlainText("") # 清空結果區域 / Clear result area
60
75
  format_code = FormatCode(
61
76
  unformatted_source=code_text,
62
- style_config="google"
77
+ style_config="google" # 使用 Google 風格 / Use Google style
63
78
  )
64
79
  if isinstance(format_code, tuple):
65
- widget.code_edit.setPlainText(format_code[0])
80
+ widget.code_edit.setPlainText(format_code[0]) # 將格式化後的程式碼寫回編輯器 / Write formatted code back
66
81
 
67
82
 
68
83
  def reformat_json_text(ui_we_want_to_set: EditorMain) -> None:
84
+ """
85
+ 重新格式化目前分頁中的 JSON 文字
86
+ Reformat JSON text in the current editor tab
87
+ """
69
88
  jeditor_logger.info(f"build_check_style_menu.py reformat_json_text ui_we_want_to_set: {ui_we_want_to_set}")
70
89
  widget = ui_we_want_to_set.tab_widget.currentWidget()
71
90
  if isinstance(widget, EditorWidget):
72
91
  code_text = widget.code_edit.toPlainText()
73
92
  widget.code_result.setPlainText("")
74
- widget.code_edit.setPlainText(reformat_json(code_text))
93
+ widget.code_edit.setPlainText(reformat_json(code_text)) # 呼叫 JSON 格式化工具 / Call JSON reformatter
75
94
 
76
95
 
77
96
  def check_python_format(ui_we_want_to_set: EditorMain) -> None:
97
+ """
98
+ 呼叫 EditorWidget 的檔案格式檢查功能
99
+ Call EditorWidget's file format checker
100
+ """
78
101
  jeditor_logger.info(f"build_check_style_menu.py check_python_format ui_we_want_to_set: {ui_we_want_to_set}")
79
102
  widget = ui_we_want_to_set.tab_widget.currentWidget()
80
103
  if isinstance(widget, EditorWidget):
@@ -1,4 +1,4 @@
1
- from __future__ import annotations
1
+ from __future__ import annotations # 啟用未來版本的型別註解功能 / Enable postponed evaluation of type annotations
2
2
 
3
3
  from pathlib import Path
4
4
  from typing import TYPE_CHECKING
@@ -6,53 +6,63 @@ from typing import TYPE_CHECKING
6
6
  from PySide6.QtCore import Qt
7
7
  from PySide6.QtGui import QAction
8
8
  from PySide6.QtWidgets import QFileDialog
9
- from frontengine import FrontEngineMainUI
9
+ from frontengine import FrontEngineMainUI # 外部模組 FrontEngine 的主 UI / External FrontEngine main UI
10
10
 
11
- from je_editor.pyside_ui.browser.browser_widget import BrowserWidget
11
+ from je_editor.pyside_ui.browser.main_browser_widget import MainBrowserWidget
12
+ from je_editor.pyside_ui.code.variable_inspector.inspector_gui import VariableInspector
13
+ # 匯入專案內的各種 Dockable widget / Import various dockable widgets from project
14
+ from je_editor.pyside_ui.git_ui.code_diff_compare.code_diff_viewer_widget import DiffViewerWidget
15
+ from je_editor.pyside_ui.git_ui.git_client.git_branch_tree_widget import GitTreeViewGUI
16
+ from je_editor.pyside_ui.git_ui.git_client.git_client_gui import GitGui
17
+ from je_editor.pyside_ui.main_ui.ai_widget.chat_ui import ChatUI
18
+ from je_editor.pyside_ui.main_ui.console_widget.console_gui import ConsoleWidget
12
19
  from je_editor.pyside_ui.main_ui.dock.destroy_dock import DestroyDock
13
20
  from je_editor.pyside_ui.main_ui.editor.editor_widget_dock import FullEditorWidget
14
21
  from je_editor.pyside_ui.main_ui.ipython_widget.rich_jupyter import IpythonWidget
15
- from je_editor.utils.file.open.open_file import read_file
16
- from je_editor.utils.logging.loggin_instance import jeditor_logger
17
- from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
22
+ from je_editor.utils.file.open.open_file import read_file # 檔案讀取工具 / File reading utility
23
+ from je_editor.utils.logging.loggin_instance import jeditor_logger # 日誌紀錄器 / Logger
24
+ from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper # 多語系支援 / Multi-language wrapper
18
25
 
19
26
  if TYPE_CHECKING:
20
- from je_editor.pyside_ui.main_ui.main_editor import EditorMain
27
+ from je_editor.pyside_ui.main_ui.main_editor import EditorMain # 僅在型別檢查時匯入 / Import only for type checking
21
28
 
22
29
 
23
30
  def set_dock_menu(ui_we_want_to_set: EditorMain) -> None:
31
+ """
32
+ 建立 Dock 功能選單,並加入各種 Dock 視窗的動作 (Action)。
33
+ Create the Dock menu and add actions for different dockable widgets.
34
+ """
24
35
  jeditor_logger.info(f"build_dock_menu.py set_dock_menu ui_we_want_to_set: {ui_we_want_to_set}")
25
- # Browser
36
+
37
+ # === 建立 Dock 主選單 / Create Dock main menu ===
26
38
  ui_we_want_to_set.dock_menu = ui_we_want_to_set.menu.addMenu(
27
39
  language_wrapper.language_word_dict.get("dock_menu_label"))
40
+
41
+ # === Browser Dock ===
28
42
  ui_we_want_to_set.dock_menu.new_dock_browser_action = QAction(
29
43
  language_wrapper.language_word_dict.get("dock_browser_label"))
30
44
  ui_we_want_to_set.dock_menu.new_dock_browser_action.triggered.connect(
31
45
  lambda: add_dock_widget(ui_we_want_to_set)
32
46
  )
33
47
  ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_dock_browser_action)
34
- # Stackoverflow
35
- ui_we_want_to_set.dock_menu.new_dock_stackoverflow_action = QAction(
36
- language_wrapper.language_word_dict.get("dock_stackoverflow_label"))
37
- ui_we_want_to_set.dock_menu.new_dock_stackoverflow_action.triggered.connect(
38
- lambda: add_dock_widget(ui_we_want_to_set, "stackoverflow")
39
- )
40
- ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_dock_stackoverflow_action)
41
- # Editor
48
+
49
+ # === Editor Dock ===
42
50
  ui_we_want_to_set.dock_menu.new_tab_dock_editor_action = QAction(
43
51
  language_wrapper.language_word_dict.get("dock_editor_label"))
44
52
  ui_we_want_to_set.dock_menu.new_tab_dock_editor_action.triggered.connect(
45
53
  lambda: add_dock_widget(ui_we_want_to_set, "editor")
46
54
  )
47
55
  ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_tab_dock_editor_action)
48
- # FrontEngine
56
+
57
+ # === FrontEngine Dock ===
49
58
  ui_we_want_to_set.dock_menu.new_frontengine = QAction(
50
59
  language_wrapper.language_word_dict.get("dock_frontengine_label"))
51
60
  ui_we_want_to_set.dock_menu.new_frontengine.triggered.connect(
52
61
  lambda: add_dock_widget(ui_we_want_to_set, "frontengine")
53
62
  )
54
63
  ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_frontengine)
55
- # Ipython
64
+
65
+ # === Ipython Dock ===
56
66
  ui_we_want_to_set.dock_menu.new_ipython = QAction(
57
67
  language_wrapper.language_word_dict.get("dock_ipython_label"))
58
68
  ui_we_want_to_set.dock_menu.new_ipython.triggered.connect(
@@ -60,38 +70,139 @@ def set_dock_menu(ui_we_want_to_set: EditorMain) -> None:
60
70
  )
61
71
  ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_ipython)
62
72
 
73
+ # === ChatUI Dock ===
74
+ ui_we_want_to_set.dock_menu.new_chat_ui = QAction(
75
+ language_wrapper.language_word_dict.get("chat_ui_dock_label"))
76
+ ui_we_want_to_set.dock_menu.new_chat_ui.triggered.connect(
77
+ lambda: add_dock_widget(ui_we_want_to_set, "chat_ui")
78
+ )
79
+ ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_chat_ui)
80
+
81
+ # === Git Client Dock ===
82
+ ui_we_want_to_set.dock_menu.new_git_client = QAction(
83
+ language_wrapper.language_word_dict.get("tab_menu_git_client_tab_name"))
84
+ ui_we_want_to_set.dock_menu.new_git_client.triggered.connect(
85
+ lambda: add_dock_widget(ui_we_want_to_set, "git_client")
86
+ )
87
+ ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_git_client)
88
+
89
+ # === Git Branch Tree View Dock ===
90
+ ui_we_want_to_set.dock_menu.new_git_branch_view = QAction(
91
+ language_wrapper.language_word_dict.get("tab_menu_git_branch_tree_view_tab_name"))
92
+ ui_we_want_to_set.dock_menu.new_git_branch_view.triggered.connect(
93
+ lambda: add_dock_widget(ui_we_want_to_set, "git_branch_tree_view")
94
+ )
95
+ ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_git_branch_view)
96
+
97
+ # === Variable Inspector Dock ===
98
+ ui_we_want_to_set.dock_menu.new_variable_inspector = QAction(
99
+ language_wrapper.language_word_dict.get("tab_menu_variable_inspector_tab_name"))
100
+ ui_we_want_to_set.dock_menu.new_variable_inspector.triggered.connect(
101
+ lambda: add_dock_widget(ui_we_want_to_set, "variable_inspector")
102
+ )
103
+ ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_variable_inspector)
104
+
105
+ # === Console Dock ===
106
+ ui_we_want_to_set.dock_menu.new_dynamic_console = QAction(
107
+ language_wrapper.language_word_dict.get("tab_menu_console_widget_tab_name"))
108
+ ui_we_want_to_set.dock_menu.new_dynamic_console.triggered.connect(
109
+ lambda: add_dock_widget(ui_we_want_to_set, "console_widget")
110
+ )
111
+ ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_dynamic_console)
112
+
113
+ # === Code Diff Viewer Dock ===
114
+ ui_we_want_to_set.dock_menu.new_code_diff_viewer = QAction(
115
+ language_wrapper.language_word_dict.get("tab_code_diff_viewer_tab_name"))
116
+ ui_we_want_to_set.dock_menu.new_code_diff_viewer.triggered.connect(
117
+ lambda: add_dock_widget(ui_we_want_to_set, "code_diff_viewer")
118
+ )
119
+ ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_code_diff_viewer)
120
+
63
121
 
64
122
  def add_dock_widget(ui_we_want_to_set: EditorMain, widget_type: str = None):
123
+ """
124
+ 根據 widget_type 新增對應的 Dock 視窗,並加到主視窗右側。
125
+ Add a dock widget based on widget_type and attach it to the right side of the main window.
126
+ """
65
127
  jeditor_logger.info("build_dock_menu.py add_dock_widget "
66
128
  f"ui_we_want_to_set: {ui_we_want_to_set} "
67
129
  f"widget_type: {widget_type}")
68
- # Dock widget
130
+
131
+ # 建立一個可銷毀的 Dock 容器
132
+ # Create a destroyable dock container
69
133
  dock_widget = DestroyDock()
70
- if widget_type == "stackoverflow":
71
- dock_widget.setWindowTitle("stackoverflow")
72
- dock_widget.setWidget(BrowserWidget(
73
- start_url="https://stackoverflow.com/", search_prefix="https://stackoverflow.com/search?q="))
74
- elif widget_type == "editor":
134
+
135
+ if widget_type == "editor":
136
+ # 開啟檔案選擇對話框,讓使用者選擇要打開的檔案
137
+ # Open file dialog for selecting a file
75
138
  file_path = QFileDialog().getOpenFileName(
76
139
  parent=ui_we_want_to_set,
77
- dir=str(Path.cwd())
140
+ dir=str(Path.cwd()) # 預設目錄為當前工作目錄 / Default directory is current working directory
78
141
  )[0]
79
142
  if file_path is not None and file_path != "":
143
+ # 建立一個完整的編輯器 Dock,並載入檔案內容
144
+ # Create a full editor dock and load file content
80
145
  widget = FullEditorWidget(current_file=file_path)
81
- file_content = read_file(file_path)[1]
82
- widget.code_edit.setPlainText(
83
- file_content
84
- )
146
+ file_content = read_file(file_path)[1] # 讀取檔案內容 / Read file content
147
+ widget.code_edit.setPlainText(file_content)
85
148
  dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("dock_editor_title"))
86
149
  dock_widget.setWidget(widget)
150
+
87
151
  elif widget_type == "frontengine":
152
+ # 建立 FrontEngine Dock
153
+ # Create FrontEngine dock
88
154
  dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("dock_frontengine_title"))
89
155
  dock_widget.setWidget(FrontEngineMainUI(redirect_output=False))
156
+
90
157
  elif widget_type == "ipython":
158
+ # 建立 Ipython 互動式控制台 Dock
159
+ # Create Ipython interactive console dock
91
160
  dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("dock_ipython_title"))
92
161
  dock_widget.setWidget(IpythonWidget(ui_we_want_to_set))
162
+
163
+ elif widget_type == "chat_ui":
164
+ # 建立 ChatUI Dock
165
+ # Create ChatUI dock
166
+ dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("chat_ui_dock_label"))
167
+ dock_widget.setWidget(ChatUI(ui_we_want_to_set))
168
+
169
+ elif widget_type == "git_client":
170
+ # 建立 Git 客戶端 Dock
171
+ # Create Git client dock
172
+ dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("tab_menu_git_client_tab_name"))
173
+ dock_widget.setWidget(GitGui())
174
+
175
+ elif widget_type == "git_branch_tree_view":
176
+ # 建立 Git 分支樹視圖 Dock
177
+ # Create Git branch tree view dock
178
+ dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("tab_menu_git_branch_tree_view_tab_name"))
179
+ dock_widget.setWidget(GitTreeViewGUI())
180
+
181
+ elif widget_type == "variable_inspector":
182
+ # 建立變數檢查器 Dock
183
+ # Create variable inspector dock
184
+ dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("tab_menu_variable_inspector_tab_name"))
185
+ dock_widget.setWidget(VariableInspector())
186
+
187
+ elif widget_type == "console_widget":
188
+ # 建立動態 Console Dock
189
+ # Create dynamic console dock
190
+ dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("tab_menu_console_widget_tab_name"))
191
+ dock_widget.setWidget(ConsoleWidget())
192
+
193
+ elif widget_type == "code_diff_viewer":
194
+ # 建立程式碼差異比較視圖 Dock
195
+ # Create code diff viewer dock
196
+ dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("tab_code_diff_viewer_tab_name"))
197
+ dock_widget.setWidget(DiffViewerWidget())
198
+
93
199
  else:
200
+ # 預設為瀏覽器 Dock
201
+ # Default: Browser dock
94
202
  dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("dock_browser_title"))
95
- dock_widget.setWidget(BrowserWidget())
203
+ dock_widget.setWidget(MainBrowserWidget())
204
+
205
+ # 如果成功建立了 widget,將其加到主視窗右側 Dock 區域
206
+ # If widget is created, add it to the right dock area of the main window
96
207
  if dock_widget.widget() is not None:
97
208
  ui_we_want_to_set.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, dock_widget)
@@ -1,70 +1,100 @@
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
+ # 匯入使用者設定字典,用來保存 UI 設定
10
+ # Import user settings dictionary for saving UI preferences
5
11
  from je_editor.pyside_ui.main_ui.save_settings.user_setting_file import user_setting_dict
12
+ # 匯入 Python 編碼清單 (例如 utf-8, gbk 等)
13
+ # Import list of Python encodings (e.g., utf-8, gbk, etc.)
6
14
  from je_editor.utils.encodings.python_encodings import python_encodings_list
15
+ # 匯入日誌紀錄器
16
+ # Import logger instance
7
17
  from je_editor.utils.logging.loggin_instance import jeditor_logger
18
+ # 匯入多語言包裝器,用於 UI 多語言顯示
19
+ # Import multi-language wrapper for UI localization
8
20
  from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
9
21
 
22
+ # 僅在型別檢查時匯入 EditorMain,避免循環依賴
23
+ # Import EditorMain only for type checking (avoids circular dependency)
10
24
  if TYPE_CHECKING:
11
25
  from je_editor.pyside_ui.main_ui.main_editor import EditorMain
26
+
27
+ # 匯入 Qt 動作與字型資料庫
28
+ # Import QAction and QFontDatabase from PySide6
12
29
  from PySide6.QtGui import QAction, QFontDatabase
13
30
 
31
+ # 匯入檔案對話框 (新建、開啟、儲存)
32
+ # Import file dialogs (create, open, save)
14
33
  from je_editor.pyside_ui.dialog.file_dialog.create_file_dialog import CreateFileDialog
15
34
  from je_editor.pyside_ui.dialog.file_dialog.open_file_dialog import choose_file_get_open_file_path, \
16
35
  choose_dir_get_dir_path
17
36
  from je_editor.pyside_ui.dialog.file_dialog.save_file_dialog import choose_file_get_save_file_path
18
37
 
19
38
 
39
+ # 設定檔案選單 (File Menu)
40
+ # Set up the File menu
20
41
  def set_file_menu(ui_we_want_to_set: EditorMain) -> None:
21
42
  jeditor_logger.info("build_file_menu.py add_dock_widget "
22
43
  f"ui_we_want_to_set: {ui_we_want_to_set}")
44
+ # 建立 File 選單
45
+ # Create File menu
23
46
  ui_we_want_to_set.file_menu = ui_we_want_to_set.menu.addMenu(
24
47
  language_wrapper.language_word_dict.get("file_menu_label"))
48
+
49
+ # 新建檔案動作
50
+ # New File action
25
51
  ui_we_want_to_set.file_menu.new_file_action = QAction(
26
52
  language_wrapper.language_word_dict.get("file_menu_new_file_label"))
27
- ui_we_want_to_set.file_menu.new_file_action.setShortcut(
28
- "Ctrl+n"
29
- )
53
+ ui_we_want_to_set.file_menu.new_file_action.setShortcut("Ctrl+n")
30
54
  ui_we_want_to_set.file_menu.new_file_action.triggered.connect(
31
55
  lambda: show_create_file_dialog(ui_we_want_to_set)
32
56
  )
33
57
  ui_we_want_to_set.file_menu.addAction(ui_we_want_to_set.file_menu.new_file_action)
58
+
59
+ # 開啟檔案動作
60
+ # Open File action
34
61
  ui_we_want_to_set.file_menu.open_file_action = QAction(
35
62
  language_wrapper.language_word_dict.get("file_menu_open_file_label"))
36
- ui_we_want_to_set.file_menu.open_file_action.setShortcut(
37
- "Ctrl+o"
38
- )
63
+ ui_we_want_to_set.file_menu.open_file_action.setShortcut("Ctrl+o")
39
64
  ui_we_want_to_set.file_menu.open_file_action.triggered.connect(
40
65
  lambda: choose_file_get_open_file_path(parent_qt_instance=ui_we_want_to_set)
41
66
  )
42
67
  ui_we_want_to_set.file_menu.addAction(ui_we_want_to_set.file_menu.open_file_action)
68
+
69
+ # 開啟資料夾動作
70
+ # Open Folder action
43
71
  ui_we_want_to_set.file_menu.open_folder_action = QAction(
44
72
  language_wrapper.language_word_dict.get("file_menu_open_folder_label"))
45
- ui_we_want_to_set.file_menu.open_folder_action.setShortcut(
46
- "Ctrl+K"
47
- )
73
+ ui_we_want_to_set.file_menu.open_folder_action.setShortcut("Ctrl+K")
48
74
  ui_we_want_to_set.file_menu.open_folder_action.triggered.connect(
49
75
  lambda: choose_dir_get_dir_path(parent_qt_instance=ui_we_want_to_set)
50
76
  )
51
77
  ui_we_want_to_set.file_menu.addAction(ui_we_want_to_set.file_menu.open_folder_action)
78
+
79
+ # 儲存檔案動作
80
+ # Save File action
52
81
  ui_we_want_to_set.file_menu.save_file_action = QAction(
53
82
  language_wrapper.language_word_dict.get("file_menu_save_file_label"))
54
- ui_we_want_to_set.file_menu.save_file_action.setShortcut(
55
- "Ctrl+s"
56
- )
83
+ ui_we_want_to_set.file_menu.save_file_action.setShortcut("Ctrl+s")
57
84
  ui_we_want_to_set.file_menu.save_file_action.triggered.connect(
58
85
  lambda: choose_file_get_save_file_path(parent_qt_instance=ui_we_want_to_set)
59
86
  )
60
87
  ui_we_want_to_set.file_menu.addAction(ui_we_want_to_set.file_menu.save_file_action)
61
- # Main UI font
88
+
89
+ # 加入字型與編碼選單
90
+ # Add font and encoding menus
62
91
  add_font_menu(ui_we_want_to_set)
63
92
  add_font_size_menu(ui_we_want_to_set)
64
- # Encoding
65
93
  add_encoding_menu(ui_we_want_to_set)
66
94
 
67
95
 
96
+ # 建立編碼選單
97
+ # Add Encoding menu
68
98
  def add_encoding_menu(ui_we_want_to_set: EditorMain) -> None:
69
99
  jeditor_logger.info("build_file_menu.py add_encoding_menu "
70
100
  f"ui_we_want_to_set: {ui_we_want_to_set}")
@@ -77,6 +107,8 @@ def add_encoding_menu(ui_we_want_to_set: EditorMain) -> None:
77
107
  ui_we_want_to_set.file_menu.encoding_menu.addAction(encoding_action)
78
108
 
79
109
 
110
+ # 設定編碼
111
+ # Set encoding
80
112
  def set_encoding(ui_we_want_to_set: EditorMain, action: QAction) -> None:
81
113
  jeditor_logger.info("build_file_menu.py set_encoding "
82
114
  f"ui_we_want_to_set: {ui_we_want_to_set} "
@@ -85,6 +117,8 @@ def set_encoding(ui_we_want_to_set: EditorMain, action: QAction) -> None:
85
117
  user_setting_dict.update({"encoding": action.text()})
86
118
 
87
119
 
120
+ # 顯示新建檔案對話框
121
+ # Show Create File dialog
88
122
  def show_create_file_dialog(ui_we_want_to_set: EditorMain):
89
123
  jeditor_logger.info("build_file_menu.py show_create_file_dialog "
90
124
  f"ui_we_want_to_set: {ui_we_want_to_set}")
@@ -92,6 +126,8 @@ def show_create_file_dialog(ui_we_want_to_set: EditorMain):
92
126
  ui_we_want_to_set.create_file_dialog.show()
93
127
 
94
128
 
129
+ # 建立字型選單
130
+ # Add Font menu
95
131
  def add_font_menu(ui_we_want_to_set: EditorMain) -> None:
96
132
  jeditor_logger.info("build_file_menu.py add_font_menu "
97
133
  f"ui_we_want_to_set: {ui_we_want_to_set}")
@@ -103,6 +139,8 @@ def add_font_menu(ui_we_want_to_set: EditorMain) -> None:
103
139
  ui_we_want_to_set.file_menu.font_menu.addAction(font_action)
104
140
 
105
141
 
142
+ # 設定字型
143
+ # Set Font
106
144
  def set_font(ui_we_want_to_set: EditorMain, action: QAction) -> None:
107
145
  jeditor_logger.info("build_file_menu.py set_font "
108
146
  f"ui_we_want_to_set: {ui_we_want_to_set}")
@@ -113,24 +151,36 @@ def set_font(ui_we_want_to_set: EditorMain, action: QAction) -> None:
113
151
  user_setting_dict.update({"ui_font": action.text()})
114
152
 
115
153
 
154
+ # 建立字型大小選單
155
+ # Add Font Size menu
116
156
  def add_font_size_menu(ui_we_want_to_set: EditorMain) -> None:
117
157
  jeditor_logger.info("build_file_menu.py add_font_size_menu "
118
158
  f"ui_we_want_to_set: {ui_we_want_to_set}")
119
159
  ui_we_want_to_set.file_menu.font_size_menu = ui_we_want_to_set.file_menu.addMenu(
120
160
  language_wrapper.language_word_dict.get("file_menu_font_size_label"))
121
- for size in range(12, 38, 2):
161
+ for size in range(12, 38, 2): # 12 到 36,每次增加 2
122
162
  font_action = QAction(str(size), parent=ui_we_want_to_set.file_menu)
123
163
  font_action.triggered.connect(
124
164
  lambda checked=False, action=font_action: set_font_size(ui_we_want_to_set, action))
125
165
  ui_we_want_to_set.file_menu.font_size_menu.addAction(font_action)
126
166
 
127
167
 
168
+ # 設定字型大小
169
+ # Set Font Size
128
170
  def set_font_size(ui_we_want_to_set: EditorMain, action: QAction) -> None:
171
+ # 紀錄日誌,方便除錯與追蹤
172
+ # Log information for debugging and tracking
129
173
  jeditor_logger.info("build_file_menu.py set_font_size "
130
174
  f"ui_we_want_to_set: {ui_we_want_to_set} "
131
175
  f"action: {action}")
176
+
177
+ # 使用 Qt 的 setStyleSheet 設定整體 UI 的字型樣式
178
+ # Apply stylesheet to set the font size and keep the current font family
132
179
  ui_we_want_to_set.setStyleSheet(
133
- f"font-size: {int(action.text())}pt;"
134
- f"font-family: {ui_we_want_to_set.font().family()};"
180
+ f"font-size: {int(action.text())}pt;" # 設定字型大小 (pt)
181
+ f"font-family: {ui_we_want_to_set.font().family()};" # 保持目前的字型家族
135
182
  )
183
+
184
+ # 更新使用者設定字典,保存字型大小設定
185
+ # Update user settings dictionary to persist font size preference
136
186
  user_setting_dict.update({"ui_font_size": int(action.text())})
@@ -1,24 +1,46 @@
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
 
5
- from je_editor.pyside_ui.browser.browser_widget import BrowserWidget
9
+ # 匯入內建瀏覽器元件,用於在程式內開啟網頁
10
+ # Import embedded browser widget for opening web pages inside the app
11
+ from je_editor.pyside_ui.browser.main_browser_widget import MainBrowserWidget
12
+ # 匯入日誌紀錄器
13
+ # Import logger instance
6
14
  from je_editor.utils.logging.loggin_instance import jeditor_logger
7
15
 
16
+ # 僅在型別檢查時匯入 EditorMain,避免循環依賴
17
+ # Import EditorMain only for type checking (avoids circular dependency)
8
18
  if TYPE_CHECKING:
9
19
  from je_editor.pyside_ui.main_ui.main_editor import EditorMain
10
20
 
21
+ # 匯入 Qt 動作與訊息框
22
+ # Import QAction and QMessageBox from PySide6
11
23
  from PySide6.QtGui import QAction
12
24
  from PySide6.QtWidgets import QMessageBox
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
+ # 設定「說明」選單 (Help Menu)
32
+ # Set up the Help menu
17
33
  def set_help_menu(ui_we_want_to_set: EditorMain) -> None:
18
34
  jeditor_logger.info("build_help_menu.py set_help_menu "
19
35
  f"ui_we_want_to_set: {ui_we_want_to_set}")
36
+
37
+ # 建立 Help 選單
38
+ # Create Help menu
20
39
  ui_we_want_to_set.help_menu = ui_we_want_to_set.menu.addMenu(
21
40
  language_wrapper.language_word_dict.get("help_menu_label"))
41
+
42
+ # 建立「開啟 GitHub」動作
43
+ # Add "Open GitHub" action
22
44
  ui_we_want_to_set.help_menu.help_github_action = QAction(
23
45
  language_wrapper.language_word_dict.get("help_menu_open_github_label"))
24
46
  ui_we_want_to_set.help_menu.help_github_action.triggered.connect(
@@ -29,6 +51,8 @@ def set_help_menu(ui_we_want_to_set: EditorMain) -> None:
29
51
  )
30
52
  ui_we_want_to_set.help_menu.addAction(ui_we_want_to_set.help_menu.help_github_action)
31
53
 
54
+ # 建立「開啟文件」動作
55
+ # Add "Open Documentation" action
32
56
  ui_we_want_to_set.help_menu.help_doc_action = QAction(
33
57
  language_wrapper.language_word_dict.get("help_menu_open_doc_label"))
34
58
  ui_we_want_to_set.help_menu.help_doc_action.triggered.connect(
@@ -39,6 +63,8 @@ def set_help_menu(ui_we_want_to_set: EditorMain) -> None:
39
63
  )
40
64
  ui_we_want_to_set.help_menu.addAction(ui_we_want_to_set.help_menu.help_doc_action)
41
65
 
66
+ # 建立「關於」動作
67
+ # Add "About" action
42
68
  ui_we_want_to_set.help_menu.help_about_action = QAction(
43
69
  language_wrapper.language_word_dict.get("help_menu_open_about_label"))
44
70
  ui_we_want_to_set.help_menu.help_about_action.triggered.connect(
@@ -47,17 +73,21 @@ def set_help_menu(ui_we_want_to_set: EditorMain) -> None:
47
73
  ui_we_want_to_set.help_menu.addAction(ui_we_want_to_set.help_menu.help_about_action)
48
74
 
49
75
 
76
+ # 開啟內建瀏覽器分頁
77
+ # Open a new tab in the embedded browser
50
78
  def open_web_browser(ui_we_want_to_set: EditorMain, url: str, tab_name: str):
51
79
  jeditor_logger.info("build_help_menu.py open_web_browser "
52
80
  f"ui_we_want_to_set: {ui_we_want_to_set} "
53
81
  f"url: {url} "
54
82
  f"tab_name: {tab_name}")
55
83
  ui_we_want_to_set.tab_widget.addTab(
56
- BrowserWidget(start_url=url),
57
- f"{tab_name}{ui_we_want_to_set.tab_widget.count()}"
84
+ MainBrowserWidget(start_url=url), # 建立瀏覽器元件並載入指定 URL
85
+ f"{tab_name}{ui_we_want_to_set.tab_widget.count()}" # 分頁名稱 + 當前分頁數
58
86
  )
59
87
 
60
88
 
89
+ # 顯示「關於」訊息框
90
+ # Show "About" message box
61
91
  def show_about():
62
92
  jeditor_logger.info("build_help_menu.py show_about")
63
93
  message_box = QMessageBox()