pygpt-net 2.6.57__py3-none-any.whl → 2.6.59__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 +10 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +30 -25
- pygpt_net/controller/debug/debug.py +3 -3
- pygpt_net/controller/dialogs/info.py +6 -2
- pygpt_net/controller/ui/tabs.py +17 -0
- pygpt_net/core/agents/runners/llama_workflow.py +0 -0
- pygpt_net/core/filesystem/parser.py +37 -24
- pygpt_net/core/filesystem/url.py +5 -2
- pygpt_net/data/config/config.json +4 -3
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/settings.json +41 -2
- pygpt_net/data/js/app/ui.js +1 -1
- pygpt_net/data/js/app.min.js +2 -2
- pygpt_net/data/locale/locale.de.ini +5 -1
- pygpt_net/data/locale/locale.en.ini +5 -1
- pygpt_net/data/locale/locale.es.ini +5 -1
- pygpt_net/data/locale/locale.fr.ini +5 -1
- pygpt_net/data/locale/locale.it.ini +5 -1
- pygpt_net/data/locale/locale.pl.ini +5 -1
- pygpt_net/data/locale/locale.uk.ini +5 -1
- pygpt_net/data/locale/locale.zh.ini +5 -1
- pygpt_net/data/locale/plugin.cmd_system.en.ini +68 -0
- pygpt_net/js_rc.py +5 -5
- pygpt_net/plugin/base/plugin.py +3 -5
- pygpt_net/plugin/cmd_system/config.py +377 -1
- pygpt_net/plugin/cmd_system/plugin.py +52 -8
- pygpt_net/plugin/cmd_system/runner.py +508 -32
- pygpt_net/plugin/cmd_system/winapi.py +481 -0
- pygpt_net/plugin/cmd_system/worker.py +88 -15
- pygpt_net/provider/agents/llama_index/workflow/supervisor.py +0 -0
- pygpt_net/provider/core/config/patch.py +8 -1
- pygpt_net/provider/llms/openai.py +6 -4
- pygpt_net/tools/code_interpreter/ui/html.py +2 -1
- pygpt_net/tools/html_canvas/ui/widgets.py +19 -18
- pygpt_net/tools/web_browser/__init__.py +12 -0
- pygpt_net/tools/web_browser/tool.py +232 -0
- pygpt_net/tools/web_browser/ui/__init__.py +0 -0
- pygpt_net/tools/web_browser/ui/dialogs.py +123 -0
- pygpt_net/tools/web_browser/ui/widgets.py +351 -0
- pygpt_net/ui/widget/textarea/html.py +172 -24
- pygpt_net/ui/widget/textarea/web.py +1 -1
- {pygpt_net-2.6.57.dist-info → pygpt_net-2.6.59.dist-info}/METADATA +81 -61
- {pygpt_net-2.6.57.dist-info → pygpt_net-2.6.59.dist-info}/RECORD +45 -39
- {pygpt_net-2.6.57.dist-info → pygpt_net-2.6.59.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.57.dist-info → pygpt_net-2.6.59.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.57.dist-info → pygpt_net-2.6.59.dist-info}/entry_points.txt +0 -0
|
@@ -810,7 +810,8 @@ class CustomWebEnginePage(QWebEnginePage):
|
|
|
810
810
|
:param line_number: line number
|
|
811
811
|
:param source_id: source ID
|
|
812
812
|
"""
|
|
813
|
-
|
|
813
|
+
pass
|
|
814
|
+
# self.signals.js_message.emit(line_number, message, source_id) # handled in debug controller
|
|
814
815
|
|
|
815
816
|
def cleanup(self):
|
|
816
817
|
"""Cleanup method to release resources"""
|
|
@@ -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.09.
|
|
9
|
+
# Updated Date: 2025.09.22 18:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import Qt, Slot, QUrl, QObject, Signal, QSize
|
|
@@ -41,7 +41,7 @@ class ToolWidget:
|
|
|
41
41
|
self.edit = None # canvas edit
|
|
42
42
|
self.btn_edit = None # edit checkbox
|
|
43
43
|
|
|
44
|
-
# --- Navigation bar state
|
|
44
|
+
# --- Navigation bar state ---
|
|
45
45
|
# This toolbar is shown only when opening via URL (open_url),
|
|
46
46
|
# and hidden when using set_output/load_output.
|
|
47
47
|
self.nav_bar = None
|
|
@@ -50,7 +50,7 @@ class ToolWidget:
|
|
|
50
50
|
self.btn_back = None
|
|
51
51
|
self.btn_next = None
|
|
52
52
|
self.btn_reload = None
|
|
53
|
-
self.btn_go = None
|
|
53
|
+
self.btn_go = None
|
|
54
54
|
|
|
55
55
|
def on_open(self):
|
|
56
56
|
"""On open"""
|
|
@@ -88,7 +88,7 @@ class ToolWidget:
|
|
|
88
88
|
lambda: self.tool.save_output()
|
|
89
89
|
)
|
|
90
90
|
|
|
91
|
-
# ---- Navigation bar
|
|
91
|
+
# ---- Navigation bar ----
|
|
92
92
|
# Visible only when navigating URLs via open_url or address bar.
|
|
93
93
|
self.nav_bar = QWidget()
|
|
94
94
|
self.nav_layout = QHBoxLayout(self.nav_bar)
|
|
@@ -101,14 +101,14 @@ class ToolWidget:
|
|
|
101
101
|
nav_height = max(32, min(44, icon_size_px + 16)) # compact, never half-screen
|
|
102
102
|
self.nav_bar.setFixedHeight(nav_height)
|
|
103
103
|
|
|
104
|
-
# Buttons
|
|
104
|
+
# Buttons
|
|
105
105
|
self.btn_back = QPushButton()
|
|
106
106
|
self.btn_back.setToolTip("Back")
|
|
107
107
|
self.btn_back.setIcon(QIcon(":/icons/back.svg"))
|
|
108
108
|
self.btn_back.setIconSize(QSize(icon_size_px, icon_size_px))
|
|
109
109
|
self.btn_back.setFixedHeight(nav_height - 8)
|
|
110
110
|
self.btn_back.setEnabled(False)
|
|
111
|
-
self.btn_back.setAutoDefault(False) # prevent Enter from triggering this
|
|
111
|
+
self.btn_back.setAutoDefault(False) # prevent Enter from triggering this
|
|
112
112
|
try:
|
|
113
113
|
self.btn_back.setDefault(False)
|
|
114
114
|
except Exception:
|
|
@@ -116,11 +116,11 @@ class ToolWidget:
|
|
|
116
116
|
|
|
117
117
|
self.btn_next = QPushButton()
|
|
118
118
|
self.btn_next.setToolTip("Next")
|
|
119
|
-
self.btn_next.setIcon(QIcon(":/icons/
|
|
119
|
+
self.btn_next.setIcon(QIcon(":/icons/forward.svg"))
|
|
120
120
|
self.btn_next.setIconSize(QSize(icon_size_px, icon_size_px))
|
|
121
121
|
self.btn_next.setFixedHeight(nav_height - 8)
|
|
122
122
|
self.btn_next.setEnabled(False)
|
|
123
|
-
self.btn_next.setAutoDefault(False)
|
|
123
|
+
self.btn_next.setAutoDefault(False)
|
|
124
124
|
try:
|
|
125
125
|
self.btn_next.setDefault(False)
|
|
126
126
|
except Exception:
|
|
@@ -131,17 +131,19 @@ class ToolWidget:
|
|
|
131
131
|
self.btn_reload.setIcon(QIcon(":/icons/reload.svg"))
|
|
132
132
|
self.btn_reload.setIconSize(QSize(icon_size_px, icon_size_px))
|
|
133
133
|
self.btn_reload.setFixedHeight(nav_height - 8)
|
|
134
|
-
self.btn_reload.setAutoDefault(False)
|
|
134
|
+
self.btn_reload.setAutoDefault(False)
|
|
135
135
|
try:
|
|
136
136
|
self.btn_reload.setDefault(False)
|
|
137
137
|
except Exception:
|
|
138
138
|
pass
|
|
139
139
|
|
|
140
|
-
# "Go" button
|
|
141
|
-
self.btn_go = QPushButton(
|
|
140
|
+
# "Go" button
|
|
141
|
+
self.btn_go = QPushButton()
|
|
142
142
|
self.btn_go.setToolTip("Open URL")
|
|
143
|
+
self.btn_go.setIcon(QIcon(":/icons/redo.svg"))
|
|
144
|
+
self.btn_go.setIconSize(QSize(icon_size_px, icon_size_px))
|
|
143
145
|
self.btn_go.setFixedHeight(nav_height - 8)
|
|
144
|
-
self.btn_go.setAutoDefault(False) # avoid stealing Enter
|
|
146
|
+
self.btn_go.setAutoDefault(False) # avoid stealing Enter
|
|
145
147
|
try:
|
|
146
148
|
self.btn_go.setDefault(False)
|
|
147
149
|
except Exception:
|
|
@@ -185,7 +187,7 @@ class ToolWidget:
|
|
|
185
187
|
|
|
186
188
|
output_layout = QVBoxLayout()
|
|
187
189
|
# put navigation bar above the web output
|
|
188
|
-
output_layout.addWidget(self.nav_bar)
|
|
190
|
+
output_layout.addWidget(self.nav_bar)
|
|
189
191
|
output_layout.addWidget(self.output)
|
|
190
192
|
output_layout.addWidget(self.edit)
|
|
191
193
|
output_layout.setContentsMargins(0, 0, 0, 0)
|
|
@@ -256,9 +258,9 @@ class ToolWidget:
|
|
|
256
258
|
# Hide navigation bar when loading from local file/path
|
|
257
259
|
self._show_navbar(False)
|
|
258
260
|
|
|
259
|
-
#
|
|
260
|
-
# Navigation helpers
|
|
261
|
-
#
|
|
261
|
+
# ------------------
|
|
262
|
+
# Navigation helpers
|
|
263
|
+
# ------------------
|
|
262
264
|
def _show_navbar(self, show: bool):
|
|
263
265
|
"""Show/hide the navigation bar."""
|
|
264
266
|
if self.nav_bar:
|
|
@@ -287,7 +289,6 @@ class ToolWidget:
|
|
|
287
289
|
text = self.address_bar.text().strip()
|
|
288
290
|
if not text:
|
|
289
291
|
return
|
|
290
|
-
# Use fromUserInput to accept entries like 'example.com'
|
|
291
292
|
url = QUrl.fromUserInput(text)
|
|
292
293
|
if url.isValid():
|
|
293
294
|
self._show_navbar(True)
|
|
@@ -371,7 +372,7 @@ class CanvasEdit(BaseCodeEditor):
|
|
|
371
372
|
return super().eventFilter(source, event)
|
|
372
373
|
|
|
373
374
|
|
|
374
|
-
# --- Address bar input widget
|
|
375
|
+
# --- Address bar input widget ---
|
|
375
376
|
class AddressLineEdit(QLineEdit):
|
|
376
377
|
"""
|
|
377
378
|
Custom QLineEdit that ensures Enter triggers opening the typed URL
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# ================================================== #
|
|
4
|
+
# This file is a part of PYGPT package #
|
|
5
|
+
# Website: https://pygpt.net #
|
|
6
|
+
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
|
+
# MIT License #
|
|
8
|
+
# Created By : Marcin Szczygliński #
|
|
9
|
+
# Updated Date: 2025.09.22 19:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
from .tool import *
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# ================================================== #
|
|
4
|
+
# This file is a part of PYGPT package #
|
|
5
|
+
# Website: https://pygpt.net #
|
|
6
|
+
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
|
+
# MIT License #
|
|
8
|
+
# Created By : Marcin Szczygliński #
|
|
9
|
+
# Updated Date: 2025.09.22 19:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
from typing import Dict
|
|
13
|
+
|
|
14
|
+
from PySide6.QtCore import QTimer, Slot
|
|
15
|
+
from PySide6.QtGui import QAction, QIcon
|
|
16
|
+
from PySide6.QtWidgets import QWidget
|
|
17
|
+
|
|
18
|
+
from pygpt_net.core.tabs.tab import Tab
|
|
19
|
+
from pygpt_net.core.text.utils import output_clean_html, output_html2text
|
|
20
|
+
from pygpt_net.tools.base import BaseTool, TabWidget
|
|
21
|
+
from pygpt_net.utils import trans
|
|
22
|
+
|
|
23
|
+
from .ui.dialogs import Tool
|
|
24
|
+
from .ui.widgets import ToolSignals
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class WebBrowser(BaseTool):
|
|
28
|
+
def __init__(self, *args, **kwargs):
|
|
29
|
+
"""
|
|
30
|
+
Web Browser tool
|
|
31
|
+
|
|
32
|
+
:param window: Window instance
|
|
33
|
+
"""
|
|
34
|
+
super(WebBrowser, self).__init__(*args, **kwargs)
|
|
35
|
+
self.id = "web_browser"
|
|
36
|
+
self.dialog_id = "web_browser"
|
|
37
|
+
self.has_tab = True
|
|
38
|
+
self.tab_title = "menu.tools.web_browser"
|
|
39
|
+
self.tab_icon = ":/icons/web_on.svg"
|
|
40
|
+
self.opened = False
|
|
41
|
+
self.is_edit = False
|
|
42
|
+
self.auto_clear = True
|
|
43
|
+
self.dialog = None
|
|
44
|
+
self.is_edit = False
|
|
45
|
+
self.auto_opened = False
|
|
46
|
+
self.signals = ToolSignals()
|
|
47
|
+
|
|
48
|
+
def setup(self):
|
|
49
|
+
"""Setup"""
|
|
50
|
+
self.update()
|
|
51
|
+
|
|
52
|
+
def on_reload(self):
|
|
53
|
+
"""On app profile reload"""
|
|
54
|
+
self.setup()
|
|
55
|
+
|
|
56
|
+
def update(self):
|
|
57
|
+
"""Update menu"""
|
|
58
|
+
self.update_menu()
|
|
59
|
+
|
|
60
|
+
def update_menu(self):
|
|
61
|
+
"""Update menu"""
|
|
62
|
+
"""
|
|
63
|
+
if self.opened:
|
|
64
|
+
self.window.ui.menu['tools.web_browser'].setChecked(True)
|
|
65
|
+
else:
|
|
66
|
+
self.window.ui.menu['tools.web_browser'].setChecked(False)
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
def get_dialog_id(self) -> str:
|
|
70
|
+
"""
|
|
71
|
+
Get dialog ID
|
|
72
|
+
|
|
73
|
+
:return: Dialog ID
|
|
74
|
+
"""
|
|
75
|
+
return self.dialog_id
|
|
76
|
+
|
|
77
|
+
def set_url(self, url: str):
|
|
78
|
+
"""
|
|
79
|
+
Set output URL
|
|
80
|
+
|
|
81
|
+
:param url: URL to load
|
|
82
|
+
"""
|
|
83
|
+
self.signals.url.emit(url)
|
|
84
|
+
|
|
85
|
+
def open(self, load: bool = True):
|
|
86
|
+
"""
|
|
87
|
+
Open HTML canvas dialog
|
|
88
|
+
|
|
89
|
+
:param load: Load output data
|
|
90
|
+
"""
|
|
91
|
+
if not self.opened:
|
|
92
|
+
self.opened = True
|
|
93
|
+
self.auto_opened = False
|
|
94
|
+
self.window.ui.dialogs.open(self.dialog_id, width=800, height=600)
|
|
95
|
+
self.dialog.widget.on_open()
|
|
96
|
+
self.update()
|
|
97
|
+
|
|
98
|
+
def auto_open(self, load: bool = True):
|
|
99
|
+
"""
|
|
100
|
+
Auto open canvas dialog or tab
|
|
101
|
+
|
|
102
|
+
:param load: Load output data
|
|
103
|
+
"""
|
|
104
|
+
if self.window.controller.ui.tabs.is_current_tool(self.id):
|
|
105
|
+
tool_col = self.window.controller.ui.tabs.get_tool_column(self.id)
|
|
106
|
+
current_col = self.window.controller.ui.tabs.column_idx
|
|
107
|
+
if tool_col == 1 and tool_col != current_col:
|
|
108
|
+
self.window.controller.ui.tabs.enable_split_screen(True) # enable split screen
|
|
109
|
+
return # do not open if already opened in tab
|
|
110
|
+
elif self.window.controller.ui.tabs.is_tool(self.id):
|
|
111
|
+
tab = self.window.controller.ui.tabs.get_first_tab_by_tool(self.id)
|
|
112
|
+
if tab:
|
|
113
|
+
tool_col = tab.column_idx
|
|
114
|
+
current_col = self.window.controller.ui.tabs.column_idx
|
|
115
|
+
self.window.controller.ui.tabs.switch_tab_by_idx(tab.idx, tab.column_idx)
|
|
116
|
+
if tool_col == 1 and tool_col != current_col:
|
|
117
|
+
self.window.controller.ui.tabs.enable_split_screen(True) # enable split screen
|
|
118
|
+
return
|
|
119
|
+
if not self.auto_opened:
|
|
120
|
+
self.auto_opened = True
|
|
121
|
+
self.open(load=load)
|
|
122
|
+
|
|
123
|
+
def close(self):
|
|
124
|
+
"""Close HTML canvas dialog"""
|
|
125
|
+
self.opened = False
|
|
126
|
+
self.signals.closed.emit()
|
|
127
|
+
self.window.ui.dialogs.close(self.dialog_id)
|
|
128
|
+
self.update()
|
|
129
|
+
|
|
130
|
+
def toggle(self):
|
|
131
|
+
"""Toggle HTML canvas dialog open/close"""
|
|
132
|
+
if self.opened:
|
|
133
|
+
self.close()
|
|
134
|
+
else:
|
|
135
|
+
self.open()
|
|
136
|
+
|
|
137
|
+
@Slot(str, str)
|
|
138
|
+
def handle_save_as(self, text: str, type: str = 'txt'):
|
|
139
|
+
"""
|
|
140
|
+
Handle save as signal
|
|
141
|
+
|
|
142
|
+
:param text: Data to save
|
|
143
|
+
:param type: File type
|
|
144
|
+
"""
|
|
145
|
+
if type == 'html':
|
|
146
|
+
text = output_clean_html(text)
|
|
147
|
+
else:
|
|
148
|
+
text = output_html2text(text)
|
|
149
|
+
# fix: QTimer required here to prevent crash if signal emitted from WebEngine window
|
|
150
|
+
QTimer.singleShot(0, lambda: self.window.controller.chat.common.save_text(text, type))
|
|
151
|
+
|
|
152
|
+
def show_hide(self, show: bool = True):
|
|
153
|
+
"""
|
|
154
|
+
Show/hide HTML canvas window
|
|
155
|
+
|
|
156
|
+
:param show: show/hide
|
|
157
|
+
"""
|
|
158
|
+
if show:
|
|
159
|
+
self.open()
|
|
160
|
+
else:
|
|
161
|
+
self.close()
|
|
162
|
+
|
|
163
|
+
def get_toolbar_icon(self) -> QWidget:
|
|
164
|
+
"""
|
|
165
|
+
Get toolbar icon
|
|
166
|
+
|
|
167
|
+
:return: QWidget
|
|
168
|
+
"""
|
|
169
|
+
return self.window.ui.nodes['icon.web_browser']
|
|
170
|
+
|
|
171
|
+
def toggle_icon(self, state: bool):
|
|
172
|
+
"""
|
|
173
|
+
Toggle canvas icon
|
|
174
|
+
|
|
175
|
+
:param state: State
|
|
176
|
+
"""
|
|
177
|
+
self.get_toolbar_icon().setVisible(state)
|
|
178
|
+
|
|
179
|
+
def setup_menu(self) -> Dict[str, QAction]:
|
|
180
|
+
"""
|
|
181
|
+
Setup main menu
|
|
182
|
+
|
|
183
|
+
:return dict with menu actions
|
|
184
|
+
"""
|
|
185
|
+
actions = {}
|
|
186
|
+
actions["web_browser"] = QAction(
|
|
187
|
+
QIcon(":/icons/web_on.svg"),
|
|
188
|
+
trans("menu.tools.web_browser"),
|
|
189
|
+
self.window,
|
|
190
|
+
checkable=False,
|
|
191
|
+
)
|
|
192
|
+
actions["web_browser"].triggered.connect(
|
|
193
|
+
lambda: self.toggle()
|
|
194
|
+
)
|
|
195
|
+
return actions
|
|
196
|
+
|
|
197
|
+
def as_tab(self, tab: Tab) -> QWidget:
|
|
198
|
+
"""
|
|
199
|
+
Spawn and return tab instance
|
|
200
|
+
|
|
201
|
+
:param tab: Parent Tab instance
|
|
202
|
+
:return: Tab widget instance
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
tool = Tool(window=self.window, tool=self) # dialog
|
|
206
|
+
tool_widget = tool.as_tab() # ToolWidget
|
|
207
|
+
widget = TabWidget()
|
|
208
|
+
widget.from_tool(tool_widget)
|
|
209
|
+
widget.setup()
|
|
210
|
+
tool.set_tab(tab)
|
|
211
|
+
return widget
|
|
212
|
+
|
|
213
|
+
def setup_dialogs(self):
|
|
214
|
+
"""Setup dialogs (static)"""
|
|
215
|
+
self.dialog = Tool(window=self.window, tool=self)
|
|
216
|
+
self.dialog.setup()
|
|
217
|
+
|
|
218
|
+
def setup_theme(self):
|
|
219
|
+
"""Setup theme"""
|
|
220
|
+
pass
|
|
221
|
+
|
|
222
|
+
def get_lang_mappings(self) -> Dict[str, Dict]:
|
|
223
|
+
"""
|
|
224
|
+
Get language mappings
|
|
225
|
+
|
|
226
|
+
:return: dict with language mappings
|
|
227
|
+
"""
|
|
228
|
+
return {
|
|
229
|
+
'menu.text': {
|
|
230
|
+
'tools.web_browser': 'menu.tools.web_browser',
|
|
231
|
+
}
|
|
232
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# ================================================== #
|
|
4
|
+
# This file is a part of PYGPT package #
|
|
5
|
+
# Website: https://pygpt.net #
|
|
6
|
+
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
|
+
# MIT License #
|
|
8
|
+
# Created By : Marcin Szczygliński #
|
|
9
|
+
# Updated Date: 2025.09.22 19:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
import re
|
|
13
|
+
|
|
14
|
+
from PySide6.QtCore import Qt
|
|
15
|
+
from PySide6.QtGui import QAction, QIcon
|
|
16
|
+
from PySide6.QtWidgets import QMenuBar, QVBoxLayout
|
|
17
|
+
|
|
18
|
+
from pygpt_net.core.tabs.tab import Tab
|
|
19
|
+
from pygpt_net.ui.widget.dialog.base import BaseDialog
|
|
20
|
+
from pygpt_net.utils import trans
|
|
21
|
+
|
|
22
|
+
from .widgets import ToolWidget
|
|
23
|
+
|
|
24
|
+
class Tool:
|
|
25
|
+
def __init__(self, window=None, tool=None):
|
|
26
|
+
"""
|
|
27
|
+
HTML/JS canvas dialog
|
|
28
|
+
|
|
29
|
+
:param window: Window instance
|
|
30
|
+
:param tool: Tool instance
|
|
31
|
+
"""
|
|
32
|
+
self.window = window
|
|
33
|
+
self.tool = tool # tool instance
|
|
34
|
+
self.widget = ToolWidget(window, tool)
|
|
35
|
+
self.layout = None
|
|
36
|
+
self.menu_bar = None
|
|
37
|
+
self.menu = {}
|
|
38
|
+
self.actions = {} # menu actions
|
|
39
|
+
|
|
40
|
+
def as_tab(self) -> ToolWidget:
|
|
41
|
+
"""
|
|
42
|
+
Return tool as tab
|
|
43
|
+
|
|
44
|
+
:return: ToolWidget
|
|
45
|
+
"""
|
|
46
|
+
return self.widget
|
|
47
|
+
|
|
48
|
+
def set_tab(self, tab: Tab):
|
|
49
|
+
"""
|
|
50
|
+
Set tab
|
|
51
|
+
|
|
52
|
+
:param tab: Tab
|
|
53
|
+
"""
|
|
54
|
+
self.widget.set_tab(tab)
|
|
55
|
+
|
|
56
|
+
def setup(self):
|
|
57
|
+
"""Setup canvas dialog"""
|
|
58
|
+
self.layout = self.widget.setup()
|
|
59
|
+
|
|
60
|
+
id = self.tool.get_dialog_id()
|
|
61
|
+
dialog = ToolDialog(window=self.window, tool=self.tool)
|
|
62
|
+
dialog.setLayout(self.layout)
|
|
63
|
+
dialog.setWindowTitle(trans("menu.tools.web_browser"))
|
|
64
|
+
dialog.resize(800, 500)
|
|
65
|
+
self.window.ui.dialog[id] = dialog
|
|
66
|
+
|
|
67
|
+
def get_widget(self) -> ToolWidget:
|
|
68
|
+
"""
|
|
69
|
+
Get widget
|
|
70
|
+
|
|
71
|
+
:return: ToolWidget
|
|
72
|
+
"""
|
|
73
|
+
return self.widget
|
|
74
|
+
|
|
75
|
+
def get_tab(self) -> QVBoxLayout:
|
|
76
|
+
"""
|
|
77
|
+
Get layout
|
|
78
|
+
|
|
79
|
+
:return: QVBoxLayout
|
|
80
|
+
"""
|
|
81
|
+
return self.layout
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ToolDialog(BaseDialog):
|
|
85
|
+
def __init__(self, window=None, id="html_canvas", tool=None):
|
|
86
|
+
"""
|
|
87
|
+
HTML canvas dialog
|
|
88
|
+
|
|
89
|
+
:param window: main window
|
|
90
|
+
:param id: logger id
|
|
91
|
+
"""
|
|
92
|
+
super(ToolDialog, self).__init__(window, id)
|
|
93
|
+
self.window = window
|
|
94
|
+
self.tool = tool
|
|
95
|
+
|
|
96
|
+
def closeEvent(self, event):
|
|
97
|
+
"""
|
|
98
|
+
Close event
|
|
99
|
+
|
|
100
|
+
:param event: close event
|
|
101
|
+
"""
|
|
102
|
+
self.cleanup()
|
|
103
|
+
super(ToolDialog, self).closeEvent(event)
|
|
104
|
+
|
|
105
|
+
def keyPressEvent(self, event):
|
|
106
|
+
"""
|
|
107
|
+
Key press event
|
|
108
|
+
|
|
109
|
+
:param event: key press event
|
|
110
|
+
"""
|
|
111
|
+
if event.key() == Qt.Key_Escape:
|
|
112
|
+
self.cleanup()
|
|
113
|
+
self.close() # close dialog when the Esc key is pressed.
|
|
114
|
+
else:
|
|
115
|
+
super(ToolDialog, self).keyPressEvent(event)
|
|
116
|
+
|
|
117
|
+
def cleanup(self):
|
|
118
|
+
"""Cleanup on close"""
|
|
119
|
+
if self.window is None or self.tool is None:
|
|
120
|
+
return
|
|
121
|
+
self.tool.opened = False
|
|
122
|
+
self.tool.close()
|
|
123
|
+
self.tool.update()
|