pygpt-net 2.4.38__py3-none-any.whl → 2.4.39__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 +6 -0
- README.md +7 -1
- pygpt_net/CHANGELOG.txt +6 -0
- pygpt_net/__init__.py +2 -2
- pygpt_net/controller/__init__.py +3 -1
- pygpt_net/controller/calendar/__init__.py +3 -1
- pygpt_net/controller/chat/render.py +8 -5
- pygpt_net/controller/ctx/__init__.py +32 -24
- pygpt_net/controller/ctx/common.py +3 -2
- pygpt_net/controller/dialogs/confirm.py +2 -2
- pygpt_net/controller/lang/custom.py +2 -7
- pygpt_net/controller/lang/mapping.py +2 -2
- pygpt_net/controller/layout.py +2 -2
- pygpt_net/controller/notepad.py +8 -5
- pygpt_net/controller/ui/tabs.py +201 -58
- pygpt_net/core/ctx/__init__.py +11 -1
- pygpt_net/core/ctx/container.py +16 -9
- pygpt_net/core/ctx/output.py +86 -67
- pygpt_net/core/debug/tabs.py +3 -2
- pygpt_net/core/filesystem/url.py +7 -3
- pygpt_net/core/render/base.py +14 -3
- pygpt_net/core/render/markdown/renderer.py +3 -1
- pygpt_net/core/render/plain/renderer.py +3 -3
- pygpt_net/core/render/web/body.py +9 -3
- pygpt_net/core/render/web/renderer.py +7 -5
- pygpt_net/core/tabs/__init__.py +180 -71
- pygpt_net/core/tabs/tab.py +13 -4
- pygpt_net/data/config/config.json +11 -5
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/modes.json +3 -3
- pygpt_net/data/locale/locale.de.ini +3 -0
- pygpt_net/data/locale/locale.en.ini +3 -0
- pygpt_net/data/locale/locale.es.ini +3 -0
- pygpt_net/data/locale/locale.fr.ini +3 -0
- pygpt_net/data/locale/locale.it.ini +3 -0
- pygpt_net/data/locale/locale.pl.ini +4 -1
- pygpt_net/data/locale/locale.uk.ini +3 -0
- pygpt_net/data/locale/locale.zh.ini +3 -0
- pygpt_net/plugin/audio_input/simple.py +4 -2
- pygpt_net/provider/core/config/patch.py +8 -1
- pygpt_net/provider/core/ctx/base.py +4 -1
- pygpt_net/provider/core/ctx/db_sqlite/__init__.py +10 -1
- pygpt_net/provider/core/ctx/db_sqlite/storage.py +22 -1
- pygpt_net/ui/layout/chat/input.py +10 -18
- pygpt_net/ui/layout/chat/output.py +26 -44
- pygpt_net/ui/layout/toolbox/footer.py +18 -2
- pygpt_net/ui/widget/tabs/layout.py +195 -0
- pygpt_net/ui/widget/tabs/output.py +124 -35
- pygpt_net/ui/widget/textarea/html.py +11 -1
- pygpt_net/ui/widget/textarea/output.py +10 -1
- pygpt_net/ui/widget/textarea/web.py +49 -9
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.39.dist-info}/METADATA +8 -2
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.39.dist-info}/RECORD +56 -55
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.39.dist-info}/LICENSE +0 -0
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.39.dist-info}/WHEEL +0 -0
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.39.dist-info}/entry_points.txt +0 -0
@@ -6,10 +6,10 @@
|
|
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.09 03:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
|
-
from PySide6.QtWidgets import QTabWidget, QMenu
|
12
|
+
from PySide6.QtWidgets import QTabWidget, QMenu, QPushButton
|
13
13
|
from PySide6.QtCore import Qt, Slot
|
14
14
|
from PySide6.QtGui import QAction, QIcon
|
15
15
|
|
@@ -19,16 +19,59 @@ import pygpt_net.icons_rc
|
|
19
19
|
|
20
20
|
|
21
21
|
class OutputTabs(QTabWidget):
|
22
|
-
def __init__(self, window=None):
|
22
|
+
def __init__(self, window=None, column=None):
|
23
23
|
super(OutputTabs, self).__init__(window)
|
24
24
|
self.window = window
|
25
|
+
self.column = column
|
25
26
|
self.setMinimumHeight(1)
|
26
27
|
self.owner = None
|
27
28
|
self.setMovable(True)
|
29
|
+
self.init()
|
30
|
+
|
31
|
+
def init(self):
|
32
|
+
"""Initialize"""
|
33
|
+
# create the [+] button
|
34
|
+
add_button = QPushButton(QIcon(":/icons/add.svg"), "")
|
35
|
+
add_button.setFixedSize(30, 25)
|
36
|
+
add_button.setFlat(True)
|
37
|
+
add_button.clicked.connect(
|
38
|
+
lambda: self.window.controller.ui.tabs.new_tab(self.column.get_idx())
|
39
|
+
)
|
40
|
+
add_button.setObjectName('tab-add')
|
41
|
+
add_button.setProperty('tabAdd', True)
|
42
|
+
add_button.setToolTip(trans('action.tab.add.chat'))
|
43
|
+
|
44
|
+
# add the button to the top right corner of the tab bar
|
45
|
+
self.setCornerWidget(add_button, corner=Qt.TopRightCorner)
|
46
|
+
|
47
|
+
# connect signals
|
48
|
+
self.currentChanged.connect(
|
49
|
+
lambda: self.window.controller.ui.tabs.on_tab_changed(self.currentIndex(), self.column.get_idx())
|
50
|
+
)
|
51
|
+
self.tabBarClicked.connect(
|
52
|
+
lambda: self.window.controller.ui.tabs.on_tab_clicked(self.currentIndex(), self.column.get_idx())
|
53
|
+
)
|
54
|
+
self.tabBarDoubleClicked.connect(
|
55
|
+
lambda: self.window.controller.ui.tabs.on_tab_dbl_clicked(self.currentIndex(), self.column.get_idx())
|
56
|
+
)
|
57
|
+
self.tabCloseRequested.connect(
|
58
|
+
lambda: self.window.controller.ui.tabs.on_tab_closed(self.currentIndex(), self.column.get_idx())
|
59
|
+
)
|
60
|
+
self.tabBar().tabMoved.connect(
|
61
|
+
lambda: self.window.controller.ui.tabs.on_tab_moved(self.currentIndex(), self.column.get_idx())
|
62
|
+
)
|
63
|
+
|
64
|
+
def get_column(self):
|
65
|
+
"""
|
66
|
+
Get column
|
67
|
+
|
68
|
+
:return: OutputColumn
|
69
|
+
"""
|
70
|
+
return self.column
|
28
71
|
|
29
72
|
def setOwner(self, owner: Tab):
|
30
73
|
"""
|
31
|
-
Set
|
74
|
+
Set internal tab instance
|
32
75
|
|
33
76
|
:param owner: parent tab instance
|
34
77
|
"""
|
@@ -42,56 +85,67 @@ class OutputTabs(QTabWidget):
|
|
42
85
|
"""
|
43
86
|
if event.button() == Qt.RightButton:
|
44
87
|
idx = self.tabBar().tabAt(event.pos())
|
45
|
-
|
88
|
+
column_idx = self.column.get_idx()
|
89
|
+
tab = self.window.core.tabs.get_tab_by_index(idx, column_idx)
|
46
90
|
if tab is not None:
|
47
91
|
if tab.type == Tab.TAB_NOTEPAD:
|
48
|
-
self.show_notepad_menu(idx, event.globalPos()) # notepad
|
92
|
+
self.show_notepad_menu(idx, column_idx, event.globalPos()) # notepad
|
49
93
|
elif tab.type == Tab.TAB_CHAT:
|
50
|
-
self.show_chat_menu(idx, event.globalPos()) # chat
|
94
|
+
self.show_chat_menu(idx, column_idx, event.globalPos()) # chat
|
51
95
|
elif tab.type == Tab.TAB_FILES:
|
52
|
-
self.show_files_menu(idx, event.globalPos()) # files
|
96
|
+
self.show_files_menu(idx, column_idx, event.globalPos()) # files
|
53
97
|
else:
|
54
|
-
self.show_default_menu(idx, event.globalPos()) # default
|
98
|
+
self.show_default_menu(idx, column_idx, event.globalPos()) # default
|
55
99
|
super(OutputTabs, self).mousePressEvent(event)
|
56
100
|
|
57
|
-
def get_common_actions(self, index):
|
101
|
+
def get_common_actions(self, index: int, column_idx: int):
|
58
102
|
"""
|
59
103
|
Get common actions
|
60
104
|
|
61
105
|
:param index: index
|
106
|
+
:param column_idx: column index
|
62
107
|
:return: dict
|
63
108
|
"""
|
64
109
|
actions = {}
|
65
110
|
actions['add_chat'] = QAction(QIcon(":/icons/add.svg"), trans('action.tab.add.chat'), self)
|
66
111
|
actions['add_chat'].triggered.connect(
|
67
|
-
lambda: self.add_tab(index, Tab.TAB_CHAT)
|
112
|
+
lambda: self.add_tab(index, column_idx, Tab.TAB_CHAT)
|
68
113
|
)
|
69
114
|
actions['add_notepad'] = QAction(QIcon(":/icons/add.svg"), trans('action.tab.add.notepad'), self)
|
70
115
|
actions['add_notepad'].triggered.connect(
|
71
|
-
lambda: self.add_tab(index, Tab.TAB_NOTEPAD)
|
116
|
+
lambda: self.add_tab(index, column_idx, Tab.TAB_NOTEPAD)
|
72
117
|
)
|
73
118
|
actions['edit'] = QAction(QIcon(":/icons/edit.svg"), trans('action.rename'), self)
|
74
119
|
actions['edit'].triggered.connect(
|
75
|
-
lambda: self.rename_tab(index)
|
120
|
+
lambda: self.rename_tab(index, column_idx)
|
121
|
+
)
|
122
|
+
actions['move_right'] = QAction(QIcon(":/icons/forward"), trans('action.tab.move.right'), self)
|
123
|
+
actions['move_right'].triggered.connect(
|
124
|
+
lambda: self.window.controller.ui.tabs.move_tab(index, column_idx, 1)
|
125
|
+
)
|
126
|
+
actions['move_left'] = QAction(QIcon(":/icons/back"), trans('action.tab.move.left'), self)
|
127
|
+
actions['move_left'].triggered.connect(
|
128
|
+
lambda: self.window.controller.ui.tabs.move_tab(index, column_idx, 0)
|
76
129
|
)
|
77
130
|
return actions
|
78
131
|
|
79
|
-
def show_notepad_menu(self, index, global_pos):
|
132
|
+
def show_notepad_menu(self, index: int, column_idx: int, global_pos):
|
80
133
|
"""
|
81
134
|
Show notepad menu
|
82
135
|
|
83
136
|
:param index: index
|
137
|
+
:param column_idx: column index
|
84
138
|
:param global_pos: global position
|
85
139
|
"""
|
86
140
|
context_menu = QMenu()
|
87
|
-
actions = self.get_common_actions(index)
|
141
|
+
actions = self.get_common_actions(index, column_idx)
|
88
142
|
actions['close'] = QAction(QIcon(":/icons/close.svg"), trans('action.tab.close'), self)
|
89
143
|
actions['close'].triggered.connect(
|
90
|
-
lambda: self.close_tab(index)
|
144
|
+
lambda: self.close_tab(index, column_idx)
|
91
145
|
)
|
92
146
|
actions['close_all'] = QAction(QIcon(":/icons/close.svg"), trans('action.tab.close_all.notepad'), self)
|
93
147
|
actions['close_all'].triggered.connect(
|
94
|
-
lambda: self.close_all(Tab.TAB_NOTEPAD)
|
148
|
+
lambda: self.close_all(Tab.TAB_NOTEPAD, column_idx)
|
95
149
|
)
|
96
150
|
context_menu.addAction(actions['add_chat'])
|
97
151
|
context_menu.addAction(actions['add_notepad'])
|
@@ -100,24 +154,32 @@ class OutputTabs(QTabWidget):
|
|
100
154
|
|
101
155
|
if self.window.core.tabs.count_by_type(Tab.TAB_NOTEPAD) > 1:
|
102
156
|
context_menu.addAction(actions['close_all'])
|
157
|
+
|
158
|
+
# move
|
159
|
+
if column_idx != 0:
|
160
|
+
context_menu.addAction(actions['move_left'])
|
161
|
+
if column_idx != 1:
|
162
|
+
context_menu.addAction(actions['move_right'])
|
163
|
+
|
103
164
|
context_menu.exec(global_pos)
|
104
165
|
|
105
|
-
def show_chat_menu(self, index, global_pos):
|
166
|
+
def show_chat_menu(self, index: int, column_idx: int, global_pos):
|
106
167
|
"""
|
107
168
|
Show chat menu
|
108
169
|
|
109
170
|
:param index: index
|
171
|
+
:param column_idx: column index
|
110
172
|
:param global_pos: global position
|
111
173
|
"""
|
112
174
|
context_menu = QMenu()
|
113
|
-
actions = self.get_common_actions(index)
|
175
|
+
actions = self.get_common_actions(index, column_idx)
|
114
176
|
actions['close'] = QAction(QIcon(":/icons/close.svg"), trans('action.tab.close'), self)
|
115
177
|
actions['close'].triggered.connect(
|
116
|
-
lambda: self.close_tab(index)
|
178
|
+
lambda: self.close_tab(index, column_idx)
|
117
179
|
)
|
118
180
|
actions['close_all'] = QAction(QIcon(":/icons/close.svg"), trans('action.tab.close_all.chat'), self)
|
119
181
|
actions['close_all'].triggered.connect(
|
120
|
-
lambda: self.close_all(Tab.TAB_CHAT)
|
182
|
+
lambda: self.close_all(Tab.TAB_CHAT, column_idx)
|
121
183
|
)
|
122
184
|
context_menu.addAction(actions['add_chat'])
|
123
185
|
context_menu.addAction(actions['add_notepad'])
|
@@ -126,21 +188,26 @@ class OutputTabs(QTabWidget):
|
|
126
188
|
# at least one chat tab must be open
|
127
189
|
if self.window.core.tabs.count_by_type(Tab.TAB_CHAT) > 1:
|
128
190
|
context_menu.addAction(actions['close'])
|
129
|
-
|
130
|
-
if self.window.core.tabs.count_by_type(Tab.TAB_CHAT) > 1:
|
131
191
|
context_menu.addAction(actions['close_all'])
|
132
192
|
|
193
|
+
# move
|
194
|
+
if column_idx != 0:
|
195
|
+
context_menu.addAction(actions['move_left'])
|
196
|
+
if column_idx != 1:
|
197
|
+
context_menu.addAction(actions['move_right'])
|
198
|
+
|
133
199
|
context_menu.exec(global_pos)
|
134
200
|
|
135
|
-
def show_files_menu(self, index, global_pos):
|
201
|
+
def show_files_menu(self, index: int, column_idx: int, global_pos):
|
136
202
|
"""
|
137
203
|
Show files menu
|
138
204
|
|
139
205
|
:param index: index
|
206
|
+
:param column_idx: column index
|
140
207
|
:param global_pos: global position
|
141
208
|
"""
|
142
209
|
context_menu = QMenu()
|
143
|
-
actions = self.get_common_actions(index)
|
210
|
+
actions = self.get_common_actions(index, column_idx)
|
144
211
|
actions['refresh'] = QAction(QIcon(":/icons/reload.svg"), trans('action.refresh'), self)
|
145
212
|
actions['refresh'].triggered.connect(
|
146
213
|
lambda: self.window.controller.files.update_explorer()
|
@@ -149,51 +216,73 @@ class OutputTabs(QTabWidget):
|
|
149
216
|
context_menu.addAction(actions['add_notepad'])
|
150
217
|
context_menu.addAction(actions['refresh'])
|
151
218
|
context_menu.addAction(actions['edit'])
|
219
|
+
|
220
|
+
# move
|
221
|
+
if column_idx != 0:
|
222
|
+
context_menu.addAction(actions['move_left'])
|
223
|
+
if column_idx != 1:
|
224
|
+
context_menu.addAction(actions['move_right'])
|
225
|
+
|
152
226
|
context_menu.exec(global_pos)
|
153
227
|
|
154
|
-
def show_default_menu(self, index, global_pos):
|
228
|
+
def show_default_menu(self, index: int, column_idx: int, global_pos):
|
155
229
|
"""
|
156
230
|
Show default menu
|
157
231
|
|
158
232
|
:param index: index
|
233
|
+
:param column_idx: column index
|
159
234
|
:param global_pos: global position
|
160
235
|
"""
|
161
236
|
context_menu = QMenu()
|
162
|
-
actions = self.get_common_actions(index)
|
237
|
+
actions = self.get_common_actions(index, column_idx)
|
163
238
|
context_menu.addAction(actions['add_chat'])
|
164
239
|
context_menu.addAction(actions['add_notepad'])
|
165
240
|
context_menu.addAction(actions['edit'])
|
241
|
+
|
242
|
+
# move
|
243
|
+
if column_idx != 0:
|
244
|
+
context_menu.addAction(actions['move_left'])
|
245
|
+
if column_idx != 1:
|
246
|
+
context_menu.addAction(actions['move_right'])
|
247
|
+
|
166
248
|
context_menu.exec(global_pos)
|
167
249
|
|
168
250
|
@Slot()
|
169
|
-
def rename_tab(self, index):
|
251
|
+
def rename_tab(self, index: int, column_idx: int):
|
170
252
|
"""
|
171
253
|
Rename tab
|
254
|
+
|
172
255
|
:param index: index
|
256
|
+
:param column_idx: column index
|
173
257
|
"""
|
174
|
-
self.window.controller.ui.tabs.rename(index)
|
258
|
+
self.window.controller.ui.tabs.rename(index, column_idx)
|
175
259
|
|
176
260
|
@Slot()
|
177
|
-
def close_tab(self, index):
|
261
|
+
def close_tab(self, index: int, column_idx: int):
|
178
262
|
"""
|
179
263
|
Close tab
|
264
|
+
|
180
265
|
:param index: index
|
266
|
+
:param column_idx: column index
|
181
267
|
"""
|
182
|
-
self.window.controller.ui.tabs.close(index)
|
268
|
+
self.window.controller.ui.tabs.close(index, column_idx)
|
183
269
|
|
184
270
|
@Slot()
|
185
|
-
def close_all(self, type):
|
271
|
+
def close_all(self, type, column_idx: int):
|
186
272
|
"""
|
187
273
|
Close all tabs
|
274
|
+
|
188
275
|
:param type: type
|
276
|
+
:param column_idx: column index
|
189
277
|
"""
|
190
|
-
self.window.controller.ui.tabs.close_all(type)
|
278
|
+
self.window.controller.ui.tabs.close_all(type, column_idx)
|
191
279
|
|
192
280
|
@Slot()
|
193
|
-
def add_tab(self, index, type):
|
281
|
+
def add_tab(self, index: int, column_idx: int, type):
|
194
282
|
"""
|
195
283
|
Add tab
|
196
284
|
:param index: index
|
285
|
+
:param column_idx: column index
|
197
286
|
:param type: type
|
198
287
|
"""
|
199
|
-
self.window.controller.ui.tabs.append(type, index)
|
288
|
+
self.window.controller.ui.tabs.append(type, index, column_idx)
|
@@ -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: 2024.
|
9
|
+
# Updated Date: 2024.12.09 00:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import re
|
@@ -42,6 +42,15 @@ class HtmlOutput(QWebEngineView):
|
|
42
42
|
self.plain = ""
|
43
43
|
self.html_content = ""
|
44
44
|
self.meta = None
|
45
|
+
self.tab = None
|
46
|
+
|
47
|
+
def set_tab(self, tab):
|
48
|
+
"""
|
49
|
+
Set tab
|
50
|
+
|
51
|
+
:param tab: Tab
|
52
|
+
"""
|
53
|
+
self.tab = tab
|
45
54
|
|
46
55
|
def set_meta(self, meta: CtxMeta):
|
47
56
|
"""
|
@@ -163,6 +172,7 @@ class HtmlOutput(QWebEngineView):
|
|
163
172
|
if success:
|
164
173
|
event = RenderEvent(RenderEvent.ON_PAGE_LOAD, {
|
165
174
|
"meta": self.meta,
|
175
|
+
"tab": self.tab,
|
166
176
|
})
|
167
177
|
self.window.dispatch(event)
|
168
178
|
|
@@ -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: 2024.
|
9
|
+
# Updated Date: 2024.12.09 00:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtCore import Qt
|
@@ -38,6 +38,15 @@ class ChatOutput(QTextBrowser):
|
|
38
38
|
self.setOpenLinks(False)
|
39
39
|
self.anchorClicked.connect(self.open_external_link)
|
40
40
|
self.setWordWrapMode(QTextOption.WordWrap)
|
41
|
+
self.tab = None
|
42
|
+
|
43
|
+
def set_tab(self, tab):
|
44
|
+
"""
|
45
|
+
Set tab
|
46
|
+
|
47
|
+
:param tab: Tab
|
48
|
+
"""
|
49
|
+
self.tab = tab
|
41
50
|
|
42
51
|
def open_external_link(self, url):
|
43
52
|
"""
|
@@ -6,21 +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.09 00:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import re
|
13
13
|
|
14
|
-
from PySide6.QtCore import Qt, QObject, Signal, Slot
|
14
|
+
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
18
|
from PySide6.QtGui import QAction, QIcon, QKeySequence
|
19
|
+
from PySide6.QtWidgets import QMenu
|
19
20
|
|
20
21
|
from pygpt_net.core.events import RenderEvent
|
21
22
|
from pygpt_net.item.ctx import CtxMeta
|
22
23
|
from pygpt_net.core.text.web_finder import WebFinder
|
24
|
+
from pygpt_net.ui.widget.tabs.layout import FocusEventFilter
|
23
25
|
from pygpt_net.utils import trans
|
26
|
+
|
24
27
|
import pygpt_net.icons_rc
|
25
28
|
|
26
29
|
|
@@ -38,9 +41,46 @@ class ChatWebOutput(QWebEngineView):
|
|
38
41
|
self.customContextMenuRequested.connect(self.on_context_menu)
|
39
42
|
self.signals = WebEngineSignals()
|
40
43
|
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
44
|
+
self.filter = FocusEventFilter(self, self.on_focus)
|
45
|
+
self.installEventFilter(self)
|
41
46
|
self.plain = ""
|
42
47
|
self.html_content = ""
|
43
48
|
self.meta = None
|
49
|
+
self.tab = None
|
50
|
+
|
51
|
+
def eventFilter(self, source, event):
|
52
|
+
"""
|
53
|
+
Focus event filter
|
54
|
+
|
55
|
+
:param source: source
|
56
|
+
:param event: event
|
57
|
+
"""
|
58
|
+
if (event.type() == QEvent.ChildAdded and
|
59
|
+
source is self and
|
60
|
+
event.child().isWidgetType()):
|
61
|
+
self._glwidget = event.child()
|
62
|
+
self._glwidget.installEventFilter(self)
|
63
|
+
elif (event.type() == event.Type.MouseButtonPress):
|
64
|
+
col_idx = self.tab.column_idx
|
65
|
+
self.window.controller.ui.tabs.on_column_focus(col_idx)
|
66
|
+
return super().eventFilter(source, event)
|
67
|
+
|
68
|
+
def on_focus(self, widget):
|
69
|
+
"""
|
70
|
+
On widget clicked
|
71
|
+
|
72
|
+
:param widget: widget
|
73
|
+
"""
|
74
|
+
self.window.controller.ui.tabs.on_column_focus(self.tab.column_idx)
|
75
|
+
self.setFocus()
|
76
|
+
|
77
|
+
def set_tab(self, tab):
|
78
|
+
"""
|
79
|
+
Set tab
|
80
|
+
|
81
|
+
:param tab: Tab
|
82
|
+
"""
|
83
|
+
self.tab = tab
|
44
84
|
|
45
85
|
def set_meta(self, meta: CtxMeta):
|
46
86
|
"""
|
@@ -72,12 +112,7 @@ class ChatWebOutput(QWebEngineView):
|
|
72
112
|
|
73
113
|
:param position: position
|
74
114
|
"""
|
75
|
-
menu = self
|
76
|
-
|
77
|
-
# remove defaults
|
78
|
-
for action in menu.actions()[::-1]:
|
79
|
-
menu.removeAction(action)
|
80
|
-
|
115
|
+
menu = QMenu(self)
|
81
116
|
selected_text = ""
|
82
117
|
is_selection = self.page().hasSelection()
|
83
118
|
if is_selection:
|
@@ -138,6 +173,10 @@ class ChatWebOutput(QWebEngineView):
|
|
138
173
|
if self.window.core.config.has("zoom"):
|
139
174
|
self.page().setZoomFactor(self.window.core.config.get("zoom"))
|
140
175
|
|
176
|
+
def on_focus_js(self):
|
177
|
+
"""Focus JavaScript"""
|
178
|
+
self.window.controller.ui.tabs.on_column_focus(self.tab.column_idx)
|
179
|
+
|
141
180
|
def get_zoom_value(self) -> float:
|
142
181
|
"""
|
143
182
|
Get zoom value
|
@@ -165,6 +204,7 @@ class ChatWebOutput(QWebEngineView):
|
|
165
204
|
if success:
|
166
205
|
event = RenderEvent(RenderEvent.ON_PAGE_LOAD, {
|
167
206
|
"meta": self.meta,
|
207
|
+
"tab": self.tab,
|
168
208
|
})
|
169
209
|
self.window.dispatch(event)
|
170
210
|
|
@@ -318,4 +358,4 @@ class WebEngineSignals(QObject):
|
|
318
358
|
|
319
359
|
|
320
360
|
class WebEnginePageSignals(QObject):
|
321
|
-
js_message = Signal(int, str, str) # on Javascript message
|
361
|
+
js_message = Signal(int, str, str) # on Javascript message
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pygpt-net
|
3
|
-
Version: 2.4.
|
3
|
+
Version: 2.4.39
|
4
4
|
Summary: Desktop AI Assistant powered by models: OpenAI o1, GPT-4o, GPT-4, GPT-4 Vision, GPT-3.5, DALL-E 3, Llama 3, Mistral, Gemini, Claude, Bielik, and other models supported by Langchain, Llama Index, and Ollama. Features include chatbot, text completion, image generation, vision analysis, speech-to-text, internet access, file handling, command execution and more.
|
5
5
|
Home-page: https://pygpt.net
|
6
6
|
License: MIT
|
@@ -92,7 +92,7 @@ Description-Content-Type: text/markdown
|
|
92
92
|
|
93
93
|
[](https://snapcraft.io/pygpt)
|
94
94
|
|
95
|
-
Release: **2.4.
|
95
|
+
Release: **2.4.39** | build: **2024.12.09** | Python: **>=3.10, <3.12**
|
96
96
|
|
97
97
|
> Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
|
98
98
|
>
|
@@ -3963,6 +3963,12 @@ may consume additional tokens that are not displayed in the main window.
|
|
3963
3963
|
|
3964
3964
|
## Recent changes:
|
3965
3965
|
|
3966
|
+
**2.4.39 (2024-12-09)**
|
3967
|
+
|
3968
|
+
- Added "Split Screen" mode (accessible via the switch in the bottom-right corner of the screen), which allows you to work in two windows simultaneously. It is currently experimental (beta). Future updates will include Code Interpreter and Canvas running in tabs.
|
3969
|
+
|
3970
|
+
- Fixed: Language switch.
|
3971
|
+
|
3966
3972
|
**2.4.38 (2024-12-08)**
|
3967
3973
|
|
3968
3974
|
- Added the ability to select a style for chat display between: Blocks, ChatGPT-like, and ChatGPT-like Wide. New option in the menu: Config -> Theme -> Style...
|