pygpt-net 2.6.21__py3-none-any.whl → 2.6.22__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.
- pygpt_net/CHANGELOG.txt +4 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +3 -1
- pygpt_net/controller/__init__.py +4 -8
- pygpt_net/controller/access/voice.py +2 -2
- pygpt_net/controller/assistant/batch.py +2 -3
- pygpt_net/controller/assistant/editor.py +2 -2
- pygpt_net/controller/assistant/files.py +2 -3
- pygpt_net/controller/assistant/store.py +2 -2
- pygpt_net/controller/audio/audio.py +2 -2
- pygpt_net/controller/ctx/ctx.py +2 -1
- pygpt_net/controller/idx/indexer.py +85 -76
- pygpt_net/controller/lang/lang.py +52 -34
- pygpt_net/controller/model/importer.py +2 -2
- pygpt_net/controller/notepad/notepad.py +86 -84
- pygpt_net/controller/plugins/settings.py +3 -4
- pygpt_net/controller/settings/profile.py +105 -124
- pygpt_net/controller/theme/menu.py +154 -57
- pygpt_net/controller/theme/nodes.py +51 -44
- pygpt_net/controller/theme/theme.py +33 -9
- pygpt_net/controller/tools/tools.py +2 -2
- pygpt_net/controller/ui/tabs.py +2 -3
- pygpt_net/core/ctx/container.py +13 -12
- pygpt_net/core/ctx/output.py +7 -4
- pygpt_net/core/debug/console/console.py +2 -2
- pygpt_net/core/filesystem/actions.py +1 -2
- pygpt_net/core/render/plain/helpers.py +2 -5
- pygpt_net/core/render/plain/renderer.py +26 -30
- pygpt_net/core/render/web/body.py +1 -1
- pygpt_net/core/settings/settings.py +43 -13
- pygpt_net/core/tabs/tabs.py +20 -13
- pygpt_net/data/config/config.json +4 -4
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/locale/locale.de.ini +4 -1
- pygpt_net/data/locale/locale.en.ini +4 -1
- pygpt_net/data/locale/locale.es.ini +4 -1
- pygpt_net/data/locale/locale.fr.ini +4 -1
- pygpt_net/data/locale/locale.it.ini +4 -1
- pygpt_net/data/locale/locale.pl.ini +5 -4
- pygpt_net/data/locale/locale.uk.ini +4 -1
- pygpt_net/data/locale/locale.zh.ini +4 -1
- pygpt_net/plugin/twitter/plugin.py +2 -2
- pygpt_net/tools/audio_transcriber/ui/dialogs.py +44 -54
- pygpt_net/tools/code_interpreter/body.py +1 -2
- pygpt_net/tools/code_interpreter/tool.py +7 -4
- pygpt_net/tools/code_interpreter/ui/html.py +1 -3
- pygpt_net/tools/code_interpreter/ui/widgets.py +2 -3
- pygpt_net/tools/html_canvas/ui/widgets.py +1 -3
- pygpt_net/tools/image_viewer/ui/dialogs.py +40 -37
- pygpt_net/tools/indexer/ui/widgets.py +2 -4
- pygpt_net/tools/media_player/tool.py +2 -5
- pygpt_net/tools/media_player/ui/widgets.py +60 -36
- pygpt_net/tools/text_editor/ui/widgets.py +18 -19
- pygpt_net/tools/translator/ui/widgets.py +39 -35
- pygpt_net/ui/base/context_menu.py +9 -4
- pygpt_net/ui/dialog/db.py +1 -3
- pygpt_net/ui/dialog/models.py +1 -3
- pygpt_net/ui/dialog/models_importer.py +2 -4
- pygpt_net/ui/dialogs.py +34 -30
- pygpt_net/ui/layout/chat/attachments.py +72 -84
- pygpt_net/ui/layout/chat/attachments_ctx.py +40 -44
- pygpt_net/ui/layout/chat/attachments_uploaded.py +36 -39
- pygpt_net/ui/layout/chat/calendar.py +100 -70
- pygpt_net/ui/layout/chat/chat.py +23 -17
- pygpt_net/ui/layout/chat/input.py +95 -118
- pygpt_net/ui/layout/chat/output.py +100 -162
- pygpt_net/ui/layout/chat/painter.py +89 -61
- pygpt_net/ui/layout/ctx/ctx_list.py +43 -52
- pygpt_net/ui/layout/status.py +23 -14
- pygpt_net/ui/layout/toolbox/agent.py +27 -38
- pygpt_net/ui/layout/toolbox/agent_llama.py +42 -45
- pygpt_net/ui/layout/toolbox/assistants.py +42 -38
- pygpt_net/ui/layout/toolbox/computer_env.py +32 -23
- pygpt_net/ui/layout/toolbox/footer.py +13 -16
- pygpt_net/ui/layout/toolbox/image.py +18 -21
- pygpt_net/ui/layout/toolbox/indexes.py +46 -89
- pygpt_net/ui/layout/toolbox/mode.py +20 -7
- pygpt_net/ui/layout/toolbox/model.py +12 -10
- pygpt_net/ui/layout/toolbox/presets.py +68 -52
- pygpt_net/ui/layout/toolbox/prompt.py +31 -58
- pygpt_net/ui/layout/toolbox/toolbox.py +25 -21
- pygpt_net/ui/layout/toolbox/vision.py +20 -22
- pygpt_net/ui/main.py +2 -4
- pygpt_net/ui/menu/about.py +64 -84
- pygpt_net/ui/menu/audio.py +87 -63
- pygpt_net/ui/menu/config.py +121 -127
- pygpt_net/ui/menu/debug.py +69 -76
- pygpt_net/ui/menu/file.py +32 -35
- pygpt_net/ui/menu/menu.py +2 -3
- pygpt_net/ui/menu/plugins.py +69 -33
- pygpt_net/ui/menu/theme.py +45 -46
- pygpt_net/ui/menu/tools.py +56 -60
- pygpt_net/ui/menu/video.py +20 -25
- pygpt_net/ui/tray.py +1 -2
- pygpt_net/ui/widget/audio/bar.py +1 -3
- pygpt_net/ui/widget/audio/input_button.py +3 -4
- pygpt_net/ui/widget/calendar/select.py +1 -2
- pygpt_net/ui/widget/dialog/base.py +12 -9
- pygpt_net/ui/widget/dialog/editor_file.py +20 -23
- pygpt_net/ui/widget/dialog/find.py +25 -24
- pygpt_net/ui/widget/dialog/profile.py +57 -53
- pygpt_net/ui/widget/draw/painter.py +62 -93
- pygpt_net/ui/widget/element/button.py +42 -30
- pygpt_net/ui/widget/element/checkbox.py +23 -15
- pygpt_net/ui/widget/element/group.py +6 -5
- pygpt_net/ui/widget/element/labels.py +1 -2
- pygpt_net/ui/widget/filesystem/explorer.py +93 -102
- pygpt_net/ui/widget/image/display.py +1 -2
- pygpt_net/ui/widget/lists/assistant.py +1 -2
- pygpt_net/ui/widget/lists/attachment.py +1 -2
- pygpt_net/ui/widget/lists/attachment_ctx.py +1 -2
- pygpt_net/ui/widget/lists/context.py +2 -4
- pygpt_net/ui/widget/lists/index.py +1 -2
- pygpt_net/ui/widget/lists/model.py +1 -2
- pygpt_net/ui/widget/lists/model_editor.py +1 -2
- pygpt_net/ui/widget/lists/model_importer.py +1 -2
- pygpt_net/ui/widget/lists/preset.py +1 -2
- pygpt_net/ui/widget/lists/preset_plugins.py +1 -2
- pygpt_net/ui/widget/lists/profile.py +1 -2
- pygpt_net/ui/widget/lists/uploaded.py +1 -2
- pygpt_net/ui/widget/option/checkbox.py +2 -4
- pygpt_net/ui/widget/option/checkbox_list.py +1 -4
- pygpt_net/ui/widget/option/cmd.py +1 -4
- pygpt_net/ui/widget/option/dictionary.py +25 -28
- pygpt_net/ui/widget/option/input.py +1 -3
- pygpt_net/ui/widget/tabs/Input.py +16 -12
- pygpt_net/ui/widget/tabs/body.py +5 -3
- pygpt_net/ui/widget/tabs/layout.py +36 -25
- pygpt_net/ui/widget/tabs/output.py +96 -74
- pygpt_net/ui/widget/textarea/calendar_note.py +1 -2
- pygpt_net/ui/widget/textarea/editor.py +41 -73
- pygpt_net/ui/widget/textarea/find.py +11 -10
- pygpt_net/ui/widget/textarea/html.py +3 -6
- pygpt_net/ui/widget/textarea/input.py +63 -64
- pygpt_net/ui/widget/textarea/notepad.py +54 -38
- pygpt_net/ui/widget/textarea/output.py +65 -54
- pygpt_net/ui/widget/textarea/search_input.py +5 -4
- pygpt_net/ui/widget/textarea/web.py +2 -4
- pygpt_net/ui/widget/vision/camera.py +2 -31
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/METADATA +15 -151
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/RECORD +144 -144
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/entry_points.txt +0 -0
|
@@ -6,21 +6,38 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtWidgets import QTabWidget, QMenu, QPushButton
|
|
13
13
|
from PySide6.QtCore import Qt, Slot
|
|
14
|
-
from PySide6.QtGui import QAction, QIcon
|
|
14
|
+
from PySide6.QtGui import QAction, QIcon, QGuiApplication
|
|
15
15
|
|
|
16
16
|
from pygpt_net.core.tabs.tab import Tab
|
|
17
17
|
from pygpt_net.utils import trans
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
_ICON_CACHE = {}
|
|
20
|
+
|
|
21
|
+
def icon(path: str) -> QIcon:
|
|
22
|
+
if QGuiApplication.instance() is None:
|
|
23
|
+
return QIcon()
|
|
24
|
+
cached = _ICON_CACHE.get(path)
|
|
25
|
+
if cached is None:
|
|
26
|
+
cached = QIcon(path)
|
|
27
|
+
_ICON_CACHE[path] = cached
|
|
28
|
+
return cached
|
|
29
|
+
|
|
30
|
+
ICON_PATH_ADD = ':/icons/add.svg'
|
|
31
|
+
ICON_PATH_EDIT = ':/icons/edit.svg'
|
|
32
|
+
ICON_PATH_CLOSE = ':/icons/close.svg'
|
|
33
|
+
ICON_PATH_RELOAD = ':/icons/reload.svg'
|
|
34
|
+
ICON_PATH_FORWARD = ':/icons/forward'
|
|
35
|
+
ICON_PATH_BACK = ':/icons/back'
|
|
19
36
|
|
|
20
37
|
|
|
21
38
|
class AddButton(QPushButton):
|
|
22
39
|
def __init__(self, window=None, column=None, tabs=None):
|
|
23
|
-
super(AddButton, self).__init__(
|
|
40
|
+
super(AddButton, self).__init__(icon(ICON_PATH_ADD), "", window)
|
|
24
41
|
self.window = window
|
|
25
42
|
self.column = column
|
|
26
43
|
self.tabs = tabs
|
|
@@ -65,23 +82,21 @@ class AddButton(QPushButton):
|
|
|
65
82
|
:return: menu
|
|
66
83
|
"""
|
|
67
84
|
menu = QMenu(self)
|
|
85
|
+
menu.setAttribute(Qt.WA_DeleteOnClose, True)
|
|
68
86
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
lambda: self.tabs.add_tab(index, column_idx, Tab.TAB_CHAT)
|
|
87
|
+
add_chat = QAction(icon(ICON_PATH_ADD), trans('action.tab.add.chat'), menu)
|
|
88
|
+
add_chat.triggered.connect(
|
|
89
|
+
lambda: self.tabs.add_tab(-2, column_idx, Tab.TAB_CHAT)
|
|
73
90
|
)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
lambda: self.tabs.add_tab(
|
|
91
|
+
add_notepad = QAction(icon(ICON_PATH_ADD), trans('action.tab.add.notepad'), menu)
|
|
92
|
+
add_notepad.triggered.connect(
|
|
93
|
+
lambda: self.tabs.add_tab(-2, column_idx, Tab.TAB_NOTEPAD)
|
|
77
94
|
)
|
|
78
95
|
|
|
79
|
-
|
|
80
|
-
menu.addAction(
|
|
81
|
-
menu.addAction(actions['add_notepad'])
|
|
96
|
+
menu.addAction(add_chat)
|
|
97
|
+
menu.addAction(add_notepad)
|
|
82
98
|
|
|
83
|
-
|
|
84
|
-
self.window.controller.tools.append_tab_menu(self, menu, index, column_idx, self.tabs)
|
|
99
|
+
self.window.controller.tools.append_tab_menu(self, menu, -2, column_idx, self.tabs)
|
|
85
100
|
|
|
86
101
|
return menu
|
|
87
102
|
|
|
@@ -113,21 +128,11 @@ class OutputTabs(QTabWidget):
|
|
|
113
128
|
self.setCornerWidget(add_button, corner=Qt.TopRightCorner)
|
|
114
129
|
|
|
115
130
|
# connect signals
|
|
116
|
-
self.currentChanged.connect(
|
|
117
|
-
|
|
118
|
-
)
|
|
119
|
-
self.
|
|
120
|
-
|
|
121
|
-
)
|
|
122
|
-
self.tabBarDoubleClicked.connect(
|
|
123
|
-
lambda: self.window.controller.ui.tabs.on_tab_dbl_clicked(self.currentIndex(), self.column.get_idx())
|
|
124
|
-
)
|
|
125
|
-
self.tabCloseRequested.connect(
|
|
126
|
-
lambda: self.window.controller.ui.tabs.on_tab_closed(self.currentIndex(), self.column.get_idx())
|
|
127
|
-
)
|
|
128
|
-
self.tabBar().tabMoved.connect(
|
|
129
|
-
lambda: self.window.controller.ui.tabs.on_tab_moved(self.currentIndex(), self.column.get_idx())
|
|
130
|
-
)
|
|
131
|
+
self.currentChanged.connect(self._on_current_changed)
|
|
132
|
+
self.tabBarClicked.connect(self._on_tabbar_clicked)
|
|
133
|
+
self.tabBarDoubleClicked.connect(self._on_tabbar_dbl_clicked)
|
|
134
|
+
self.tabCloseRequested.connect(self._on_tab_close_requested)
|
|
135
|
+
self.tabBar().tabMoved.connect(self._on_tab_moved)
|
|
131
136
|
|
|
132
137
|
def get_column(self):
|
|
133
138
|
"""
|
|
@@ -177,44 +182,40 @@ class OutputTabs(QTabWidget):
|
|
|
177
182
|
:return: menu
|
|
178
183
|
"""
|
|
179
184
|
menu = QMenu(self)
|
|
185
|
+
menu.setAttribute(Qt.WA_DeleteOnClose, True)
|
|
180
186
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
actions['add_chat'].triggered.connect(
|
|
187
|
+
add_chat = QAction(icon(ICON_PATH_ADD), trans('action.tab.add.chat'), menu)
|
|
188
|
+
add_chat.triggered.connect(
|
|
184
189
|
lambda: self.add_tab(index, column_idx, Tab.TAB_CHAT)
|
|
185
190
|
)
|
|
186
|
-
|
|
187
|
-
|
|
191
|
+
add_notepad = QAction(icon(ICON_PATH_ADD), trans('action.tab.add.notepad'), menu)
|
|
192
|
+
add_notepad.triggered.connect(
|
|
188
193
|
lambda: self.add_tab(index, column_idx, Tab.TAB_NOTEPAD)
|
|
189
194
|
)
|
|
190
|
-
|
|
191
|
-
|
|
195
|
+
edit = QAction(icon(ICON_PATH_EDIT), trans('action.rename'), menu)
|
|
196
|
+
edit.triggered.connect(
|
|
192
197
|
lambda: self.rename_tab(index, column_idx)
|
|
193
198
|
)
|
|
194
|
-
|
|
195
|
-
|
|
199
|
+
move_right = QAction(icon(ICON_PATH_FORWARD), trans('action.tab.move.right'), menu)
|
|
200
|
+
move_right.triggered.connect(
|
|
196
201
|
lambda: self.window.controller.ui.tabs.move_tab(index, column_idx, 1)
|
|
197
202
|
)
|
|
198
|
-
|
|
199
|
-
|
|
203
|
+
move_left = QAction(icon(ICON_PATH_BACK), trans('action.tab.move.left'), menu)
|
|
204
|
+
move_left.triggered.connect(
|
|
200
205
|
lambda: self.window.controller.ui.tabs.move_tab(index, column_idx, 0)
|
|
201
206
|
)
|
|
202
207
|
|
|
203
|
-
|
|
204
|
-
menu.addAction(
|
|
205
|
-
menu.addAction(actions['add_notepad'])
|
|
208
|
+
menu.addAction(add_chat)
|
|
209
|
+
menu.addAction(add_notepad)
|
|
206
210
|
|
|
207
|
-
# add tools submenu
|
|
208
211
|
self.window.controller.tools.append_tab_menu(self, menu, index, column_idx, self)
|
|
209
212
|
|
|
210
|
-
|
|
211
|
-
menu.addAction(actions['edit'])
|
|
213
|
+
menu.addAction(edit)
|
|
212
214
|
|
|
213
|
-
# move tab left, move tab right
|
|
214
215
|
if column_idx != 0:
|
|
215
|
-
menu.addAction(
|
|
216
|
+
menu.addAction(move_left)
|
|
216
217
|
if column_idx != 1:
|
|
217
|
-
menu.addAction(
|
|
218
|
+
menu.addAction(move_right)
|
|
218
219
|
|
|
219
220
|
return menu
|
|
220
221
|
|
|
@@ -227,19 +228,18 @@ class OutputTabs(QTabWidget):
|
|
|
227
228
|
:param global_pos: global position
|
|
228
229
|
"""
|
|
229
230
|
context_menu = self.prepare_menu(index, column_idx)
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
actions['close'].triggered.connect(
|
|
231
|
+
close_act = QAction(icon(ICON_PATH_CLOSE), trans('action.tab.close'), context_menu)
|
|
232
|
+
close_act.triggered.connect(
|
|
233
233
|
lambda: self.close_tab(index, column_idx)
|
|
234
234
|
)
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
close_all_act = QAction(icon(ICON_PATH_CLOSE), trans('action.tab.close_all.notepad'), context_menu)
|
|
236
|
+
close_all_act.triggered.connect(
|
|
237
237
|
lambda: self.close_all(Tab.TAB_NOTEPAD, column_idx)
|
|
238
238
|
)
|
|
239
|
-
context_menu.addAction(
|
|
239
|
+
context_menu.addAction(close_act)
|
|
240
240
|
|
|
241
241
|
if self.window.core.tabs.count_by_type(Tab.TAB_NOTEPAD) > 1:
|
|
242
|
-
context_menu.addAction(
|
|
242
|
+
context_menu.addAction(close_all_act)
|
|
243
243
|
|
|
244
244
|
context_menu.exec(global_pos)
|
|
245
245
|
|
|
@@ -252,20 +252,19 @@ class OutputTabs(QTabWidget):
|
|
|
252
252
|
:param global_pos: global position
|
|
253
253
|
"""
|
|
254
254
|
context_menu = self.prepare_menu(index, column_idx)
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
actions['close'].triggered.connect(
|
|
255
|
+
close_act = QAction(icon(ICON_PATH_CLOSE), trans('action.tab.close'), context_menu)
|
|
256
|
+
close_act.triggered.connect(
|
|
258
257
|
lambda: self.close_tab(index, column_idx)
|
|
259
258
|
)
|
|
260
|
-
|
|
261
|
-
|
|
259
|
+
close_all_act = QAction(icon(ICON_PATH_CLOSE), trans('action.tab.close_all.chat'), context_menu)
|
|
260
|
+
close_all_act.triggered.connect(
|
|
262
261
|
lambda: self.close_all(Tab.TAB_CHAT, column_idx)
|
|
263
262
|
)
|
|
264
263
|
|
|
265
264
|
# at least one chat tab must be open
|
|
266
265
|
if self.window.core.tabs.count_by_type(Tab.TAB_CHAT) > 1:
|
|
267
|
-
context_menu.addAction(
|
|
268
|
-
context_menu.addAction(
|
|
266
|
+
context_menu.addAction(close_act)
|
|
267
|
+
context_menu.addAction(close_all_act)
|
|
269
268
|
|
|
270
269
|
context_menu.exec(global_pos)
|
|
271
270
|
|
|
@@ -278,12 +277,11 @@ class OutputTabs(QTabWidget):
|
|
|
278
277
|
:param global_pos: global position
|
|
279
278
|
"""
|
|
280
279
|
context_menu = self.prepare_menu(index, column_idx)
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
actions['refresh'].triggered.connect(
|
|
280
|
+
refresh = QAction(icon(ICON_PATH_RELOAD), trans('action.refresh'), context_menu)
|
|
281
|
+
refresh.triggered.connect(
|
|
284
282
|
lambda: self.window.controller.files.update_explorer()
|
|
285
283
|
)
|
|
286
|
-
context_menu.addAction(
|
|
284
|
+
context_menu.addAction(refresh)
|
|
287
285
|
context_menu.exec(global_pos)
|
|
288
286
|
|
|
289
287
|
def show_tool_menu(self, index: int, column_idx: int, global_pos):
|
|
@@ -295,12 +293,11 @@ class OutputTabs(QTabWidget):
|
|
|
295
293
|
:param global_pos: global position
|
|
296
294
|
"""
|
|
297
295
|
context_menu = self.prepare_menu(index, column_idx)
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
actions['close'].triggered.connect(
|
|
296
|
+
close_act = QAction(icon(ICON_PATH_CLOSE), trans('action.tab.close'), context_menu)
|
|
297
|
+
close_act.triggered.connect(
|
|
301
298
|
lambda: self.close_tab(index, column_idx)
|
|
302
299
|
)
|
|
303
|
-
context_menu.addAction(
|
|
300
|
+
context_menu.addAction(close_act)
|
|
304
301
|
context_menu.exec(global_pos)
|
|
305
302
|
|
|
306
303
|
def show_default_menu(self, index: int, column_idx: int, global_pos):
|
|
@@ -314,6 +311,26 @@ class OutputTabs(QTabWidget):
|
|
|
314
311
|
context_menu = self.prepare_menu(index, column_idx)
|
|
315
312
|
context_menu.exec(global_pos)
|
|
316
313
|
|
|
314
|
+
@Slot(int)
|
|
315
|
+
def _on_current_changed(self, _idx: int):
|
|
316
|
+
self.window.controller.ui.tabs.on_tab_changed(self.currentIndex(), self.column.get_idx())
|
|
317
|
+
|
|
318
|
+
@Slot(int)
|
|
319
|
+
def _on_tabbar_clicked(self, _idx: int):
|
|
320
|
+
self.window.controller.ui.tabs.on_tab_clicked(self.currentIndex(), self.column.get_idx())
|
|
321
|
+
|
|
322
|
+
@Slot(int)
|
|
323
|
+
def _on_tabbar_dbl_clicked(self, _idx: int):
|
|
324
|
+
self.window.controller.ui.tabs.on_tab_dbl_clicked(self.currentIndex(), self.column.get_idx())
|
|
325
|
+
|
|
326
|
+
@Slot(int)
|
|
327
|
+
def _on_tab_close_requested(self, _idx: int):
|
|
328
|
+
self.window.controller.ui.tabs.on_tab_closed(self.currentIndex(), self.column.get_idx())
|
|
329
|
+
|
|
330
|
+
@Slot(int, int)
|
|
331
|
+
def _on_tab_moved(self, _from: int, _to: int):
|
|
332
|
+
self.window.controller.ui.tabs.on_tab_moved(self.currentIndex(), self.column.get_idx())
|
|
333
|
+
|
|
317
334
|
@Slot()
|
|
318
335
|
def rename_tab(self, index: int, column_idx: int):
|
|
319
336
|
"""
|
|
@@ -354,9 +371,14 @@ class OutputTabs(QTabWidget):
|
|
|
354
371
|
:param type: type
|
|
355
372
|
:param tool_id: tool id
|
|
356
373
|
"""
|
|
374
|
+
if index == -2: # new btn
|
|
375
|
+
index = self.window.core.tabs.get_max_idx_by_column(column_idx)
|
|
376
|
+
if index == -1:
|
|
377
|
+
index = 0
|
|
378
|
+
|
|
357
379
|
self.window.controller.ui.tabs.append(
|
|
358
380
|
type=type,
|
|
359
381
|
tool_id=tool_id,
|
|
360
382
|
idx=index,
|
|
361
383
|
column_idx=column_idx,
|
|
362
|
-
)
|
|
384
|
+
)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import Qt
|
|
@@ -16,7 +16,6 @@ from PySide6.QtWidgets import QTextEdit
|
|
|
16
16
|
from pygpt_net.core.tabs.tab import Tab
|
|
17
17
|
from pygpt_net.core.text.finder import Finder
|
|
18
18
|
from pygpt_net.utils import trans
|
|
19
|
-
import pygpt_net.icons_rc
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
class CalendarNote(QTextEdit):
|
|
@@ -6,27 +6,32 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import Qt
|
|
13
|
-
from PySide6.QtGui import QAction, QIcon, QKeySequence,
|
|
13
|
+
from PySide6.QtGui import QAction, QIcon, QKeySequence, QFontMetrics
|
|
14
14
|
from PySide6.QtWidgets import QTextEdit
|
|
15
15
|
|
|
16
16
|
from pygpt_net.core.text.finder import Finder
|
|
17
17
|
from pygpt_net.utils import trans
|
|
18
18
|
|
|
19
|
-
import pygpt_net.icons_rc
|
|
20
|
-
|
|
21
19
|
|
|
22
20
|
class BaseCodeEditor(QTextEdit):
|
|
21
|
+
|
|
22
|
+
_ICON_VOLUME = QIcon(":/icons/volume.svg")
|
|
23
|
+
_ICON_SAVE = QIcon(":/icons/save.svg")
|
|
24
|
+
_ICON_SEARCH = QIcon(":/icons/search.svg")
|
|
25
|
+
_ICON_CLOSE = QIcon(":/icons/close.svg")
|
|
26
|
+
_FIND_SEQ = QKeySequence("Ctrl+F")
|
|
27
|
+
|
|
23
28
|
def __init__(self, window=None):
|
|
24
29
|
"""
|
|
25
30
|
Base code editor
|
|
26
31
|
|
|
27
32
|
:param window: main window
|
|
28
33
|
"""
|
|
29
|
-
super(
|
|
34
|
+
super().__init__(window)
|
|
30
35
|
self.window = window
|
|
31
36
|
self.finder = Finder(window, self)
|
|
32
37
|
self.setReadOnly(True)
|
|
@@ -40,114 +45,89 @@ class BaseCodeEditor(QTextEdit):
|
|
|
40
45
|
self.excluded_copy_to = []
|
|
41
46
|
self.textChanged.connect(self.text_changed)
|
|
42
47
|
|
|
43
|
-
# tabulation
|
|
44
48
|
metrics = QFontMetrics(self.font())
|
|
45
49
|
space_width = metrics.horizontalAdvance(" ")
|
|
46
50
|
self.setTabStopDistance(4 * space_width)
|
|
47
51
|
|
|
48
52
|
def text_changed(self):
|
|
49
|
-
"""On text changed"""
|
|
50
53
|
self.finder.text_changed()
|
|
51
54
|
|
|
52
55
|
def update_stylesheet(self, data: str):
|
|
53
|
-
"""
|
|
54
|
-
Update stylesheet
|
|
55
|
-
|
|
56
|
-
:param data: stylesheet CSS
|
|
57
|
-
"""
|
|
58
56
|
self.setStyleSheet(self.default_stylesheet + data)
|
|
59
57
|
|
|
60
58
|
def contextMenuEvent(self, event):
|
|
61
|
-
"""
|
|
62
|
-
Context menu event
|
|
63
|
-
|
|
64
|
-
:param event: Event
|
|
65
|
-
"""
|
|
66
59
|
menu = self.createStandardContextMenu()
|
|
67
|
-
|
|
60
|
+
cursor = self.textCursor()
|
|
61
|
+
selected_text = cursor.selectedText()
|
|
68
62
|
|
|
69
63
|
if selected_text:
|
|
70
|
-
|
|
71
|
-
plain_text = self.textCursor().selection().toPlainText()
|
|
64
|
+
plain_text = cursor.selection().toPlainText()
|
|
72
65
|
|
|
73
|
-
|
|
74
|
-
action = QAction(QIcon(":/icons/volume.svg"), trans('text.context_menu.audio.read'), self)
|
|
66
|
+
action = QAction(self._ICON_VOLUME, trans('text.context_menu.audio.read'), menu)
|
|
75
67
|
action.triggered.connect(self.audio_read_selection)
|
|
76
68
|
menu.addAction(action)
|
|
77
69
|
|
|
78
|
-
# copy to
|
|
79
70
|
copy_to_menu = self.window.ui.context_menu.get_copy_to_menu(
|
|
80
|
-
|
|
71
|
+
menu,
|
|
81
72
|
selected_text,
|
|
82
73
|
excluded=self.excluded_copy_to
|
|
83
74
|
)
|
|
75
|
+
try:
|
|
76
|
+
copy_to_menu.setParent(menu)
|
|
77
|
+
except Exception:
|
|
78
|
+
pass
|
|
84
79
|
menu.addMenu(copy_to_menu)
|
|
85
80
|
|
|
86
|
-
|
|
87
|
-
action = QAction(QIcon(":/icons/save.svg"), trans('action.save_selection_as'), self)
|
|
81
|
+
action = QAction(self._ICON_SAVE, trans('action.save_selection_as'), menu)
|
|
88
82
|
action.triggered.connect(
|
|
89
83
|
lambda: self.window.controller.chat.common.save_text(plain_text))
|
|
90
84
|
menu.addAction(action)
|
|
91
85
|
else:
|
|
92
|
-
|
|
93
|
-
action = QAction(QIcon(":/icons/save.svg"), trans('action.save_as'), self)
|
|
86
|
+
action = QAction(self._ICON_SAVE, trans('action.save_as'), menu)
|
|
94
87
|
action.triggered.connect(
|
|
95
88
|
lambda: self.window.controller.chat.common.save_text(self.toPlainText()))
|
|
96
89
|
menu.addAction(action)
|
|
97
90
|
|
|
98
|
-
action = QAction(
|
|
91
|
+
action = QAction(self._ICON_SEARCH, trans('text.context_menu.find'), menu)
|
|
99
92
|
action.triggered.connect(self.find_open)
|
|
100
|
-
action.setShortcut(
|
|
93
|
+
action.setShortcut(self._FIND_SEQ)
|
|
101
94
|
menu.addAction(action)
|
|
102
95
|
|
|
103
|
-
|
|
104
|
-
action
|
|
105
|
-
action.triggered.connect(
|
|
106
|
-
lambda: self.clear_content())
|
|
96
|
+
action = QAction(self._ICON_CLOSE, trans('action.clear'), menu)
|
|
97
|
+
action.triggered.connect(self.clear_content)
|
|
107
98
|
menu.addAction(action)
|
|
108
99
|
|
|
109
|
-
menu.
|
|
100
|
+
menu.exec(event.globalPos())
|
|
101
|
+
menu.deleteLater()
|
|
110
102
|
|
|
111
103
|
def clear_content(self):
|
|
112
|
-
|
|
113
|
-
cursor = self.textCursor()
|
|
114
|
-
cursor.select(QTextCursor.Document)
|
|
115
|
-
cursor.removeSelectedText()
|
|
104
|
+
self.clear()
|
|
116
105
|
|
|
117
106
|
def audio_read_selection(self):
|
|
118
|
-
"""Read selected text (audio)"""
|
|
119
107
|
self.window.controller.audio.read_text(self.textCursor().selectedText())
|
|
120
108
|
|
|
121
109
|
def find_open(self):
|
|
122
|
-
"""Open find dialog"""
|
|
123
110
|
self.window.controller.finder.open(self.finder)
|
|
124
111
|
|
|
125
112
|
def on_update(self):
|
|
126
|
-
|
|
127
|
-
self.finder.clear() # clear finder
|
|
113
|
+
self.finder.clear()
|
|
128
114
|
|
|
129
115
|
def on_destroy(self):
|
|
130
|
-
|
|
131
|
-
|
|
116
|
+
try:
|
|
117
|
+
self.textChanged.disconnect(self.text_changed)
|
|
118
|
+
except Exception:
|
|
119
|
+
pass
|
|
120
|
+
self.window.controller.finder.unset(self.finder)
|
|
132
121
|
|
|
133
122
|
def keyPressEvent(self, e):
|
|
134
|
-
"""
|
|
135
|
-
Key press event
|
|
136
|
-
|
|
137
|
-
:param e: Event
|
|
138
|
-
"""
|
|
139
123
|
if e.key() == Qt.Key_F and e.modifiers() & Qt.ControlModifier:
|
|
140
124
|
self.find_open()
|
|
141
125
|
else:
|
|
142
|
-
super(
|
|
126
|
+
super().keyPressEvent(e)
|
|
143
127
|
|
|
144
128
|
def wheelEvent(self, event):
|
|
145
|
-
"""
|
|
146
|
-
Wheel event: set font size
|
|
147
|
-
|
|
148
|
-
:param event: Event
|
|
149
|
-
"""
|
|
150
129
|
if event.modifiers() & Qt.ControlModifier:
|
|
130
|
+
prev = self.value
|
|
151
131
|
if event.angleDelta().y() > 0:
|
|
152
132
|
if self.value < self.max_font_size:
|
|
153
133
|
self.value += 1
|
|
@@ -155,18 +135,14 @@ class BaseCodeEditor(QTextEdit):
|
|
|
155
135
|
if self.value > self.min_font_size:
|
|
156
136
|
self.value -= 1
|
|
157
137
|
|
|
158
|
-
self.
|
|
138
|
+
if self.value != prev:
|
|
139
|
+
self.update_stylesheet(f"QTextEdit {{ font-size: {self.value}px }};")
|
|
159
140
|
event.accept()
|
|
160
141
|
else:
|
|
161
|
-
super(
|
|
142
|
+
super().wheelEvent(event)
|
|
162
143
|
|
|
163
144
|
def focusInEvent(self, e):
|
|
164
|
-
|
|
165
|
-
Focus in event
|
|
166
|
-
|
|
167
|
-
:param e: focus event
|
|
168
|
-
"""
|
|
169
|
-
super(BaseCodeEditor, self).focusInEvent(e)
|
|
145
|
+
super().focusInEvent(e)
|
|
170
146
|
self.window.controller.finder.focus_in(self.finder)
|
|
171
147
|
|
|
172
148
|
|
|
@@ -177,12 +153,4 @@ class CodeEditor(BaseCodeEditor):
|
|
|
177
153
|
|
|
178
154
|
:param window: main window
|
|
179
155
|
"""
|
|
180
|
-
super(
|
|
181
|
-
self.window = window
|
|
182
|
-
self.setReadOnly(True)
|
|
183
|
-
self.value = 12
|
|
184
|
-
self.max_font_size = 42
|
|
185
|
-
self.min_font_size = 8
|
|
186
|
-
self.setProperty('class', 'code-editor')
|
|
187
|
-
self.default_stylesheet = ""
|
|
188
|
-
self.setStyleSheet(self.default_stylesheet)
|
|
156
|
+
super().__init__(window)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6 import QtCore
|
|
@@ -21,13 +21,15 @@ class FindInput(QLineEdit):
|
|
|
21
21
|
:param window: main window
|
|
22
22
|
:param id: info window id
|
|
23
23
|
"""
|
|
24
|
-
super(
|
|
24
|
+
super().__init__(window)
|
|
25
25
|
|
|
26
26
|
self.window = window
|
|
27
27
|
self.id = id
|
|
28
|
-
self.textChanged.connect(
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
self.textChanged.connect(self._on_text_changed)
|
|
29
|
+
|
|
30
|
+
@QtCore.Slot(str)
|
|
31
|
+
def _on_text_changed(self, text):
|
|
32
|
+
self.window.controller.finder.search_text_changed(text)
|
|
31
33
|
|
|
32
34
|
def keyPressEvent(self, event):
|
|
33
35
|
"""
|
|
@@ -35,10 +37,10 @@ class FindInput(QLineEdit):
|
|
|
35
37
|
|
|
36
38
|
:param event: key event
|
|
37
39
|
"""
|
|
38
|
-
super(
|
|
40
|
+
super().keyPressEvent(event)
|
|
39
41
|
|
|
40
42
|
# update on Enter
|
|
41
|
-
if event.key()
|
|
43
|
+
if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
|
|
42
44
|
self.window.controller.finder.focus_input(self.text())
|
|
43
45
|
|
|
44
46
|
def focusInEvent(self, e):
|
|
@@ -47,6 +49,5 @@ class FindInput(QLineEdit):
|
|
|
47
49
|
|
|
48
50
|
:param e: focus event
|
|
49
51
|
"""
|
|
50
|
-
super(
|
|
51
|
-
self.window.controller.finder.focus_input(self.text())
|
|
52
|
-
|
|
52
|
+
super().focusInEvent(e)
|
|
53
|
+
self.window.controller.finder.focus_input(self.text())
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.08.
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import re
|
|
@@ -15,16 +15,13 @@ from PySide6.QtCore import Qt, QObject, Signal, Slot, QEvent
|
|
|
15
15
|
from PySide6.QtWebChannel import QWebChannel
|
|
16
16
|
from PySide6.QtWebEngineCore import QWebEngineSettings, QWebEnginePage
|
|
17
17
|
from PySide6.QtWebEngineWidgets import QWebEngineView
|
|
18
|
-
from PySide6.QtGui import QAction, QIcon
|
|
18
|
+
from PySide6.QtGui import QAction, QIcon
|
|
19
19
|
from PySide6.QtWidgets import QMenu
|
|
20
20
|
|
|
21
|
-
from pygpt_net.core.events import RenderEvent
|
|
22
21
|
from pygpt_net.item.ctx import CtxMeta
|
|
23
22
|
from pygpt_net.core.text.web_finder import WebFinder
|
|
24
23
|
from pygpt_net.utils import trans
|
|
25
24
|
|
|
26
|
-
import pygpt_net.icons_rc
|
|
27
|
-
|
|
28
25
|
|
|
29
26
|
class HtmlOutput(QWebEngineView):
|
|
30
27
|
def __init__(self, window=None):
|
|
@@ -142,7 +139,7 @@ class HtmlOutput(QWebEngineView):
|
|
|
142
139
|
menu.addAction(action)
|
|
143
140
|
|
|
144
141
|
# copy to
|
|
145
|
-
copy_to_menu = self.window.ui.context_menu.get_copy_to_menu(
|
|
142
|
+
copy_to_menu = self.window.ui.context_menu.get_copy_to_menu(menu, selected_text)
|
|
146
143
|
menu.addMenu(copy_to_menu)
|
|
147
144
|
|
|
148
145
|
# save as (selected)
|