pygpt-net 2.6.21__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 +4 -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/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/audio/audio.py +2 -2
- pygpt_net/controller/ctx/ctx.py +2 -1
- pygpt_net/controller/idx/indexer.py +85 -76
- pygpt_net/controller/lang/lang.py +52 -34
- pygpt_net/controller/model/importer.py +2 -2
- pygpt_net/controller/notepad/notepad.py +86 -84
- pygpt_net/controller/plugins/settings.py +3 -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/core/ctx/container.py +13 -12
- pygpt_net/core/ctx/output.py +7 -4
- pygpt_net/core/debug/console/console.py +2 -2
- pygpt_net/core/filesystem/actions.py +1 -2
- 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/settings/settings.py +43 -13
- pygpt_net/core/tabs/tabs.py +20 -13
- pygpt_net/data/config/config.json +4 -4
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/locale/locale.de.ini +4 -1
- pygpt_net/data/locale/locale.en.ini +4 -1
- 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/plugin/twitter/plugin.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.21.dist-info → pygpt_net-2.6.22.dist-info}/METADATA +15 -151
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/RECORD +144 -144
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.21.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:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -19,8 +19,6 @@ from pygpt_net.ui.widget.element.labels import HelpLabel
|
|
|
19
19
|
from pygpt_net.ui.widget.lists.attachment_ctx import AttachmentCtxList
|
|
20
20
|
from pygpt_net.utils import trans
|
|
21
21
|
|
|
22
|
-
import pygpt_net.icons_rc
|
|
23
|
-
|
|
24
22
|
class AttachmentsCtx:
|
|
25
23
|
def __init__(self, window=None):
|
|
26
24
|
"""
|
|
@@ -65,11 +63,9 @@ class AttachmentsCtx:
|
|
|
65
63
|
self.window.controller.chat.attachment.MODE_DISABLED
|
|
66
64
|
))
|
|
67
65
|
|
|
68
|
-
# buttons layout
|
|
69
66
|
buttons_layout = QHBoxLayout()
|
|
70
67
|
buttons_layout.addWidget(self.window.ui.nodes['attachments_ctx.btn.clear'])
|
|
71
68
|
buttons_layout.addWidget(empty_widget)
|
|
72
|
-
# buttons_layout.addStretch()
|
|
73
69
|
buttons_layout.addWidget(self.window.ui.nodes['input.attachments.ctx.mode.label'])
|
|
74
70
|
buttons_layout.addWidget(self.window.ui.nodes['input.attachments.ctx.mode.full'])
|
|
75
71
|
buttons_layout.addWidget(self.window.ui.nodes['input.attachments.ctx.mode.query'])
|
|
@@ -77,7 +73,6 @@ class AttachmentsCtx:
|
|
|
77
73
|
buttons_layout.addWidget(self.window.ui.nodes['input.attachments.ctx.mode.off'])
|
|
78
74
|
buttons_layout.addStretch()
|
|
79
75
|
|
|
80
|
-
# layout
|
|
81
76
|
layout = QVBoxLayout()
|
|
82
77
|
layout.addWidget(self.window.ui.nodes['tip.input.attachments.ctx'])
|
|
83
78
|
layout.addWidget(self.window.ui.nodes['attachments_ctx'])
|
|
@@ -87,16 +82,14 @@ class AttachmentsCtx:
|
|
|
87
82
|
|
|
88
83
|
def setup_attachments(self):
|
|
89
84
|
"""Setup attachments uploaded list"""
|
|
90
|
-
# attachments
|
|
91
85
|
self.window.ui.nodes[self.id] = AttachmentCtxList(self.window)
|
|
92
86
|
|
|
93
|
-
# buttons
|
|
94
87
|
self.window.ui.nodes['attachments_ctx.btn.clear'] = QPushButton(QIcon(":/icons/close.svg"), trans('attachments_uploaded.btn.clear'))
|
|
95
88
|
self.window.ui.nodes['attachments_ctx.btn.clear'].clicked.connect(
|
|
96
89
|
lambda: self.window.controller.chat.attachment.clear()
|
|
97
90
|
)
|
|
98
91
|
|
|
99
|
-
self.window.ui.models[self.id] = self.create_model(self.window)
|
|
92
|
+
self.window.ui.models[self.id] = self.create_model(self.window.ui.nodes[self.id])
|
|
100
93
|
self.window.ui.nodes[self.id].setModel(self.window.ui.models[self.id])
|
|
101
94
|
|
|
102
95
|
def create_model(self, parent) -> QStandardItemModel:
|
|
@@ -120,43 +113,46 @@ class AttachmentsCtx:
|
|
|
120
113
|
|
|
121
114
|
:param data: Data to update
|
|
122
115
|
"""
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
116
|
+
model = self.window.ui.models[self.id]
|
|
117
|
+
row_count = len(data)
|
|
118
|
+
model.beginResetModel()
|
|
119
|
+
model.setRowCount(row_count)
|
|
120
|
+
|
|
121
|
+
m_index = model.index
|
|
122
|
+
m_setData = model.setData
|
|
123
|
+
tooltip_role = QtCore.Qt.ToolTipRole
|
|
124
|
+
trans_indexed = trans("attachments.ctx.indexed")
|
|
125
|
+
sizeof_fmt = self.window.core.filesystem.sizeof_fmt
|
|
126
|
+
stat = os.stat
|
|
127
|
+
|
|
128
|
+
for i, item in enumerate(data):
|
|
129
|
+
name = item.get('name', "No name")
|
|
130
|
+
path = item.get('path', "No path")
|
|
131
|
+
uuid = item.get('uuid', "")
|
|
137
132
|
length = "-"
|
|
138
133
|
if 'length' in item:
|
|
139
134
|
length = str(item['length'])
|
|
140
135
|
if 'tokens' in item:
|
|
141
136
|
length += ' / ~' + str(item['tokens'])
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
137
|
+
idx_str = trans_indexed if item.get('indexed') else ""
|
|
138
|
+
|
|
139
|
+
size = "-"
|
|
140
|
+
if isinstance(path, str):
|
|
141
|
+
try:
|
|
142
|
+
st = stat(path)
|
|
143
|
+
except (OSError, ValueError, TypeError):
|
|
144
|
+
pass
|
|
145
|
+
else:
|
|
146
|
+
size = sizeof_fmt(st.st_size)
|
|
147
|
+
if size == "-" and 'size' in item:
|
|
148
|
+
size = sizeof_fmt(item['size'])
|
|
149
|
+
|
|
150
|
+
idx0 = m_index(i, 0)
|
|
151
|
+
m_setData(idx0, "uuid: " + str(uuid), tooltip_role)
|
|
152
|
+
m_setData(idx0, name)
|
|
153
|
+
m_setData(m_index(i, 1), path)
|
|
154
|
+
m_setData(m_index(i, 2), size)
|
|
155
|
+
m_setData(m_index(i, 3), length)
|
|
156
|
+
m_setData(m_index(i, 4), idx_str)
|
|
157
|
+
|
|
158
|
+
model.endResetModel()
|
|
@@ -6,22 +6,20 @@
|
|
|
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
|
import os
|
|
13
13
|
|
|
14
14
|
from PySide6 import QtCore
|
|
15
15
|
from PySide6.QtGui import QStandardItemModel, Qt, QIcon
|
|
16
|
-
from PySide6.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout,
|
|
16
|
+
from PySide6.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QWidget
|
|
17
17
|
|
|
18
18
|
from pygpt_net.ui.widget.element.button import SyncButton
|
|
19
19
|
from pygpt_net.ui.widget.element.labels import HelpLabel
|
|
20
20
|
from pygpt_net.ui.widget.lists.uploaded import UploadedFileList
|
|
21
21
|
from pygpt_net.utils import trans
|
|
22
22
|
|
|
23
|
-
import pygpt_net.icons_rc
|
|
24
|
-
|
|
25
23
|
class AttachmentsUploaded:
|
|
26
24
|
def __init__(self, window=None):
|
|
27
25
|
"""
|
|
@@ -39,16 +37,15 @@ class AttachmentsUploaded:
|
|
|
39
37
|
:return: QVBoxLayout
|
|
40
38
|
"""
|
|
41
39
|
self.setup_attachments()
|
|
42
|
-
empty_widget = QWidget()
|
|
40
|
+
empty_widget = QWidget(self.window)
|
|
43
41
|
|
|
44
|
-
self.window.ui.nodes['attachments_uploaded.sync.tip'] = HelpLabel(trans('attachments_uploaded.sync.tip'))
|
|
42
|
+
self.window.ui.nodes['attachments_uploaded.sync.tip'] = HelpLabel(trans('attachments_uploaded.sync.tip'), self.window)
|
|
45
43
|
self.window.ui.nodes['attachments_uploaded.sync.tip'].setWordWrap(False)
|
|
46
44
|
self.window.ui.nodes['attachments_uploaded.sync.tip'].setAlignment(Qt.AlignCenter)
|
|
47
45
|
|
|
48
46
|
self.window.ui.nodes['tip.input.attachments.uploaded'] = HelpLabel(trans('tip.input.attachments.uploaded'),
|
|
49
47
|
self.window)
|
|
50
48
|
|
|
51
|
-
# buttons layout
|
|
52
49
|
buttons_layout = QHBoxLayout()
|
|
53
50
|
buttons_layout.addWidget(self.window.ui.nodes['attachments_uploaded.btn.sync'])
|
|
54
51
|
buttons_layout.addWidget(self.window.ui.nodes['attachments_uploaded.btn.clear'])
|
|
@@ -56,8 +53,6 @@ class AttachmentsUploaded:
|
|
|
56
53
|
buttons_layout.addWidget(self.window.ui.nodes['attachments_uploaded.sync.tip'])
|
|
57
54
|
buttons_layout.addStretch()
|
|
58
55
|
|
|
59
|
-
|
|
60
|
-
# layout
|
|
61
56
|
layout = QVBoxLayout()
|
|
62
57
|
layout.addWidget(self.window.ui.nodes['tip.input.attachments.uploaded'])
|
|
63
58
|
layout.addWidget(self.window.ui.nodes['attachments_uploaded'])
|
|
@@ -69,10 +64,8 @@ class AttachmentsUploaded:
|
|
|
69
64
|
"""
|
|
70
65
|
Setup attachments uploaded list
|
|
71
66
|
"""
|
|
72
|
-
# attachments
|
|
73
67
|
self.window.ui.nodes[self.id] = UploadedFileList(self.window)
|
|
74
68
|
|
|
75
|
-
# buttons
|
|
76
69
|
self.window.ui.nodes['attachments_uploaded.btn.sync'] = SyncButton(trans('attachments_uploaded.btn.sync'), self.window)
|
|
77
70
|
self.window.ui.nodes['attachments_uploaded.btn.clear'] = QPushButton(QIcon(":/icons/close.svg"), trans('attachments_uploaded.btn.clear'))
|
|
78
71
|
self.window.ui.nodes['attachments_uploaded.btn.clear'].clicked.connect(
|
|
@@ -102,32 +95,36 @@ class AttachmentsUploaded:
|
|
|
102
95
|
|
|
103
96
|
:param data: Data to update
|
|
104
97
|
"""
|
|
98
|
+
model = self.window.ui.models[self.id]
|
|
105
99
|
store_names = self.window.core.assistants.store.get_names()
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
100
|
+
thread_only_label = trans("assistant.store.thread_only")
|
|
101
|
+
fs = self.window.core.filesystem
|
|
102
|
+
|
|
103
|
+
model.beginResetModel()
|
|
104
|
+
model.setRowCount(0)
|
|
105
|
+
count = len(data)
|
|
106
|
+
if count:
|
|
107
|
+
model.setRowCount(count)
|
|
108
|
+
for i, item in enumerate(data.values()):
|
|
109
|
+
path = item.path
|
|
110
|
+
if item.size is not None:
|
|
111
|
+
size_str = fs.sizeof_fmt(item.size)
|
|
112
|
+
else:
|
|
113
|
+
size_str = "-"
|
|
114
|
+
if path:
|
|
115
|
+
try:
|
|
116
|
+
st = os.stat(path)
|
|
117
|
+
except OSError:
|
|
118
|
+
pass
|
|
119
|
+
else:
|
|
120
|
+
size_str = fs.sizeof_fmt(st.st_size)
|
|
121
|
+
|
|
122
|
+
store_name = store_names.get(item.store_id, thread_only_label)
|
|
123
|
+
|
|
124
|
+
idx0 = model.index(i, 0)
|
|
125
|
+
model.setData(idx0, item.name)
|
|
126
|
+
model.setData(idx0, f"file_id: {item.file_id}", QtCore.Qt.ToolTipRole)
|
|
127
|
+
model.setData(model.index(i, 1), path)
|
|
128
|
+
model.setData(model.index(i, 2), size_str)
|
|
129
|
+
model.setData(model.index(i, 3), store_name)
|
|
130
|
+
model.endResetModel()
|
|
@@ -6,11 +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: 2025.
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import Qt
|
|
13
|
-
from PySide6.QtWidgets import QVBoxLayout, QLabel, QHBoxLayout, QWidget, QSplitter, QSizePolicy, QRadioButton, QCheckBox
|
|
13
|
+
from PySide6.QtWidgets import QVBoxLayout, QLabel, QHBoxLayout, QWidget, QSplitter, QSizePolicy, QRadioButton, QCheckBox, QButtonGroup
|
|
14
14
|
|
|
15
15
|
from pygpt_net.ui.widget.calendar.select import CalendarSelect
|
|
16
16
|
from pygpt_net.ui.widget.element.checkbox import ColorCheckbox
|
|
@@ -20,6 +20,8 @@ from pygpt_net.utils import trans
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class Calendar:
|
|
23
|
+
__slots__ = ('window',)
|
|
24
|
+
|
|
23
25
|
def __init__(self, window=None):
|
|
24
26
|
"""
|
|
25
27
|
Calendar UI
|
|
@@ -34,8 +36,11 @@ class Calendar:
|
|
|
34
36
|
|
|
35
37
|
:return: QWidget
|
|
36
38
|
"""
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
ui = self.window.ui
|
|
40
|
+
ui.calendar['select'] = CalendarSelect(self.window)
|
|
41
|
+
ui.calendar['select'].setMinimumSize(200, 200)
|
|
42
|
+
ui.calendar['select'].setGridVisible(True)
|
|
43
|
+
ui.calendar['note'] = CalendarNote(self.window)
|
|
39
44
|
|
|
40
45
|
def setup(self) -> QWidget:
|
|
41
46
|
"""
|
|
@@ -49,58 +54,76 @@ class Calendar:
|
|
|
49
54
|
body.append(self.window.ui.calendar['select'])
|
|
50
55
|
return body
|
|
51
56
|
|
|
57
|
+
def _on_filter_id_clicked(self, id_: int) -> None:
|
|
58
|
+
key = "all" if id_ == 0 else ("pinned" if id_ == 1 else "indexed")
|
|
59
|
+
self.window.controller.ctx.common.toggle_display_filter(key)
|
|
60
|
+
|
|
61
|
+
def _on_counters_all_toggled(self, checked: bool) -> None:
|
|
62
|
+
self.window.controller.calendar.note.toggle_counters_all(checked)
|
|
63
|
+
|
|
52
64
|
def setup_filters(self) -> QWidget:
|
|
53
65
|
"""
|
|
54
66
|
Setup calendar filters
|
|
55
67
|
|
|
56
68
|
:return: QWidget
|
|
57
69
|
"""
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
ui = self.window.ui
|
|
71
|
+
nodes = ui.nodes
|
|
72
|
+
|
|
73
|
+
label_existing = nodes.get('filter.ctx.label')
|
|
74
|
+
if label_existing is None:
|
|
75
|
+
layout = QHBoxLayout()
|
|
76
|
+
widget = QWidget()
|
|
77
|
+
rows = QVBoxLayout()
|
|
78
|
+
widget.setLayout(rows)
|
|
79
|
+
|
|
80
|
+
label = QLabel(trans("filter.ctx.label"), widget)
|
|
81
|
+
|
|
82
|
+
radio_all = QRadioButton(trans("filter.ctx.radio.all"), widget)
|
|
83
|
+
radio_pinned = QRadioButton(trans("filter.ctx.radio.pinned"), widget)
|
|
84
|
+
radio_indexed = QRadioButton(trans("filter.ctx.radio.indexed"), widget)
|
|
85
|
+
|
|
86
|
+
counters_all = QCheckBox(trans("filter.ctx.counters.all"), widget)
|
|
87
|
+
|
|
88
|
+
layout.addWidget(label)
|
|
89
|
+
layout.addWidget(radio_all)
|
|
90
|
+
layout.addWidget(radio_pinned)
|
|
91
|
+
layout.addWidget(radio_indexed)
|
|
92
|
+
layout.addWidget(counters_all)
|
|
93
|
+
layout.addStretch()
|
|
94
|
+
|
|
95
|
+
nodes['filter.ctx.labels'] = ColorCheckbox(self.window)
|
|
96
|
+
|
|
97
|
+
rows.addLayout(layout)
|
|
98
|
+
rows.addWidget(nodes['filter.ctx.labels'])
|
|
99
|
+
|
|
100
|
+
group = QButtonGroup(widget)
|
|
101
|
+
group.setExclusive(True)
|
|
102
|
+
group.addButton(radio_all, 0)
|
|
103
|
+
group.addButton(radio_pinned, 1)
|
|
104
|
+
group.addButton(radio_indexed, 2)
|
|
105
|
+
group.idClicked.connect(self._on_filter_id_clicked)
|
|
106
|
+
|
|
107
|
+
counters_all.toggled.connect(self._on_counters_all_toggled)
|
|
108
|
+
|
|
109
|
+
nodes['filter.ctx.label'] = label
|
|
110
|
+
nodes['filter.ctx.radio.all'] = radio_all
|
|
111
|
+
nodes['filter.ctx.radio.pinned'] = radio_pinned
|
|
112
|
+
nodes['filter.ctx.radio.indexed'] = radio_indexed
|
|
113
|
+
nodes['filter.ctx.counters.all'] = counters_all
|
|
83
114
|
else:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
rows = QVBoxLayout()
|
|
98
|
-
rows.addLayout(layout)
|
|
99
|
-
rows.addWidget(self.window.ui.nodes['filter.ctx.labels'])
|
|
100
|
-
|
|
101
|
-
widget = QWidget()
|
|
102
|
-
widget.setLayout(rows)
|
|
103
|
-
|
|
115
|
+
widget = nodes['filter.ctx.label'].parentWidget()
|
|
116
|
+
nodes['filter.ctx.label'].setText(trans("filter.ctx.label"))
|
|
117
|
+
nodes['filter.ctx.radio.all'].setText(trans("filter.ctx.radio.all"))
|
|
118
|
+
nodes['filter.ctx.radio.pinned'].setText(trans("filter.ctx.radio.pinned"))
|
|
119
|
+
nodes['filter.ctx.radio.indexed'].setText(trans("filter.ctx.radio.indexed"))
|
|
120
|
+
nodes['filter.ctx.counters.all'].setText(trans("filter.ctx.counters.all"))
|
|
121
|
+
|
|
122
|
+
desired = bool(self.window.core.config.get("ctx.counters.all"))
|
|
123
|
+
if nodes['filter.ctx.counters.all'].isChecked() != desired:
|
|
124
|
+
nodes['filter.ctx.counters.all'].setChecked(desired)
|
|
125
|
+
|
|
126
|
+
widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
104
127
|
return widget
|
|
105
128
|
|
|
106
129
|
def setup_calendar(self) -> QWidget:
|
|
@@ -109,22 +132,32 @@ class Calendar:
|
|
|
109
132
|
|
|
110
133
|
:return: QSplitter
|
|
111
134
|
"""
|
|
112
|
-
|
|
135
|
+
ui = self.window.ui
|
|
136
|
+
nodes = ui.nodes
|
|
137
|
+
calendar = ui.calendar
|
|
138
|
+
|
|
113
139
|
select_layout = QVBoxLayout()
|
|
114
|
-
|
|
115
|
-
self.window.ui.calendar['select'].setMinimumWidth(200)
|
|
116
|
-
self.window.ui.calendar['select'].setGridVisible(True)
|
|
117
|
-
select_layout.addWidget(self.window.ui.calendar['select'])
|
|
140
|
+
select_layout.addWidget(calendar['select'])
|
|
118
141
|
select_layout.setContentsMargins(5, 0, 5, 0)
|
|
119
142
|
|
|
120
|
-
|
|
143
|
+
tip = nodes.get('tip.output.tab.calendar')
|
|
144
|
+
if tip is None:
|
|
145
|
+
tip = HelpLabel(trans('tip.output.tab.calendar'), self.window)
|
|
146
|
+
nodes['tip.output.tab.calendar'] = tip
|
|
147
|
+
else:
|
|
148
|
+
tip.setText(trans('tip.output.tab.calendar'))
|
|
149
|
+
|
|
150
|
+
note_label = calendar.get('note.label')
|
|
151
|
+
if note_label is None:
|
|
152
|
+
note_label = QLabel(trans('calendar.note.label'))
|
|
153
|
+
calendar['note.label'] = note_label
|
|
154
|
+
else:
|
|
155
|
+
note_label.setText(trans('calendar.note.label'))
|
|
121
156
|
|
|
122
|
-
# note
|
|
123
|
-
self.window.ui.calendar['note.label'] = QLabel(trans('calendar.note.label'))
|
|
124
157
|
layout = QVBoxLayout()
|
|
125
|
-
layout.addWidget(
|
|
126
|
-
layout.addWidget(
|
|
127
|
-
layout.addWidget(
|
|
158
|
+
layout.addWidget(note_label)
|
|
159
|
+
layout.addWidget(calendar['note'])
|
|
160
|
+
layout.addWidget(tip)
|
|
128
161
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
129
162
|
|
|
130
163
|
widget = QWidget()
|
|
@@ -136,16 +169,13 @@ class Calendar:
|
|
|
136
169
|
select_widget = QWidget()
|
|
137
170
|
select_widget.setLayout(select_layout)
|
|
138
171
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
self.window.ui.splitters['calendar'].setStretchFactor(1, 4) # 40%
|
|
172
|
+
ui.splitters['calendar'] = QSplitter(Qt.Horizontal)
|
|
173
|
+
ui.splitters['calendar'].addWidget(select_widget)
|
|
174
|
+
ui.splitters['calendar'].addWidget(widget)
|
|
175
|
+
ui.splitters['calendar'].setStretchFactor(0, 6)
|
|
176
|
+
ui.splitters['calendar'].setStretchFactor(1, 4)
|
|
145
177
|
|
|
146
|
-
|
|
178
|
+
ui.splitters['calendar'].setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
|
147
179
|
filters.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
148
180
|
|
|
149
|
-
|
|
150
|
-
return self.window.core.tabs.from_widget(self.window.ui.splitters['calendar'])
|
|
151
|
-
|
|
181
|
+
return self.window.core.tabs.from_widget(ui.splitters['calendar'])
|
pygpt_net/ui/layout/chat/chat.py
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
|
-
from PySide6.QtCore import Qt
|
|
12
|
+
from PySide6.QtCore import Qt, Slot
|
|
13
13
|
from PySide6.QtWidgets import QSplitter
|
|
14
14
|
|
|
15
15
|
from pygpt_net.ui.layout.chat.input import Input
|
|
@@ -34,28 +34,34 @@ class ChatMain:
|
|
|
34
34
|
:return: QSplitter
|
|
35
35
|
:rtype: QSplitter
|
|
36
36
|
"""
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
input_widget = self.input.setup()
|
|
38
|
+
output_widget = self.output.setup()
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
self.window.ui.splitters['main.output'] =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
self.window.controller.ui.splitter_output_size_input =
|
|
40
|
+
splitter = QSplitter(Qt.Vertical)
|
|
41
|
+
self.window.ui.splitters['main.output'] = splitter
|
|
42
|
+
splitter.addWidget(output_widget)
|
|
43
|
+
splitter.addWidget(input_widget)
|
|
44
|
+
splitter.setStretchFactor(0, 9) # Output widget stretch factor
|
|
45
|
+
splitter.setStretchFactor(1, 1) # Input widget stretch factor
|
|
46
|
+
splitter.splitterMoved.connect(self.on_splitter_moved)
|
|
47
|
+
self.window.controller.ui.splitter_output_size_input = splitter.sizes()
|
|
48
48
|
|
|
49
|
-
return
|
|
49
|
+
return splitter
|
|
50
50
|
|
|
51
|
+
@Slot(int, int)
|
|
51
52
|
def on_splitter_moved(self, pos, index):
|
|
52
53
|
"""
|
|
53
54
|
Store the size of the output splitter when it is moved
|
|
54
55
|
"""
|
|
55
|
-
|
|
56
|
+
tabs = self.window.ui.tabs
|
|
57
|
+
if "input" not in tabs:
|
|
56
58
|
return
|
|
57
|
-
|
|
59
|
+
splitter = self.window.ui.splitters.get('main.output')
|
|
60
|
+
if splitter is None:
|
|
61
|
+
return
|
|
62
|
+
idx = tabs['input'].currentIndex()
|
|
63
|
+
sizes = splitter.sizes()
|
|
58
64
|
if idx != 0:
|
|
59
|
-
self.window.controller.ui.splitter_output_size_files =
|
|
65
|
+
self.window.controller.ui.splitter_output_size_files = sizes
|
|
60
66
|
else:
|
|
61
|
-
self.window.controller.ui.splitter_output_size_input =
|
|
67
|
+
self.window.controller.ui.splitter_output_size_input = sizes
|