pygpt-net 2.6.20__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 +13 -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/agent/agent.py +130 -2
- pygpt_net/controller/agent/experts.py +93 -96
- pygpt_net/controller/agent/llama.py +2 -1
- pygpt_net/controller/assistant/assistant.py +18 -1
- 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/attachment/attachment.py +17 -1
- pygpt_net/controller/audio/audio.py +2 -2
- pygpt_net/controller/camera/camera.py +15 -7
- pygpt_net/controller/chat/chat.py +2 -2
- pygpt_net/controller/chat/common.py +50 -33
- pygpt_net/controller/chat/image.py +67 -77
- pygpt_net/controller/chat/input.py +94 -166
- pygpt_net/controller/chat/output.py +83 -140
- pygpt_net/controller/chat/response.py +83 -102
- pygpt_net/controller/chat/text.py +116 -149
- pygpt_net/controller/ctx/common.py +2 -1
- pygpt_net/controller/ctx/ctx.py +87 -6
- pygpt_net/controller/files/files.py +13 -1
- pygpt_net/controller/idx/idx.py +26 -2
- pygpt_net/controller/idx/indexer.py +85 -76
- pygpt_net/controller/kernel/reply.py +53 -66
- pygpt_net/controller/kernel/stack.py +16 -16
- pygpt_net/controller/lang/lang.py +52 -34
- pygpt_net/controller/model/importer.py +3 -2
- pygpt_net/controller/model/model.py +62 -3
- pygpt_net/controller/notepad/notepad.py +86 -84
- pygpt_net/controller/plugins/settings.py +3 -4
- pygpt_net/controller/settings/editor.py +4 -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/controller/ui/ui.py +16 -2
- pygpt_net/core/agents/observer/evaluation.py +3 -3
- pygpt_net/core/agents/provider.py +25 -3
- pygpt_net/core/agents/runner.py +4 -1
- pygpt_net/core/agents/runners/llama_workflow.py +19 -7
- pygpt_net/core/agents/runners/loop.py +3 -1
- pygpt_net/core/agents/runners/openai_workflow.py +17 -3
- pygpt_net/core/agents/tools.py +4 -1
- pygpt_net/core/bridge/context.py +34 -37
- pygpt_net/core/ctx/container.py +13 -12
- pygpt_net/core/ctx/ctx.py +1 -1
- pygpt_net/core/ctx/output.py +7 -4
- pygpt_net/core/db/database.py +2 -2
- pygpt_net/core/debug/console/console.py +2 -2
- pygpt_net/core/debug/debug.py +12 -1
- pygpt_net/core/dispatcher/dispatcher.py +24 -1
- pygpt_net/core/events/app.py +7 -7
- pygpt_net/core/events/control.py +26 -26
- pygpt_net/core/events/event.py +6 -3
- pygpt_net/core/events/kernel.py +2 -2
- pygpt_net/core/events/render.py +13 -13
- pygpt_net/core/experts/experts.py +76 -82
- pygpt_net/core/experts/worker.py +12 -12
- pygpt_net/core/filesystem/actions.py +1 -2
- pygpt_net/core/models/models.py +5 -1
- pygpt_net/core/models/ollama.py +14 -5
- 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/render/web/helpers.py +2 -2
- pygpt_net/core/render/web/renderer.py +4 -4
- pygpt_net/core/settings/settings.py +43 -13
- pygpt_net/core/tabs/tabs.py +20 -13
- pygpt_net/core/types/__init__.py +2 -1
- pygpt_net/core/types/agent.py +4 -4
- pygpt_net/core/types/base.py +19 -0
- pygpt_net/core/types/console.py +6 -6
- pygpt_net/core/types/mode.py +8 -8
- pygpt_net/core/types/multimodal.py +3 -3
- pygpt_net/core/types/openai.py +2 -1
- pygpt_net/data/config/config.json +5 -5
- pygpt_net/data/config/models.json +19 -3
- pygpt_net/data/config/settings.json +14 -14
- pygpt_net/data/locale/locale.de.ini +4 -1
- pygpt_net/data/locale/locale.en.ini +6 -3
- 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/item/ctx.py +256 -240
- pygpt_net/item/model.py +59 -116
- pygpt_net/item/preset.py +122 -105
- pygpt_net/plugin/twitter/plugin.py +2 -2
- pygpt_net/provider/agents/llama_index/workflow/planner.py +3 -3
- pygpt_net/provider/agents/openai/agent.py +4 -12
- pygpt_net/provider/agents/openai/agent_b2b.py +10 -15
- pygpt_net/provider/agents/openai/agent_planner.py +4 -4
- pygpt_net/provider/agents/openai/agent_with_experts.py +3 -7
- pygpt_net/provider/agents/openai/agent_with_experts_feedback.py +4 -8
- pygpt_net/provider/agents/openai/agent_with_feedback.py +4 -8
- pygpt_net/provider/agents/openai/bot_researcher.py +2 -18
- pygpt_net/provider/agents/openai/bots/__init__.py +0 -0
- pygpt_net/provider/agents/openai/bots/research_bot/__init__.py +0 -0
- pygpt_net/provider/agents/openai/bots/research_bot/agents/__init__.py +0 -0
- pygpt_net/provider/agents/openai/bots/research_bot/agents/planner_agent.py +1 -1
- pygpt_net/provider/agents/openai/bots/research_bot/agents/search_agent.py +1 -0
- pygpt_net/provider/agents/openai/bots/research_bot/agents/writer_agent.py +1 -1
- pygpt_net/provider/agents/openai/bots/research_bot/manager.py +1 -10
- pygpt_net/provider/agents/openai/evolve.py +5 -9
- pygpt_net/provider/agents/openai/supervisor.py +4 -8
- pygpt_net/provider/core/config/patch.py +10 -3
- pygpt_net/provider/core/ctx/db_sqlite/utils.py +43 -43
- pygpt_net/provider/core/model/patch.py +11 -1
- pygpt_net/provider/core/preset/json_file.py +47 -49
- pygpt_net/provider/gpt/agents/experts.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.20.dist-info → pygpt_net-2.6.22.dist-info}/METADATA +25 -154
- {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/RECORD +218 -217
- {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/entry_points.txt +0 -0
|
@@ -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.25 03:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -19,8 +19,6 @@ from PySide6.QtWidgets import (QWidget, QPushButton, QHBoxLayout, QVBoxLayout,
|
|
|
19
19
|
from pygpt_net.ui.widget.element.labels import HelpLabel
|
|
20
20
|
from pygpt_net.utils import trans
|
|
21
21
|
|
|
22
|
-
import pygpt_net.icons_rc
|
|
23
|
-
|
|
24
22
|
class VideoPlayerWidget(QWidget):
|
|
25
23
|
def __init__(self, window=None):
|
|
26
24
|
super().__init__(window)
|
|
@@ -28,14 +26,18 @@ class VideoPlayerWidget(QWidget):
|
|
|
28
26
|
self.player = None
|
|
29
27
|
self.audio = None
|
|
30
28
|
self.video = None
|
|
31
|
-
self._QMediaPlayer = None
|
|
32
|
-
self._QAudioOutput = None
|
|
33
|
-
self._QVideoWidget = None
|
|
34
29
|
self.loaded = False
|
|
35
30
|
self.path = None
|
|
36
31
|
self.stopped = False
|
|
37
32
|
self.seeking = False
|
|
38
33
|
|
|
34
|
+
self._QMediaPlayer = None
|
|
35
|
+
self._QAudioOutput = None
|
|
36
|
+
self._QVideoWidget = None
|
|
37
|
+
|
|
38
|
+
self._waiting_position_set = False
|
|
39
|
+
self._last_position = -1
|
|
40
|
+
|
|
39
41
|
self.update_timer = QTimer(self)
|
|
40
42
|
self.update_timer.setInterval(200)
|
|
41
43
|
self.update_timer.timeout.connect(self.update_ui)
|
|
@@ -48,11 +50,15 @@ class VideoPlayerWidget(QWidget):
|
|
|
48
50
|
self._video_placeholder.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
|
49
51
|
self._video_placeholder.setMinimumSize(640, 480)
|
|
50
52
|
|
|
53
|
+
self._icon_play = self.style().standardIcon(QStyle.SP_MediaPlay)
|
|
54
|
+
self._icon_pause = self.style().standardIcon(QStyle.SP_MediaPause)
|
|
55
|
+
self._icon_stop = self.style().standardIcon(QStyle.SP_MediaStop)
|
|
56
|
+
|
|
51
57
|
self.btn_play_pause = QPushButton()
|
|
52
58
|
self.btn_play_pause.setEnabled(False)
|
|
53
59
|
|
|
54
60
|
self.btn_stop = QPushButton()
|
|
55
|
-
self.btn_stop.setIcon(self.
|
|
61
|
+
self.btn_stop.setIcon(self._icon_stop)
|
|
56
62
|
self.btn_stop.setEnabled(False)
|
|
57
63
|
|
|
58
64
|
self.btn_mute = QPushButton()
|
|
@@ -149,6 +155,7 @@ class VideoPlayerWidget(QWidget):
|
|
|
149
155
|
self.volume_slider.valueChanged.connect(self.adjust_volume)
|
|
150
156
|
self.slider.sliderPressed.connect(self.on_slider_pressed)
|
|
151
157
|
self.slider.sliderReleased.connect(self.on_slider_released)
|
|
158
|
+
self.slider.valueChanged.connect(self.on_slider_value_changed)
|
|
152
159
|
self._video_placeholder.mousePressEvent = self.video_widget_clicked
|
|
153
160
|
self.seeking = False
|
|
154
161
|
|
|
@@ -210,7 +217,7 @@ class VideoPlayerWidget(QWidget):
|
|
|
210
217
|
self.stopped = True
|
|
211
218
|
self.slider.setValue(0)
|
|
212
219
|
self.label_time.setText(self.format_time(0))
|
|
213
|
-
self.btn_play_pause.setIcon(self.
|
|
220
|
+
self.btn_play_pause.setIcon(self._icon_play)
|
|
214
221
|
self.update_timer.stop()
|
|
215
222
|
|
|
216
223
|
def toggle_play_pause(self):
|
|
@@ -226,11 +233,13 @@ class VideoPlayerWidget(QWidget):
|
|
|
226
233
|
if self.player and self.player.source():
|
|
227
234
|
self.player.stop()
|
|
228
235
|
self.player.setSource(QUrl())
|
|
229
|
-
self.btn_play_pause.setIcon(self.
|
|
236
|
+
self.btn_play_pause.setIcon(self._icon_play)
|
|
230
237
|
self.update_timer.stop()
|
|
231
238
|
self.slider.setValue(0)
|
|
232
239
|
self.seeking = False
|
|
233
240
|
self.loaded = False
|
|
241
|
+
self._waiting_position_set = False
|
|
242
|
+
self._last_position = -1
|
|
234
243
|
|
|
235
244
|
def reset_player(self):
|
|
236
245
|
"""Reset player to default state"""
|
|
@@ -296,6 +305,7 @@ class VideoPlayerWidget(QWidget):
|
|
|
296
305
|
def on_close(self):
|
|
297
306
|
"""Stop video"""
|
|
298
307
|
self.reset()
|
|
308
|
+
self.autoplay_timer.stop()
|
|
299
309
|
|
|
300
310
|
def toggle_fullscreen(self):
|
|
301
311
|
"""Toggle fullscreen"""
|
|
@@ -387,22 +397,28 @@ class VideoPlayerWidget(QWidget):
|
|
|
387
397
|
return
|
|
388
398
|
if self._QMediaPlayer and self.player.playbackState() == self._QMediaPlayer.PlayingState:
|
|
389
399
|
self.player.pause()
|
|
390
|
-
self.
|
|
400
|
+
self._waiting_position_set = True
|
|
391
401
|
self.player.setPosition(position)
|
|
392
402
|
|
|
393
403
|
def on_slider_pressed(self):
|
|
394
404
|
"""Slider pressed"""
|
|
395
405
|
self.seeking = True
|
|
406
|
+
self._waiting_position_set = False
|
|
396
407
|
if self.player:
|
|
397
408
|
self.player.pause()
|
|
398
409
|
|
|
410
|
+
def on_slider_value_changed(self, value):
|
|
411
|
+
"""Slider value changed"""
|
|
412
|
+
if self.seeking:
|
|
413
|
+
self.label_time.setText(self.format_time(value))
|
|
414
|
+
|
|
399
415
|
def on_slider_released(self):
|
|
400
416
|
"""Slider released"""
|
|
401
417
|
if self.seeking:
|
|
402
418
|
if self.player:
|
|
403
419
|
self.player.setPosition(self.slider.value())
|
|
404
420
|
self.update_audio()
|
|
405
|
-
self.player.play
|
|
421
|
+
QTimer.singleShot(0, self.player.play)
|
|
406
422
|
self.seeking = False
|
|
407
423
|
|
|
408
424
|
def position_changed(self, position):
|
|
@@ -411,25 +427,15 @@ class VideoPlayerWidget(QWidget):
|
|
|
411
427
|
|
|
412
428
|
:param position: position
|
|
413
429
|
"""
|
|
430
|
+
if self._waiting_position_set and self.player:
|
|
431
|
+
self._waiting_position_set = False
|
|
432
|
+
if self._QMediaPlayer and self.player.playbackState() == self._QMediaPlayer.PausedState:
|
|
433
|
+
QTimer.singleShot(100, self.player.play)
|
|
414
434
|
if not self.seeking:
|
|
435
|
+
self._last_position = position
|
|
415
436
|
self.slider.setValue(position)
|
|
416
437
|
self.label_time.setText(self.format_time(position))
|
|
417
438
|
|
|
418
|
-
def on_position_set(self, position):
|
|
419
|
-
"""
|
|
420
|
-
On position set
|
|
421
|
-
|
|
422
|
-
:param position: position
|
|
423
|
-
"""
|
|
424
|
-
if self.seeking and self.player:
|
|
425
|
-
try:
|
|
426
|
-
self.player.positionChanged.disconnect(self.on_position_set)
|
|
427
|
-
except Exception:
|
|
428
|
-
pass
|
|
429
|
-
if self._QMediaPlayer and self.player.playbackState() == self._QMediaPlayer.PausedState:
|
|
430
|
-
QTimer.singleShot(100, self.player.play)
|
|
431
|
-
self.seeking = False
|
|
432
|
-
|
|
433
439
|
def update_label_path(self):
|
|
434
440
|
"""Update label path"""
|
|
435
441
|
if self.path:
|
|
@@ -440,32 +446,50 @@ class VideoPlayerWidget(QWidget):
|
|
|
440
446
|
def update_play_pause_icon(self):
|
|
441
447
|
"""Update play/pause icon"""
|
|
442
448
|
if self.player and self._QMediaPlayer and self.player.playbackState() == self._QMediaPlayer.PlayingState:
|
|
443
|
-
self.btn_play_pause.setIcon(self.
|
|
444
|
-
self.update_timer.
|
|
449
|
+
self.btn_play_pause.setIcon(self._icon_pause)
|
|
450
|
+
if not self.update_timer.isActive():
|
|
451
|
+
self.update_timer.start()
|
|
445
452
|
else:
|
|
446
|
-
self.btn_play_pause.setIcon(self.
|
|
447
|
-
self.update_timer.
|
|
453
|
+
self.btn_play_pause.setIcon(self._icon_play)
|
|
454
|
+
if self.update_timer.isActive():
|
|
455
|
+
self.update_timer.stop()
|
|
448
456
|
|
|
449
457
|
def update_audio(self):
|
|
450
458
|
"""Re-assign audio"""
|
|
451
459
|
if self.player and self.audio:
|
|
452
|
-
|
|
453
|
-
|
|
460
|
+
try:
|
|
461
|
+
current = self.player.audioOutput()
|
|
462
|
+
except Exception:
|
|
463
|
+
current = None
|
|
464
|
+
if current is not self.audio:
|
|
465
|
+
self.player.setAudioOutput(self.audio)
|
|
454
466
|
|
|
455
467
|
def update_mute_icon(self):
|
|
456
468
|
"""Update mute icon"""
|
|
457
469
|
if self.audio:
|
|
458
|
-
self.
|
|
470
|
+
muted = self.audio.isMuted()
|
|
471
|
+
if self.btn_mute.isChecked() != muted:
|
|
472
|
+
block = self.btn_mute.blockSignals(True)
|
|
473
|
+
self.btn_mute.setChecked(muted)
|
|
474
|
+
self.btn_mute.blockSignals(block)
|
|
459
475
|
|
|
460
476
|
def update_volume_slider(self):
|
|
461
477
|
"""Update volume slider"""
|
|
462
478
|
if self.audio:
|
|
463
|
-
|
|
479
|
+
v = int(self.audio.volume() * 100)
|
|
480
|
+
if self.volume_slider.value() != v:
|
|
481
|
+
block = self.volume_slider.blockSignals(True)
|
|
482
|
+
self.volume_slider.setValue(v)
|
|
483
|
+
self.volume_slider.blockSignals(block)
|
|
464
484
|
|
|
465
485
|
def update_ui(self):
|
|
466
486
|
"""Update UI"""
|
|
467
|
-
if self.player:
|
|
468
|
-
self.
|
|
487
|
+
if self.player and not self.seeking:
|
|
488
|
+
pos = self.player.position()
|
|
489
|
+
if pos != self._last_position:
|
|
490
|
+
self._last_position = pos
|
|
491
|
+
self.slider.setValue(pos)
|
|
492
|
+
self.label_time.setText(self.format_time(pos))
|
|
469
493
|
|
|
470
494
|
def format_time(self, ms):
|
|
471
495
|
"""
|
|
@@ -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.QtGui import QAction, QIcon, QKeySequence
|
|
@@ -14,8 +14,6 @@ from PySide6.QtGui import QAction, QIcon, QKeySequence
|
|
|
14
14
|
from pygpt_net.ui.widget.textarea.editor import BaseCodeEditor
|
|
15
15
|
from pygpt_net.utils import trans
|
|
16
16
|
|
|
17
|
-
import pygpt_net.icons_rc
|
|
18
|
-
|
|
19
17
|
class TextFileEditor(BaseCodeEditor):
|
|
20
18
|
def __init__(self, window=None):
|
|
21
19
|
"""
|
|
@@ -23,7 +21,7 @@ class TextFileEditor(BaseCodeEditor):
|
|
|
23
21
|
|
|
24
22
|
:param window: main window
|
|
25
23
|
"""
|
|
26
|
-
super(
|
|
24
|
+
super().__init__(window)
|
|
27
25
|
self.window = window
|
|
28
26
|
self.setReadOnly(True)
|
|
29
27
|
self.value = 12
|
|
@@ -33,6 +31,10 @@ class TextFileEditor(BaseCodeEditor):
|
|
|
33
31
|
self.default_stylesheet = ""
|
|
34
32
|
self.setStyleSheet(self.default_stylesheet)
|
|
35
33
|
|
|
34
|
+
self._icon_volume = QIcon(":/icons/volume.svg")
|
|
35
|
+
self._icon_save = QIcon(":/icons/save.svg")
|
|
36
|
+
self._icon_search = QIcon(":/icons/search.svg")
|
|
37
|
+
|
|
36
38
|
def contextMenuEvent(self, event):
|
|
37
39
|
"""
|
|
38
40
|
Context menu event
|
|
@@ -40,38 +42,35 @@ class TextFileEditor(BaseCodeEditor):
|
|
|
40
42
|
:param event: Event
|
|
41
43
|
"""
|
|
42
44
|
menu = self.createStandardContextMenu()
|
|
43
|
-
|
|
45
|
+
cursor = self.textCursor()
|
|
44
46
|
|
|
45
|
-
if
|
|
46
|
-
|
|
47
|
-
plain_text =
|
|
47
|
+
if cursor.hasSelection():
|
|
48
|
+
selected_text = cursor.selectedText()
|
|
49
|
+
plain_text = cursor.selection().toPlainText()
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
action = QAction(QIcon(":/icons/volume.svg"), trans('text.context_menu.audio.read'), self)
|
|
51
|
+
action = QAction(self._icon_volume, trans('text.context_menu.audio.read'), menu)
|
|
51
52
|
action.triggered.connect(self.audio_read_selection)
|
|
52
53
|
menu.addAction(action)
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
copy_to_menu = self.window.ui.context_menu.get_copy_to_menu(self, selected_text)
|
|
55
|
+
copy_to_menu = self.window.ui.context_menu.get_copy_to_menu(menu, selected_text)
|
|
56
56
|
menu.addMenu(copy_to_menu)
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
action = QAction(QIcon(":/icons/save.svg"), trans('action.save_as'), self)
|
|
58
|
+
action = QAction(self._icon_save, trans('action.save_as'), menu)
|
|
60
59
|
action.triggered.connect(
|
|
61
60
|
lambda: self.window.controller.chat.common.save_text(plain_text)
|
|
62
61
|
)
|
|
63
62
|
menu.addAction(action)
|
|
64
63
|
else:
|
|
65
|
-
|
|
66
|
-
action = QAction(QIcon(":/icons/save.svg"), trans('action.save_as'), self)
|
|
64
|
+
action = QAction(self._icon_save, trans('action.save_as'), menu)
|
|
67
65
|
action.triggered.connect(
|
|
68
66
|
lambda: self.window.controller.chat.common.save_text(self.toPlainText())
|
|
69
67
|
)
|
|
70
68
|
menu.addAction(action)
|
|
71
69
|
|
|
72
|
-
action = QAction(
|
|
70
|
+
action = QAction(self._icon_search, trans('text.context_menu.find'), menu)
|
|
73
71
|
action.triggered.connect(self.find_open)
|
|
74
|
-
action.setShortcut(QKeySequence
|
|
72
|
+
action.setShortcut(QKeySequence.StandardKey.Find)
|
|
75
73
|
menu.addAction(action)
|
|
76
74
|
|
|
77
|
-
menu.exec_(event.globalPos())
|
|
75
|
+
menu.exec_(event.globalPos())
|
|
76
|
+
menu.deleteLater()
|
|
@@ -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
|
from PySide6.QtCore import Qt, Slot, QObject, Signal
|
|
@@ -16,7 +16,6 @@ from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QTextEdit, QWidget, QSpl
|
|
|
16
16
|
from pygpt_net.core.text.finder import Finder
|
|
17
17
|
from pygpt_net.ui.widget.option.combo import OptionCombo
|
|
18
18
|
|
|
19
|
-
import pygpt_net.icons_rc
|
|
20
19
|
from pygpt_net.ui.widget.textarea.search_input import SearchInput
|
|
21
20
|
from pygpt_net.utils import trans
|
|
22
21
|
|
|
@@ -338,11 +337,11 @@ class TextareaField(QTextEdit):
|
|
|
338
337
|
|
|
339
338
|
:param window: main window
|
|
340
339
|
"""
|
|
341
|
-
super(
|
|
340
|
+
super().__init__(window)
|
|
342
341
|
self.window = window
|
|
343
342
|
self.id = id # assigned in setup
|
|
344
343
|
self.setReadOnly(False)
|
|
345
|
-
self.
|
|
344
|
+
self.setAcceptRichText(False)
|
|
346
345
|
self.value = 12
|
|
347
346
|
self.max_font_size = 42
|
|
348
347
|
self.min_font_size = 8
|
|
@@ -353,6 +352,12 @@ class TextareaField(QTextEdit):
|
|
|
353
352
|
self.finder = Finder(window, self)
|
|
354
353
|
self.installEventFilter(self)
|
|
355
354
|
|
|
355
|
+
self._icon_volume = QIcon(":/icons/volume.svg")
|
|
356
|
+
self._icon_save = QIcon(":/icons/save.svg")
|
|
357
|
+
self._icon_search = QIcon(":/icons/search.svg")
|
|
358
|
+
self._icon_clear = QIcon(":/icons/clear.svg")
|
|
359
|
+
self._seq_find = QKeySequence("Ctrl+F")
|
|
360
|
+
|
|
356
361
|
# tabulation
|
|
357
362
|
metrics = QFontMetrics(self.font())
|
|
358
363
|
space_width = metrics.horizontalAdvance(" ")
|
|
@@ -381,7 +386,6 @@ class TextareaField(QTextEdit):
|
|
|
381
386
|
"""
|
|
382
387
|
return super().eventFilter(source, event)
|
|
383
388
|
|
|
384
|
-
|
|
385
389
|
def contextMenuEvent(self, event):
|
|
386
390
|
"""
|
|
387
391
|
Context menu event
|
|
@@ -389,13 +393,14 @@ class TextareaField(QTextEdit):
|
|
|
389
393
|
:param event: Event
|
|
390
394
|
"""
|
|
391
395
|
menu = self.createStandardContextMenu()
|
|
392
|
-
|
|
396
|
+
cursor = self.textCursor()
|
|
397
|
+
selected_text = cursor.selectedText()
|
|
393
398
|
if selected_text:
|
|
394
399
|
# plain text
|
|
395
|
-
plain_text =
|
|
400
|
+
plain_text = cursor.selection().toPlainText()
|
|
396
401
|
|
|
397
402
|
# audio read
|
|
398
|
-
action = QAction(
|
|
403
|
+
action = QAction(self._icon_volume, trans('text.context_menu.audio.read'), menu)
|
|
399
404
|
action.triggered.connect(self.audio_read_selection)
|
|
400
405
|
menu.addAction(action)
|
|
401
406
|
|
|
@@ -405,31 +410,31 @@ class TextareaField(QTextEdit):
|
|
|
405
410
|
excluded = ["translator_left"]
|
|
406
411
|
elif self.id == "right":
|
|
407
412
|
excluded = ["translator_right"]
|
|
408
|
-
copy_to_menu = self.window.ui.context_menu.get_copy_to_menu(
|
|
409
|
-
|
|
413
|
+
copy_to_menu = self.window.ui.context_menu.get_copy_to_menu(menu, selected_text, excluded=excluded)
|
|
414
|
+
if copy_to_menu is not None:
|
|
415
|
+
menu.addMenu(copy_to_menu)
|
|
410
416
|
|
|
411
417
|
# save as (selected)
|
|
412
|
-
action = QAction(
|
|
413
|
-
action.triggered.connect(
|
|
414
|
-
lambda: self.window.controller.chat.common.save_text(plain_text))
|
|
418
|
+
action = QAction(self._icon_save, trans('action.save_selection_as'), menu)
|
|
419
|
+
action.triggered.connect(lambda pt=plain_text: self.window.controller.chat.common.save_text(pt))
|
|
415
420
|
menu.addAction(action)
|
|
416
421
|
else:
|
|
417
422
|
# save as (all)
|
|
418
|
-
action = QAction(
|
|
419
|
-
action.triggered.connect(
|
|
420
|
-
lambda: self.window.controller.chat.common.save_text(self.toPlainText()))
|
|
423
|
+
action = QAction(self._icon_save, trans('action.save_as'), menu)
|
|
424
|
+
action.triggered.connect(lambda: self.window.controller.chat.common.save_text(self.toPlainText()))
|
|
421
425
|
menu.addAction(action)
|
|
422
426
|
|
|
423
|
-
action = QAction(
|
|
427
|
+
action = QAction(self._icon_search, trans('text.context_menu.find'), menu)
|
|
424
428
|
action.triggered.connect(self.find_open)
|
|
425
|
-
action.setShortcut(
|
|
429
|
+
action.setShortcut(self._seq_find)
|
|
426
430
|
menu.addAction(action)
|
|
427
431
|
|
|
428
|
-
action = QAction(
|
|
432
|
+
action = QAction(self._icon_clear, trans('translators.menu.file.clear'), menu)
|
|
429
433
|
action.triggered.connect(self.action_clear)
|
|
430
434
|
menu.addAction(action)
|
|
431
435
|
|
|
432
436
|
menu.exec_(event.globalPos())
|
|
437
|
+
menu.deleteLater()
|
|
433
438
|
|
|
434
439
|
def action_clear(self):
|
|
435
440
|
"""
|
|
@@ -462,9 +467,9 @@ class TextareaField(QTextEdit):
|
|
|
462
467
|
"""
|
|
463
468
|
if e.key() == Qt.Key_F and e.modifiers() & Qt.ControlModifier:
|
|
464
469
|
self.find_open()
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
470
|
+
return
|
|
471
|
+
self.finder.clear(restore=True, to_end=False)
|
|
472
|
+
super().keyPressEvent(e)
|
|
468
473
|
|
|
469
474
|
def update_stylesheet(self, data: str):
|
|
470
475
|
"""
|
|
@@ -472,7 +477,9 @@ class TextareaField(QTextEdit):
|
|
|
472
477
|
|
|
473
478
|
:param data: stylesheet CSS
|
|
474
479
|
"""
|
|
475
|
-
self.
|
|
480
|
+
combined = self.default_stylesheet + data
|
|
481
|
+
if combined != self.styleSheet():
|
|
482
|
+
self.setStyleSheet(combined)
|
|
476
483
|
|
|
477
484
|
def wheelEvent(self, event):
|
|
478
485
|
"""
|
|
@@ -481,17 +488,14 @@ class TextareaField(QTextEdit):
|
|
|
481
488
|
:param event: Event
|
|
482
489
|
"""
|
|
483
490
|
if event.modifiers() & Qt.ControlModifier:
|
|
484
|
-
if event.angleDelta().y() > 0
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
self.value -= 1
|
|
490
|
-
|
|
491
|
-
self.update_stylesheet(f"QTextEdit {{ font-size: {self.value}px }};")
|
|
491
|
+
delta = 1 if event.angleDelta().y() > 0 else -1
|
|
492
|
+
new_value = max(self.min_font_size, min(self.max_font_size, self.value + delta))
|
|
493
|
+
if new_value != self.value:
|
|
494
|
+
self.value = new_value
|
|
495
|
+
self.update_stylesheet(f"QTextEdit {{ font-size: {self.value}px }};")
|
|
492
496
|
event.accept()
|
|
493
|
-
|
|
494
|
-
|
|
497
|
+
return
|
|
498
|
+
super().wheelEvent(event)
|
|
495
499
|
|
|
496
500
|
def focusInEvent(self, e):
|
|
497
501
|
"""
|
|
@@ -500,7 +504,7 @@ class TextareaField(QTextEdit):
|
|
|
500
504
|
:param e: focus event
|
|
501
505
|
"""
|
|
502
506
|
self.window.controller.finder.focus_in(self.finder)
|
|
503
|
-
super(
|
|
507
|
+
super().focusInEvent(e)
|
|
504
508
|
|
|
505
509
|
def focusOutEvent(self, e):
|
|
506
510
|
"""
|
|
@@ -508,7 +512,7 @@ class TextareaField(QTextEdit):
|
|
|
508
512
|
|
|
509
513
|
:param e: focus event
|
|
510
514
|
"""
|
|
511
|
-
super(
|
|
515
|
+
super().focusOutEvent(e)
|
|
512
516
|
self.window.controller.finder.focus_out(self.finder)
|
|
513
517
|
|
|
514
518
|
|
|
@@ -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
|
from PySide6.QtWidgets import QMenu
|
|
@@ -14,10 +14,10 @@ from PySide6.QtGui import QAction, QIcon
|
|
|
14
14
|
|
|
15
15
|
from pygpt_net.core.tabs.tab import Tab
|
|
16
16
|
from pygpt_net.utils import trans
|
|
17
|
-
import pygpt_net.icons_rc
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
class ContextMenu:
|
|
20
|
+
|
|
21
21
|
_ICON_INPUT = QIcon(":/icons/input.svg")
|
|
22
22
|
_ICON_SCHEDULE = QIcon(":/icons/schedule.svg")
|
|
23
23
|
_ICON_PASTE = QIcon(":/icons/paste.svg")
|
|
@@ -32,11 +32,16 @@ class ContextMenu:
|
|
|
32
32
|
"""
|
|
33
33
|
self.window = window
|
|
34
34
|
|
|
35
|
-
def get_copy_to_menu(
|
|
35
|
+
def get_copy_to_menu(
|
|
36
|
+
self,
|
|
37
|
+
parent,
|
|
38
|
+
selected_text: str = None,
|
|
39
|
+
excluded: list = None
|
|
40
|
+
) -> QMenu:
|
|
36
41
|
"""
|
|
37
42
|
Get copy to menu
|
|
38
43
|
|
|
39
|
-
:param parent: Parent
|
|
44
|
+
:param parent: Parent menu
|
|
40
45
|
:param selected_text: Selected text
|
|
41
46
|
:param excluded: Excluded items
|
|
42
47
|
:return: Menu
|
pygpt_net/ui/dialog/db.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.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import Qt
|
|
@@ -17,8 +17,6 @@ from PySide6.QtWidgets import QGridLayout, QScrollArea, QSplitter, QComboBox, QL
|
|
|
17
17
|
from pygpt_net.ui.widget.dialog.db import DatabaseDialog
|
|
18
18
|
from pygpt_net.ui.widget.lists.db import DatabaseList, DatabaseTableModel
|
|
19
19
|
from pygpt_net.ui.widget.textarea.editor import CodeEditor
|
|
20
|
-
|
|
21
|
-
import pygpt_net.icons_rc
|
|
22
20
|
from pygpt_net.utils import trans
|
|
23
21
|
|
|
24
22
|
|
pygpt_net/ui/dialog/models.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: 2025.08.
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import copy
|
|
@@ -30,8 +30,6 @@ from pygpt_net.ui.widget.option.slider import OptionSlider
|
|
|
30
30
|
from pygpt_net.ui.widget.option.textarea import OptionTextarea
|
|
31
31
|
from pygpt_net.utils import trans
|
|
32
32
|
|
|
33
|
-
import pygpt_net.icons_rc
|
|
34
|
-
|
|
35
33
|
class Models:
|
|
36
34
|
def __init__(self, window=None):
|
|
37
35
|
"""
|
|
@@ -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
|
from PySide6 import QtCore
|
|
12
12
|
from PySide6.QtGui import QIcon
|
|
@@ -14,11 +14,9 @@ from PySide6.QtWidgets import QPushButton, QHBoxLayout, QVBoxLayout, QLabel
|
|
|
14
14
|
|
|
15
15
|
from pygpt_net.ui.widget.lists.model_importer import ModelImporter
|
|
16
16
|
from pygpt_net.ui.widget.dialog.model_importer import ModelImporterOllamaDialog
|
|
17
|
-
from pygpt_net.ui.widget.option.combo import
|
|
17
|
+
from pygpt_net.ui.widget.option.combo import OptionCombo
|
|
18
18
|
from pygpt_net.utils import trans
|
|
19
19
|
|
|
20
|
-
import pygpt_net.icons_rc
|
|
21
|
-
|
|
22
20
|
|
|
23
21
|
class ModelsImporter:
|
|
24
22
|
def __init__(self, window=None):
|