pygpt-net 2.4.54__py3-none-any.whl → 2.4.56__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 +10 -0
- README.md +11 -1
- pygpt_net/CHANGELOG.txt +10 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/access/__init__.py +1 -3
- pygpt_net/controller/access/voice.py +20 -7
- pygpt_net/controller/{attachment.py → attachment/__init__.py} +0 -0
- pygpt_net/controller/{camera.py → camera/__init__.py} +1 -1
- pygpt_net/controller/{files.py → files/__init__.py} +0 -0
- pygpt_net/controller/{finder.py → finder/__init__.py} +0 -0
- pygpt_net/controller/lang/mapping.py +2 -1
- pygpt_net/controller/{launcher.py → launcher/__init__.py} +0 -0
- pygpt_net/controller/{layout.py → layout/__init__.py} +0 -0
- pygpt_net/controller/{notepad.py → notepad/__init__.py} +0 -0
- pygpt_net/controller/settings/editor.py +4 -0
- pygpt_net/core/access/shortcuts.py +48 -29
- pygpt_net/core/{camera.py → camera/__init__.py} +5 -4
- pygpt_net/core/{command.py → command/__init__.py} +4 -3
- pygpt_net/core/{dispatcher.py → dispatcher/__init__.py} +0 -0
- pygpt_net/core/{history.py → history/__init__.py} +0 -2
- pygpt_net/core/{image.py → image/__init__.py} +0 -0
- pygpt_net/core/{info.py → info/__init__.py} +0 -0
- pygpt_net/core/{locale.py → locale/__init__.py} +0 -0
- pygpt_net/core/{notepad.py → notepad/__init__.py} +0 -0
- pygpt_net/core/{platforms.py → platforms/__init__.py} +0 -0
- pygpt_net/core/{plugins.py → plugins/__init__.py} +0 -0
- pygpt_net/core/{settings.py → settings/__init__.py} +0 -0
- pygpt_net/core/tabs/__init__.py +8 -6
- pygpt_net/core/{tokens.py → tokens/__init__.py} +0 -0
- pygpt_net/data/config/config.json +11 -9
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/modes.json +3 -3
- pygpt_net/data/config/settings.json +24 -0
- 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/launcher.py +3 -2
- pygpt_net/plugin/audio_input/simple.py +10 -7
- pygpt_net/plugin/audio_input/worker.py +1 -1
- pygpt_net/provider/core/config/patch.py +21 -1
- pygpt_net/tools/code_interpreter/__init__.py +2 -1
- pygpt_net/tools/code_interpreter/ui/dialogs.py +10 -1
- pygpt_net/tools/code_interpreter/ui/widgets.py +56 -1
- pygpt_net/tools/html_canvas/__init__.py +2 -1
- pygpt_net/tools/html_canvas/ui/dialogs.py +10 -1
- pygpt_net/tools/html_canvas/ui/widgets.py +33 -1
- pygpt_net/ui/__init__.py +1 -1
- pygpt_net/ui/layout/chat/calendar.py +5 -2
- pygpt_net/ui/layout/chat/explorer.py +4 -2
- pygpt_net/ui/layout/chat/painter.py +4 -2
- pygpt_net/ui/main.py +63 -2
- pygpt_net/ui/widget/calendar/select.py +29 -1
- pygpt_net/ui/widget/draw/painter.py +25 -1
- pygpt_net/ui/widget/filesystem/explorer.py +24 -1
- pygpt_net/ui/widget/tabs/body.py +54 -4
- pygpt_net/ui/widget/textarea/calendar_note.py +26 -2
- pygpt_net/ui/widget/textarea/html.py +21 -2
- pygpt_net/ui/widget/textarea/notepad.py +37 -3
- pygpt_net/ui/widget/textarea/web.py +4 -2
- {pygpt_net-2.4.54.dist-info → pygpt_net-2.4.56.dist-info}/METADATA +12 -2
- {pygpt_net-2.4.54.dist-info → pygpt_net-2.4.56.dist-info}/RECORD +77 -77
- /pygpt_net/controller/{command.py → command/__init__.py} +0 -0
- /pygpt_net/controller/{mode.py → mode/__init__.py} +0 -0
- /pygpt_net/core/{installer.py → installer/__init__.py} +0 -0
- /pygpt_net/core/{models.py → models/__init__.py} +0 -0
- /pygpt_net/core/{modes.py → modes/__init__.py} +0 -0
- /pygpt_net/core/{presets.py → presets/__init__.py} +0 -0
- /pygpt_net/core/{profile.py → profile/__init__.py} +0 -0
- /pygpt_net/core/{worker.py → worker/__init__.py} +0 -0
- {pygpt_net-2.4.54.dist-info → pygpt_net-2.4.56.dist-info}/LICENSE +0 -0
- {pygpt_net-2.4.54.dist-info → pygpt_net-2.4.56.dist-info}/WHEEL +0 -0
- {pygpt_net-2.4.54.dist-info → pygpt_net-2.4.56.dist-info}/entry_points.txt +0 -0
@@ -878,6 +878,9 @@ settings.audio.input.rate = 采样率
|
|
878
878
|
settings.audio.input.rate.desc = 采样率,默认: 44100
|
879
879
|
settings.audio.input.stop_interval = 连续录音自动转录间隔
|
880
880
|
settings.audio.input.stop_interval.desc = 自动转录音频片段的间隔(以秒为单位),默认:10
|
881
|
+
settings.audio.input.timeout = 录音超时
|
882
|
+
settings.audio.input.timeout.desc = 自动停止录音的超时时间(秒),0为禁用,默认:120
|
883
|
+
settings.audio.input.timeout.continuous = 在连续模式下启用超时
|
881
884
|
settings.check_updates = 啟動時檢查更新
|
882
885
|
settings.check_updates.bg = 在後台檢查更新
|
883
886
|
settings.cmd.field.desc = 启用 `{cmd}` 工具。
|
pygpt_net/launcher.py
CHANGED
@@ -6,8 +6,9 @@
|
|
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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
|
+
|
11
12
|
import os
|
12
13
|
import sys
|
13
14
|
import argparse
|
@@ -266,5 +267,5 @@ class Launcher:
|
|
266
267
|
self.window.ui.tray.setup(self.app)
|
267
268
|
self.window.controller.after_setup()
|
268
269
|
self.window.dispatch(AppEvent(AppEvent.APP_STARTED)) # app event
|
269
|
-
self.window.
|
270
|
+
self.window.setup_global_shortcuts()
|
270
271
|
sys.exit(self.app.exec())
|
@@ -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.01.
|
9
|
+
# Updated Date: 2025.01.18 23:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import os
|
@@ -20,7 +20,6 @@ from pygpt_net.utils import trans
|
|
20
20
|
|
21
21
|
class Simple:
|
22
22
|
|
23
|
-
TIMEOUT_SECONDS = 120 # 2 minutes, max recording time before timeout
|
24
23
|
MIN_FRAMES = 25 # minimum frames to start transcription
|
25
24
|
|
26
25
|
def __init__(self, plugin=None):
|
@@ -92,10 +91,14 @@ class Simple:
|
|
92
91
|
)
|
93
92
|
|
94
93
|
# start timeout timer to prevent infinite recording
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
94
|
+
# disable in continuous mode
|
95
|
+
timeout = int(self.plugin.window.core.config.get('audio.input.timeout', 120) or 0) # get timeout
|
96
|
+
timeout_continuous = self.plugin.window.core.config.get('audio.input.timeout.continuous', False) # enable continuous timeout
|
97
|
+
if timeout > 0:
|
98
|
+
if self.timer is None and (not continuous_enabled or timeout_continuous):
|
99
|
+
self.timer = QTimer()
|
100
|
+
self.timer.timeout.connect(self.stop_timeout)
|
101
|
+
self.timer.start(timeout * 1000)
|
99
102
|
|
100
103
|
if not force:
|
101
104
|
if not self.plugin.window.core.audio.capture.check_audio_input():
|
@@ -141,7 +144,7 @@ class Simple:
|
|
141
144
|
self.plugin.window.core.audio.capture.stop() # stop recording
|
142
145
|
# abort if timeout
|
143
146
|
if timeout:
|
144
|
-
self.plugin.window.update_status("Aborted.".format(
|
147
|
+
self.plugin.window.update_status("Aborted.".format(timeout))
|
145
148
|
return
|
146
149
|
|
147
150
|
if self.plugin.window.core.audio.capture.has_frames():
|
@@ -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.01.
|
9
|
+
# Updated Date: 2025.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import copy
|
@@ -1811,6 +1811,26 @@ class Patch:
|
|
1811
1811
|
if 'audio.input.continuous' not in data:
|
1812
1812
|
data["audio.input.continuous"] = False
|
1813
1813
|
|
1814
|
+
# < 2.4.55
|
1815
|
+
if old < parse_version("2.4.55"):
|
1816
|
+
print("Migrating config from < 2.4.55...")
|
1817
|
+
if 'audio.input.timeout' not in data:
|
1818
|
+
data["audio.input.timeout"] = 120
|
1819
|
+
if 'audio.input.timeout.continuous' not in data:
|
1820
|
+
data["audio.input.timeout.continuous"] = False
|
1821
|
+
|
1822
|
+
# < 2.4.56
|
1823
|
+
if old < parse_version("2.4.56"):
|
1824
|
+
print("Migrating config from < 2.4.56...")
|
1825
|
+
remove_modifiers = ["Meta", "Keypad", "GroupSwitch"]
|
1826
|
+
if 'access.shortcuts' in data:
|
1827
|
+
for item in data['access.shortcuts']:
|
1828
|
+
if 'key_modifier' in item and item['key_modifier'] == 'Control':
|
1829
|
+
item['key_modifier'] = 'Ctrl'
|
1830
|
+
elif 'key_modifier' in item and item['key_modifier'] in remove_modifiers:
|
1831
|
+
item['key_modifier'] = ''
|
1832
|
+
updated = True
|
1833
|
+
|
1814
1834
|
# update file
|
1815
1835
|
migrated = False
|
1816
1836
|
if updated:
|
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import os
|
@@ -539,6 +539,7 @@ class CodeInterpreter(BaseTool):
|
|
539
539
|
widget.setLayout(layout)
|
540
540
|
self.load_history()
|
541
541
|
self.load_output()
|
542
|
+
tool.set_tab(tab)
|
542
543
|
return widget
|
543
544
|
|
544
545
|
def setup_dialogs(self):
|
@@ -6,13 +6,14 @@
|
|
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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtCore import Qt
|
13
13
|
from PySide6.QtGui import QAction, QIcon
|
14
14
|
from PySide6.QtWidgets import QMenuBar
|
15
15
|
|
16
|
+
from pygpt_net.core.tabs.tab import Tab
|
16
17
|
from pygpt_net.tools.code_interpreter.ui.widgets import ToolWidget
|
17
18
|
from pygpt_net.ui.widget.dialog.base import BaseDialog
|
18
19
|
from pygpt_net.utils import trans
|
@@ -33,6 +34,14 @@ class Tool:
|
|
33
34
|
self.menu = {}
|
34
35
|
self.actions = {} # menu actions
|
35
36
|
|
37
|
+
def set_tab(self, tab: Tab):
|
38
|
+
"""
|
39
|
+
Set tab
|
40
|
+
|
41
|
+
:param tab: Tab
|
42
|
+
"""
|
43
|
+
self.widget.set_tab(tab)
|
44
|
+
|
36
45
|
def setup_menu(self) -> QMenuBar:
|
37
46
|
"""
|
38
47
|
Setup dialog menu
|
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6 import QtCore
|
@@ -42,6 +42,15 @@ class ToolWidget:
|
|
42
42
|
self.label_output = None # output label
|
43
43
|
self.label_history = None # history label
|
44
44
|
|
45
|
+
def set_tab(self, tab):
|
46
|
+
"""
|
47
|
+
Set tab
|
48
|
+
|
49
|
+
:param tab: Tab
|
50
|
+
"""
|
51
|
+
self.output.set_tab(tab)
|
52
|
+
self.input.set_tab(tab)
|
53
|
+
|
45
54
|
def setup(self, all: bool = True) -> QVBoxLayout:
|
46
55
|
"""
|
47
56
|
Setup widget body
|
@@ -297,6 +306,29 @@ class PythonInput(QTextEdit):
|
|
297
306
|
lambda: self.tool.update_input()
|
298
307
|
)
|
299
308
|
self.setFocus()
|
309
|
+
self.tab = None
|
310
|
+
self.installEventFilter(self)
|
311
|
+
|
312
|
+
def set_tab(self, tab):
|
313
|
+
"""
|
314
|
+
Set tab
|
315
|
+
|
316
|
+
:param tab: Tab
|
317
|
+
"""
|
318
|
+
self.tab = tab
|
319
|
+
|
320
|
+
def eventFilter(self, source, event):
|
321
|
+
"""
|
322
|
+
Focus event filter
|
323
|
+
|
324
|
+
:param source: source
|
325
|
+
:param event: event
|
326
|
+
"""
|
327
|
+
if event.type() == event.Type.FocusIn:
|
328
|
+
if self.tab is not None:
|
329
|
+
col_idx = self.tab.column_idx
|
330
|
+
self.window.controller.ui.tabs.on_column_focus(col_idx)
|
331
|
+
return super().eventFilter(source, event)
|
300
332
|
|
301
333
|
def update_stylesheet(self, data: str):
|
302
334
|
"""
|
@@ -364,6 +396,29 @@ class PythonOutput(BaseCodeEditor):
|
|
364
396
|
self.setProperty('class', 'interpreter-output')
|
365
397
|
self.default_stylesheet = ""
|
366
398
|
self.setStyleSheet(self.default_stylesheet)
|
399
|
+
self.tab = None
|
400
|
+
self.installEventFilter(self)
|
401
|
+
|
402
|
+
def set_tab(self, tab):
|
403
|
+
"""
|
404
|
+
Set tab
|
405
|
+
|
406
|
+
:param tab: Tab
|
407
|
+
"""
|
408
|
+
self.tab = tab
|
409
|
+
|
410
|
+
def eventFilter(self, source, event):
|
411
|
+
"""
|
412
|
+
Focus event filter
|
413
|
+
|
414
|
+
:param source: source
|
415
|
+
:param event: event
|
416
|
+
"""
|
417
|
+
if event.type() == event.Type.FocusIn:
|
418
|
+
if self.tab is not None:
|
419
|
+
col_idx = self.tab.column_idx
|
420
|
+
self.window.controller.ui.tabs.on_column_focus(col_idx)
|
421
|
+
return super().eventFilter(source, event)
|
367
422
|
|
368
423
|
def clear_content(self):
|
369
424
|
"""Clear content"""
|
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import os
|
@@ -295,6 +295,7 @@ class HtmlCanvas(BaseTool):
|
|
295
295
|
layout = canvas.widget.setup()
|
296
296
|
widget = QWidget()
|
297
297
|
widget.setLayout(layout)
|
298
|
+
canvas.set_tab(tab)
|
298
299
|
self.load_output()
|
299
300
|
return widget
|
300
301
|
|
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import re
|
@@ -15,6 +15,7 @@ from PySide6.QtCore import Qt
|
|
15
15
|
from PySide6.QtGui import QAction, QIcon
|
16
16
|
from PySide6.QtWidgets import QMenuBar, QVBoxLayout
|
17
17
|
|
18
|
+
from pygpt_net.core.tabs.tab import Tab
|
18
19
|
from pygpt_net.ui.widget.dialog.base import BaseDialog
|
19
20
|
from pygpt_net.utils import trans
|
20
21
|
|
@@ -71,6 +72,14 @@ class Tool:
|
|
71
72
|
self.menu["file"].addAction(self.actions["file.clear"])
|
72
73
|
return self.menu_bar
|
73
74
|
|
75
|
+
def set_tab(self, tab: Tab):
|
76
|
+
"""
|
77
|
+
Set tab
|
78
|
+
|
79
|
+
:param tab: Tab
|
80
|
+
"""
|
81
|
+
self.widget.set_tab(tab)
|
82
|
+
|
74
83
|
def setup(self):
|
75
84
|
"""Setup canvas dialog"""
|
76
85
|
self.layout = self.widget.setup()
|
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtCore import Qt, Slot, QUrl, QObject, Signal
|
@@ -34,6 +34,15 @@ class ToolWidget:
|
|
34
34
|
self.edit = None # canvas edit
|
35
35
|
self.btn_edit = None # edit checkbox
|
36
36
|
|
37
|
+
def set_tab(self, tab):
|
38
|
+
"""
|
39
|
+
Set tab
|
40
|
+
|
41
|
+
:param tab: Tab
|
42
|
+
"""
|
43
|
+
self.output.set_tab(tab)
|
44
|
+
self.edit.set_tab(tab)
|
45
|
+
|
37
46
|
def setup(self) -> QVBoxLayout:
|
38
47
|
"""
|
39
48
|
Setup widget body
|
@@ -128,6 +137,29 @@ class CanvasEdit(BaseCodeEditor):
|
|
128
137
|
self.setProperty('class', 'interpreter-output')
|
129
138
|
self.default_stylesheet = ""
|
130
139
|
self.setStyleSheet(self.default_stylesheet)
|
140
|
+
self.tab = None
|
141
|
+
self.installEventFilter(self)
|
142
|
+
|
143
|
+
def set_tab(self, tab):
|
144
|
+
"""
|
145
|
+
Set tab
|
146
|
+
|
147
|
+
:param tab: Tab
|
148
|
+
"""
|
149
|
+
self.tab = tab
|
150
|
+
|
151
|
+
def eventFilter(self, source, event):
|
152
|
+
"""
|
153
|
+
Focus event filter
|
154
|
+
|
155
|
+
:param source: source
|
156
|
+
:param event: event
|
157
|
+
"""
|
158
|
+
if event.type() == event.Type.FocusIn:
|
159
|
+
if self.tab is not None:
|
160
|
+
col_idx = self.tab.column_idx
|
161
|
+
self.window.controller.ui.tabs.on_column_focus(col_idx)
|
162
|
+
return super().eventFilter(source, event)
|
131
163
|
|
132
164
|
|
133
165
|
class ToolSignals(QObject):
|
pygpt_net/ui/__init__.py
CHANGED
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtCore import Qt
|
@@ -44,7 +44,10 @@ class Calendar:
|
|
44
44
|
:return: QWidget
|
45
45
|
"""
|
46
46
|
self.init()
|
47
|
-
|
47
|
+
body = self.window.core.tabs.from_widget(self.setup_calendar())
|
48
|
+
body.append(self.window.ui.calendar['note'])
|
49
|
+
body.append(self.window.ui.calendar['select'])
|
50
|
+
return body
|
48
51
|
|
49
52
|
def setup_filters(self) -> QWidget:
|
50
53
|
"""
|
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from pygpt_net.ui.widget.tabs.body import TabBody
|
@@ -36,4 +36,6 @@ class Explorer:
|
|
36
36
|
self.window.ui.nodes['output_files'] = FileExplorer(self.window, path, index_data)
|
37
37
|
|
38
38
|
# build tab body
|
39
|
-
|
39
|
+
body = self.window.core.tabs.from_widget(self.window.ui.nodes['output_files'])
|
40
|
+
body.append(self.window.ui.nodes['output_files'])
|
41
|
+
return body
|
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtGui import QPixmap, QIcon
|
@@ -83,7 +83,9 @@ class Painter:
|
|
83
83
|
"""
|
84
84
|
# build tab body
|
85
85
|
self.init()
|
86
|
-
|
86
|
+
body = self.window.core.tabs.from_layout(self.setup_painter())
|
87
|
+
body.append(self.window.ui.painter)
|
88
|
+
return body
|
87
89
|
|
88
90
|
def setup_painter(self) -> QVBoxLayout:
|
89
91
|
"""
|
pygpt_net/ui/main.py
CHANGED
@@ -6,16 +6,19 @@
|
|
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.01.19 03:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
|
+
import copy
|
12
13
|
import os
|
13
14
|
|
15
|
+
from PySide6 import QtWidgets
|
14
16
|
from PySide6.QtCore import QTimer, Signal, Slot, QThreadPool, QEvent, Qt, QLoggingCategory
|
17
|
+
from PySide6.QtGui import QShortcut, QKeySequence
|
15
18
|
from PySide6.QtWidgets import QApplication, QMainWindow
|
16
19
|
from qt_material import QtStyleTools
|
17
20
|
|
18
|
-
from pygpt_net.core.events import BaseEvent, KernelEvent
|
21
|
+
from pygpt_net.core.events import BaseEvent, KernelEvent, ControlEvent
|
19
22
|
from pygpt_net.container import Container
|
20
23
|
from pygpt_net.controller import Controller
|
21
24
|
from pygpt_net.tools import Tools
|
@@ -85,6 +88,9 @@ class MainWindow(QMainWindow, QtStyleTools):
|
|
85
88
|
self.ui = UI(self)
|
86
89
|
self.ui.init()
|
87
90
|
|
91
|
+
# global shortcuts
|
92
|
+
self.shortcuts = []
|
93
|
+
|
88
94
|
# setup signals
|
89
95
|
self.statusChanged.connect(self.update_status)
|
90
96
|
self.stateChanged.connect(self.update_state)
|
@@ -338,3 +344,58 @@ class MainWindow(QMainWindow, QtStyleTools):
|
|
338
344
|
self.showNormal()
|
339
345
|
self.activateWindow()
|
340
346
|
self.ui.tray_menu['restore'].setVisible(False)
|
347
|
+
|
348
|
+
def setup_global_shortcuts(self):
|
349
|
+
"""Setup global shortcuts"""
|
350
|
+
if not hasattr(self, 'core') or not hasattr(self.core, 'config'):
|
351
|
+
return
|
352
|
+
|
353
|
+
# unregister existing shortcuts
|
354
|
+
if hasattr(self, 'shortcuts'):
|
355
|
+
for shortcut in self.shortcuts:
|
356
|
+
# disconnect signals
|
357
|
+
shortcut.activated.disconnect()
|
358
|
+
# disable the shortcut to prevent it from handling events
|
359
|
+
shortcut.setEnabled(False)
|
360
|
+
# remove the parent to break the QObject tree
|
361
|
+
shortcut.setParent(None)
|
362
|
+
# schedule the shortcut for deletion
|
363
|
+
shortcut.deleteLater()
|
364
|
+
# clear the list of shortcuts
|
365
|
+
self.shortcuts.clear()
|
366
|
+
# process events to delete shortcuts immediately
|
367
|
+
QtWidgets.QApplication.processEvents()
|
368
|
+
else:
|
369
|
+
self.shortcuts = []
|
370
|
+
|
371
|
+
# Handle the Escape key
|
372
|
+
escape_shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self)
|
373
|
+
escape_shortcut.setContext(Qt.ApplicationShortcut)
|
374
|
+
escape_shortcut.activated.connect(self.controller.access.on_escape)
|
375
|
+
self.shortcuts.append(escape_shortcut)
|
376
|
+
|
377
|
+
config = copy.deepcopy(self.core.config.get("access.shortcuts"))
|
378
|
+
for shortcut_conf in config:
|
379
|
+
print(shortcut_conf)
|
380
|
+
key = shortcut_conf.get('key', '')
|
381
|
+
key_modifier = shortcut_conf.get('key_modifier', '')
|
382
|
+
action_name = shortcut_conf.get('action')
|
383
|
+
|
384
|
+
if not key or not action_name:
|
385
|
+
continue
|
386
|
+
|
387
|
+
key_sequence_parts = []
|
388
|
+
if key_modifier and key_modifier != '---':
|
389
|
+
if key_modifier == "Control":
|
390
|
+
key_modifier = "Ctrl"
|
391
|
+
key_sequence_parts.append(key_modifier)
|
392
|
+
key_sequence_parts.append(key)
|
393
|
+
key_sequence_str = '+'.join(key_sequence_parts)
|
394
|
+
key_sequence = QKeySequence(key_sequence_str)
|
395
|
+
|
396
|
+
shortcut = QShortcut(key_sequence, self)
|
397
|
+
shortcut.setContext(Qt.ApplicationShortcut)
|
398
|
+
shortcut.activated.connect(
|
399
|
+
lambda checked=False, action=action_name: self.dispatch(ControlEvent(action))
|
400
|
+
)
|
401
|
+
self.shortcuts.append(shortcut)
|
@@ -6,13 +6,14 @@
|
|
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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtCore import QRect, QDate
|
13
13
|
from PySide6.QtGui import QColor, QBrush, QFont, Qt, QAction, QContextMenuEvent, QIcon, QPixmap, QPen
|
14
14
|
from PySide6.QtWidgets import QCalendarWidget, QMenu
|
15
15
|
|
16
|
+
from pygpt_net.core.tabs.tab import Tab
|
16
17
|
from pygpt_net.utils import trans
|
17
18
|
import pygpt_net.icons_rc
|
18
19
|
|
@@ -44,6 +45,29 @@ class CalendarSelect(QCalendarWidget):
|
|
44
45
|
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
45
46
|
self.customContextMenuRequested.connect(self.open_context_menu)
|
46
47
|
self.setProperty('class', 'calendar')
|
48
|
+
self.tab = None
|
49
|
+
self.installEventFilter(self)
|
50
|
+
|
51
|
+
def set_tab(self, tab: Tab):
|
52
|
+
"""
|
53
|
+
Set tab
|
54
|
+
|
55
|
+
:param tab: Tab
|
56
|
+
"""
|
57
|
+
self.tab = tab
|
58
|
+
|
59
|
+
def eventFilter(self, source, event):
|
60
|
+
"""
|
61
|
+
Focus event filter
|
62
|
+
|
63
|
+
:param source: source
|
64
|
+
:param event: event
|
65
|
+
"""
|
66
|
+
if event.type() == event.Type.FocusIn:
|
67
|
+
if self.tab is not None:
|
68
|
+
col_idx = self.tab.column_idx
|
69
|
+
self.window.controller.ui.tabs.on_column_focus(col_idx)
|
70
|
+
return super().eventFilter(source, event)
|
47
71
|
|
48
72
|
def page_changed(self, year, month):
|
49
73
|
"""
|
@@ -172,6 +196,10 @@ class CalendarSelect(QCalendarWidget):
|
|
172
196
|
# if date in self.counters['ctx']:
|
173
197
|
self.window.controller.calendar.on_ctx_select(year, month, day)
|
174
198
|
|
199
|
+
if self.tab is not None:
|
200
|
+
col_idx = self.tab.column_idx
|
201
|
+
self.window.controller.ui.tabs.on_column_focus(col_idx)
|
202
|
+
|
175
203
|
def add_ctx(self, date: QDate, num: int):
|
176
204
|
"""
|
177
205
|
Add ctx counter to counter list
|
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import datetime
|
@@ -15,6 +15,7 @@ from PySide6.QtCore import Qt, QPoint
|
|
15
15
|
from PySide6.QtGui import QImage, QPainter, QPen, QAction, QIcon, QKeySequence
|
16
16
|
from PySide6.QtWidgets import QMenu, QWidget, QFileDialog, QMessageBox, QApplication
|
17
17
|
|
18
|
+
from pygpt_net.core.tabs.tab import Tab
|
18
19
|
from pygpt_net.utils import trans
|
19
20
|
import pygpt_net.icons_rc
|
20
21
|
|
@@ -35,6 +36,16 @@ class PainterWidget(QWidget):
|
|
35
36
|
self.undoLimit = 10
|
36
37
|
self.setFocusPolicy(Qt.StrongFocus)
|
37
38
|
self.setFocus()
|
39
|
+
self.installEventFilter(self)
|
40
|
+
self.tab = None
|
41
|
+
|
42
|
+
def set_tab(self, tab: Tab):
|
43
|
+
"""
|
44
|
+
Set tab
|
45
|
+
|
46
|
+
:param tab: Tab
|
47
|
+
"""
|
48
|
+
self.tab = tab
|
38
49
|
|
39
50
|
def handle_paste(self):
|
40
51
|
"""Handle clipboard paste"""
|
@@ -353,3 +364,16 @@ class PainterWidget(QWidget):
|
|
353
364
|
painter = QPainter(new)
|
354
365
|
painter.drawImage(QPoint(0, 0), self.image)
|
355
366
|
self.image = new
|
367
|
+
|
368
|
+
def eventFilter(self, source, event):
|
369
|
+
"""
|
370
|
+
Focus event filter
|
371
|
+
|
372
|
+
:param source: source
|
373
|
+
:param event: event
|
374
|
+
"""
|
375
|
+
if event.type() == event.Type.FocusIn:
|
376
|
+
if self.tab is not None:
|
377
|
+
col_idx = self.tab.column_idx
|
378
|
+
self.window.controller.ui.tabs.on_column_focus(col_idx)
|
379
|
+
return super().eventFilter(source, event)
|
@@ -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.01.19 02:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import datetime
|
@@ -118,6 +118,29 @@ class FileExplorer(QWidget):
|
|
118
118
|
vertical-align: middle;
|
119
119
|
}
|
120
120
|
""")
|
121
|
+
self.tab = None
|
122
|
+
self.installEventFilter(self)
|
123
|
+
|
124
|
+
def eventFilter(self, source, event):
|
125
|
+
"""
|
126
|
+
Focus event filter
|
127
|
+
|
128
|
+
:param source: source
|
129
|
+
:param event: event
|
130
|
+
"""
|
131
|
+
if event.type() == event.Type.FocusIn:
|
132
|
+
if self.tab is not None:
|
133
|
+
col_idx = self.tab.column_idx
|
134
|
+
self.window.controller.ui.tabs.on_column_focus(col_idx)
|
135
|
+
return super().eventFilter(source, event)
|
136
|
+
|
137
|
+
def set_tab(self, tab: Tab):
|
138
|
+
"""
|
139
|
+
Set tab
|
140
|
+
|
141
|
+
:param tab: Tab
|
142
|
+
"""
|
143
|
+
self.tab = tab
|
121
144
|
|
122
145
|
def setOwner(self, owner: Tab):
|
123
146
|
"""
|