je-editor 0.0.211__py3-none-any.whl → 0.0.212__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.
- je_editor/code_scan/ruff_thread.py +31 -0
- je_editor/code_scan/watchdog_implement.py +34 -0
- je_editor/code_scan/watchdog_thread.py +33 -0
- je_editor/pyside_ui/code/variable_inspector/inspector_gui.py +122 -0
- je_editor/pyside_ui/main_ui/console_widget/__init__.py +0 -0
- je_editor/pyside_ui/main_ui/console_widget/console_gui.py +130 -0
- je_editor/pyside_ui/main_ui/console_widget/qprocess_adapter.py +63 -0
- je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py +44 -0
- je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py +66 -7
- je_editor/utils/multi_language/english.py +79 -3
- je_editor/utils/multi_language/traditional_chinese.py +79 -7
- {je_editor-0.0.211.dist-info → je_editor-0.0.212.dist-info}/METADATA +1 -1
- {je_editor-0.0.211.dist-info → je_editor-0.0.212.dist-info}/RECORD +18 -16
- je_editor/pyside_ui/main_ui/ai_widget/ai_config.py +0 -19
- je_editor/pyside_ui/main_ui/ai_widget/ask_thread.py +0 -17
- je_editor/pyside_ui/main_ui/ai_widget/chat_ui.py +0 -130
- je_editor/pyside_ui/main_ui/ai_widget/langchain_interface.py +0 -45
- je_editor/pyside_ui/main_ui/menu/check_style_menu/build_check_style_menu.py +0 -81
- /je_editor/{pyside_ui/main_ui/ai_widget → code_scan}/__init__.py +0 -0
- /je_editor/pyside_ui/{main_ui/menu/check_style_menu → code/variable_inspector}/__init__.py +0 -0
- {je_editor-0.0.211.dist-info → je_editor-0.0.212.dist-info}/WHEEL +0 -0
- {je_editor-0.0.211.dist-info → je_editor-0.0.212.dist-info}/licenses/LICENSE +0 -0
- {je_editor-0.0.211.dist-info → je_editor-0.0.212.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
import subprocess
|
2
|
+
import threading
|
3
|
+
import time
|
4
|
+
from queue import Queue
|
5
|
+
|
6
|
+
|
7
|
+
class RuffThread(threading.Thread):
|
8
|
+
|
9
|
+
def __init__(self, ruff_commands: list, std_queue: Queue, stderr_queue: Queue):
|
10
|
+
super().__init__()
|
11
|
+
if ruff_commands is None:
|
12
|
+
self.ruff_commands = ["ruff", "check"]
|
13
|
+
else:
|
14
|
+
self.ruff_commands = ruff_commands
|
15
|
+
self.ruff_process = None
|
16
|
+
self.std_queue = std_queue
|
17
|
+
self.stderr_queue = stderr_queue
|
18
|
+
|
19
|
+
def run(self):
|
20
|
+
self.ruff_process = subprocess.Popen(
|
21
|
+
self.ruff_commands, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1)
|
22
|
+
while self.ruff_process.poll() is None:
|
23
|
+
time.sleep(1)
|
24
|
+
else:
|
25
|
+
for line in self.ruff_process.stdout:
|
26
|
+
print(line.strip())
|
27
|
+
for line in self.ruff_process.stderr:
|
28
|
+
print(line.strip())
|
29
|
+
|
30
|
+
|
31
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from queue import Queue
|
2
|
+
|
3
|
+
from watchdog.events import FileSystemEventHandler
|
4
|
+
|
5
|
+
from je_editor.code_scan.ruff_thread import RuffThread
|
6
|
+
|
7
|
+
|
8
|
+
class RuffPythonFileChangeHandler(FileSystemEventHandler):
|
9
|
+
|
10
|
+
def __init__(self, ruff_commands: list = None):
|
11
|
+
super(RuffPythonFileChangeHandler, self).__init__()
|
12
|
+
self.ruff_commands = ruff_commands
|
13
|
+
self.stdout_queue = Queue()
|
14
|
+
self.stderr_queue = Queue()
|
15
|
+
self.ruff_threads_dict = dict()
|
16
|
+
|
17
|
+
def on_modified(self, event):
|
18
|
+
if event.is_directory:
|
19
|
+
return
|
20
|
+
if event.src_path.endswith(".py"):
|
21
|
+
if self.ruff_threads_dict.get(event.src_path) is None:
|
22
|
+
ruff_thread = RuffThread(self.ruff_commands, self.stdout_queue, self.stderr_queue)
|
23
|
+
self.ruff_threads_dict.update({event.src_path: ruff_thread})
|
24
|
+
ruff_thread.start()
|
25
|
+
else:
|
26
|
+
ruff_thread = self.ruff_threads_dict.get(event.src_path)
|
27
|
+
if not ruff_thread.is_alive():
|
28
|
+
ruff_thread = RuffThread(self.ruff_commands, self.stdout_queue, self.stderr_queue)
|
29
|
+
self.ruff_threads_dict.update({event.src_path: ruff_thread})
|
30
|
+
ruff_thread.start()
|
31
|
+
else:
|
32
|
+
pass
|
33
|
+
|
34
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import threading
|
2
|
+
import time
|
3
|
+
|
4
|
+
from watchdog.observers import Observer
|
5
|
+
|
6
|
+
from je_editor.code_scan.watchdog_implement import RuffPythonFileChangeHandler
|
7
|
+
|
8
|
+
|
9
|
+
class WatchdogThread(threading.Thread):
|
10
|
+
|
11
|
+
def __init__(self, check_path: str):
|
12
|
+
super().__init__()
|
13
|
+
self.check_path = check_path
|
14
|
+
self.ruff_handler = RuffPythonFileChangeHandler()
|
15
|
+
self.running = True
|
16
|
+
|
17
|
+
def run(self):
|
18
|
+
observer = Observer()
|
19
|
+
observer.schedule(self.ruff_handler, str(self.check_path), recursive=True)
|
20
|
+
observer.start()
|
21
|
+
try:
|
22
|
+
while self.running:
|
23
|
+
time.sleep(1)
|
24
|
+
finally:
|
25
|
+
observer.stop()
|
26
|
+
|
27
|
+
|
28
|
+
if __name__ == '__main__':
|
29
|
+
watchdog_thread = WatchdogThread(".")
|
30
|
+
watchdog_thread.start()
|
31
|
+
while True:
|
32
|
+
time.sleep(1)
|
33
|
+
|
@@ -0,0 +1,122 @@
|
|
1
|
+
import ast
|
2
|
+
|
3
|
+
from PySide6.QtCore import QAbstractTableModel, Qt, QTimer, QSortFilterProxyModel
|
4
|
+
from PySide6.QtWidgets import QTableView, QVBoxLayout, QWidget, QLineEdit, QLabel
|
5
|
+
|
6
|
+
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
|
7
|
+
|
8
|
+
|
9
|
+
class VariableModel(QAbstractTableModel):
|
10
|
+
def __init__(self, parent=None):
|
11
|
+
super().__init__(parent)
|
12
|
+
self.variables = []
|
13
|
+
|
14
|
+
def update_data(self):
|
15
|
+
parent_widget = self.parent()
|
16
|
+
if parent_widget and getattr(parent_widget, "table", None):
|
17
|
+
if parent_widget.table.state() != QTableView.State.NoState:
|
18
|
+
return
|
19
|
+
|
20
|
+
vars_dict = globals()
|
21
|
+
self.beginResetModel()
|
22
|
+
self.variables = [
|
23
|
+
[name, type(value).__name__, repr(value), value]
|
24
|
+
for name, value in vars_dict.items()
|
25
|
+
if not name.startswith("__") # 過濾內建變數
|
26
|
+
]
|
27
|
+
self.endResetModel()
|
28
|
+
|
29
|
+
def rowCount(self, parent=None):
|
30
|
+
return len(self.variables)
|
31
|
+
|
32
|
+
def columnCount(self, parent=None):
|
33
|
+
return 3
|
34
|
+
|
35
|
+
def data(self, index, role=Qt.ItemDataRole.DisplayRole):
|
36
|
+
if not index.isValid() or not (0 <= index.row() < len(self.variables)):
|
37
|
+
return None
|
38
|
+
if role == Qt.ItemDataRole.DisplayRole:
|
39
|
+
return self.variables[index.row()][index.column()]
|
40
|
+
return None
|
41
|
+
|
42
|
+
def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole):
|
43
|
+
if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
|
44
|
+
return [
|
45
|
+
language_wrapper.language_word_dict.get("variable_inspector_var_name"),
|
46
|
+
language_wrapper.language_word_dict.get("variable_inspector_var_type"),
|
47
|
+
language_wrapper.language_word_dict.get("variable_inspector_var_value")
|
48
|
+
][section]
|
49
|
+
return None
|
50
|
+
|
51
|
+
def flags(self, index):
|
52
|
+
if not index.isValid() or not (0 <= index.row() < len(self.variables)):
|
53
|
+
return Qt.ItemFlag.NoItemFlags
|
54
|
+
base = super().flags(index)
|
55
|
+
if index.column() == 2: # 只允許編輯值欄
|
56
|
+
base |= Qt.ItemFlag.ItemIsEditable
|
57
|
+
return base
|
58
|
+
|
59
|
+
def setData(self, index, value, role=Qt.ItemDataRole.EditRole):
|
60
|
+
if role == Qt.ItemDataRole.EditRole and index.column() == 2:
|
61
|
+
|
62
|
+
if value == "":
|
63
|
+
return False
|
64
|
+
|
65
|
+
old_repr = self.variables[index.row()][2]
|
66
|
+
if str(value) == old_repr:
|
67
|
+
return False
|
68
|
+
|
69
|
+
var_name = self.variables[index.row()][0]
|
70
|
+
try:
|
71
|
+
new_value = ast.literal_eval(value)
|
72
|
+
except Exception:
|
73
|
+
new_value = value
|
74
|
+
|
75
|
+
if new_value == self.variables[index.row()][3]:
|
76
|
+
return False
|
77
|
+
|
78
|
+
globals()[var_name] = new_value
|
79
|
+
self.variables[index.row()][2] = repr(new_value)
|
80
|
+
self.variables[index.row()][3] = new_value
|
81
|
+
self.dataChanged.emit(index, index, [Qt.ItemDataRole.DisplayRole])
|
82
|
+
return True
|
83
|
+
return False
|
84
|
+
|
85
|
+
class VariableProxy(QSortFilterProxyModel):
|
86
|
+
def setData(self, index, value, role=Qt.ItemDataRole.EditRole):
|
87
|
+
return self.sourceModel().setData(
|
88
|
+
self.mapToSource(index), value, role
|
89
|
+
)
|
90
|
+
|
91
|
+
class VariableInspector(QWidget):
|
92
|
+
def __init__(self):
|
93
|
+
super().__init__()
|
94
|
+
self.setWindowTitle(language_wrapper.language_word_dict.get("variable_inspector_title"))
|
95
|
+
layout = QVBoxLayout(self)
|
96
|
+
|
97
|
+
self.search_box = QLineEdit()
|
98
|
+
self.search_box.setPlaceholderText(language_wrapper.language_word_dict.get("variable_inspector_search"))
|
99
|
+
layout.addWidget(QLabel(language_wrapper.language_word_dict.get("variable_inspector_search")))
|
100
|
+
layout.addWidget(self.search_box)
|
101
|
+
|
102
|
+
self.model = VariableModel(parent=self)
|
103
|
+
self.proxy_model = VariableProxy(self)
|
104
|
+
self.proxy_model.setSourceModel(self.model)
|
105
|
+
self.proxy_model.setFilterCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
|
106
|
+
self.proxy_model.setFilterKeyColumn(0)
|
107
|
+
|
108
|
+
self.table = QTableView()
|
109
|
+
self.table.setModel(self.proxy_model)
|
110
|
+
self.table.horizontalHeader().setStretchLastSection(True)
|
111
|
+
self.table.horizontalHeader().setSectionResizeMode(
|
112
|
+
self.table.horizontalHeader().ResizeMode.Stretch
|
113
|
+
)
|
114
|
+
layout.addWidget(self.table, stretch=1)
|
115
|
+
|
116
|
+
self.search_box.textChanged.connect(
|
117
|
+
self.proxy_model.setFilterFixedString
|
118
|
+
)
|
119
|
+
|
120
|
+
self.timer = QTimer(self)
|
121
|
+
self.timer.timeout.connect(self.model.update_data)
|
122
|
+
self.timer.start(500)
|
File without changes
|
@@ -0,0 +1,130 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from PySide6.QtCore import Qt, QEvent
|
4
|
+
from PySide6.QtGui import QTextCursor, QColor, QKeyEvent
|
5
|
+
from PySide6.QtWidgets import (
|
6
|
+
QWidget, QVBoxLayout, QHBoxLayout, QPlainTextEdit, QLineEdit,
|
7
|
+
QPushButton, QLabel, QFileDialog, QComboBox
|
8
|
+
)
|
9
|
+
|
10
|
+
from je_editor.pyside_ui.main_ui.console_widget.qprocess_adapter import ConsoleProcessAdapter
|
11
|
+
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
|
12
|
+
|
13
|
+
|
14
|
+
class ConsoleWidget(QWidget):
|
15
|
+
def __init__(self, parent=None):
|
16
|
+
super().__init__(parent)
|
17
|
+
self.language_word_dict_get = language_wrapper.language_word_dict.get
|
18
|
+
self.proc = ConsoleProcessAdapter(self)
|
19
|
+
self.proc.stdout.connect(self.append_text)
|
20
|
+
self.proc.stderr.connect(lambda t: self.append_text(t, "#d33"))
|
21
|
+
self.proc.system.connect(
|
22
|
+
lambda t: self.append_text(f"{self.language_word_dict_get('dynamic_console_system_prefix')}{t}\n", "#888"))
|
23
|
+
self.proc.started.connect(lambda: self.proc.system.emit(self.language_word_dict_get("dynamic_console_running")))
|
24
|
+
self.proc.finished.connect(self.on_finished)
|
25
|
+
|
26
|
+
self.history, self.history_index = [], -1
|
27
|
+
|
28
|
+
self.output = QPlainTextEdit(readOnly=True)
|
29
|
+
self.output.setMaximumBlockCount(10000)
|
30
|
+
self.output.setStyleSheet("font-family: Consolas, monospace;")
|
31
|
+
|
32
|
+
self.input = QLineEdit()
|
33
|
+
self.input.setPlaceholderText("Enter command")
|
34
|
+
self.input.returnPressed.connect(self.run_command)
|
35
|
+
self.input.installEventFilter(self)
|
36
|
+
|
37
|
+
self.btn_run = QPushButton(self.language_word_dict_get("dynamic_console_run"))
|
38
|
+
self.btn_run.clicked.connect(self.run_command)
|
39
|
+
self.btn_stop = QPushButton(self.language_word_dict_get("dynamic_console_stop"))
|
40
|
+
self.btn_stop.clicked.connect(self.proc.stop)
|
41
|
+
self.btn_clear = QPushButton(self.language_word_dict_get("dynamic_console_clear"))
|
42
|
+
self.btn_clear.clicked.connect(self.output.clear)
|
43
|
+
|
44
|
+
self.cwd_label = QLabel(f"{self.language_word_dict_get('dynamic_console_cwd')}: {os.getcwd()}")
|
45
|
+
self.btn_pick_cwd = QPushButton("…")
|
46
|
+
self.btn_pick_cwd.clicked.connect(self.pick_cwd)
|
47
|
+
|
48
|
+
self.shell_combo = QComboBox()
|
49
|
+
self.shell_combo.addItems(["auto", "cmd", "powershell", "bash", "sh"])
|
50
|
+
|
51
|
+
top = QHBoxLayout()
|
52
|
+
top.addWidget(self.cwd_label)
|
53
|
+
top.addWidget(self.btn_pick_cwd)
|
54
|
+
top.addStretch()
|
55
|
+
top.addWidget(QLabel(self.language_word_dict_get("dynamic_console_shell")))
|
56
|
+
top.addWidget(self.shell_combo)
|
57
|
+
|
58
|
+
mid = QHBoxLayout()
|
59
|
+
mid.addWidget(self.input, 1)
|
60
|
+
mid.addWidget(self.btn_run)
|
61
|
+
mid.addWidget(self.btn_stop)
|
62
|
+
mid.addWidget(self.btn_clear)
|
63
|
+
|
64
|
+
lay = QVBoxLayout(self)
|
65
|
+
lay.addLayout(top)
|
66
|
+
lay.addWidget(self.output, 1)
|
67
|
+
lay.addLayout(mid)
|
68
|
+
|
69
|
+
self.proc.system.emit(self.language_word_dict_get("dynamic_console_ready"))
|
70
|
+
# 啟動互動式 shell
|
71
|
+
self.proc.start_shell(self.shell_combo.currentText())
|
72
|
+
|
73
|
+
def eventFilter(self, obj, event):
|
74
|
+
if obj is self.input and isinstance(event, QKeyEvent) and event.type() == QEvent.Type.KeyPress:
|
75
|
+
if event.key() == Qt.Key.Key_Up:
|
76
|
+
self.history_prev()
|
77
|
+
return True
|
78
|
+
if event.key() == Qt.Key.Key_Down:
|
79
|
+
self.history_next()
|
80
|
+
return True
|
81
|
+
return super().eventFilter(obj, event)
|
82
|
+
|
83
|
+
def history_prev(self):
|
84
|
+
if not self.history: return
|
85
|
+
self.history_index = len(self.history) - 1 if self.history_index < 0 else max(0, self.history_index - 1)
|
86
|
+
self.input.setText(self.history[self.history_index])
|
87
|
+
self.input.end(False)
|
88
|
+
|
89
|
+
def history_next(self):
|
90
|
+
if not self.history: return
|
91
|
+
if self.history_index < 0: return
|
92
|
+
self.history_index += 1
|
93
|
+
if self.history_index >= len(self.history):
|
94
|
+
self.history_index = -1
|
95
|
+
self.input.clear()
|
96
|
+
else:
|
97
|
+
self.input.setText(self.history[self.history_index])
|
98
|
+
self.input.end(False)
|
99
|
+
|
100
|
+
def pick_cwd(self):
|
101
|
+
d = QFileDialog.getExistingDirectory(self, "Select working directory", os.getcwd())
|
102
|
+
if d:
|
103
|
+
self.proc.set_cwd(d)
|
104
|
+
self.cwd_label.setText(f"{self.language_word_dict_get('dynamic_console_cwd')}: {d}")
|
105
|
+
self.proc.system.emit(f'cd "{d}"')
|
106
|
+
|
107
|
+
def append_text(self, text, color=None):
|
108
|
+
cursor = self.output.textCursor()
|
109
|
+
cursor.movePosition(QTextCursor.MoveOperation.End)
|
110
|
+
fmt = self.output.currentCharFormat()
|
111
|
+
if color: fmt.setForeground(QColor(color))
|
112
|
+
cursor.setCharFormat(fmt)
|
113
|
+
cursor.insertText(text)
|
114
|
+
self.output.setTextCursor(cursor)
|
115
|
+
self.output.ensureCursorVisible()
|
116
|
+
|
117
|
+
def run_command(self):
|
118
|
+
cmd = self.input.text().strip()
|
119
|
+
if not cmd: return
|
120
|
+
if not self.history or self.history[-1] != cmd:
|
121
|
+
self.history.append(cmd)
|
122
|
+
self.history_index = -1
|
123
|
+
self.append_text(f"{self.language_word_dict_get('dynamic_console_prompt')}{cmd}\n", "#0aa")
|
124
|
+
self.proc.send_command(cmd)
|
125
|
+
self.input.clear()
|
126
|
+
|
127
|
+
def on_finished(self, code, status):
|
128
|
+
self.append_text(f"\n{self.language_word_dict_get('dynamic_console_done').format(code=code, status=status)}\n",
|
129
|
+
"#888")
|
130
|
+
self.proc.system.emit(self.language_word_dict_get("dynamic_console_ready"))
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from PySide6.QtCore import QObject, QProcess, Signal, QTimer
|
4
|
+
|
5
|
+
|
6
|
+
class ConsoleProcessAdapter(QObject):
|
7
|
+
started = Signal()
|
8
|
+
finished = Signal(int, QProcess.ExitStatus)
|
9
|
+
stdout = Signal(str)
|
10
|
+
stderr = Signal(str)
|
11
|
+
system = Signal(str)
|
12
|
+
|
13
|
+
def __init__(self, parent=None):
|
14
|
+
super().__init__(parent)
|
15
|
+
self.proc = QProcess(self)
|
16
|
+
self.proc.setProcessChannelMode(QProcess.ProcessChannelMode.SeparateChannels)
|
17
|
+
self.proc.readyReadStandardOutput.connect(self._on_stdout)
|
18
|
+
self.proc.readyReadStandardError.connect(self._on_stderr)
|
19
|
+
self.proc.started.connect(self.started)
|
20
|
+
self.proc.finished.connect(self.finished)
|
21
|
+
|
22
|
+
def set_cwd(self, path: str):
|
23
|
+
self.proc.setWorkingDirectory(path)
|
24
|
+
|
25
|
+
def start_shell(self, shell: str = "auto"):
|
26
|
+
if self.is_running():
|
27
|
+
self.system.emit("Shell already running")
|
28
|
+
return
|
29
|
+
program, args = self._build_shell_command(shell)
|
30
|
+
self.proc.start(program, args)
|
31
|
+
|
32
|
+
if os.name == "nt":
|
33
|
+
QTimer.singleShot(500, lambda: self.send_command("chcp 65001"))
|
34
|
+
|
35
|
+
def send_command(self, cmd: str):
|
36
|
+
if not self.is_running():
|
37
|
+
self.system.emit("Shell not running")
|
38
|
+
return
|
39
|
+
self.proc.write((cmd + "\n").encode("utf-8"))
|
40
|
+
|
41
|
+
def stop(self):
|
42
|
+
if not self.is_running():
|
43
|
+
return
|
44
|
+
self.proc.terminate()
|
45
|
+
QTimer.singleShot(1000, lambda: self.is_running() and self.proc.kill())
|
46
|
+
|
47
|
+
def is_running(self):
|
48
|
+
return self.proc.state() != QProcess.ProcessState.NotRunning
|
49
|
+
|
50
|
+
def _on_stdout(self):
|
51
|
+
self.stdout.emit(bytes(self.proc.readAllStandardOutput()).decode("utf-8", errors="replace"))
|
52
|
+
|
53
|
+
def _on_stderr(self):
|
54
|
+
self.stderr.emit(bytes(self.proc.readAllStandardError()).decode("utf-8", errors="replace"))
|
55
|
+
|
56
|
+
def _build_shell_command(self, shell: str):
|
57
|
+
if shell == "auto":
|
58
|
+
shell = "cmd" if os.name == "nt" else "bash"
|
59
|
+
if os.name == "nt":
|
60
|
+
if shell == "powershell":
|
61
|
+
return "powershell.exe", ["-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass"]
|
62
|
+
return "cmd.exe", []
|
63
|
+
return ("/bin/bash" if shell == "bash" else "/bin/sh"), []
|
@@ -9,7 +9,11 @@ from PySide6.QtWidgets import QFileDialog
|
|
9
9
|
from frontengine import FrontEngineMainUI
|
10
10
|
|
11
11
|
from je_editor.pyside_ui.browser.browser_widget import BrowserWidget
|
12
|
+
from je_editor.pyside_ui.code.variable_inspector.inspector_gui import VariableInspector
|
13
|
+
from je_editor.pyside_ui.git.git_branch_tree_widget import GitTreeViewGUI
|
14
|
+
from je_editor.pyside_ui.git.git_client_gui import Gitgui
|
12
15
|
from je_editor.pyside_ui.main_ui.ai_widget.chat_ui import ChatUI
|
16
|
+
from je_editor.pyside_ui.main_ui.console_widget.console_gui import ConsoleWidget
|
13
17
|
from je_editor.pyside_ui.main_ui.dock.destroy_dock import DestroyDock
|
14
18
|
from je_editor.pyside_ui.main_ui.editor.editor_widget_dock import FullEditorWidget
|
15
19
|
from je_editor.pyside_ui.main_ui.ipython_widget.rich_jupyter import IpythonWidget
|
@@ -67,6 +71,34 @@ def set_dock_menu(ui_we_want_to_set: EditorMain) -> None:
|
|
67
71
|
lambda: add_dock_widget(ui_we_want_to_set, "chat_ui")
|
68
72
|
)
|
69
73
|
ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_chat_ui)
|
74
|
+
# Git Client
|
75
|
+
ui_we_want_to_set.dock_menu.new_git_client = QAction(
|
76
|
+
language_wrapper.language_word_dict.get("tab_menu_git_client_tab_name"))
|
77
|
+
ui_we_want_to_set.dock_menu.new_git_client.triggered.connect(
|
78
|
+
lambda: add_dock_widget(ui_we_want_to_set, "git_client")
|
79
|
+
)
|
80
|
+
ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_git_client)
|
81
|
+
# Git branch tree view
|
82
|
+
ui_we_want_to_set.dock_menu.new_git_branch_view = QAction(
|
83
|
+
language_wrapper.language_word_dict.get("tab_menu_git_branch_tree_view_tab_name"))
|
84
|
+
ui_we_want_to_set.dock_menu.new_git_branch_view.triggered.connect(
|
85
|
+
lambda: add_dock_widget(ui_we_want_to_set, "git_branch_tree_view")
|
86
|
+
)
|
87
|
+
ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_git_branch_view)
|
88
|
+
# Variable Inspector
|
89
|
+
ui_we_want_to_set.dock_menu.new_variable_inspector = QAction(
|
90
|
+
language_wrapper.language_word_dict.get("tab_menu_variable_inspector_tab_name"))
|
91
|
+
ui_we_want_to_set.dock_menu.new_variable_inspector.triggered.connect(
|
92
|
+
lambda: add_dock_widget(ui_we_want_to_set, "variable_inspector")
|
93
|
+
)
|
94
|
+
ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_variable_inspector)
|
95
|
+
# Dynamic Console
|
96
|
+
ui_we_want_to_set.dock_menu.new_dynamic_console = QAction(
|
97
|
+
language_wrapper.language_word_dict.get("tab_menu_console_widget_tab_name"))
|
98
|
+
ui_we_want_to_set.dock_menu.new_dynamic_console.triggered.connect(
|
99
|
+
lambda: add_dock_widget(ui_we_want_to_set, "console_widget")
|
100
|
+
)
|
101
|
+
ui_we_want_to_set.dock_menu.addAction(ui_we_want_to_set.dock_menu.new_dynamic_console)
|
70
102
|
|
71
103
|
def add_dock_widget(ui_we_want_to_set: EditorMain, widget_type: str = None):
|
72
104
|
jeditor_logger.info("build_dock_menu.py add_dock_widget "
|
@@ -100,6 +132,18 @@ def add_dock_widget(ui_we_want_to_set: EditorMain, widget_type: str = None):
|
|
100
132
|
elif widget_type == "chat_ui":
|
101
133
|
dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("chat_ui_dock_label"))
|
102
134
|
dock_widget.setWidget(ChatUI(ui_we_want_to_set))
|
135
|
+
elif widget_type == "git_client":
|
136
|
+
dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("tab_menu_git_client_tab_name"))
|
137
|
+
dock_widget.setWidget(Gitgui())
|
138
|
+
elif widget_type == "git_branch_tree_view":
|
139
|
+
dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("tab_menu_git_branch_tree_view_tab_name"))
|
140
|
+
dock_widget.setWidget(GitTreeViewGUI())
|
141
|
+
elif widget_type == "variable_inspector":
|
142
|
+
dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("tab_menu_variable_inspector_tab_name"))
|
143
|
+
dock_widget.setWidget(VariableInspector())
|
144
|
+
elif widget_type == "console_widget":
|
145
|
+
dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("tab_menu_console_widget_tab_name"))
|
146
|
+
dock_widget.setWidget(ConsoleWidget())
|
103
147
|
else:
|
104
148
|
dock_widget.setWindowTitle(language_wrapper.language_word_dict.get("dock_browser_title"))
|
105
149
|
dock_widget.setWidget(BrowserWidget())
|
@@ -5,7 +5,11 @@ from typing import TYPE_CHECKING
|
|
5
5
|
from frontengine import FrontEngineMainUI
|
6
6
|
|
7
7
|
from je_editor.pyside_ui.browser.browser_widget import BrowserWidget
|
8
|
+
from je_editor.pyside_ui.code.variable_inspector.inspector_gui import VariableInspector
|
9
|
+
from je_editor.pyside_ui.git.git_branch_tree_widget import GitTreeViewGUI
|
10
|
+
from je_editor.pyside_ui.git.git_client_gui import Gitgui
|
8
11
|
from je_editor.pyside_ui.main_ui.ai_widget.chat_ui import ChatUI
|
12
|
+
from je_editor.pyside_ui.main_ui.console_widget.console_gui import ConsoleWidget
|
9
13
|
from je_editor.pyside_ui.main_ui.editor.editor_widget import EditorWidget
|
10
14
|
from je_editor.pyside_ui.main_ui.ipython_widget.rich_jupyter import IpythonWidget
|
11
15
|
from je_editor.utils.logging.loggin_instance import jeditor_logger
|
@@ -63,10 +67,37 @@ def set_tab_menu(ui_we_want_to_set: EditorMain) -> None:
|
|
63
67
|
lambda: add_chat_ui_tab(ui_we_want_to_set)
|
64
68
|
)
|
65
69
|
ui_we_want_to_set.tab_menu.addAction(ui_we_want_to_set.tab_menu.add_chat_ui_action)
|
66
|
-
|
70
|
+
# Git Client
|
71
|
+
ui_we_want_to_set.tab_menu.add_git_client_ui_action = QAction(
|
72
|
+
language_wrapper.language_word_dict.get("tab_menu_git_client_tab_name"))
|
73
|
+
ui_we_want_to_set.tab_menu.add_git_client_ui_action.triggered.connect(
|
74
|
+
lambda: add_git_client_tab(ui_we_want_to_set)
|
75
|
+
)
|
76
|
+
ui_we_want_to_set.tab_menu.addAction(ui_we_want_to_set.tab_menu.add_git_client_ui_action)
|
77
|
+
# Git Branch tree
|
78
|
+
ui_we_want_to_set.tab_menu.add_git_branch_view_ui_action = QAction(
|
79
|
+
language_wrapper.language_word_dict.get("tab_menu_git_branch_tree_view_tab_name"))
|
80
|
+
ui_we_want_to_set.tab_menu.add_git_branch_view_ui_action.triggered.connect(
|
81
|
+
lambda: add_git_tree_view_tab(ui_we_want_to_set)
|
82
|
+
)
|
83
|
+
ui_we_want_to_set.tab_menu.addAction(ui_we_want_to_set.tab_menu.add_git_branch_view_ui_action)
|
84
|
+
# Variable Inspector
|
85
|
+
ui_we_want_to_set.tab_menu.add_variable_inspector_ui_action = QAction(
|
86
|
+
language_wrapper.language_word_dict.get("tab_menu_variable_inspector_tab_name"))
|
87
|
+
ui_we_want_to_set.tab_menu.add_variable_inspector_ui_action.triggered.connect(
|
88
|
+
lambda: add_variable_inspector_tab(ui_we_want_to_set)
|
89
|
+
)
|
90
|
+
ui_we_want_to_set.tab_menu.addAction(ui_we_want_to_set.tab_menu.add_variable_inspector_ui_action)
|
91
|
+
# Dynamic Console
|
92
|
+
ui_we_want_to_set.tab_menu.add_console_widget_ui_action = QAction(
|
93
|
+
language_wrapper.language_word_dict.get("tab_menu_console_widget_tab_name"))
|
94
|
+
ui_we_want_to_set.tab_menu.add_console_widget_ui_action.triggered.connect(
|
95
|
+
lambda: add_console_widget_tab(ui_we_want_to_set)
|
96
|
+
)
|
97
|
+
ui_we_want_to_set.tab_menu.addAction(ui_we_want_to_set.tab_menu.add_console_widget_ui_action)
|
67
98
|
|
68
99
|
def add_editor_tab(ui_we_want_to_set: EditorMain):
|
69
|
-
jeditor_logger.info(f"build_tab_menu.py
|
100
|
+
jeditor_logger.info(f"build_tab_menu.py add editor tab ui_we_want_to_set: {ui_we_want_to_set}")
|
70
101
|
widget = EditorWidget(ui_we_want_to_set)
|
71
102
|
ui_we_want_to_set.tab_widget.addTab(
|
72
103
|
widget,
|
@@ -76,7 +107,7 @@ def add_editor_tab(ui_we_want_to_set: EditorMain):
|
|
76
107
|
|
77
108
|
|
78
109
|
def add_frontengine_tab(ui_we_want_to_set: EditorMain):
|
79
|
-
jeditor_logger.info(f"build_tab_menu.py
|
110
|
+
jeditor_logger.info(f"build_tab_menu.py add frontengine tab ui_we_want_to_set: {ui_we_want_to_set}")
|
80
111
|
ui_we_want_to_set.tab_widget.addTab(
|
81
112
|
FrontEngineMainUI(show_system_tray_ray=False, redirect_output=False),
|
82
113
|
f"{language_wrapper.language_word_dict.get('tab_menu_frontengine_tab_name')} "
|
@@ -84,7 +115,7 @@ def add_frontengine_tab(ui_we_want_to_set: EditorMain):
|
|
84
115
|
|
85
116
|
|
86
117
|
def add_web_tab(ui_we_want_to_set: EditorMain):
|
87
|
-
jeditor_logger.info(f"build_tab_menu.py
|
118
|
+
jeditor_logger.info(f"build_tab_menu.py add web tab ui_we_want_to_set: {ui_we_want_to_set}")
|
88
119
|
ui_we_want_to_set.tab_widget.addTab(
|
89
120
|
BrowserWidget(),
|
90
121
|
f"{language_wrapper.language_word_dict.get('tab_menu_web_tab_name')} "
|
@@ -92,7 +123,7 @@ def add_web_tab(ui_we_want_to_set: EditorMain):
|
|
92
123
|
|
93
124
|
|
94
125
|
def add_stackoverflow_tab(ui_we_want_to_set: EditorMain):
|
95
|
-
jeditor_logger.info(f"build_tab_menu.py
|
126
|
+
jeditor_logger.info(f"build_tab_menu.py add stackoverflow tab ui_we_want_to_set: {ui_we_want_to_set}")
|
96
127
|
ui_we_want_to_set.tab_widget.addTab(
|
97
128
|
BrowserWidget(start_url="https://stackoverflow.com/", search_prefix="https://stackoverflow.com/search?q="),
|
98
129
|
f"{language_wrapper.language_word_dict.get('tab_menu_stackoverflow_tab_name')} "
|
@@ -100,7 +131,7 @@ def add_stackoverflow_tab(ui_we_want_to_set: EditorMain):
|
|
100
131
|
|
101
132
|
|
102
133
|
def add_ipython_tab(ui_we_want_to_set: EditorMain):
|
103
|
-
jeditor_logger.info(f"build_tab_menu.py
|
134
|
+
jeditor_logger.info(f"build_tab_menu.py add ipython tab ui_we_want_to_set: {ui_we_want_to_set}")
|
104
135
|
ui_we_want_to_set.tab_widget.addTab(
|
105
136
|
IpythonWidget(ui_we_want_to_set),
|
106
137
|
f"{language_wrapper.language_word_dict.get('tab_menu_ipython_tab_name')} "
|
@@ -108,10 +139,38 @@ def add_ipython_tab(ui_we_want_to_set: EditorMain):
|
|
108
139
|
|
109
140
|
|
110
141
|
def add_chat_ui_tab(ui_we_want_to_set: EditorMain):
|
111
|
-
jeditor_logger.info(f"build_tab_menu.py
|
142
|
+
jeditor_logger.info(f"build_tab_menu.py add chat_ui tab ui_we_want_to_set: {ui_we_want_to_set}")
|
112
143
|
ui_we_want_to_set.tab_widget.addTab(
|
113
144
|
ChatUI(ui_we_want_to_set),
|
114
145
|
f"{language_wrapper.language_word_dict.get('tab_menu_chat_ui_tab_name')} "
|
115
146
|
f"{ui_we_want_to_set.tab_widget.count()}")
|
116
147
|
|
117
148
|
|
149
|
+
def add_git_client_tab(ui_we_want_to_set: EditorMain):
|
150
|
+
jeditor_logger.info(f"build_tab_menu.py add git client tab ui_we_want_to_set: {ui_we_want_to_set}")
|
151
|
+
ui_we_want_to_set.tab_widget.addTab(
|
152
|
+
Gitgui(),
|
153
|
+
f"{language_wrapper.language_word_dict.get('tab_menu_git_client_tab_name')} "
|
154
|
+
f"{ui_we_want_to_set.tab_widget.count()}")
|
155
|
+
|
156
|
+
def add_git_tree_view_tab(ui_we_want_to_set: EditorMain):
|
157
|
+
jeditor_logger.info(f"build_tab_menu.py add git tree view tab ui_we_want_to_set: {ui_we_want_to_set}")
|
158
|
+
ui_we_want_to_set.tab_widget.addTab(
|
159
|
+
GitTreeViewGUI(),
|
160
|
+
f"{language_wrapper.language_word_dict.get('tab_menu_git_branch_tree_view_tab_name')} "
|
161
|
+
f"{ui_we_want_to_set.tab_widget.count()}")
|
162
|
+
|
163
|
+
def add_variable_inspector_tab(ui_we_want_to_set: EditorMain):
|
164
|
+
jeditor_logger.info(f"build_tab_menu.py add variable inspector tab ui_we_want_to_set: {ui_we_want_to_set}")
|
165
|
+
ui_we_want_to_set.tab_widget.addTab(
|
166
|
+
VariableInspector(),
|
167
|
+
f"{language_wrapper.language_word_dict.get('tab_menu_variable_inspector_tab_name')} "
|
168
|
+
f"{ui_we_want_to_set.tab_widget.count()}")
|
169
|
+
|
170
|
+
|
171
|
+
def add_console_widget_tab(ui_we_want_to_set: EditorMain):
|
172
|
+
jeditor_logger.info(f"build_tab_menu.py add console widget tab ui_we_want_to_set: {ui_we_want_to_set}")
|
173
|
+
ui_we_want_to_set.tab_widget.addTab(
|
174
|
+
ConsoleWidget(),
|
175
|
+
f"{language_wrapper.language_word_dict.get('tab_menu_console_widget_tab_name')} "
|
176
|
+
f"{ui_we_want_to_set.tab_widget.count()}")
|
@@ -82,11 +82,11 @@ english_word_dict = {
|
|
82
82
|
"run_menu_run_help_tip": """
|
83
83
|
If you are unable to run a Python program, please make sure you are have python interpreter,
|
84
84
|
And if python conflict please choose another interpreter.
|
85
|
-
|
85
|
+
""",
|
86
86
|
"run_menu_shell_run_tip": """
|
87
87
|
When executing a shell command, if you encounter a decoding error,
|
88
88
|
please make sure that the current encoding is consistent with the default encoding of the system shell.
|
89
|
-
|
89
|
+
""",
|
90
90
|
# Debugger and menu
|
91
91
|
"editor_debugger_input_title_label": "Debugger",
|
92
92
|
"show_debugger_input": "Show debugger input",
|
@@ -110,6 +110,10 @@ please make sure that the current encoding is consistent with the default encodi
|
|
110
110
|
"tab_menu_stackoverflow_tab_name": "Stackoverflow",
|
111
111
|
"tab_menu_ipython_tab_name": "IPython(Jupyter)",
|
112
112
|
"tab_menu_chat_ui_tab_name": "ChatUI",
|
113
|
+
"tab_menu_git_client_tab_name": "Git Client",
|
114
|
+
"tab_menu_git_branch_tree_view_tab_name": "Git BranchTreeViewer",
|
115
|
+
"tab_menu_variable_inspector_tab_name": "Variable Inspector",
|
116
|
+
"tab_menu_console_widget_tab_name": "Console Widget",
|
113
117
|
# Text Menu
|
114
118
|
"text_menu_label": "Text",
|
115
119
|
"text_menu_label_font": "Font",
|
@@ -141,4 +145,76 @@ please make sure that the current encoding is consistent with the default encodi
|
|
141
145
|
"ai_model_label": "AI Model",
|
142
146
|
"load_ai_messagebox_title": "Load complete",
|
143
147
|
"load_ai_messagebox_text": "Load complete",
|
144
|
-
|
148
|
+
# gitGUI
|
149
|
+
"label_repo_initial": "Repo: -",
|
150
|
+
"btn_open_repo": "Open Repo",
|
151
|
+
"btn_switch_branch": "Switch",
|
152
|
+
"btn_pull": "Pull",
|
153
|
+
"btn_push": "Push",
|
154
|
+
"btn_clone_remote": "Clone Remote Repo",
|
155
|
+
"label_remote": "Remote:",
|
156
|
+
"label_branch": "Branch:",
|
157
|
+
"placeholder_commit_message": "Commit message...",
|
158
|
+
"btn_stage_all": "Stage All",
|
159
|
+
"btn_commit": "Commit",
|
160
|
+
"label_message": "Message:",
|
161
|
+
"dialog_choose_repo": "Choose Git Repo",
|
162
|
+
"err_open_repo": "Failed to open repository",
|
163
|
+
"default_remote": "origin",
|
164
|
+
"err_load_branches": "Failed to load branches",
|
165
|
+
"err_load_commits": "Failed to load commits",
|
166
|
+
"err_checkout": "Checkout Failure",
|
167
|
+
"info_checkout_title": "Checkout",
|
168
|
+
"info_checkout_msg": "Already check out to {branch}",
|
169
|
+
"err_read_diff": "Failed to read diff",
|
170
|
+
"err_stage": "Stage failed",
|
171
|
+
"info_stage_title": "Stage",
|
172
|
+
"info_stage_msg": "Executed git add -A",
|
173
|
+
"err_commit": "Commit failed",
|
174
|
+
"info_commit_title": "Commit",
|
175
|
+
"info_commit_msg": "Commit created",
|
176
|
+
"err_pull": "Pull failed",
|
177
|
+
"info_pull_title": "Pull",
|
178
|
+
"err_push": "Push failed",
|
179
|
+
"info_push_title": "Push",
|
180
|
+
"dialog_clone_title": "Clone Remote Repo",
|
181
|
+
"dialog_clone_prompt": "Enter Git repository URL:",
|
182
|
+
"dialog_select_folder": "Select Local Folder",
|
183
|
+
"info_clone_success_title": "Clone Successful",
|
184
|
+
"info_clone_success_msg": "Repository cloned to:\\n{repo_path}",
|
185
|
+
"err_clone_failed_title": "Clone Failed",
|
186
|
+
# Git graph
|
187
|
+
"git_graph_title": "Git Branch Viewer",
|
188
|
+
"git_graph_menu_file": "File",
|
189
|
+
"git_graph_menu_open_repo": "Open Repository...",
|
190
|
+
"git_graph_menu_refresh": "Refresh",
|
191
|
+
"git_graph_menu_exit": "Exit",
|
192
|
+
"git_graph_status_loading": "Loading repository...",
|
193
|
+
"git_graph_status_ready": "Ready",
|
194
|
+
"git_graph_status_repo_set": "Repository: {path}",
|
195
|
+
"git_graph_error_not_git": "Selected path is not a Git repository.",
|
196
|
+
"git_graph_error_exec_failed": "Git command failed.",
|
197
|
+
"git_graph_tooltip_commit": "Commit: {short}\nAuthor: {author}\nDate: {date}\nMessage: {msg}",
|
198
|
+
"git_graph_toolbar_open": "Open",
|
199
|
+
"git_graph_toolbar_refresh": "Refresh",
|
200
|
+
# Variable inspector
|
201
|
+
"variable_inspector_title": "Variable Inspector",
|
202
|
+
"variable_inspector_search": "Search Variables:",
|
203
|
+
"variable_inspector_var_name": "Variable Name",
|
204
|
+
"variable_inspector_var_type": "Type",
|
205
|
+
"variable_inspector_var_value": "Value",
|
206
|
+
# Dynamic Console
|
207
|
+
"dynamic_console_title": "Dynamic Console",
|
208
|
+
"dynamic_console_run": "Run",
|
209
|
+
"dynamic_console_stop": "Stop",
|
210
|
+
"dynamic_console_clear": "Clear",
|
211
|
+
"dynamic_console_cwd": "CWD",
|
212
|
+
"dynamic_console_shell": "Shell",
|
213
|
+
"dynamic_console_prompt": "❯ ",
|
214
|
+
"dynamic_console_running": "[running]",
|
215
|
+
"dynamic_console_ready": "[ready]",
|
216
|
+
"dynamic_console_process_running": "Process is running; stop it first",
|
217
|
+
"dynamic_console_done": "[done] exit={code}, status={status}",
|
218
|
+
"dynamic_console_system_prefix": "[system] ",
|
219
|
+
|
220
|
+
}
|
@@ -79,12 +79,8 @@ traditional_chinese_word_dict = {
|
|
79
79
|
"run_menu_shell_help_label": "終端運行幫助",
|
80
80
|
"please_stop_current_running_shell": "請先關閉目前正在運行的終端",
|
81
81
|
"please_stop_current_running_program": "請先關閉目前正在運行的程式",
|
82
|
-
"run_menu_run_help_tip": ""
|
83
|
-
|
84
|
-
""",
|
85
|
-
"run_menu_shell_run_tip": """
|
86
|
-
如果有亂碼等問題請重新選擇編碼至與系統 Shell 編碼相同
|
87
|
-
""",
|
82
|
+
"run_menu_run_help_tip": "如果不能運行程式, 請檢查是否有 Python 直譯器,如有 Python 衝突請選擇其他直譯器.",
|
83
|
+
"run_menu_shell_run_tip": "如果有亂碼等問題請重新選擇編碼至與系統 Shell 編碼相同",
|
88
84
|
# Debugger
|
89
85
|
"editor_debugger_input_title_label": "除錯器",
|
90
86
|
"show_debugger_input": "開啟除錯輸入",
|
@@ -108,6 +104,10 @@ traditional_chinese_word_dict = {
|
|
108
104
|
"tab_menu_stackoverflow_tab_name": "Stackoverflow",
|
109
105
|
"tab_menu_ipython_tab_name": "IPython(Jupyter)",
|
110
106
|
"tab_menu_chat_ui_tab_name": "ChatUI",
|
107
|
+
"tab_menu_git_client_tab_name": "Git Client",
|
108
|
+
"tab_menu_git_branch_tree_view_tab_name": "Git BranchTreeViewer",
|
109
|
+
"tab_menu_variable_inspector_tab_name": "Variable Inspector",
|
110
|
+
"tab_menu_console_widget_tab_name": "ConsoleWidget",
|
111
111
|
# Text Menu
|
112
112
|
"text_menu_label": "文字",
|
113
113
|
"text_menu_label_font": "字體",
|
@@ -139,4 +139,76 @@ traditional_chinese_word_dict = {
|
|
139
139
|
"ai_model_label": "AI Model",
|
140
140
|
"load_ai_messagebox_title": "載入成功",
|
141
141
|
"load_ai_messagebox_text": "載入成功",
|
142
|
-
|
142
|
+
# gitGUI
|
143
|
+
"label_repo_initial": "儲存庫: -",
|
144
|
+
"btn_open_repo": "開啟儲存庫",
|
145
|
+
"btn_switch_branch": "切換",
|
146
|
+
"btn_pull": "拉取",
|
147
|
+
"btn_push": "推送",
|
148
|
+
"btn_clone_remote": "複製遠端儲存庫",
|
149
|
+
"label_remote": "遠端:",
|
150
|
+
"label_branch": "分支:",
|
151
|
+
"placeholder_commit_message": "提交訊息...",
|
152
|
+
"btn_stage_all": "暫存全部",
|
153
|
+
"btn_commit": "提交",
|
154
|
+
"label_message": "訊息:",
|
155
|
+
"dialog_choose_repo": "選擇 Git 儲存庫",
|
156
|
+
"err_open_repo": "開啟儲存庫失敗",
|
157
|
+
"default_remote": "origin",
|
158
|
+
"err_load_branches": "載入分支失敗",
|
159
|
+
"err_load_commits": "載入提交記錄失敗",
|
160
|
+
"err_checkout": "切換分支失敗",
|
161
|
+
"info_checkout_title": "切換分支",
|
162
|
+
"info_checkout_msg": "已切換至",
|
163
|
+
"err_read_diff": "讀取差異失敗",
|
164
|
+
"err_stage": "暫存失敗",
|
165
|
+
"info_stage_title": "暫存",
|
166
|
+
"info_stage_msg": "已執行 git add -A",
|
167
|
+
"err_commit": "提交失敗",
|
168
|
+
"info_commit_title": "提交",
|
169
|
+
"info_commit_msg": "已建立提交",
|
170
|
+
"err_pull": "拉取失敗",
|
171
|
+
"info_pull_title": "拉取",
|
172
|
+
"err_push": "推送失敗",
|
173
|
+
"info_push_title": "推送",
|
174
|
+
"dialog_clone_title": "複製遠端儲存庫",
|
175
|
+
"dialog_clone_prompt": "輸入 Git 儲存庫 URL:",
|
176
|
+
"dialog_select_folder": "選擇本機資料夾",
|
177
|
+
"info_clone_success_title": "複製成功",
|
178
|
+
"info_clone_success_msg": "儲存庫已複製至:\\n",
|
179
|
+
"err_clone_failed_title": "複製失敗",
|
180
|
+
# Git 圖形
|
181
|
+
"git_graph_title": "Git 分支檢視器",
|
182
|
+
"git_graph_menu_file": "檔案",
|
183
|
+
"git_graph_menu_open_repo": "開啟儲存庫...",
|
184
|
+
"git_graph_menu_refresh": "重新整理",
|
185
|
+
"git_graph_menu_exit": "退出",
|
186
|
+
"git_graph_status_loading": "正在載入儲存庫...",
|
187
|
+
"git_graph_status_ready": "就緒",
|
188
|
+
"git_graph_status_repo_set": "儲存庫:{path}",
|
189
|
+
"git_graph_error_not_git": "所選路徑不是 Git 儲存庫。",
|
190
|
+
"git_graph_error_exec_failed": "Git 指令執行失敗。",
|
191
|
+
"git_graph_tooltip_commit": "提交:{short}\n作者:{author}\n日期:{date}\n訊息:{msg}",
|
192
|
+
"git_graph_toolbar_open": "開啟",
|
193
|
+
"git_graph_toolbar_refresh": "重新整理",
|
194
|
+
# Variable inspector
|
195
|
+
"variable_inspector_title": "變數查看器",
|
196
|
+
"variable_inspector_search": "搜尋變數:",
|
197
|
+
"variable_inspector_var_name": "變數名稱",
|
198
|
+
"variable_inspector_var_type": "型別",
|
199
|
+
"variable_inspector_var_value": "值",
|
200
|
+
# Dynamic Console
|
201
|
+
"dynamic_console_title": "動態主控台",
|
202
|
+
"dynamic_console_run": "執行",
|
203
|
+
"dynamic_console_stop": "停止",
|
204
|
+
"dynamic_console_clear": "清除",
|
205
|
+
"dynamic_console_cwd": "工作目錄",
|
206
|
+
"dynamic_console_shell": "Shell",
|
207
|
+
"dynamic_console_prompt": "❯ ",
|
208
|
+
"dynamic_console_running": "[執行中]",
|
209
|
+
"dynamic_console_ready": "[就緒]",
|
210
|
+
"dynamic_console_process_running": "程序正在執行;請先停止",
|
211
|
+
"dynamic_console_done": "[完成] 退出碼={code}, 狀態={status}",
|
212
|
+
"dynamic_console_system_prefix": "[系統] ",
|
213
|
+
|
214
|
+
}
|
@@ -1,6 +1,10 @@
|
|
1
1
|
je_editor/__init__.py,sha256=IZm-mUID0W7-smb9SYEtwcWrpr8mz6OyF4e5akHGrFU,2405
|
2
2
|
je_editor/__main__.py,sha256=2ymm4ESRcqP4K1YQyeaDbGhuK-0C1IausIiEOpbm6Ds,570
|
3
3
|
je_editor/start_editor.py,sha256=hW7JFOjBkcW7hdC7q-9JsaVTeSNCep1GsqxLmbMU4wg,543
|
4
|
+
je_editor/code_scan/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
je_editor/code_scan/ruff_thread.py,sha256=pQjfsaQXI2ZJ6nAGq0Fpw-k3S2V_gYQ0lPgYnNC9Re0,938
|
6
|
+
je_editor/code_scan/watchdog_implement.py,sha256=9N5TCvWQKi66DSrViUaNhUwP5TkYhmbz_ncS9KTGPx8,1313
|
7
|
+
je_editor/code_scan/watchdog_thread.py,sha256=jHJCIsDN1kcfK4dIY5MHORafV4EJNN93x4GgNnEx1G4,833
|
4
8
|
je_editor/pyside_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
9
|
je_editor/pyside_ui/browser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
10
|
je_editor/pyside_ui/browser/browser_download_window.py,sha256=KEO8AoZYSDuES0z5os9ziD44lS47kIo3kbd5iOUM2Go,2018
|
@@ -25,6 +29,8 @@ je_editor/pyside_ui/code/syntax/python_syntax.py,sha256=9rK7_DYAANgf28PUdVl9xs42
|
|
25
29
|
je_editor/pyside_ui/code/syntax/syntax_setting.py,sha256=oaLRF_83Oa6bcAorf7AlZG0Mrt4FmsK7b4aA-LS_bRo,2284
|
26
30
|
je_editor/pyside_ui/code/textedit_code_result/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
31
|
je_editor/pyside_ui/code/textedit_code_result/code_record.py,sha256=pT-CmcADEaXLZ0ih6D6rpe1XywgszrEpcJxtJYgopJE,2162
|
32
|
+
je_editor/pyside_ui/code/variable_inspector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
|
+
je_editor/pyside_ui/code/variable_inspector/inspector_gui.py,sha256=QMcwN3td5Nr01bWpUHEFJzl-wb0Ifigqx6ybfvQSzJY,4747
|
28
34
|
je_editor/pyside_ui/dialog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
29
35
|
je_editor/pyside_ui/dialog/ai_dialog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
36
|
je_editor/pyside_ui/dialog/ai_dialog/set_ai_dialog.py,sha256=w_cku2dQthtk0TDSxEeDB-tvzdHV4vmUhFVDlb2ynO8,2392
|
@@ -37,11 +43,9 @@ je_editor/pyside_ui/dialog/search_ui/search_error_box.py,sha256=jSa423cQW_xQ2WAj
|
|
37
43
|
je_editor/pyside_ui/dialog/search_ui/search_text_box.py,sha256=ul-98FVByq_TNkkLZcBSF4VSwIQNBBj-4e6jYlh6YEA,1229
|
38
44
|
je_editor/pyside_ui/main_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
45
|
je_editor/pyside_ui/main_ui/main_editor.py,sha256=jS18_PBEWcXQh8A3lsN_Z9qRjLbwmVx1GcF5YMBpHoU,11077
|
40
|
-
je_editor/pyside_ui/main_ui/
|
41
|
-
je_editor/pyside_ui/main_ui/
|
42
|
-
je_editor/pyside_ui/main_ui/
|
43
|
-
je_editor/pyside_ui/main_ui/ai_widget/chat_ui.py,sha256=yBoWXvGvgUCWjmPoBcOhj0mtOm0R42mYEs7FokYQmnE,6763
|
44
|
-
je_editor/pyside_ui/main_ui/ai_widget/langchain_interface.py,sha256=OgBaUcUMR0Z2VQUO9QfCX2wJc_qBFw3IvoMCiEGBTug,1768
|
46
|
+
je_editor/pyside_ui/main_ui/console_widget/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
|
+
je_editor/pyside_ui/main_ui/console_widget/console_gui.py,sha256=3H0Ocj9oDtgAoH7mT2YjDsSeFW3FphsstJqtIesS4yA,5572
|
48
|
+
je_editor/pyside_ui/main_ui/console_widget/qprocess_adapter.py,sha256=UIyIoCEyt6hMxc2oLH68ioERFyuPDnPub05_Yi_-rGs,2304
|
45
49
|
je_editor/pyside_ui/main_ui/dock/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
46
50
|
je_editor/pyside_ui/main_ui/dock/destroy_dock.py,sha256=MTN45BykNm6FA4gMW7gI4Kr9orTdcxVTm7mch3DUhaw,604
|
47
51
|
je_editor/pyside_ui/main_ui/editor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -52,10 +56,8 @@ je_editor/pyside_ui/main_ui/ipython_widget/__init__.py,sha256=47DEQpj8HBSa-_TImW
|
|
52
56
|
je_editor/pyside_ui/main_ui/ipython_widget/rich_jupyter.py,sha256=LKbMbgpstsk_EiwbBSJ9Ljn7Ia3j2UNpQ_JAI6_LJ4Q,1629
|
53
57
|
je_editor/pyside_ui/main_ui/menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
58
|
je_editor/pyside_ui/main_ui/menu/set_menu_bar.py,sha256=I12DXLyRO4cKe17fQY-QDazKEIh9W36LNV1aKUw47MU,1823
|
55
|
-
je_editor/pyside_ui/main_ui/menu/check_style_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
56
|
-
je_editor/pyside_ui/main_ui/menu/check_style_menu/build_check_style_menu.py,sha256=1wD6FI21Dw3IcQONuTkHP9rUPGwY70OvCtSc-ZcTKMk,3793
|
57
59
|
je_editor/pyside_ui/main_ui/menu/dock_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
58
|
-
je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py,sha256=
|
60
|
+
je_editor/pyside_ui/main_ui/menu/dock_menu/build_dock_menu.py,sha256=SP1fmfPeJFkroSm7b89QJUe72-WuzWdGVnypkI8WhTo,8396
|
59
61
|
je_editor/pyside_ui/main_ui/menu/file_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
62
|
je_editor/pyside_ui/main_ui/menu/file_menu/build_file_menu.py,sha256=YT6kvXShRbfM4Qo51VveO_IK8uDqlNrGwHZUiM6_Tes,6881
|
61
63
|
je_editor/pyside_ui/main_ui/menu/help_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -74,7 +76,7 @@ je_editor/pyside_ui/main_ui/menu/run_menu/under_run_menu/utils.py,sha256=zk5adQ7
|
|
74
76
|
je_editor/pyside_ui/main_ui/menu/style_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
77
|
je_editor/pyside_ui/main_ui/menu/style_menu/build_style_menu.py,sha256=OjfcjQ7fA1Z1rMwIS9oGkIkC-jy-e0jdGoYo1btTqUQ,1852
|
76
78
|
je_editor/pyside_ui/main_ui/menu/tab_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
77
|
-
je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py,sha256=
|
79
|
+
je_editor/pyside_ui/main_ui/menu/tab_menu/build_tab_menu.py,sha256=foJA_HYzEtgiLmjp0oA8-jVgdunxHgWYs5KDwz9AU9w,9232
|
78
80
|
je_editor/pyside_ui/main_ui/menu/text_menu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
79
81
|
je_editor/pyside_ui/main_ui/menu/text_menu/build_text_menu.py,sha256=k3pOpK4i8ccs3D8VIrNx8g3kUDp1fZdqv9H5uEvNl5c,3558
|
80
82
|
je_editor/pyside_ui/main_ui/save_settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -101,15 +103,15 @@ je_editor/utils/json_format/json_process.py,sha256=tszo48OnVivVkuuPrl-FtGaaq-1YO
|
|
101
103
|
je_editor/utils/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
102
104
|
je_editor/utils/logging/loggin_instance.py,sha256=5MUuLesU_WpR_Iu1uoAATi5Bj2yMYkimZrMfiXbk5pI,881
|
103
105
|
je_editor/utils/multi_language/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
104
|
-
je_editor/utils/multi_language/english.py,sha256=
|
106
|
+
je_editor/utils/multi_language/english.py,sha256=Od7UyWqtg2xE-my7xNmAjL4ahTDSzbD5Zvkgi07IsUk,9967
|
105
107
|
je_editor/utils/multi_language/multi_language_wrapper.py,sha256=_MtYrE51poQ1p_iWvT2eg_604uj6IsiBgGpifWpYLGc,1050
|
106
|
-
je_editor/utils/multi_language/traditional_chinese.py,sha256=
|
108
|
+
je_editor/utils/multi_language/traditional_chinese.py,sha256=12rUsAbpTEi2q7OwfSsbXe2zWwYebrmwIOSPbS9Rg10,10045
|
107
109
|
je_editor/utils/redirect_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
108
110
|
je_editor/utils/redirect_manager/redirect_manager_class.py,sha256=1gICetKpohBvmxmVhnqeCRq7AQS2YWK4AURmrqnVYVw,2277
|
109
111
|
je_editor/utils/venv_check/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
110
112
|
je_editor/utils/venv_check/check_venv.py,sha256=oCrMdue4NYUUGrVifh_iHFwIgxVx9azYN4jz3Xiulgg,999
|
111
|
-
je_editor-0.0.
|
112
|
-
je_editor-0.0.
|
113
|
-
je_editor-0.0.
|
114
|
-
je_editor-0.0.
|
115
|
-
je_editor-0.0.
|
113
|
+
je_editor-0.0.212.dist-info/licenses/LICENSE,sha256=KMhUHh6pnIUvmXDW-49L_Sz63bqkOlPDqsecaqKiitU,1091
|
114
|
+
je_editor-0.0.212.dist-info/METADATA,sha256=z1c0VSsD0gYUnVEO3kUhvUFm-Ri0m7eFBMjD0jvnY58,3446
|
115
|
+
je_editor-0.0.212.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
116
|
+
je_editor-0.0.212.dist-info/top_level.txt,sha256=_9YA7BgxpkmdLs-5V_UQILxClcMRgPyG1a3qaE-Bkcs,10
|
117
|
+
je_editor-0.0.212.dist-info/RECORD,,
|
@@ -1,19 +0,0 @@
|
|
1
|
-
from queue import Queue
|
2
|
-
|
3
|
-
|
4
|
-
class AIConfig(object):
|
5
|
-
|
6
|
-
def __init__(self):
|
7
|
-
self.current_ai_model_system_prompt: str = ""
|
8
|
-
self.choosable_ai: dict[str, dict[str, str]] = {
|
9
|
-
"AI_model": {
|
10
|
-
"ai_base_url": "",
|
11
|
-
"ai_api_key": "",
|
12
|
-
"chat_model": "",
|
13
|
-
"prompt_template": "",
|
14
|
-
}
|
15
|
-
}
|
16
|
-
self.message_queue = Queue()
|
17
|
-
|
18
|
-
|
19
|
-
ai_config = AIConfig()
|
@@ -1,17 +0,0 @@
|
|
1
|
-
from threading import Thread
|
2
|
-
|
3
|
-
from je_editor.pyside_ui.main_ui.ai_widget.ai_config import ai_config
|
4
|
-
from je_editor.pyside_ui.main_ui.ai_widget.langchain_interface import LangChainInterface
|
5
|
-
|
6
|
-
|
7
|
-
class AskThread(Thread):
|
8
|
-
|
9
|
-
def __init__(self, lang_chain_interface: LangChainInterface, prompt):
|
10
|
-
super().__init__()
|
11
|
-
self.lang_chain_interface = lang_chain_interface
|
12
|
-
self.prompt = prompt
|
13
|
-
|
14
|
-
|
15
|
-
def run(self):
|
16
|
-
ai_response = self.lang_chain_interface.call_ai_model(prompt=self.prompt)
|
17
|
-
ai_config.message_queue.put(ai_response)
|
@@ -1,130 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from pathlib import Path
|
4
|
-
from typing import TYPE_CHECKING, Union
|
5
|
-
|
6
|
-
from PySide6.QtCore import Qt, QTimer
|
7
|
-
from PySide6.QtGui import QFontDatabase
|
8
|
-
from PySide6.QtWidgets import QWidget, QPlainTextEdit, QScrollArea, QLabel, QComboBox, QGridLayout, QPushButton, \
|
9
|
-
QMessageBox, QSizePolicy, QLineEdit
|
10
|
-
|
11
|
-
from je_editor.pyside_ui.dialog.ai_dialog.set_ai_dialog import SetAIDialog
|
12
|
-
from je_editor.pyside_ui.main_ui.ai_widget.ai_config import AIConfig, ai_config
|
13
|
-
from je_editor.pyside_ui.main_ui.ai_widget.ask_thread import AskThread
|
14
|
-
from je_editor.pyside_ui.main_ui.ai_widget.langchain_interface import LangChainInterface
|
15
|
-
from je_editor.utils.json.json_file import read_json
|
16
|
-
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
|
17
|
-
|
18
|
-
if TYPE_CHECKING:
|
19
|
-
from je_editor.pyside_ui.main_ui.main_editor import EditorMain
|
20
|
-
|
21
|
-
|
22
|
-
class ChatUI(QWidget):
|
23
|
-
|
24
|
-
def __init__(self, main_window: EditorMain):
|
25
|
-
super().__init__()
|
26
|
-
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
|
27
|
-
self.main_window = main_window
|
28
|
-
# Chat panel
|
29
|
-
self.chat_panel = QPlainTextEdit()
|
30
|
-
self.chat_panel.setLineWrapMode(self.chat_panel.LineWrapMode.NoWrap)
|
31
|
-
self.chat_panel.setReadOnly(True)
|
32
|
-
self.chat_panel_scroll_area = QScrollArea()
|
33
|
-
self.chat_panel_scroll_area.setWidgetResizable(True)
|
34
|
-
self.chat_panel_scroll_area.setViewportMargins(0, 0, 0, 0)
|
35
|
-
self.chat_panel_scroll_area.setWidget(self.chat_panel)
|
36
|
-
self.chat_panel.setFont(QFontDatabase.font(self.font().family(), "", 16))
|
37
|
-
# Prompt input
|
38
|
-
self.prompt_input = QLineEdit()
|
39
|
-
self.prompt_input.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
40
|
-
self.prompt_input.returnPressed.connect(self.call_ai_model)
|
41
|
-
# Font size combobox
|
42
|
-
self.font_size_label = QLabel(language_wrapper.language_word_dict.get("font_size"))
|
43
|
-
self.font_size_combobox = QComboBox()
|
44
|
-
for font_size in range(2, 101, 2):
|
45
|
-
self.font_size_combobox.addItem(str(font_size))
|
46
|
-
self.font_size_combobox.setCurrentText("16")
|
47
|
-
self.font_size_combobox.currentTextChanged.connect(self.update_panel_text_size)
|
48
|
-
# Buttons
|
49
|
-
self.set_ai_config_button = QPushButton(language_wrapper.language_word_dict.get("chat_ui_set_ai_button"))
|
50
|
-
self.set_ai_config_button.clicked.connect(self.set_ai_config)
|
51
|
-
self.load_ai_config_button = QPushButton(language_wrapper.language_word_dict.get("chat_ui_load_ai_button"))
|
52
|
-
self.load_ai_config_button.clicked.connect(lambda: self.load_ai_config(show_load_complete=True))
|
53
|
-
self.call_ai_model_button = QPushButton(language_wrapper.language_word_dict.get("chat_ui_call_ai_model_button"))
|
54
|
-
self.call_ai_model_button.clicked.connect(self.call_ai_model)
|
55
|
-
# Add to layout
|
56
|
-
self.grid_layout = QGridLayout()
|
57
|
-
self.grid_layout.addWidget(self.chat_panel_scroll_area, 0, 0, 1, 4)
|
58
|
-
self.grid_layout.addWidget(self.call_ai_model_button, 1, 0)
|
59
|
-
self.grid_layout.addWidget(self.font_size_combobox, 1, 1)
|
60
|
-
self.grid_layout.addWidget(self.set_ai_config_button, 1, 2)
|
61
|
-
self.grid_layout.addWidget(self.load_ai_config_button, 1, 3)
|
62
|
-
self.grid_layout.addWidget(self.prompt_input, 2, 0, 1, 4)
|
63
|
-
|
64
|
-
# Variable
|
65
|
-
self.ai_config: AIConfig = ai_config
|
66
|
-
self.lang_chain_interface: Union[LangChainInterface, None] = None
|
67
|
-
self.set_ai_config_dialog = None
|
68
|
-
# Timer to pop queue
|
69
|
-
self.pull_message_timer = QTimer(self)
|
70
|
-
self.pull_message_timer.setInterval(1000)
|
71
|
-
self.pull_message_timer.timeout.connect(self.pull_message)
|
72
|
-
self.pull_message_timer.start()
|
73
|
-
|
74
|
-
# Set layout
|
75
|
-
self.setLayout(self.grid_layout)
|
76
|
-
|
77
|
-
self.load_ai_config()
|
78
|
-
|
79
|
-
def update_panel_text_size(self):
|
80
|
-
self.chat_panel.setFont(
|
81
|
-
QFontDatabase.font(self.font().family(), "", int(self.font_size_combobox.currentText())))
|
82
|
-
|
83
|
-
def load_ai_config(self, show_load_complete: bool = False):
|
84
|
-
ai_config_file = Path(str(Path.cwd()) + "/" + ".jeditor/ai_config.json")
|
85
|
-
if ai_config_file.exists():
|
86
|
-
with open(ai_config_file, "r", encoding="utf-8"):
|
87
|
-
json_data: dict = read_json(str(ai_config_file))
|
88
|
-
if json_data:
|
89
|
-
if json_data.get("AI_model") and len(json_data.get("AI_model")) == 4:
|
90
|
-
ai_info: dict = json_data.get("AI_model")
|
91
|
-
if ai_info.get("ai_base_url") and ai_info.get("chat_model"):
|
92
|
-
ai_config.choosable_ai.update(json_data)
|
93
|
-
self.lang_chain_interface = LangChainInterface(
|
94
|
-
main_window=self,
|
95
|
-
api_key=ai_info.get("ai_api_key"),
|
96
|
-
base_url=ai_info.get("ai_base_url"),
|
97
|
-
chat_model=ai_info.get("chat_model"),
|
98
|
-
prompt_template=ai_info.get("prompt_template"),
|
99
|
-
)
|
100
|
-
if show_load_complete:
|
101
|
-
load_complete = QMessageBox(self)
|
102
|
-
load_complete.setWindowTitle(language_wrapper.language_word_dict.get("load_ai_messagebox_title"))
|
103
|
-
load_complete.setText(language_wrapper.language_word_dict.get("load_ai_messagebox_text"))
|
104
|
-
load_complete.exec()
|
105
|
-
|
106
|
-
|
107
|
-
def call_ai_model(self):
|
108
|
-
if isinstance(self.lang_chain_interface, LangChainInterface):
|
109
|
-
thread = AskThread(lang_chain_interface=self.lang_chain_interface, prompt=self.prompt_input.text())
|
110
|
-
thread.start()
|
111
|
-
else:
|
112
|
-
ai_info = ai_config.choosable_ai.get('AI_model')
|
113
|
-
QMessageBox.warning(self,
|
114
|
-
language_wrapper.language_word_dict.get("call_ai_model_error_title"),
|
115
|
-
language_wrapper.language_word_dict.get(
|
116
|
-
f"ai_api_key: {ai_info.get('ai_api_key')}, \n"
|
117
|
-
f"ai_base_url: {ai_info.get('ai_base_url')}, \n"
|
118
|
-
f"chat_model: {ai_info.get('chat_model')}, \n"
|
119
|
-
f"prompt_template: {ai_info.get('prompt_template')}"))
|
120
|
-
|
121
|
-
def pull_message(self):
|
122
|
-
if not ai_config.message_queue.empty():
|
123
|
-
ai_response = ai_config.message_queue.get_nowait()
|
124
|
-
self.chat_panel.appendPlainText(ai_response)
|
125
|
-
self.chat_panel.appendPlainText("\n")
|
126
|
-
|
127
|
-
def set_ai_config(self):
|
128
|
-
# Set and output AI a config file
|
129
|
-
self.set_ai_config_dialog = SetAIDialog()
|
130
|
-
self.set_ai_config_dialog.show()
|
@@ -1,45 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import os
|
4
|
-
import re
|
5
|
-
from typing import Union, TYPE_CHECKING
|
6
|
-
|
7
|
-
from PySide6.QtWidgets import QMessageBox
|
8
|
-
from langchain.prompts.chat import SystemMessagePromptTemplate
|
9
|
-
from langchain_openai import ChatOpenAI
|
10
|
-
from pydantic import SecretStr
|
11
|
-
|
12
|
-
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
|
13
|
-
|
14
|
-
if TYPE_CHECKING:
|
15
|
-
from je_editor.pyside_ui.main_ui.ai_widget.chat_ui import ChatUI
|
16
|
-
|
17
|
-
class LangChainInterface(object):
|
18
|
-
|
19
|
-
def __init__(self, main_window: ChatUI, prompt_template: str, base_url: str, api_key: Union[SecretStr, str],
|
20
|
-
chat_model: str):
|
21
|
-
self.system_message_prompt = SystemMessagePromptTemplate.from_template(prompt_template)
|
22
|
-
self.base_url = base_url
|
23
|
-
self.api_key = api_key
|
24
|
-
self.chat_model = chat_model
|
25
|
-
self.main_window = main_window
|
26
|
-
os.environ["OPENAI_BASE_URL"] = self.base_url
|
27
|
-
os.environ["OPENAI_API_KEY"] = self.api_key
|
28
|
-
os.environ["CHAT_MODEL"] = self.chat_model
|
29
|
-
self.chat_ai = ChatOpenAI(base_url=self.base_url, api_key=self.api_key, model=self.chat_model)
|
30
|
-
|
31
|
-
def call_ai_model(self, prompt: str) -> str | None:
|
32
|
-
message = None
|
33
|
-
try:
|
34
|
-
message = self.chat_ai.invoke(prompt).text()
|
35
|
-
match = re.search(r"</think>\s*(.*)", message, re.DOTALL)
|
36
|
-
if match:
|
37
|
-
message = match.group(1).strip()
|
38
|
-
else:
|
39
|
-
message = message
|
40
|
-
|
41
|
-
except Exception as error:
|
42
|
-
QMessageBox.warning(self.main_window,
|
43
|
-
language_wrapper.language_word_dict.get("call_ai_model_error_title"),
|
44
|
-
str(error))
|
45
|
-
return message
|
@@ -1,81 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from typing import TYPE_CHECKING
|
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
|
8
|
-
|
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
|
13
|
-
|
14
|
-
from je_editor.utils.json_format.json_process import reformat_json
|
15
|
-
|
16
|
-
|
17
|
-
def set_check_menu(ui_we_want_to_set: EditorMain) -> None:
|
18
|
-
jeditor_logger.info(f"build_check_style_menu.py set_check_menu ui_we_want_to_set: {ui_we_want_to_set}")
|
19
|
-
ui_we_want_to_set.check_menu = ui_we_want_to_set.menu.addMenu(
|
20
|
-
language_wrapper.language_word_dict.get("check_code_style_menu_label"))
|
21
|
-
# Yapf code check
|
22
|
-
ui_we_want_to_set.check_menu.yapf_check_python_action = QAction(
|
23
|
-
language_wrapper.language_word_dict.get("yapf_reformat_label"))
|
24
|
-
ui_we_want_to_set.check_menu.yapf_check_python_action.setShortcut(
|
25
|
-
QKeySequence("Ctrl+Shift+Y"))
|
26
|
-
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
|
-
)
|
30
|
-
)
|
31
|
-
ui_we_want_to_set.check_menu.addAction(ui_we_want_to_set.check_menu.yapf_check_python_action)
|
32
|
-
# Reformat JSON
|
33
|
-
ui_we_want_to_set.check_menu.reformat_json_action = QAction(
|
34
|
-
language_wrapper.language_word_dict.get("reformat_json_label"))
|
35
|
-
ui_we_want_to_set.check_menu.reformat_json_action.setShortcut("Ctrl+j")
|
36
|
-
ui_we_want_to_set.check_menu.reformat_json_action.triggered.connect(
|
37
|
-
lambda: reformat_json_text(
|
38
|
-
ui_we_want_to_set
|
39
|
-
)
|
40
|
-
)
|
41
|
-
ui_we_want_to_set.check_menu.addAction(ui_we_want_to_set.check_menu.reformat_json_action)
|
42
|
-
# Python formate check
|
43
|
-
ui_we_want_to_set.check_menu.check_python_format = QAction(
|
44
|
-
language_wrapper.language_word_dict.get("python_format_checker"))
|
45
|
-
ui_we_want_to_set.check_menu.check_python_format.setShortcut("Ctrl+Alt+p")
|
46
|
-
ui_we_want_to_set.check_menu.check_python_format.triggered.connect(
|
47
|
-
lambda: check_python_format(
|
48
|
-
ui_we_want_to_set
|
49
|
-
)
|
50
|
-
)
|
51
|
-
ui_we_want_to_set.check_menu.addAction(ui_we_want_to_set.check_menu.check_python_format)
|
52
|
-
|
53
|
-
|
54
|
-
def yapf_check_python_code(ui_we_want_to_set: EditorMain) -> None:
|
55
|
-
jeditor_logger.info(f"build_check_style_menu.py yapf_check_python_code ui_we_want_to_set: {ui_we_want_to_set}")
|
56
|
-
widget = ui_we_want_to_set.tab_widget.currentWidget()
|
57
|
-
if isinstance(widget, EditorWidget):
|
58
|
-
code_text = widget.code_edit.toPlainText()
|
59
|
-
widget.code_result.setPlainText("")
|
60
|
-
format_code = FormatCode(
|
61
|
-
unformatted_source=code_text,
|
62
|
-
style_config="google"
|
63
|
-
)
|
64
|
-
if isinstance(format_code, tuple):
|
65
|
-
widget.code_edit.setPlainText(format_code[0])
|
66
|
-
|
67
|
-
|
68
|
-
def reformat_json_text(ui_we_want_to_set: EditorMain) -> None:
|
69
|
-
jeditor_logger.info(f"build_check_style_menu.py reformat_json_text ui_we_want_to_set: {ui_we_want_to_set}")
|
70
|
-
widget = ui_we_want_to_set.tab_widget.currentWidget()
|
71
|
-
if isinstance(widget, EditorWidget):
|
72
|
-
code_text = widget.code_edit.toPlainText()
|
73
|
-
widget.code_result.setPlainText("")
|
74
|
-
widget.code_edit.setPlainText(reformat_json(code_text))
|
75
|
-
|
76
|
-
|
77
|
-
def check_python_format(ui_we_want_to_set: EditorMain) -> None:
|
78
|
-
jeditor_logger.info(f"build_check_style_menu.py check_python_format ui_we_want_to_set: {ui_we_want_to_set}")
|
79
|
-
widget = ui_we_want_to_set.tab_widget.currentWidget()
|
80
|
-
if isinstance(widget, EditorWidget):
|
81
|
-
widget.check_file_format()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|