pygpt-net 2.7.4__py3-none-any.whl → 2.7.6__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 +15 -0
- pygpt_net/__init__.py +4 -4
- pygpt_net/app_core.py +4 -2
- pygpt_net/controller/__init__.py +5 -1
- pygpt_net/controller/assistant/assistant.py +1 -4
- pygpt_net/controller/assistant/batch.py +5 -504
- pygpt_net/controller/assistant/editor.py +5 -5
- pygpt_net/controller/assistant/files.py +16 -16
- pygpt_net/controller/chat/handler/google_stream.py +307 -1
- pygpt_net/controller/chat/handler/worker.py +10 -25
- pygpt_net/controller/chat/handler/xai_stream.py +621 -52
- pygpt_net/controller/chat/image.py +2 -2
- pygpt_net/controller/debug/fixtures.py +3 -2
- pygpt_net/controller/dialogs/confirm.py +73 -101
- pygpt_net/controller/files/files.py +65 -4
- pygpt_net/controller/lang/mapping.py +9 -9
- pygpt_net/controller/painter/capture.py +50 -1
- pygpt_net/controller/presets/presets.py +2 -1
- pygpt_net/controller/remote_store/__init__.py +12 -0
- pygpt_net/{provider/core/assistant_file/db_sqlite → controller/remote_store/google}/__init__.py +2 -2
- pygpt_net/controller/remote_store/google/batch.py +402 -0
- pygpt_net/controller/remote_store/google/store.py +615 -0
- pygpt_net/controller/remote_store/openai/__init__.py +12 -0
- pygpt_net/controller/remote_store/openai/batch.py +524 -0
- pygpt_net/controller/{assistant → remote_store/openai}/store.py +63 -60
- pygpt_net/controller/remote_store/remote_store.py +35 -0
- pygpt_net/controller/ui/ui.py +20 -1
- pygpt_net/core/assistants/assistants.py +3 -15
- pygpt_net/core/db/database.py +5 -3
- pygpt_net/core/filesystem/url.py +4 -1
- pygpt_net/core/locale/placeholder.py +35 -0
- pygpt_net/core/remote_store/__init__.py +12 -0
- pygpt_net/core/remote_store/google/__init__.py +11 -0
- pygpt_net/core/remote_store/google/files.py +224 -0
- pygpt_net/core/remote_store/google/store.py +248 -0
- pygpt_net/core/remote_store/openai/__init__.py +11 -0
- pygpt_net/core/{assistants → remote_store/openai}/files.py +26 -19
- pygpt_net/core/{assistants → remote_store/openai}/store.py +32 -15
- pygpt_net/core/remote_store/remote_store.py +24 -0
- pygpt_net/core/render/web/body.py +3 -2
- pygpt_net/core/types/chunk.py +27 -0
- pygpt_net/data/config/config.json +8 -4
- pygpt_net/data/config/models.json +77 -3
- pygpt_net/data/config/settings.json +45 -0
- pygpt_net/data/js/app/template.js +1 -1
- pygpt_net/data/js/app.min.js +2 -2
- pygpt_net/data/locale/locale.de.ini +44 -41
- pygpt_net/data/locale/locale.en.ini +56 -43
- pygpt_net/data/locale/locale.es.ini +44 -41
- pygpt_net/data/locale/locale.fr.ini +44 -41
- pygpt_net/data/locale/locale.it.ini +44 -41
- pygpt_net/data/locale/locale.pl.ini +45 -42
- pygpt_net/data/locale/locale.uk.ini +44 -41
- pygpt_net/data/locale/locale.zh.ini +44 -41
- pygpt_net/data/locale/plugin.cmd_history.de.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.en.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.es.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.fr.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.it.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.pl.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.uk.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.zh.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_mouse_control.en.ini +14 -0
- pygpt_net/data/locale/plugin.cmd_web.de.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.en.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.es.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.fr.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.it.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.pl.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.uk.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.zh.ini +1 -1
- pygpt_net/data/locale/plugin.idx_llama_index.de.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.en.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.es.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.fr.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.it.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.pl.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.uk.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.zh.ini +2 -2
- pygpt_net/item/assistant.py +1 -211
- pygpt_net/item/ctx.py +3 -3
- pygpt_net/item/store.py +238 -0
- pygpt_net/js_rc.py +2449 -2447
- pygpt_net/migrations/Version20260102190000.py +35 -0
- pygpt_net/migrations/__init__.py +3 -1
- pygpt_net/plugin/cmd_mouse_control/config.py +471 -1
- pygpt_net/plugin/cmd_mouse_control/plugin.py +487 -22
- pygpt_net/plugin/cmd_mouse_control/worker.py +464 -87
- pygpt_net/plugin/cmd_mouse_control/worker_sandbox.py +729 -0
- pygpt_net/plugin/idx_llama_index/config.py +2 -2
- pygpt_net/provider/api/anthropic/__init__.py +10 -8
- pygpt_net/provider/api/google/__init__.py +21 -58
- pygpt_net/provider/api/google/chat.py +545 -129
- pygpt_net/provider/api/google/computer.py +190 -0
- pygpt_net/provider/api/google/realtime/realtime.py +2 -2
- pygpt_net/provider/api/google/remote_tools.py +93 -0
- pygpt_net/provider/api/google/store.py +546 -0
- pygpt_net/provider/api/google/worker/__init__.py +0 -0
- pygpt_net/provider/api/google/worker/importer.py +392 -0
- pygpt_net/provider/api/openai/__init__.py +7 -3
- pygpt_net/provider/api/openai/computer.py +10 -1
- pygpt_net/provider/api/openai/responses.py +0 -0
- pygpt_net/provider/api/openai/store.py +6 -6
- pygpt_net/provider/api/openai/worker/importer.py +24 -24
- pygpt_net/provider/api/x_ai/__init__.py +10 -9
- pygpt_net/provider/api/x_ai/chat.py +272 -102
- pygpt_net/provider/core/config/patch.py +16 -1
- pygpt_net/provider/core/config/patches/patch_before_2_6_42.py +3 -3
- pygpt_net/provider/core/model/patch.py +17 -3
- pygpt_net/provider/core/preset/json_file.py +13 -7
- pygpt_net/provider/core/{assistant_file → remote_file}/__init__.py +1 -1
- pygpt_net/provider/core/{assistant_file → remote_file}/base.py +9 -9
- pygpt_net/provider/core/remote_file/db_sqlite/__init__.py +12 -0
- pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/patch.py +1 -1
- pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/provider.py +23 -20
- pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/storage.py +35 -27
- pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/utils.py +5 -4
- pygpt_net/provider/core/{assistant_store → remote_store}/__init__.py +1 -1
- pygpt_net/provider/core/{assistant_store → remote_store}/base.py +10 -10
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/__init__.py +1 -1
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/patch.py +1 -1
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/provider.py +16 -15
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/storage.py +30 -23
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/utils.py +5 -4
- pygpt_net/provider/core/{assistant_store → remote_store}/json_file.py +9 -9
- pygpt_net/provider/llms/google.py +2 -2
- pygpt_net/tools/image_viewer/ui/dialogs.py +298 -12
- pygpt_net/tools/text_editor/ui/widgets.py +5 -1
- pygpt_net/ui/base/config_dialog.py +3 -2
- pygpt_net/ui/base/context_menu.py +44 -1
- pygpt_net/ui/dialog/assistant.py +3 -3
- pygpt_net/ui/dialog/plugins.py +3 -1
- pygpt_net/ui/dialog/remote_store_google.py +539 -0
- pygpt_net/ui/dialog/{assistant_store.py → remote_store_openai.py} +95 -95
- pygpt_net/ui/dialogs.py +5 -3
- pygpt_net/ui/layout/chat/attachments_uploaded.py +3 -3
- pygpt_net/ui/layout/toolbox/computer_env.py +26 -8
- pygpt_net/ui/layout/toolbox/indexes.py +22 -19
- pygpt_net/ui/layout/toolbox/model.py +28 -5
- pygpt_net/ui/menu/tools.py +13 -5
- pygpt_net/ui/widget/dialog/remote_store_google.py +56 -0
- pygpt_net/ui/widget/dialog/{assistant_store.py → remote_store_openai.py} +9 -9
- pygpt_net/ui/widget/element/button.py +4 -4
- pygpt_net/ui/widget/image/display.py +25 -8
- pygpt_net/ui/widget/lists/remote_store_google.py +248 -0
- pygpt_net/ui/widget/lists/{assistant_store.py → remote_store_openai.py} +21 -21
- pygpt_net/ui/widget/option/checkbox_list.py +47 -9
- pygpt_net/ui/widget/option/combo.py +39 -3
- pygpt_net/ui/widget/tabs/output.py +9 -1
- pygpt_net/ui/widget/textarea/editor.py +14 -1
- pygpt_net/ui/widget/textarea/input.py +20 -7
- pygpt_net/ui/widget/textarea/notepad.py +24 -1
- pygpt_net/ui/widget/textarea/output.py +23 -1
- pygpt_net/ui/widget/textarea/web.py +16 -1
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/METADATA +41 -2
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/RECORD +158 -132
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/LICENSE +0 -0
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/WHEEL +0 -0
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/entry_points.txt +0 -0
|
@@ -6,10 +6,11 @@
|
|
|
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: 2026.01.03 17:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
|
-
|
|
12
|
-
from PySide6.
|
|
11
|
+
from PySide6.QtCore import Qt, QSize
|
|
12
|
+
from PySide6.QtGui import QIcon
|
|
13
|
+
from PySide6.QtWidgets import QVBoxLayout, QWidget, QPushButton, QHBoxLayout, QSizePolicy
|
|
13
14
|
|
|
14
15
|
from pygpt_net.ui.widget.element.labels import TitleLabel
|
|
15
16
|
from pygpt_net.ui.widget.lists.model_combo import ModelCombo
|
|
@@ -27,6 +28,7 @@ class Model:
|
|
|
27
28
|
self.window = window
|
|
28
29
|
self.id = 'prompt.model'
|
|
29
30
|
self.label_key = f'{self.id}.label'
|
|
31
|
+
self._settings_icon = QIcon(":/icons/settings.svg")
|
|
30
32
|
|
|
31
33
|
def setup(self) -> QWidget:
|
|
32
34
|
"""
|
|
@@ -51,12 +53,33 @@ class Model:
|
|
|
51
53
|
nodes[self.label_key] = label
|
|
52
54
|
|
|
53
55
|
combo = ModelCombo(self.window, self.id)
|
|
56
|
+
# Ensure combo takes maximum horizontal space
|
|
57
|
+
combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
54
58
|
nodes[self.id] = combo
|
|
55
59
|
|
|
60
|
+
nodes['prompt.model.settings'] = QPushButton(self._settings_icon, "")
|
|
61
|
+
# Configure compact, borderless settings button aligned to the right
|
|
62
|
+
icon_size = 20
|
|
63
|
+
nodes['prompt.model.settings'].setFlat(True)
|
|
64
|
+
nodes['prompt.model.settings'].setStyleSheet("QPushButton { border: none; padding: 0; }")
|
|
65
|
+
nodes['prompt.model.settings'].setIconSize(QSize(icon_size, icon_size))
|
|
66
|
+
nodes['prompt.model.settings'].setFixedSize(icon_size, icon_size)
|
|
67
|
+
nodes['prompt.model.settings'].setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
|
68
|
+
nodes['prompt.model.settings'].setFocusPolicy(Qt.NoFocus)
|
|
69
|
+
nodes['prompt.model.settings'].clicked.connect(self._open_settings)
|
|
70
|
+
|
|
71
|
+
model_cols = QHBoxLayout()
|
|
72
|
+
model_cols.addWidget(combo, 1) # stretch to take remaining space
|
|
73
|
+
model_cols.addWidget(nodes['prompt.model.settings'], alignment=Qt.AlignRight)
|
|
74
|
+
model_cols.setContentsMargins(0, 0, 0, 0)
|
|
75
|
+
|
|
56
76
|
layout = QVBoxLayout()
|
|
57
77
|
layout.addWidget(label)
|
|
58
|
-
layout.
|
|
78
|
+
layout.addLayout(model_cols)
|
|
59
79
|
layout.addStretch()
|
|
60
80
|
layout.setContentsMargins(2, 5, 5, 5)
|
|
61
81
|
|
|
62
|
-
return layout
|
|
82
|
+
return layout
|
|
83
|
+
|
|
84
|
+
def _open_settings(self):
|
|
85
|
+
self.window.controller.model.editor.open()
|
pygpt_net/ui/menu/tools.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: 2026.01.02 19:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtGui import QAction, QIcon
|
|
@@ -26,8 +26,11 @@ class Tools:
|
|
|
26
26
|
action = self.window.sender()
|
|
27
27
|
self.window.controller.tools.open_tab(action.data())
|
|
28
28
|
|
|
29
|
-
def
|
|
30
|
-
self.window.controller.
|
|
29
|
+
def _toggle_remote_store_openai(self, checked=False):
|
|
30
|
+
self.window.controller.remote_store.openai.toggle_editor()
|
|
31
|
+
|
|
32
|
+
def _toggle_remote_store_google(self, checked=False):
|
|
33
|
+
self.window.controller.remote_store.google.toggle_editor()
|
|
31
34
|
|
|
32
35
|
def _rebuild_ipython(self, checked=False):
|
|
33
36
|
self.window.core.plugins.get("cmd_code_interpreter").builder.build_and_restart()
|
|
@@ -69,9 +72,14 @@ class Tools:
|
|
|
69
72
|
|
|
70
73
|
menu_tools.addSeparator()
|
|
71
74
|
db_icon = QIcon(":/icons/db.svg")
|
|
72
|
-
ui_menu['menu.tools.openai.stores'] = QAction(db_icon, trans("dialog.
|
|
75
|
+
ui_menu['menu.tools.openai.stores'] = QAction(db_icon, trans("dialog.remote_store.openai"), window)
|
|
73
76
|
menu_tools.addAction(ui_menu['menu.tools.openai.stores'])
|
|
74
|
-
ui_menu['menu.tools.openai.stores'].triggered.connect(self.
|
|
77
|
+
ui_menu['menu.tools.openai.stores'].triggered.connect(self._toggle_remote_store_openai)
|
|
78
|
+
|
|
79
|
+
ui_menu['menu.tools.google.stores'] = QAction(db_icon, trans("dialog.remote_store.google"), window)
|
|
80
|
+
menu_tools.addAction(ui_menu['menu.tools.google.stores'])
|
|
81
|
+
ui_menu['menu.tools.google.stores'].triggered.connect(self._toggle_remote_store_google)
|
|
82
|
+
# ------------------------------------------------- #
|
|
75
83
|
|
|
76
84
|
menu_tools.addSeparator()
|
|
77
85
|
reload_icon = QIcon(":/icons/reload.svg")
|
|
@@ -0,0 +1,56 @@
|
|
|
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: 2026.01.02 20:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
from PySide6.QtCore import Qt
|
|
13
|
+
|
|
14
|
+
from .base import BaseDialog
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RemoteStoreGoogleDialog(BaseDialog):
|
|
18
|
+
def __init__(self, window=None, id=None):
|
|
19
|
+
"""
|
|
20
|
+
Models dialog (Google File Search)
|
|
21
|
+
|
|
22
|
+
:param window: main window
|
|
23
|
+
:param id: settings id
|
|
24
|
+
"""
|
|
25
|
+
super(RemoteStoreGoogleDialog, self).__init__(window, id)
|
|
26
|
+
self.window = window
|
|
27
|
+
self.id = id
|
|
28
|
+
|
|
29
|
+
def closeEvent(self, event):
|
|
30
|
+
"""
|
|
31
|
+
Close event
|
|
32
|
+
|
|
33
|
+
:param event: close event
|
|
34
|
+
"""
|
|
35
|
+
self.window.controller.remote_store.google.dialog = False
|
|
36
|
+
self.window.controller.remote_store.google.update()
|
|
37
|
+
super(RemoteStoreGoogleDialog, self).closeEvent(event)
|
|
38
|
+
|
|
39
|
+
def keyPressEvent(self, event):
|
|
40
|
+
"""
|
|
41
|
+
Key press event
|
|
42
|
+
|
|
43
|
+
:param event: key press event
|
|
44
|
+
"""
|
|
45
|
+
if event.key() == Qt.Key_Escape:
|
|
46
|
+
self.cleanup()
|
|
47
|
+
self.close()
|
|
48
|
+
else:
|
|
49
|
+
super(RemoteStoreGoogleDialog, self).keyPressEvent(event)
|
|
50
|
+
|
|
51
|
+
def cleanup(self):
|
|
52
|
+
"""
|
|
53
|
+
Cleanup on close
|
|
54
|
+
"""
|
|
55
|
+
self.window.controller.remote_store.google.dialog = False
|
|
56
|
+
self.window.controller.remote_store.google.update()
|
|
@@ -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: 2026.01.02 19:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import Qt
|
|
@@ -14,7 +14,7 @@ from PySide6.QtCore import Qt
|
|
|
14
14
|
from .base import BaseDialog
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
class
|
|
17
|
+
class RemoteStoreOpenAIDialog(BaseDialog):
|
|
18
18
|
def __init__(self, window=None, id=None):
|
|
19
19
|
"""
|
|
20
20
|
Models dialog
|
|
@@ -22,7 +22,7 @@ class AssistantVectorStoreDialog(BaseDialog):
|
|
|
22
22
|
:param window: main window
|
|
23
23
|
:param id: settings id
|
|
24
24
|
"""
|
|
25
|
-
super(
|
|
25
|
+
super(RemoteStoreOpenAIDialog, self).__init__(window, id)
|
|
26
26
|
self.window = window
|
|
27
27
|
self.id = id
|
|
28
28
|
|
|
@@ -32,9 +32,9 @@ class AssistantVectorStoreDialog(BaseDialog):
|
|
|
32
32
|
|
|
33
33
|
:param event: close event
|
|
34
34
|
"""
|
|
35
|
-
self.window.controller.
|
|
36
|
-
self.window.controller.
|
|
37
|
-
super(
|
|
35
|
+
self.window.controller.remote_store.openai.dialog = False
|
|
36
|
+
self.window.controller.remote_store.openai.update()
|
|
37
|
+
super(RemoteStoreOpenAIDialog, self).closeEvent(event)
|
|
38
38
|
|
|
39
39
|
def keyPressEvent(self, event):
|
|
40
40
|
"""
|
|
@@ -46,11 +46,11 @@ class AssistantVectorStoreDialog(BaseDialog):
|
|
|
46
46
|
self.cleanup()
|
|
47
47
|
self.close() # close dialog when the Esc key is pressed.
|
|
48
48
|
else:
|
|
49
|
-
super(
|
|
49
|
+
super(RemoteStoreOpenAIDialog, self).keyPressEvent(event)
|
|
50
50
|
|
|
51
51
|
def cleanup(self):
|
|
52
52
|
"""
|
|
53
53
|
Cleanup on close
|
|
54
54
|
"""
|
|
55
|
-
self.window.controller.
|
|
56
|
-
self.window.controller.
|
|
55
|
+
self.window.controller.remote_store.openai.dialog = False
|
|
56
|
+
self.window.controller.remote_store.openai.update()
|
|
@@ -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: 2026.01.02 19:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import Qt
|
|
@@ -87,7 +87,7 @@ class SyncButton(QPushButton):
|
|
|
87
87
|
super().__init__(title)
|
|
88
88
|
self.window = window
|
|
89
89
|
self.clicked.connect(
|
|
90
|
-
lambda: self.window.controller.
|
|
90
|
+
lambda: self.window.controller.remote_store.openai.batch.import_files_current()
|
|
91
91
|
)
|
|
92
92
|
|
|
93
93
|
@classmethod
|
|
@@ -112,11 +112,11 @@ class SyncButton(QPushButton):
|
|
|
112
112
|
menu = QMenu(parent)
|
|
113
113
|
act_current = menu.addAction(type(self)._icon_download, trans('attachments_uploaded.btn.sync.current'))
|
|
114
114
|
act_current.triggered.connect(
|
|
115
|
-
lambda checked=False: self.window.controller.
|
|
115
|
+
lambda checked=False: self.window.controller.remote_store.openai.batch.import_files_current()
|
|
116
116
|
)
|
|
117
117
|
act_all = menu.addAction(type(self)._icon_download, trans('attachments_uploaded.btn.sync.all'))
|
|
118
118
|
act_all.triggered.connect(
|
|
119
|
-
lambda checked=False: self.window.controller.
|
|
119
|
+
lambda checked=False: self.window.controller.remote_store.openai.batch.import_files()
|
|
120
120
|
)
|
|
121
121
|
menu.exec_(parent.mapToGlobal(pos))
|
|
122
122
|
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:
|
|
9
|
+
# Updated Date: 2026.01.03 17:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtGui import QAction, QIcon
|
|
@@ -27,6 +27,17 @@ class ImageLabel(QLabel):
|
|
|
27
27
|
self.window = window
|
|
28
28
|
self.path = path
|
|
29
29
|
|
|
30
|
+
def _get_window(self):
|
|
31
|
+
"""
|
|
32
|
+
Get main window instance
|
|
33
|
+
|
|
34
|
+
:return: Window instance
|
|
35
|
+
"""
|
|
36
|
+
if self.window is not None:
|
|
37
|
+
if hasattr(self.window, 'window'):
|
|
38
|
+
return self.window.window
|
|
39
|
+
return self.window
|
|
40
|
+
|
|
30
41
|
def contextMenuEvent(self, event):
|
|
31
42
|
"""
|
|
32
43
|
Context menu event
|
|
@@ -36,6 +47,8 @@ class ImageLabel(QLabel):
|
|
|
36
47
|
if not self.path:
|
|
37
48
|
return
|
|
38
49
|
|
|
50
|
+
win = self._get_window()
|
|
51
|
+
|
|
39
52
|
actions = {}
|
|
40
53
|
use_actions = []
|
|
41
54
|
actions['open'] = QAction(QIcon(":/icons/fullscreen.svg"), trans('img.action.open'), self)
|
|
@@ -64,13 +77,13 @@ class ImageLabel(QLabel):
|
|
|
64
77
|
self,
|
|
65
78
|
)
|
|
66
79
|
actions['use_attachment'].triggered.connect(
|
|
67
|
-
lambda:
|
|
80
|
+
lambda: win.controller.files.use_attachment(self.path),
|
|
68
81
|
)
|
|
69
82
|
use_actions.append(actions['use_attachment'])
|
|
70
83
|
|
|
71
84
|
# use by filetype
|
|
72
|
-
if
|
|
73
|
-
extra_use_actions =
|
|
85
|
+
if win.core.filesystem.actions.has_use(self.path):
|
|
86
|
+
extra_use_actions = win.core.filesystem.actions.get_use(self, self.path)
|
|
74
87
|
for action in extra_use_actions:
|
|
75
88
|
use_actions.append(action)
|
|
76
89
|
|
|
@@ -97,7 +110,8 @@ class ImageLabel(QLabel):
|
|
|
97
110
|
|
|
98
111
|
:param event: mouse event
|
|
99
112
|
"""
|
|
100
|
-
self.
|
|
113
|
+
win = self._get_window()
|
|
114
|
+
win.tools.get("viewer").open(self.path)
|
|
101
115
|
|
|
102
116
|
def action_open_dir(self, event):
|
|
103
117
|
"""
|
|
@@ -105,7 +119,8 @@ class ImageLabel(QLabel):
|
|
|
105
119
|
|
|
106
120
|
:param event: mouse event
|
|
107
121
|
"""
|
|
108
|
-
self.
|
|
122
|
+
win = self._get_window()
|
|
123
|
+
win.tools.get("viewer").open_dir(self.path)
|
|
109
124
|
|
|
110
125
|
def action_save(self, event):
|
|
111
126
|
"""
|
|
@@ -113,7 +128,8 @@ class ImageLabel(QLabel):
|
|
|
113
128
|
|
|
114
129
|
:param event: mouse event
|
|
115
130
|
"""
|
|
116
|
-
self.
|
|
131
|
+
win = self._get_window()
|
|
132
|
+
win.tools.get("viewer").save(self.path)
|
|
117
133
|
|
|
118
134
|
def action_delete(self, event):
|
|
119
135
|
"""
|
|
@@ -121,4 +137,5 @@ class ImageLabel(QLabel):
|
|
|
121
137
|
|
|
122
138
|
:param event: mouse event
|
|
123
139
|
"""
|
|
124
|
-
self.
|
|
140
|
+
win = self._get_window()
|
|
141
|
+
win.tools.get("viewer").delete(self.path)
|
|
@@ -0,0 +1,248 @@
|
|
|
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: 2026.01.02 20:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
from PySide6.QtGui import QAction, QIcon
|
|
13
|
+
from PySide6.QtCore import Qt, QItemSelectionModel
|
|
14
|
+
from PySide6.QtWidgets import QMenu, QAbstractItemView
|
|
15
|
+
|
|
16
|
+
from pygpt_net.ui.widget.lists.base import BaseList
|
|
17
|
+
from pygpt_net.utils import trans
|
|
18
|
+
import pygpt_net.icons_rc
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RemoteStoreGoogleEditorList(BaseList):
|
|
22
|
+
def __init__(self, window=None, id=None):
|
|
23
|
+
"""
|
|
24
|
+
Store select menu (in editor) - Google File Search
|
|
25
|
+
|
|
26
|
+
:param window: main window
|
|
27
|
+
:param id: parent id
|
|
28
|
+
"""
|
|
29
|
+
super(RemoteStoreGoogleEditorList, self).__init__(window)
|
|
30
|
+
self.window = window
|
|
31
|
+
self.id = id
|
|
32
|
+
|
|
33
|
+
self._suppress_item_click = False
|
|
34
|
+
self._ctrl_multi_active = False
|
|
35
|
+
self._ctrl_multi_index = None
|
|
36
|
+
self._was_shift_click = False
|
|
37
|
+
|
|
38
|
+
self._backup_selection = None
|
|
39
|
+
self.restore_after_ctx_menu = True
|
|
40
|
+
|
|
41
|
+
self.setSelectionBehavior(QAbstractItemView.SelectRows)
|
|
42
|
+
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
|
43
|
+
|
|
44
|
+
# Disable BaseList click handler; business action handled manually
|
|
45
|
+
self.clicked.disconnect(self.click)
|
|
46
|
+
|
|
47
|
+
def _selected_rows(self) -> list[int]:
|
|
48
|
+
try:
|
|
49
|
+
return sorted([ix.row() for ix in self.selectionModel().selectedRows()])
|
|
50
|
+
except Exception:
|
|
51
|
+
return []
|
|
52
|
+
|
|
53
|
+
def _has_multi_selection(self) -> bool:
|
|
54
|
+
try:
|
|
55
|
+
return len(self.selectionModel().selectedRows()) > 1
|
|
56
|
+
except Exception:
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
def mousePressEvent(self, event):
|
|
60
|
+
if event.button() == Qt.LeftButton and (event.modifiers() & Qt.ControlModifier):
|
|
61
|
+
idx = self.indexAt(event.pos())
|
|
62
|
+
if idx.isValid():
|
|
63
|
+
self._ctrl_multi_active = True
|
|
64
|
+
self._ctrl_multi_index = idx
|
|
65
|
+
self._suppress_item_click = True
|
|
66
|
+
event.accept()
|
|
67
|
+
return
|
|
68
|
+
self._suppress_item_click = True
|
|
69
|
+
event.accept()
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
if event.button() == Qt.LeftButton and (event.modifiers() & Qt.ShiftModifier):
|
|
73
|
+
idx = self.indexAt(event.pos())
|
|
74
|
+
self._suppress_item_click = True
|
|
75
|
+
self._was_shift_click = True
|
|
76
|
+
if idx.isValid():
|
|
77
|
+
super(RemoteStoreGoogleEditorList, self).mousePressEvent(event)
|
|
78
|
+
else:
|
|
79
|
+
event.accept()
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
if event.button() == Qt.LeftButton:
|
|
83
|
+
idx = self.indexAt(event.pos())
|
|
84
|
+
if self._has_multi_selection():
|
|
85
|
+
sel_model = self.selectionModel()
|
|
86
|
+
sel_model.clearSelection()
|
|
87
|
+
if not idx.isValid():
|
|
88
|
+
event.accept()
|
|
89
|
+
return
|
|
90
|
+
super(RemoteStoreGoogleEditorList, self).mousePressEvent(event)
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
if event.button() == Qt.RightButton:
|
|
94
|
+
idx = self.indexAt(event.pos())
|
|
95
|
+
sel_model = self.selectionModel()
|
|
96
|
+
selected_rows = [ix.row() for ix in sel_model.selectedRows()]
|
|
97
|
+
multi = len(selected_rows) > 1
|
|
98
|
+
|
|
99
|
+
if idx.isValid():
|
|
100
|
+
if multi and idx.row() in selected_rows:
|
|
101
|
+
self._backup_selection = None
|
|
102
|
+
else:
|
|
103
|
+
self._backup_selection = list(sel_model.selectedIndexes())
|
|
104
|
+
sel_model.clearSelection()
|
|
105
|
+
sel_model.select(idx, QItemSelectionModel.Select | QItemSelectionModel.Rows)
|
|
106
|
+
event.accept()
|
|
107
|
+
return
|
|
108
|
+
|
|
109
|
+
super(RemoteStoreGoogleEditorList, self).mousePressEvent(event)
|
|
110
|
+
|
|
111
|
+
def mouseReleaseEvent(self, event):
|
|
112
|
+
if event.button() == Qt.LeftButton and self._was_shift_click:
|
|
113
|
+
self._was_shift_click = False
|
|
114
|
+
self._suppress_item_click = False
|
|
115
|
+
super(RemoteStoreGoogleEditorList, self).mouseReleaseEvent(event)
|
|
116
|
+
return
|
|
117
|
+
|
|
118
|
+
if event.button() == Qt.LeftButton and self._ctrl_multi_active:
|
|
119
|
+
try:
|
|
120
|
+
idx = self.indexAt(event.pos())
|
|
121
|
+
if idx.isValid() and self._ctrl_multi_index and idx == self._ctrl_multi_index:
|
|
122
|
+
sel_model = self.selectionModel()
|
|
123
|
+
sel_model.select(idx, QItemSelectionModel.Toggle | QItemSelectionModel.Rows)
|
|
124
|
+
finally:
|
|
125
|
+
self._ctrl_multi_active = False
|
|
126
|
+
self._ctrl_multi_index = None
|
|
127
|
+
self._suppress_item_click = False
|
|
128
|
+
event.accept()
|
|
129
|
+
return
|
|
130
|
+
|
|
131
|
+
if event.button() == Qt.LeftButton:
|
|
132
|
+
idx = self.indexAt(event.pos())
|
|
133
|
+
if not self._has_multi_selection():
|
|
134
|
+
if idx.isValid() and not self._suppress_item_click:
|
|
135
|
+
self.window.controller.remote_store.google.select(idx.row())
|
|
136
|
+
self._suppress_item_click = False
|
|
137
|
+
super(RemoteStoreGoogleEditorList, self).mouseReleaseEvent(event)
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
super(RemoteStoreGoogleEditorList, self).mouseReleaseEvent(event)
|
|
141
|
+
|
|
142
|
+
def click(self, val):
|
|
143
|
+
pass
|
|
144
|
+
|
|
145
|
+
def contextMenuEvent(self, event):
|
|
146
|
+
actions = {}
|
|
147
|
+
actions['refresh'] = QAction(
|
|
148
|
+
QIcon(":/icons/reload.svg"),
|
|
149
|
+
trans('dialog.remote_store.menu.current.refresh_store'),
|
|
150
|
+
self
|
|
151
|
+
)
|
|
152
|
+
actions['delete'] = QAction(QIcon(":/icons/delete.svg"), trans('action.delete'), self)
|
|
153
|
+
actions['clear'] = QAction(
|
|
154
|
+
QIcon(":/icons/close.svg"),
|
|
155
|
+
trans('dialog.remote_store.menu.current.clear_files'),
|
|
156
|
+
self
|
|
157
|
+
)
|
|
158
|
+
actions['truncate'] = QAction(
|
|
159
|
+
QIcon(":/icons/delete.svg"),
|
|
160
|
+
trans('dialog.remote_store.menu.current.truncate_files'),
|
|
161
|
+
self
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
menu = QMenu(self)
|
|
165
|
+
menu.addAction(actions['refresh'])
|
|
166
|
+
menu.addAction(actions['delete'])
|
|
167
|
+
menu.addAction(actions['clear'])
|
|
168
|
+
menu.addAction(actions['truncate'])
|
|
169
|
+
|
|
170
|
+
index = self.indexAt(event.pos())
|
|
171
|
+
idx = index.row() if index.isValid() else -1
|
|
172
|
+
|
|
173
|
+
selected_rows = self._selected_rows()
|
|
174
|
+
multi = len(selected_rows) > 1
|
|
175
|
+
|
|
176
|
+
if not index.isValid() and not multi:
|
|
177
|
+
if self._backup_selection is not None and self.restore_after_ctx_menu:
|
|
178
|
+
sel_model = self.selectionModel()
|
|
179
|
+
sel_model.clearSelection()
|
|
180
|
+
for i in self._backup_selection:
|
|
181
|
+
sel_model.select(i, QItemSelectionModel.Select | QItemSelectionModel.Rows)
|
|
182
|
+
self._backup_selection = None
|
|
183
|
+
return
|
|
184
|
+
|
|
185
|
+
if multi:
|
|
186
|
+
actions['refresh'].triggered.connect(lambda: self.action_refresh(list(selected_rows)))
|
|
187
|
+
actions['delete'].triggered.connect(lambda: self.action_delete(list(selected_rows)))
|
|
188
|
+
actions['clear'].triggered.connect(lambda: self.action_clear(list(selected_rows)))
|
|
189
|
+
actions['truncate'].triggered.connect(lambda: self.action_truncate(list(selected_rows)))
|
|
190
|
+
else:
|
|
191
|
+
actions['refresh'].triggered.connect(lambda: self.action_refresh(idx))
|
|
192
|
+
actions['delete'].triggered.connect(lambda: self.action_delete(idx))
|
|
193
|
+
actions['clear'].triggered.connect(lambda: self.action_clear(idx))
|
|
194
|
+
actions['truncate'].triggered.connect(lambda: self.action_truncate(idx))
|
|
195
|
+
|
|
196
|
+
menu.exec_(event.globalPos())
|
|
197
|
+
|
|
198
|
+
if self.restore_after_ctx_menu and self._backup_selection is not None:
|
|
199
|
+
sel_model = self.selectionModel()
|
|
200
|
+
sel_model.clearSelection()
|
|
201
|
+
for i in self._backup_selection:
|
|
202
|
+
sel_model.select(i, QItemSelectionModel.Select | QItemSelectionModel.Rows)
|
|
203
|
+
self._backup_selection = None
|
|
204
|
+
self.restore_after_ctx_menu = True
|
|
205
|
+
|
|
206
|
+
def action_delete(self, item):
|
|
207
|
+
if isinstance(item, (list, tuple)):
|
|
208
|
+
if item:
|
|
209
|
+
self.restore_after_ctx_menu = False
|
|
210
|
+
self.window.controller.remote_store.google.delete_by_idx(list(item))
|
|
211
|
+
return
|
|
212
|
+
idx = int(item)
|
|
213
|
+
if idx >= 0:
|
|
214
|
+
self.restore_after_ctx_menu = False
|
|
215
|
+
self.window.controller.remote_store.google.delete_by_idx(idx)
|
|
216
|
+
|
|
217
|
+
def action_clear(self, item):
|
|
218
|
+
if isinstance(item, (list, tuple)):
|
|
219
|
+
if item:
|
|
220
|
+
self.restore_after_ctx_menu = False
|
|
221
|
+
self.window.controller.remote_store.google.batch.clear_store_files_by_idx(list(item))
|
|
222
|
+
return
|
|
223
|
+
idx = int(item)
|
|
224
|
+
if idx >= 0:
|
|
225
|
+
self.restore_after_ctx_menu = False
|
|
226
|
+
self.window.controller.remote_store.google.batch.clear_store_files_by_idx(idx)
|
|
227
|
+
|
|
228
|
+
def action_truncate(self, item):
|
|
229
|
+
if isinstance(item, (list, tuple)):
|
|
230
|
+
if item:
|
|
231
|
+
self.restore_after_ctx_menu = False
|
|
232
|
+
self.window.controller.remote_store.google.batch.truncate_store_files_by_idx(list(item))
|
|
233
|
+
return
|
|
234
|
+
idx = int(item)
|
|
235
|
+
if idx >= 0:
|
|
236
|
+
self.restore_after_ctx_menu = False
|
|
237
|
+
self.window.controller.remote_store.google.batch.truncate_store_files_by_idx(idx)
|
|
238
|
+
|
|
239
|
+
def action_refresh(self, item):
|
|
240
|
+
if isinstance(item, (list, tuple)):
|
|
241
|
+
if item:
|
|
242
|
+
self.restore_after_ctx_menu = False
|
|
243
|
+
self.window.controller.remote_store.google.refresh_by_idx(list(item))
|
|
244
|
+
return
|
|
245
|
+
idx = int(item)
|
|
246
|
+
if idx >= 0:
|
|
247
|
+
self.restore_after_ctx_menu = False
|
|
248
|
+
self.window.controller.remote_store.google.refresh_by_idx(idx)
|