pygpt-net 2.4.39__py3-none-any.whl → 2.4.40__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.
- CHANGELOG.md +13 -0
- README.md +19 -2
- pygpt_net/CHANGELOG.txt +13 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/__init__.py +5 -3
- pygpt_net/controller/audio/__init__.py +9 -1
- pygpt_net/controller/chat/input.py +2 -1
- pygpt_net/controller/chat/render.py +2 -2
- pygpt_net/controller/ctx/__init__.py +2 -2
- pygpt_net/controller/debug/__init__.py +13 -2
- pygpt_net/controller/kernel/__init__.py +2 -1
- pygpt_net/controller/notepad.py +7 -6
- pygpt_net/controller/theme/nodes.py +2 -5
- pygpt_net/controller/tools/__init__.py +37 -1
- pygpt_net/controller/ui/__init__.py +1 -5
- pygpt_net/controller/ui/tabs.py +104 -12
- pygpt_net/core/command.py +3 -1
- pygpt_net/core/ctx/__init__.py +6 -2
- pygpt_net/core/ctx/container.py +5 -5
- pygpt_net/core/debug/tabs.py +3 -1
- pygpt_net/core/render/base.py +2 -2
- pygpt_net/core/render/web/body.py +1 -1
- pygpt_net/core/render/web/renderer.py +208 -38
- pygpt_net/core/tabs/__init__.py +104 -43
- pygpt_net/core/tabs/tab.py +4 -1
- pygpt_net/core/web.py +127 -1
- pygpt_net/data/config/config.json +4 -3
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/modes.json +3 -3
- pygpt_net/data/css/web-blocks.css +18 -0
- pygpt_net/data/css/web-blocks.light.css +7 -0
- pygpt_net/data/css/web-chatgpt.css +8 -0
- pygpt_net/data/css/web-chatgpt_wide.css +8 -0
- pygpt_net/data/icons/split_screen.svg +1 -0
- pygpt_net/data/locale/locale.de.ini +1 -1
- pygpt_net/data/locale/locale.en.ini +4 -2
- pygpt_net/data/locale/locale.es.ini +1 -1
- pygpt_net/data/locale/locale.fr.ini +1 -1
- pygpt_net/data/locale/locale.it.ini +1 -1
- pygpt_net/data/locale/locale.pl.ini +2 -2
- pygpt_net/data/locale/locale.uk.ini +1 -1
- pygpt_net/data/locale/locale.zh.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.de.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.en.ini +20 -10
- pygpt_net/data/locale/plugin.cmd_web.es.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.fr.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.it.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.pl.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.uk.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.zh.ini +2 -0
- pygpt_net/icons.qrc +1 -0
- pygpt_net/icons_rc.py +165 -136
- pygpt_net/item/ctx.py +46 -24
- pygpt_net/plugin/audio_output/__init__.py +4 -1
- pygpt_net/plugin/base/plugin.py +18 -4
- pygpt_net/plugin/cmd_code_interpreter/__init__.py +39 -37
- pygpt_net/plugin/cmd_code_interpreter/runner.py +25 -12
- pygpt_net/plugin/cmd_web/__init__.py +46 -6
- pygpt_net/plugin/cmd_web/config.py +74 -48
- pygpt_net/plugin/cmd_web/websearch.py +61 -28
- pygpt_net/plugin/cmd_web/worker.py +79 -13
- pygpt_net/provider/core/config/patch.py +22 -1
- pygpt_net/tools/__init__.py +9 -1
- pygpt_net/tools/base.py +15 -1
- pygpt_net/tools/code_interpreter/__init__.py +174 -75
- pygpt_net/tools/code_interpreter/ui/dialogs.py +21 -103
- pygpt_net/tools/code_interpreter/ui/widgets.py +284 -9
- pygpt_net/tools/html_canvas/__init__.py +78 -23
- pygpt_net/tools/html_canvas/ui/dialogs.py +46 -62
- pygpt_net/tools/html_canvas/ui/widgets.py +96 -3
- pygpt_net/ui/base/context_menu.py +2 -2
- pygpt_net/ui/layout/ctx/ctx_list.py +13 -4
- pygpt_net/ui/layout/toolbox/footer.py +1 -1
- pygpt_net/ui/main.py +2 -2
- pygpt_net/ui/menu/debug.py +11 -1
- pygpt_net/ui/widget/filesystem/explorer.py +2 -2
- pygpt_net/ui/widget/lists/context.py +26 -5
- pygpt_net/ui/widget/tabs/Input.py +2 -2
- pygpt_net/ui/widget/tabs/body.py +2 -1
- pygpt_net/ui/widget/tabs/output.py +126 -61
- {pygpt_net-2.4.39.dist-info → pygpt_net-2.4.40.dist-info}/METADATA +20 -3
- {pygpt_net-2.4.39.dist-info → pygpt_net-2.4.40.dist-info}/RECORD +85 -84
- {pygpt_net-2.4.39.dist-info → pygpt_net-2.4.40.dist-info}/LICENSE +0 -0
- {pygpt_net-2.4.39.dist-info → pygpt_net-2.4.40.dist-info}/WHEEL +0 -0
- {pygpt_net-2.4.39.dist-info → pygpt_net-2.4.40.dist-info}/entry_points.txt +0 -0
@@ -6,20 +6,24 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2024.
|
9
|
+
# Updated Date: 2024.12.12 04:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import os
|
13
13
|
|
14
14
|
from PySide6.QtCore import QTimer
|
15
15
|
from PySide6.QtGui import QTextCursor, QAction, QIcon
|
16
|
+
from PySide6.QtWidgets import QWidget
|
16
17
|
|
18
|
+
from pygpt_net.core.tabs.tab import Tab
|
17
19
|
from pygpt_net.tools.base import BaseTool
|
18
|
-
from pygpt_net.tools.code_interpreter.ui.dialogs import
|
20
|
+
from pygpt_net.tools.code_interpreter.ui.dialogs import Tool
|
19
21
|
from pygpt_net.core.events import Event
|
20
22
|
from pygpt_net.item.ctx import CtxItem
|
21
23
|
from pygpt_net.utils import trans
|
22
24
|
|
25
|
+
from .ui.widgets import PythonInput, PythonOutput, ToolWidget, ToolSignals
|
26
|
+
|
23
27
|
|
24
28
|
class CodeInterpreter(BaseTool):
|
25
29
|
def __init__(self, *args, **kwargs):
|
@@ -30,11 +34,15 @@ class CodeInterpreter(BaseTool):
|
|
30
34
|
"""
|
31
35
|
super(CodeInterpreter, self).__init__(*args, **kwargs)
|
32
36
|
self.id = "interpreter"
|
37
|
+
self.has_tab = True
|
38
|
+
self.tab_title = "menu.tools.interpreter"
|
39
|
+
self.tab_icon = ":/icons/code.svg"
|
33
40
|
self.opened = False
|
34
41
|
self.is_edit = False
|
35
42
|
self.auto_clear = False
|
36
43
|
self.dialog = None
|
37
44
|
self.ipython = True
|
45
|
+
self.signals = ToolSignals()
|
38
46
|
|
39
47
|
# interpreter data files in /data directory
|
40
48
|
self.file_current = ".interpreter.current.py"
|
@@ -49,15 +57,15 @@ class CodeInterpreter(BaseTool):
|
|
49
57
|
|
50
58
|
# restore
|
51
59
|
if self.window.core.config.has("interpreter.input"):
|
52
|
-
self.
|
60
|
+
self.signals.update_input.emit(self.window.core.config.get("interpreter.input"))
|
53
61
|
if self.window.core.config.has("interpreter.execute_all"):
|
54
|
-
self.
|
62
|
+
self.signals.set_checkbox_all.emit(self.window.core.config.get("interpreter.execute_all"))
|
55
63
|
if self.window.core.config.has("interpreter.auto_clear"):
|
56
|
-
self.
|
64
|
+
self.signals.set_checkbox_auto_clear.emit(self.window.core.config.get("interpreter.auto_clear"))
|
57
65
|
if self.window.core.config.has("interpreter.ipython"):
|
58
|
-
self.
|
66
|
+
self.signals.set_checkbox_ipython.emit(self.window.core.config.get("interpreter.ipython"))
|
59
67
|
if self.ipython:
|
60
|
-
self.
|
68
|
+
self.signals.toggle_all_visible.emit(False)
|
61
69
|
|
62
70
|
# set initial size
|
63
71
|
if not self.window.core.config.has("interpreter.dialog.initialized"):
|
@@ -119,28 +127,62 @@ class CodeInterpreter(BaseTool):
|
|
119
127
|
:param type: Output type
|
120
128
|
:param kwargs: Additional parameters
|
121
129
|
"""
|
122
|
-
|
123
|
-
if type == "stdin":
|
124
|
-
data = ">> " + str(output)
|
125
|
-
else:
|
126
|
-
data = str(output)
|
127
|
-
cur = area.textCursor()
|
128
|
-
cur.movePosition(QTextCursor.End)
|
129
|
-
s = data + "\n"
|
130
|
-
while s:
|
131
|
-
head, sep, s = s.partition("\n")
|
132
|
-
cur.insertText(head)
|
133
|
-
if sep: # New line if LF
|
134
|
-
cur.insertText("\n")
|
135
|
-
area.setTextCursor(cur)
|
130
|
+
self.signals.update.emit(output, type)
|
136
131
|
self.save_output()
|
137
132
|
self.load_history()
|
138
133
|
|
134
|
+
def get_path_input(self) -> str:
|
135
|
+
"""
|
136
|
+
Get input path
|
137
|
+
|
138
|
+
:return: Input path
|
139
|
+
"""
|
140
|
+
return os.path.join(self.window.core.config.get_user_dir("data"), self.file_input)
|
141
|
+
|
142
|
+
def get_path_output(self) -> str:
|
143
|
+
"""
|
144
|
+
Get output path
|
145
|
+
|
146
|
+
:return: Output path
|
147
|
+
"""
|
148
|
+
return os.path.join(self.window.core.config.get_user_dir("data"), self.file_output)
|
149
|
+
|
150
|
+
def get_widget(self) -> ToolWidget:
|
151
|
+
"""
|
152
|
+
Get tool widget
|
153
|
+
|
154
|
+
:return: ToolWidget instance
|
155
|
+
"""
|
156
|
+
return self.dialog.widget
|
157
|
+
|
158
|
+
def get_widget_history(self) -> PythonOutput:
|
159
|
+
"""
|
160
|
+
Get history widget
|
161
|
+
|
162
|
+
:return: PythonOutput widget
|
163
|
+
"""
|
164
|
+
return self.dialog.widget.history
|
165
|
+
|
166
|
+
def get_widget_output(self) -> PythonOutput:
|
167
|
+
"""
|
168
|
+
Get output widget
|
169
|
+
|
170
|
+
:return: PythonOutput widget
|
171
|
+
"""
|
172
|
+
return self.dialog.widget.output
|
173
|
+
|
174
|
+
def get_widget_input(self) -> PythonInput:
|
175
|
+
"""
|
176
|
+
Get input widget
|
177
|
+
|
178
|
+
:return: PythonInput widget
|
179
|
+
"""
|
180
|
+
return self.dialog.widget.input
|
181
|
+
|
139
182
|
def load_history(self):
|
140
183
|
"""Load history data from file"""
|
141
184
|
data = self.get_history()
|
142
|
-
self.
|
143
|
-
self.cursor_to_end()
|
185
|
+
self.signals.update_history.emit(data)
|
144
186
|
|
145
187
|
def get_output(self) -> str:
|
146
188
|
"""
|
@@ -149,7 +191,7 @@ class CodeInterpreter(BaseTool):
|
|
149
191
|
:return: Output data
|
150
192
|
"""
|
151
193
|
data = ""
|
152
|
-
path =
|
194
|
+
path = self.get_path_output()
|
153
195
|
if os.path.exists(path):
|
154
196
|
with open(path, "r", encoding="utf-8") as f:
|
155
197
|
try:
|
@@ -161,13 +203,13 @@ class CodeInterpreter(BaseTool):
|
|
161
203
|
def load_output(self):
|
162
204
|
"""Load output data from file"""
|
163
205
|
data = self.get_output()
|
164
|
-
self.
|
165
|
-
self.
|
206
|
+
self.signals.update.emit(data, "stdout")
|
207
|
+
self.signals.focus_input.emit()
|
166
208
|
|
167
209
|
def save_output(self):
|
168
210
|
"""Save output data to file"""
|
169
|
-
path =
|
170
|
-
data = self.
|
211
|
+
path = self.get_path_output()
|
212
|
+
data = self.get_widget_output().toPlainText()
|
171
213
|
with open(path, "w", encoding="utf-8") as f:
|
172
214
|
f.write(data)
|
173
215
|
|
@@ -178,7 +220,7 @@ class CodeInterpreter(BaseTool):
|
|
178
220
|
:return: History data
|
179
221
|
"""
|
180
222
|
data = ""
|
181
|
-
path =
|
223
|
+
path = self.get_path_input()
|
182
224
|
if os.path.exists(path):
|
183
225
|
with open(path, "r", encoding="utf-8") as f:
|
184
226
|
try:
|
@@ -193,23 +235,23 @@ class CodeInterpreter(BaseTool):
|
|
193
235
|
|
194
236
|
:param input: Input data
|
195
237
|
"""
|
196
|
-
path =
|
238
|
+
path = self.get_path_input()
|
197
239
|
with open(path , "w", encoding="utf-8") as f:
|
198
240
|
f.write(input)
|
199
241
|
|
200
242
|
def clear_history(self):
|
201
243
|
"""Clear input"""
|
202
|
-
path =
|
244
|
+
path = self.get_path_input()
|
203
245
|
if os.path.exists(path):
|
204
246
|
os.remove(path)
|
205
|
-
self.
|
247
|
+
self.signals.clear_history.emit()
|
206
248
|
|
207
249
|
def clear_output(self):
|
208
250
|
"""Clear output"""
|
209
|
-
path =
|
251
|
+
path = self.get_path_output()
|
210
252
|
if os.path.exists(path):
|
211
253
|
os.remove(path)
|
212
|
-
self.
|
254
|
+
self.signals.clear_output.emit()
|
213
255
|
|
214
256
|
def clear(self, force: bool = False):
|
215
257
|
"""
|
@@ -248,15 +290,32 @@ class CodeInterpreter(BaseTool):
|
|
248
290
|
})
|
249
291
|
event.ctx = CtxItem() # tmp
|
250
292
|
self.window.controller.command.dispatch_only(event)
|
251
|
-
self.
|
293
|
+
self.signals.focus_input.emit()
|
294
|
+
|
295
|
+
def send_input(self, widget: ToolWidget):
|
296
|
+
"""
|
297
|
+
Send input to interpreter
|
252
298
|
|
253
|
-
|
254
|
-
"""
|
255
|
-
self.store_history()
|
299
|
+
:param widget: PythonInput widget
|
300
|
+
"""
|
301
|
+
self.store_history(widget)
|
256
302
|
if self.auto_clear:
|
257
303
|
self.clear_output()
|
258
304
|
|
259
|
-
|
305
|
+
input_textarea = widget.input
|
306
|
+
input = str(input_textarea.toPlainText()).strip()
|
307
|
+
|
308
|
+
if input == "/restart":
|
309
|
+
self.restart_kernel()
|
310
|
+
input_textarea.clear()
|
311
|
+
input_textarea.setFocus()
|
312
|
+
return
|
313
|
+
elif input == "/clear":
|
314
|
+
self.clear(force=True)
|
315
|
+
input_textarea.clear()
|
316
|
+
input_textarea.setFocus()
|
317
|
+
return
|
318
|
+
|
260
319
|
if self.is_all():
|
261
320
|
cmd = "code_execute_all"
|
262
321
|
else:
|
@@ -284,12 +343,12 @@ class CodeInterpreter(BaseTool):
|
|
284
343
|
})
|
285
344
|
event.ctx = CtxItem() # tmp
|
286
345
|
self.window.controller.command.dispatch_only(event)
|
287
|
-
|
288
|
-
|
346
|
+
input_textarea.clear()
|
347
|
+
input_textarea.setFocus()
|
289
348
|
|
290
349
|
def update_input(self):
|
291
350
|
"""Update input data"""
|
292
|
-
data = self.
|
351
|
+
data = self.get_widget_input().toPlainText()
|
293
352
|
self.window.core.config.set("interpreter.input", data)
|
294
353
|
|
295
354
|
def append_to_input(self, data: str):
|
@@ -298,11 +357,7 @@ class CodeInterpreter(BaseTool):
|
|
298
357
|
|
299
358
|
:param data: Data
|
300
359
|
"""
|
301
|
-
|
302
|
-
if current:
|
303
|
-
current += "\n"
|
304
|
-
current += data
|
305
|
-
self.window.ui.nodes['interpreter.input'].setPlainText(current)
|
360
|
+
self.signals.append_input.emit(data)
|
306
361
|
|
307
362
|
def append_to_edit(self, data: str):
|
308
363
|
"""
|
@@ -317,9 +372,15 @@ class CodeInterpreter(BaseTool):
|
|
317
372
|
self.save_history(prev)
|
318
373
|
self.load_history()
|
319
374
|
|
320
|
-
def store_history(self):
|
321
|
-
"""
|
322
|
-
data
|
375
|
+
def store_history(self, widget: ToolWidget):
|
376
|
+
"""
|
377
|
+
Save history data to file
|
378
|
+
|
379
|
+
:param widget: ToolWidget
|
380
|
+
"""
|
381
|
+
if not widget.history:
|
382
|
+
return
|
383
|
+
data = widget.history.toPlainText()
|
323
384
|
self.save_history(data)
|
324
385
|
|
325
386
|
def open(self):
|
@@ -328,7 +389,7 @@ class CodeInterpreter(BaseTool):
|
|
328
389
|
self.load_history()
|
329
390
|
self.load_output()
|
330
391
|
self.window.ui.dialogs.open('interpreter', width=800, height=600)
|
331
|
-
self.
|
392
|
+
self.get_widget_input().setFocus()
|
332
393
|
self.cursor_to_end()
|
333
394
|
self.scroll_to_bottom()
|
334
395
|
self.update()
|
@@ -341,11 +402,11 @@ class CodeInterpreter(BaseTool):
|
|
341
402
|
|
342
403
|
def scroll_to_bottom(self):
|
343
404
|
"""Scroll down"""
|
344
|
-
self.
|
345
|
-
self.
|
405
|
+
self.get_widget_history().verticalScrollBar().setValue(
|
406
|
+
self.get_widget_history().verticalScrollBar().maximum()
|
346
407
|
)
|
347
|
-
self.
|
348
|
-
self.
|
408
|
+
self.get_widget_output().verticalScrollBar().setValue(
|
409
|
+
self.get_widget_output().verticalScrollBar().maximum()
|
349
410
|
)
|
350
411
|
|
351
412
|
def toggle(self):
|
@@ -366,31 +427,55 @@ class CodeInterpreter(BaseTool):
|
|
366
427
|
else:
|
367
428
|
self.close()
|
368
429
|
|
430
|
+
def get_toolbar_icon(self) -> QWidget:
|
431
|
+
"""
|
432
|
+
Get toolbar icon
|
433
|
+
|
434
|
+
:return: QWidget
|
435
|
+
"""
|
436
|
+
return self.window.ui.nodes['icon.interpreter']
|
437
|
+
|
369
438
|
def toggle_icon(self, state: bool):
|
370
439
|
"""
|
371
440
|
Toggle interpreter icon
|
372
441
|
|
373
442
|
:param state: State
|
374
443
|
"""
|
375
|
-
self.
|
444
|
+
self.get_toolbar_icon().setVisible(state)
|
376
445
|
|
377
|
-
def toggle_auto_clear(self):
|
378
|
-
"""
|
379
|
-
|
446
|
+
def toggle_auto_clear(self, widget: ToolWidget):
|
447
|
+
"""
|
448
|
+
Toggle auto clear
|
449
|
+
|
450
|
+
:param widget: ToolWidget instance
|
451
|
+
"""
|
452
|
+
self.auto_clear = widget.checkbox_auto_clear.isChecked()
|
380
453
|
self.window.core.config.set("interpreter.auto_clear", self.auto_clear)
|
454
|
+
self.signals.set_checkbox_auto_clear.emit(self.auto_clear)
|
455
|
+
|
456
|
+
def toggle_ipython(self, widget: ToolWidget):
|
457
|
+
"""
|
458
|
+
Toggle ipython
|
381
459
|
|
382
|
-
|
383
|
-
"""
|
384
|
-
self.ipython =
|
460
|
+
:param widget: ToolWidget instance
|
461
|
+
"""
|
462
|
+
self.ipython = widget.checkbox_ipython.isChecked()
|
385
463
|
self.window.core.config.set("interpreter.ipython", self.ipython)
|
464
|
+
self.signals.set_checkbox_ipython.emit(self.ipython)
|
386
465
|
if self.ipython:
|
387
|
-
self.
|
466
|
+
self.signals.toggle_all_visible.emit(False)
|
388
467
|
else:
|
389
|
-
self.
|
468
|
+
self.signals.toggle_all_visible.emit(True)
|
469
|
+
|
470
|
+
def toggle_all(self, widget: ToolWidget):
|
471
|
+
"""
|
472
|
+
Toggle execute all
|
390
473
|
|
391
|
-
|
392
|
-
"""
|
393
|
-
|
474
|
+
:param widget: ToolWidget instance
|
475
|
+
"""
|
476
|
+
state = widget.checkbox_all.isChecked()
|
477
|
+
self.window.core.config.set("interpreter.execute_all", state)
|
478
|
+
self.signals.set_checkbox_all.emit(state)
|
394
479
|
|
395
480
|
def get_current_output(self) -> str:
|
396
481
|
"""
|
@@ -398,7 +483,7 @@ class CodeInterpreter(BaseTool):
|
|
398
483
|
|
399
484
|
:return: Output data
|
400
485
|
"""
|
401
|
-
return self.
|
486
|
+
return self.get_output()
|
402
487
|
|
403
488
|
def get_current_history(self) -> str:
|
404
489
|
"""
|
@@ -406,7 +491,7 @@ class CodeInterpreter(BaseTool):
|
|
406
491
|
|
407
492
|
:return: Edit code
|
408
493
|
"""
|
409
|
-
return self.
|
494
|
+
return self.get_history()
|
410
495
|
|
411
496
|
def is_all(self) -> bool:
|
412
497
|
"""
|
@@ -414,13 +499,13 @@ class CodeInterpreter(BaseTool):
|
|
414
499
|
|
415
500
|
:return: True if execute all is enabled
|
416
501
|
"""
|
417
|
-
return self.
|
502
|
+
return self.get_widget().checkbox_all.isChecked()
|
418
503
|
|
419
504
|
def cursor_to_end(self):
|
420
505
|
"""Move cursor to end"""
|
421
|
-
cur = self.
|
506
|
+
cur = self.get_widget_history().textCursor()
|
422
507
|
cur.movePosition(QTextCursor.End)
|
423
|
-
self.
|
508
|
+
self.get_widget_history().setTextCursor(cur)
|
424
509
|
|
425
510
|
def setup_menu(self) -> dict:
|
426
511
|
"""
|
@@ -440,15 +525,29 @@ class CodeInterpreter(BaseTool):
|
|
440
525
|
)
|
441
526
|
return actions
|
442
527
|
|
528
|
+
def as_tab(self, tab: Tab) -> QWidget:
|
529
|
+
"""
|
530
|
+
Spawn and return tab instance
|
531
|
+
|
532
|
+
:param tab: Parent Tab instance
|
533
|
+
:return: Tab widget instance
|
534
|
+
"""
|
535
|
+
tool = Tool(window=self.window, tool=self)
|
536
|
+
layout = tool.widget.setup(all=False)
|
537
|
+
widget = QWidget()
|
538
|
+
widget.setLayout(layout)
|
539
|
+
self.load_history()
|
540
|
+
self.load_output()
|
541
|
+
return widget
|
542
|
+
|
443
543
|
def setup_dialogs(self):
|
444
544
|
"""Setup dialogs (static)"""
|
445
|
-
self.dialog =
|
545
|
+
self.dialog = Tool(self.window, self)
|
446
546
|
self.dialog.setup()
|
447
547
|
|
448
548
|
def setup_theme(self):
|
449
549
|
"""Setup theme"""
|
450
|
-
|
451
|
-
self.window.interpreter.value = size
|
550
|
+
self.get_widget_output().value = self.window.core.config.get('font_size')
|
452
551
|
|
453
552
|
def get_lang_mappings(self) -> dict:
|
454
553
|
"""
|
@@ -6,25 +6,29 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2024.
|
9
|
+
# Updated Date: 2024.12.12 01:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtCore import Qt
|
13
13
|
from PySide6.QtGui import QAction, QIcon
|
14
|
-
from PySide6.QtWidgets import
|
14
|
+
from PySide6.QtWidgets import QMenuBar
|
15
15
|
|
16
|
-
from pygpt_net.tools.code_interpreter.ui.widgets import
|
16
|
+
from pygpt_net.tools.code_interpreter.ui.widgets import ToolWidget
|
17
17
|
from pygpt_net.ui.widget.dialog.base import BaseDialog
|
18
18
|
from pygpt_net.utils import trans
|
19
19
|
|
20
|
-
class
|
21
|
-
def __init__(self, window=None):
|
20
|
+
class Tool:
|
21
|
+
def __init__(self, window=None, tool=None):
|
22
22
|
"""
|
23
23
|
Python interpreter dialog
|
24
24
|
|
25
25
|
:param window: Window instance
|
26
|
+
:param tool: Tool instance
|
26
27
|
"""
|
27
28
|
self.window = window
|
29
|
+
self.tool = tool # tool instance
|
30
|
+
self.layout = None
|
31
|
+
self.widget = ToolWidget(window, tool)
|
28
32
|
self.menu_bar = None
|
29
33
|
self.menu = {}
|
30
34
|
self.actions = {} # menu actions
|
@@ -43,23 +47,23 @@ class Interpreter:
|
|
43
47
|
self.actions["file.clear_output"] = QAction(QIcon(":/icons/close.svg"),
|
44
48
|
trans("interpreter.menu.file.clear_output"))
|
45
49
|
self.actions["file.clear_output"].triggered.connect(
|
46
|
-
lambda: self.
|
50
|
+
lambda: self.tool.clear_output()
|
47
51
|
)
|
48
52
|
self.actions["file.clear_history"] = QAction(QIcon(":/icons/close.svg"),
|
49
53
|
trans("interpreter.menu.file.clear_history"))
|
50
54
|
self.actions["file.clear_history"].triggered.connect(
|
51
|
-
lambda: self.
|
55
|
+
lambda: self.tool.clear_history()
|
52
56
|
)
|
53
57
|
self.actions["file.clear_all"] = QAction(QIcon(":/icons/close.svg"),
|
54
58
|
trans("interpreter.menu.file.clear_all"))
|
55
59
|
self.actions["file.clear_all"].triggered.connect(
|
56
|
-
lambda: self.
|
60
|
+
lambda: self.tool.clear_all()
|
57
61
|
)
|
58
62
|
|
59
63
|
self.actions["kernel.restart"] = QAction(QIcon(":/icons/reload.svg"),
|
60
64
|
trans("interpreter.menu.kernel.restart"))
|
61
65
|
self.actions["kernel.restart"].triggered.connect(
|
62
|
-
lambda: self.
|
66
|
+
lambda: self.tool.restart_kernel()
|
63
67
|
)
|
64
68
|
|
65
69
|
# add actions
|
@@ -71,102 +75,16 @@ class Interpreter:
|
|
71
75
|
|
72
76
|
def setup(self):
|
73
77
|
"""Setup interpreter dialog"""
|
74
|
-
self.
|
75
|
-
self.
|
78
|
+
self.layout = self.widget.setup(all=True)
|
79
|
+
self.layout.setMenuBar(self.setup_menu()) # add menu bar
|
76
80
|
|
77
|
-
self.window.ui.
|
78
|
-
self.window.ui.
|
79
|
-
lambda: self.window.tools.get("interpreter").store_history()
|
80
|
-
)
|
81
|
-
self.window.ui.nodes['interpreter.code'].setReadOnly(False)
|
82
|
-
self.window.ui.nodes['interpreter.code'].excluded_copy_to = ["interpreter_edit"]
|
83
|
-
|
84
|
-
self.window.ui.nodes['interpreter.output_label'] = QLabel(trans("interpreter.edit_label.output"))
|
85
|
-
self.window.ui.nodes['interpreter.edit_label'] = QLabel(trans("interpreter.edit_label.edit"))
|
86
|
-
|
87
|
-
self.window.ui.nodes['interpreter.all'] = QCheckBox(trans("interpreter.all"))
|
88
|
-
self.window.ui.nodes['interpreter.all'].setChecked(True)
|
89
|
-
self.window.ui.nodes['interpreter.all'].clicked.connect(
|
90
|
-
lambda: self.window.tools.get("interpreter").toggle_all()
|
91
|
-
)
|
92
|
-
|
93
|
-
self.window.ui.nodes['interpreter.auto_clear'] = QCheckBox(trans("interpreter.auto_clear"))
|
94
|
-
self.window.ui.nodes['interpreter.auto_clear'].setChecked(False)
|
95
|
-
self.window.ui.nodes['interpreter.auto_clear'].clicked.connect(
|
96
|
-
lambda: self.window.tools.get("interpreter").toggle_auto_clear()
|
97
|
-
)
|
98
|
-
|
99
|
-
self.window.ui.nodes['interpreter.ipython'] = QCheckBox("IPython")
|
100
|
-
self.window.ui.nodes['interpreter.ipython'].setChecked(True)
|
101
|
-
self.window.ui.nodes['interpreter.ipython'].clicked.connect(
|
102
|
-
lambda: self.window.tools.get("interpreter").toggle_ipython()
|
103
|
-
)
|
104
|
-
|
105
|
-
self.window.ui.nodes['interpreter.btn.clear'] = QPushButton(trans("interpreter.btn.clear"))
|
106
|
-
self.window.ui.nodes['interpreter.btn.clear'].clicked.connect(
|
107
|
-
lambda: self.window.tools.get("interpreter").clear())
|
108
|
-
|
109
|
-
self.window.ui.nodes['interpreter.btn.send'] = QPushButton(trans("interpreter.btn.send"))
|
110
|
-
self.window.ui.nodes['interpreter.btn.send'].clicked.connect(
|
111
|
-
lambda: self.window.tools.get("interpreter").send_input()
|
112
|
-
)
|
113
|
-
|
114
|
-
self.window.ui.nodes['interpreter.input'] = PythonInput(self.window)
|
115
|
-
self.window.ui.nodes['interpreter.input'].setPlaceholderText(trans("interpreter.input.placeholder"))
|
116
|
-
self.window.ui.nodes['interpreter.input'].excluded_copy_to = ["interpreter_input"]
|
117
|
-
|
118
|
-
left_layout = QVBoxLayout()
|
119
|
-
left_layout.addWidget(self.window.ui.nodes['interpreter.output_label'])
|
120
|
-
left_layout.addWidget(self.window.interpreter)
|
121
|
-
left_layout.setContentsMargins(0, 0, 0, 0)
|
122
|
-
left_widget = QWidget()
|
123
|
-
left_widget.setLayout(left_layout)
|
124
|
-
|
125
|
-
right_layout = QVBoxLayout()
|
126
|
-
right_layout.addWidget(self.window.ui.nodes['interpreter.edit_label'])
|
127
|
-
right_layout.addWidget(self.window.ui.nodes['interpreter.code'])
|
128
|
-
right_layout.setContentsMargins(0, 0, 0, 0)
|
129
|
-
right_widget = QWidget()
|
130
|
-
right_widget.setLayout(right_layout)
|
131
|
-
right_widget.setMinimumWidth(300)
|
132
|
-
|
133
|
-
self.window.ui.splitters['interpreter.columns'] = QSplitter(Qt.Horizontal)
|
134
|
-
self.window.ui.splitters['interpreter.columns'].addWidget(left_widget)
|
135
|
-
self.window.ui.splitters['interpreter.columns'].addWidget(right_widget)
|
136
|
-
|
137
|
-
bottom_layout = QHBoxLayout()
|
138
|
-
bottom_layout.addWidget(self.window.ui.nodes['interpreter.btn.clear'])
|
139
|
-
bottom_layout.addWidget(self.window.ui.nodes['interpreter.ipython'])
|
140
|
-
bottom_layout.addWidget(self.window.ui.nodes['interpreter.auto_clear'])
|
141
|
-
bottom_layout.addStretch()
|
142
|
-
bottom_layout.addWidget(self.window.ui.nodes['interpreter.all'])
|
143
|
-
bottom_layout.addWidget(self.window.ui.nodes['interpreter.btn.send'])
|
144
|
-
|
145
|
-
edit_layout = QVBoxLayout()
|
146
|
-
edit_layout.addWidget(self.window.ui.splitters['interpreter.columns'])
|
147
|
-
edit_layout.setContentsMargins(0, 0, 0, 0)
|
148
|
-
|
149
|
-
edit_widget = QWidget()
|
150
|
-
edit_widget.setLayout(edit_layout)
|
151
|
-
|
152
|
-
self.window.ui.splitters['interpreter'] = QSplitter(Qt.Vertical)
|
153
|
-
self.window.ui.splitters['interpreter'].addWidget(edit_widget)
|
154
|
-
self.window.ui.splitters['interpreter'].addWidget(self.window.ui.nodes['interpreter.input'])
|
155
|
-
self.window.ui.splitters['interpreter'].setStretchFactor(0, 4)
|
156
|
-
self.window.ui.splitters['interpreter'].setStretchFactor(1, 1)
|
157
|
-
|
158
|
-
layout = QVBoxLayout()
|
159
|
-
layout.setMenuBar(self.setup_menu()) # add menu bar
|
160
|
-
layout.addWidget(self.window.ui.splitters['interpreter'])
|
161
|
-
layout.addLayout(bottom_layout)
|
162
|
-
|
163
|
-
self.window.ui.dialog['interpreter'] = InterpreterDialog(self.window)
|
164
|
-
self.window.ui.dialog['interpreter'].setLayout(layout)
|
81
|
+
self.window.ui.dialog['interpreter'] = ToolDialog(self.window)
|
82
|
+
self.window.ui.dialog['interpreter'].setLayout(self.layout)
|
165
83
|
self.window.ui.dialog['interpreter'].setWindowTitle(trans("dialog.interpreter.title"))
|
166
84
|
self.window.ui.dialog['interpreter'].resize(800, 500)
|
167
85
|
|
168
86
|
|
169
|
-
class
|
87
|
+
class ToolDialog(BaseDialog):
|
170
88
|
def __init__(self, window=None, id="interpreter"):
|
171
89
|
"""
|
172
90
|
Interpreter dialog
|
@@ -174,7 +92,7 @@ class InterpreterDialog(BaseDialog):
|
|
174
92
|
:param window: main window
|
175
93
|
:param id: logger id
|
176
94
|
"""
|
177
|
-
super(
|
95
|
+
super(ToolDialog, self).__init__(window, id)
|
178
96
|
self.window = window
|
179
97
|
|
180
98
|
def closeEvent(self, event):
|
@@ -184,7 +102,7 @@ class InterpreterDialog(BaseDialog):
|
|
184
102
|
:param event: close event
|
185
103
|
"""
|
186
104
|
self.cleanup()
|
187
|
-
super(
|
105
|
+
super(ToolDialog, self).closeEvent(event)
|
188
106
|
|
189
107
|
def keyPressEvent(self, event):
|
190
108
|
"""
|
@@ -196,7 +114,7 @@ class InterpreterDialog(BaseDialog):
|
|
196
114
|
self.cleanup()
|
197
115
|
self.close() # close dialog when the Esc key is pressed.
|
198
116
|
else:
|
199
|
-
super(
|
117
|
+
super(ToolDialog, self).keyPressEvent(event)
|
200
118
|
|
201
119
|
def cleanup(self):
|
202
120
|
"""
|