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.
Files changed (144) hide show
  1. pygpt_net/CHANGELOG.txt +4 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +3 -1
  4. pygpt_net/controller/__init__.py +4 -8
  5. pygpt_net/controller/access/voice.py +2 -2
  6. pygpt_net/controller/assistant/batch.py +2 -3
  7. pygpt_net/controller/assistant/editor.py +2 -2
  8. pygpt_net/controller/assistant/files.py +2 -3
  9. pygpt_net/controller/assistant/store.py +2 -2
  10. pygpt_net/controller/audio/audio.py +2 -2
  11. pygpt_net/controller/ctx/ctx.py +2 -1
  12. pygpt_net/controller/idx/indexer.py +85 -76
  13. pygpt_net/controller/lang/lang.py +52 -34
  14. pygpt_net/controller/model/importer.py +2 -2
  15. pygpt_net/controller/notepad/notepad.py +86 -84
  16. pygpt_net/controller/plugins/settings.py +3 -4
  17. pygpt_net/controller/settings/profile.py +105 -124
  18. pygpt_net/controller/theme/menu.py +154 -57
  19. pygpt_net/controller/theme/nodes.py +51 -44
  20. pygpt_net/controller/theme/theme.py +33 -9
  21. pygpt_net/controller/tools/tools.py +2 -2
  22. pygpt_net/controller/ui/tabs.py +2 -3
  23. pygpt_net/core/ctx/container.py +13 -12
  24. pygpt_net/core/ctx/output.py +7 -4
  25. pygpt_net/core/debug/console/console.py +2 -2
  26. pygpt_net/core/filesystem/actions.py +1 -2
  27. pygpt_net/core/render/plain/helpers.py +2 -5
  28. pygpt_net/core/render/plain/renderer.py +26 -30
  29. pygpt_net/core/render/web/body.py +1 -1
  30. pygpt_net/core/settings/settings.py +43 -13
  31. pygpt_net/core/tabs/tabs.py +20 -13
  32. pygpt_net/data/config/config.json +4 -4
  33. pygpt_net/data/config/models.json +3 -3
  34. pygpt_net/data/locale/locale.de.ini +4 -1
  35. pygpt_net/data/locale/locale.en.ini +4 -1
  36. pygpt_net/data/locale/locale.es.ini +4 -1
  37. pygpt_net/data/locale/locale.fr.ini +4 -1
  38. pygpt_net/data/locale/locale.it.ini +4 -1
  39. pygpt_net/data/locale/locale.pl.ini +5 -4
  40. pygpt_net/data/locale/locale.uk.ini +4 -1
  41. pygpt_net/data/locale/locale.zh.ini +4 -1
  42. pygpt_net/plugin/twitter/plugin.py +2 -2
  43. pygpt_net/tools/audio_transcriber/ui/dialogs.py +44 -54
  44. pygpt_net/tools/code_interpreter/body.py +1 -2
  45. pygpt_net/tools/code_interpreter/tool.py +7 -4
  46. pygpt_net/tools/code_interpreter/ui/html.py +1 -3
  47. pygpt_net/tools/code_interpreter/ui/widgets.py +2 -3
  48. pygpt_net/tools/html_canvas/ui/widgets.py +1 -3
  49. pygpt_net/tools/image_viewer/ui/dialogs.py +40 -37
  50. pygpt_net/tools/indexer/ui/widgets.py +2 -4
  51. pygpt_net/tools/media_player/tool.py +2 -5
  52. pygpt_net/tools/media_player/ui/widgets.py +60 -36
  53. pygpt_net/tools/text_editor/ui/widgets.py +18 -19
  54. pygpt_net/tools/translator/ui/widgets.py +39 -35
  55. pygpt_net/ui/base/context_menu.py +9 -4
  56. pygpt_net/ui/dialog/db.py +1 -3
  57. pygpt_net/ui/dialog/models.py +1 -3
  58. pygpt_net/ui/dialog/models_importer.py +2 -4
  59. pygpt_net/ui/dialogs.py +34 -30
  60. pygpt_net/ui/layout/chat/attachments.py +72 -84
  61. pygpt_net/ui/layout/chat/attachments_ctx.py +40 -44
  62. pygpt_net/ui/layout/chat/attachments_uploaded.py +36 -39
  63. pygpt_net/ui/layout/chat/calendar.py +100 -70
  64. pygpt_net/ui/layout/chat/chat.py +23 -17
  65. pygpt_net/ui/layout/chat/input.py +95 -118
  66. pygpt_net/ui/layout/chat/output.py +100 -162
  67. pygpt_net/ui/layout/chat/painter.py +89 -61
  68. pygpt_net/ui/layout/ctx/ctx_list.py +43 -52
  69. pygpt_net/ui/layout/status.py +23 -14
  70. pygpt_net/ui/layout/toolbox/agent.py +27 -38
  71. pygpt_net/ui/layout/toolbox/agent_llama.py +42 -45
  72. pygpt_net/ui/layout/toolbox/assistants.py +42 -38
  73. pygpt_net/ui/layout/toolbox/computer_env.py +32 -23
  74. pygpt_net/ui/layout/toolbox/footer.py +13 -16
  75. pygpt_net/ui/layout/toolbox/image.py +18 -21
  76. pygpt_net/ui/layout/toolbox/indexes.py +46 -89
  77. pygpt_net/ui/layout/toolbox/mode.py +20 -7
  78. pygpt_net/ui/layout/toolbox/model.py +12 -10
  79. pygpt_net/ui/layout/toolbox/presets.py +68 -52
  80. pygpt_net/ui/layout/toolbox/prompt.py +31 -58
  81. pygpt_net/ui/layout/toolbox/toolbox.py +25 -21
  82. pygpt_net/ui/layout/toolbox/vision.py +20 -22
  83. pygpt_net/ui/main.py +2 -4
  84. pygpt_net/ui/menu/about.py +64 -84
  85. pygpt_net/ui/menu/audio.py +87 -63
  86. pygpt_net/ui/menu/config.py +121 -127
  87. pygpt_net/ui/menu/debug.py +69 -76
  88. pygpt_net/ui/menu/file.py +32 -35
  89. pygpt_net/ui/menu/menu.py +2 -3
  90. pygpt_net/ui/menu/plugins.py +69 -33
  91. pygpt_net/ui/menu/theme.py +45 -46
  92. pygpt_net/ui/menu/tools.py +56 -60
  93. pygpt_net/ui/menu/video.py +20 -25
  94. pygpt_net/ui/tray.py +1 -2
  95. pygpt_net/ui/widget/audio/bar.py +1 -3
  96. pygpt_net/ui/widget/audio/input_button.py +3 -4
  97. pygpt_net/ui/widget/calendar/select.py +1 -2
  98. pygpt_net/ui/widget/dialog/base.py +12 -9
  99. pygpt_net/ui/widget/dialog/editor_file.py +20 -23
  100. pygpt_net/ui/widget/dialog/find.py +25 -24
  101. pygpt_net/ui/widget/dialog/profile.py +57 -53
  102. pygpt_net/ui/widget/draw/painter.py +62 -93
  103. pygpt_net/ui/widget/element/button.py +42 -30
  104. pygpt_net/ui/widget/element/checkbox.py +23 -15
  105. pygpt_net/ui/widget/element/group.py +6 -5
  106. pygpt_net/ui/widget/element/labels.py +1 -2
  107. pygpt_net/ui/widget/filesystem/explorer.py +93 -102
  108. pygpt_net/ui/widget/image/display.py +1 -2
  109. pygpt_net/ui/widget/lists/assistant.py +1 -2
  110. pygpt_net/ui/widget/lists/attachment.py +1 -2
  111. pygpt_net/ui/widget/lists/attachment_ctx.py +1 -2
  112. pygpt_net/ui/widget/lists/context.py +2 -4
  113. pygpt_net/ui/widget/lists/index.py +1 -2
  114. pygpt_net/ui/widget/lists/model.py +1 -2
  115. pygpt_net/ui/widget/lists/model_editor.py +1 -2
  116. pygpt_net/ui/widget/lists/model_importer.py +1 -2
  117. pygpt_net/ui/widget/lists/preset.py +1 -2
  118. pygpt_net/ui/widget/lists/preset_plugins.py +1 -2
  119. pygpt_net/ui/widget/lists/profile.py +1 -2
  120. pygpt_net/ui/widget/lists/uploaded.py +1 -2
  121. pygpt_net/ui/widget/option/checkbox.py +2 -4
  122. pygpt_net/ui/widget/option/checkbox_list.py +1 -4
  123. pygpt_net/ui/widget/option/cmd.py +1 -4
  124. pygpt_net/ui/widget/option/dictionary.py +25 -28
  125. pygpt_net/ui/widget/option/input.py +1 -3
  126. pygpt_net/ui/widget/tabs/Input.py +16 -12
  127. pygpt_net/ui/widget/tabs/body.py +5 -3
  128. pygpt_net/ui/widget/tabs/layout.py +36 -25
  129. pygpt_net/ui/widget/tabs/output.py +96 -74
  130. pygpt_net/ui/widget/textarea/calendar_note.py +1 -2
  131. pygpt_net/ui/widget/textarea/editor.py +41 -73
  132. pygpt_net/ui/widget/textarea/find.py +11 -10
  133. pygpt_net/ui/widget/textarea/html.py +3 -6
  134. pygpt_net/ui/widget/textarea/input.py +63 -64
  135. pygpt_net/ui/widget/textarea/notepad.py +54 -38
  136. pygpt_net/ui/widget/textarea/output.py +65 -54
  137. pygpt_net/ui/widget/textarea/search_input.py +5 -4
  138. pygpt_net/ui/widget/textarea/web.py +2 -4
  139. pygpt_net/ui/widget/vision/camera.py +2 -31
  140. {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/METADATA +15 -151
  141. {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/RECORD +144 -144
  142. {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/LICENSE +0 -0
  143. {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/WHEEL +0 -0
  144. {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: 2025.08.16 00:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import datetime
@@ -14,13 +14,11 @@ import functools
14
14
 
15
15
  from PySide6 import QtWidgets, QtCore, QtGui
16
16
  from PySide6.QtCore import Qt, QPoint, QItemSelectionModel
17
- from PySide6.QtGui import QAction, QIcon, QColor, QPixmap, QStandardItem
17
+ from PySide6.QtGui import QIcon, QColor, QPixmap, QStandardItem
18
18
  from PySide6.QtWidgets import QMenu
19
- from overrides import overrides
20
19
 
21
20
  from pygpt_net.ui.widget.lists.base import BaseList
22
21
  from pygpt_net.utils import trans
23
- import pygpt_net.icons_rc
24
22
 
25
23
 
26
24
  class ContextList(BaseList):
@@ -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: 2024.01.31 18:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QAction, QIcon
@@ -14,7 +14,6 @@ from PySide6.QtWidgets import QMenu
14
14
 
15
15
  from pygpt_net.ui.widget.lists.base import BaseList
16
16
  from pygpt_net.utils import trans
17
- import pygpt_net.icons_rc
18
17
 
19
18
 
20
19
  class IndexList(BaseList):
@@ -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: 2024.01.29 14:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QAction, QIcon
@@ -14,7 +14,6 @@ from PySide6.QtWidgets import QMenu
14
14
 
15
15
  from pygpt_net.ui.widget.lists.base import BaseList
16
16
  from pygpt_net.utils import trans
17
- import pygpt_net.icons_rc
18
17
 
19
18
 
20
19
  class ModelList(BaseList):
@@ -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.07.12 19:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QAction, QIcon
@@ -14,7 +14,6 @@ from PySide6.QtWidgets import QMenu
14
14
 
15
15
  from pygpt_net.ui.widget.lists.base import BaseList
16
16
  from pygpt_net.utils import trans
17
- import pygpt_net.icons_rc
18
17
 
19
18
 
20
19
  class ModelEditorList(BaseList):
@@ -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.02 20:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6 import QtCore
@@ -15,7 +15,6 @@ from PySide6.QtWidgets import QWidget, QHBoxLayout, QPushButton, QVBoxLayout, QL
15
15
 
16
16
  from pygpt_net.ui.widget.lists.base import BaseList
17
17
  from pygpt_net.utils import trans
18
- import pygpt_net.icons_rc
19
18
 
20
19
  class ModelImporter(QWidget):
21
20
  def __init__(self, window=None):
@@ -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.15 03:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import QPoint, QItemSelectionModel
@@ -18,7 +18,6 @@ from pygpt_net.core.types import (
18
18
  )
19
19
  from pygpt_net.ui.widget.lists.base import BaseList
20
20
  from pygpt_net.utils import trans
21
- import pygpt_net.icons_rc
22
21
 
23
22
 
24
23
  class PresetList(BaseList):
@@ -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: 2024.03.06 22:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QAction, QIcon
@@ -14,7 +14,6 @@ from PySide6.QtWidgets import QMenu
14
14
 
15
15
  from pygpt_net.ui.widget.lists.base import BaseList
16
16
  from pygpt_net.utils import trans
17
- import pygpt_net.icons_rc
18
17
 
19
18
 
20
19
  class PresetPluginsList(BaseList):
@@ -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: 2024.04.09 23:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QAction, QIcon
@@ -14,7 +14,6 @@ from PySide6.QtWidgets import QMenu
14
14
 
15
15
  from pygpt_net.ui.widget.lists.base import BaseList
16
16
  from pygpt_net.utils import trans
17
- import pygpt_net.icons_rc
18
17
 
19
18
 
20
19
  class ProfileList(BaseList):
@@ -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: 2024.04.26 23:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QAction, QIcon, QResizeEvent, Qt
@@ -14,7 +14,6 @@ from PySide6.QtWidgets import QMenu
14
14
 
15
15
  from pygpt_net.ui.widget.lists.base import BaseList
16
16
  from pygpt_net.utils import trans
17
- import pygpt_net.icons_rc
18
17
 
19
18
 
20
19
  class UploadedFileList(BaseList):
@@ -6,17 +6,15 @@
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.22 10:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QIcon
13
- from PySide6.QtWidgets import QCheckBox, QHBoxLayout, QWidget, QLabel
13
+ from PySide6.QtWidgets import QHBoxLayout, QWidget, QLabel
14
14
 
15
15
  from pygpt_net.ui.widget.anims.toggles import AnimToggle
16
16
  from pygpt_net.utils import trans
17
17
 
18
- import pygpt_net.icons_rc
19
-
20
18
  class OptionCheckbox(QWidget):
21
19
  def __init__(
22
20
  self,
@@ -6,17 +6,14 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.06.30 02:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
- from typing import Dict
12
11
 
13
12
  from PySide6.QtWidgets import QCheckBox, QWidget
14
13
 
15
14
  from pygpt_net.ui.base.flow_layout import FlowLayout
16
15
  from pygpt_net.utils import trans
17
16
 
18
- import pygpt_net.icons_rc
19
-
20
17
  class OptionCheckboxList(QWidget):
21
18
  def __init__(
22
19
  self,
@@ -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: 2024.11.24 22:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QIcon
@@ -19,9 +19,6 @@ from pygpt_net.ui.widget.option.dictionary import OptionDict
19
19
  from pygpt_net.ui.widget.option.textarea import OptionTextarea
20
20
  from pygpt_net.utils import trans
21
21
 
22
- import pygpt_net.icons_rc
23
-
24
-
25
22
  class OptionCmd(QWidget):
26
23
  def __init__(
27
24
  self,
@@ -6,17 +6,15 @@
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.07.18 19:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt, QAbstractItemModel, QModelIndex, QSize
13
- from PySide6.QtGui import QAction, QIcon
13
+ from PySide6.QtGui import QIcon
14
14
  from PySide6.QtWidgets import QWidget, QVBoxLayout, QPushButton, QTreeView, QMenu, QStyledItemDelegate, QComboBox, \
15
15
  QCheckBox, QHeaderView, QHBoxLayout
16
16
 
17
17
  from pygpt_net.utils import trans
18
- import pygpt_net.icons_rc
19
-
20
18
 
21
19
  class OptionDict(QWidget):
22
20
  def __init__(self, window=None, parent_id: str = None, id: str = None, option: dict = None):
@@ -112,8 +110,7 @@ class OptionDict(QWidget):
112
110
  if index.isValid():
113
111
  idx = index.row()
114
112
  data = self.model.items[idx]
115
- id = self.parent_id + "." + self.id # dictionary id
116
- self.window.ui.dialogs.open_dictionary_editor(id, self.option, data, idx)
113
+ self.window.ui.dialogs.open_dictionary_editor(f"{self.parent_id}.{self.id}", self.option, data, idx)
117
114
 
118
115
  def update_item(self, idx, data):
119
116
  """
@@ -194,20 +191,26 @@ class OptionDictItems(QTreeView):
194
191
  header.setStretchLastSection(True)
195
192
  header.setSectionResizeMode(QHeaderView.Stretch)
196
193
 
197
- # setup fields
194
+ self._icon_edit = QIcon(":/icons/edit.svg")
195
+ self._icon_delete = QIcon(":/icons/delete.svg")
196
+ self._act_edit_text = trans('action.edit')
197
+ self._act_delete_text = trans('action.delete')
198
+ self._bool_delegate = None
199
+
198
200
  keys = self.parent.keys
201
+ set_delegate_col = self.setItemDelegateForColumn
199
202
  idx = 0
200
203
  for key in keys:
201
204
  item = keys[key]
202
205
  if type(item) is dict:
203
- if "type" in item:
204
- if item["type"] == "combo":
205
- handler = ComboBoxDelegate(self, item["keys"])
206
- self.setItemDelegateForColumn(idx, handler)
206
+ t = item.get("type")
207
+ if t == "combo":
208
+ set_delegate_col(idx, ComboBoxDelegate(self, item["keys"]))
207
209
  elif type(item) is str:
208
210
  if item == "bool":
209
- handler = CheckBoxDelegate(self)
210
- self.setItemDelegateForColumn(idx, handler)
211
+ if self._bool_delegate is None:
212
+ self._bool_delegate = CheckBoxDelegate(self)
213
+ set_delegate_col(idx, self._bool_delegate)
211
214
  elif item == "hidden":
212
215
  continue
213
216
  idx += 1
@@ -218,22 +221,16 @@ class OptionDictItems(QTreeView):
218
221
 
219
222
  :param event: context menu event
220
223
  """
221
- actions = {}
222
- actions['edit'] = QAction(QIcon(":/icons/edit.svg"), trans('action.edit'), self)
223
- actions['edit'].triggered.connect(
224
- lambda: self.parent.edit_item(event))
225
- actions['delete'] = QAction(QIcon(":/icons/delete.svg"), trans('action.delete'), self)
226
- actions['delete'].triggered.connect(
227
- lambda: self.parent.delete_item(event))
228
- menu = QMenu(self)
229
- menu.addAction(actions['edit'])
230
- menu.addAction(actions['delete'])
231
-
232
- # get index of item
233
224
  item = self.indexAt(event.pos())
234
- idx = item.row()
235
- if idx >= 0:
236
- menu.exec_(event.globalPos())
225
+ if not item.isValid():
226
+ return
227
+
228
+ menu = QMenu(self)
229
+ edit_action = menu.addAction(self._icon_edit, self._act_edit_text)
230
+ delete_action = menu.addAction(self._icon_delete, self._act_delete_text)
231
+ edit_action.triggered.connect(lambda: self.parent.edit_item(event))
232
+ delete_action.triggered.connect(lambda: self.parent.delete_item(event))
233
+ menu.exec_(event.globalPos())
237
234
 
238
235
 
239
236
  class OptionDictModel(QAbstractItemModel):
@@ -6,13 +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: 2024.04.26 23:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
- from PySide6.QtCore import Qt
13
12
  from PySide6.QtGui import QAction, QIcon
14
13
  from PySide6.QtWidgets import QLineEdit, QFileDialog
15
- import pygpt_net.icons_rc
16
14
 
17
15
 
18
16
  class OptionInputInline(QLineEdit):
@@ -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: 2024.12.09 23:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtWidgets import QTabWidget, QMenu
@@ -14,13 +14,17 @@ from PySide6.QtCore import Qt
14
14
  from PySide6.QtGui import QAction, QIcon
15
15
 
16
16
  from pygpt_net.utils import trans
17
- import pygpt_net.icons_rc
18
17
 
19
18
 
20
19
  class InputTabs(QTabWidget):
21
20
  def __init__(self, window=None):
22
- super(InputTabs, self).__init__(window)
21
+ super().__init__(window)
23
22
  self.window = window
23
+ self._attachments_tab_index = 1
24
+ self._context_menu = QMenu(self)
25
+ self._action_clear = QAction(QIcon(":/icons/delete.svg"), trans('attachments.btn.clear'), self)
26
+ self._action_clear.triggered.connect(self._on_clear_triggered)
27
+ self._context_menu.addAction(self._action_clear)
24
28
 
25
29
  def mousePressEvent(self, event):
26
30
  """
@@ -29,10 +33,12 @@ class InputTabs(QTabWidget):
29
33
  :param event: QMouseEvent
30
34
  """
31
35
  if event.button() == Qt.RightButton:
32
- if self.tabBar().tabAt(event.pos()) == 1: # attachments tab
36
+ tb = self.tabBar()
37
+ pos_in_tabbar = tb.mapFrom(self, event.pos())
38
+ if tb.tabAt(pos_in_tabbar) == self._attachments_tab_index:
33
39
  self.show_context_menu(event.globalPos())
34
40
 
35
- super(InputTabs, self).mousePressEvent(event)
41
+ super().mousePressEvent(event)
36
42
 
37
43
  def show_context_menu(self, global_pos):
38
44
  """
@@ -40,10 +46,8 @@ class InputTabs(QTabWidget):
40
46
 
41
47
  :param global_pos: QPoint
42
48
  """
43
- context_menu = QMenu(self)
44
- actions = {}
45
- actions['clear'] = QAction(QIcon(":/icons/delete.svg"), trans('attachments.btn.clear'), self)
46
- actions['clear'].triggered.connect(
47
- lambda: self.window.controller.attachment.clear())
48
- context_menu.addAction(actions['clear'])
49
- context_menu.exec(global_pos)
49
+ self._action_clear.setText(trans('attachments.btn.clear'))
50
+ self._context_menu.exec(global_pos)
51
+
52
+ def _on_clear_triggered(self, checked=False):
53
+ self.window.controller.attachment.clear()
@@ -6,8 +6,9 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.08.05 21:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
+
11
12
  from typing import Any
12
13
 
13
14
  from PySide6.QtCore import QEvent
@@ -104,12 +105,13 @@ class TabBody(QTabWidget):
104
105
  :param source: source
105
106
  :param event: event
106
107
  """
107
- if (event.type() == QEvent.ChildAdded and
108
+ t = event.type()
109
+ if (t == QEvent.ChildAdded and
108
110
  source is self and
109
111
  event.child().isWidgetType()):
110
112
  self._glwidget = event.child()
111
113
  self._glwidget.installEventFilter(self)
112
- elif (event.type() == event.Type.MouseButtonPress):
114
+ elif t == event.Type.MouseButtonPress:
113
115
  # handle column focus
114
116
  if self.owner is not None:
115
117
  col_idx = self.owner.column_idx
@@ -6,9 +6,12 @@
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.07.13 15:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
+ from typing import Optional
13
+ import weakref
14
+
12
15
  from PySide6.QtCore import Qt, QObject, QEvent
13
16
  from PySide6.QtWidgets import QTabWidget, QWidget, QVBoxLayout, QSplitter, QSizePolicy
14
17
 
@@ -41,7 +44,8 @@ class OutputColumn(QWidget):
41
44
  :param widget: widget
42
45
  """
43
46
  self.window.controller.ui.tabs.on_column_focus(self.idx)
44
- widget.setFocus()
47
+ if widget is not None and not widget.hasFocus():
48
+ widget.setFocus()
45
49
 
46
50
  def set_idx(self, idx: int):
47
51
  """
@@ -112,9 +116,9 @@ class OutputLayout(QWidget):
112
116
  :param pos: Position of the splitter
113
117
  :param index: Index of the widget that was moved
114
118
  """
115
- widget = self.splitter.widget(1)
116
- if widget:
117
- current_width = widget.width()
119
+ if self.splitter.count() > 1:
120
+ sizes = self.splitter.sizes()
121
+ current_width = sizes[1] if len(sizes) > 1 else 0
118
122
  if current_width == 0:
119
123
  if self._was_width_zero is not True:
120
124
  self._was_width_zero = True
@@ -142,17 +146,15 @@ class OutputLayout(QWidget):
142
146
  column.set_idx(idx)
143
147
  self.columns.append(column)
144
148
 
145
- def get_tabs_by_idx(self, idx: int) -> OutputTabs:
149
+ def get_tabs_by_idx(self, idx: int) -> Optional[OutputTabs]:
146
150
  """
147
151
  Get tabs by column index
148
152
 
149
153
  :param idx: int
150
154
  :return: OutputTabs
151
155
  """
152
- for column in self.columns:
153
- if column.idx == idx:
154
- return column.tabs
155
- return None
156
+ column = self.get_column_by_idx(idx)
157
+ return column.tabs if column is not None else None
156
158
 
157
159
  def get_active_tabs(self) -> OutputTabs:
158
160
  """
@@ -161,17 +163,21 @@ class OutputLayout(QWidget):
161
163
  :return: OutputTabs
162
164
  """
163
165
  current = self.window.controller.ui.tabs.get_current_column_idx()
164
- for column in self.columns:
165
- if column.idx == current:
166
- return column.tabs
166
+ column = self.get_column_by_idx(current)
167
+ if column is not None:
168
+ return column.tabs
167
169
 
168
- def get_column_by_idx(self, idx: int) -> OutputColumn:
170
+ def get_column_by_idx(self, idx: int) -> Optional[OutputColumn]:
169
171
  """
170
172
  Get column by index
171
173
 
172
174
  :param idx: int
173
175
  :return: OutputColumn
174
176
  """
177
+ if 0 <= idx < len(self.columns):
178
+ column = self.columns[idx]
179
+ if column.idx == idx:
180
+ return column
175
181
  for column in self.columns:
176
182
  if column.idx == idx:
177
183
  return column
@@ -184,9 +190,8 @@ class OutputLayout(QWidget):
184
190
  :return: OutputColumn
185
191
  """
186
192
  current = self.window.controller.ui.tabs.get_current_column_idx()
187
- for column in self.columns:
188
- if column.idx == current:
189
- return column
193
+ return self.get_column_by_idx(current)
194
+
190
195
 
191
196
  class FocusEventFilter(QObject):
192
197
  def __init__(self, column, callback):
@@ -196,9 +201,9 @@ class FocusEventFilter(QObject):
196
201
  :param column: parent column
197
202
  :param callback: callback
198
203
  """
199
- super().__init__()
200
- self.column = column
201
- self.callback = callback
204
+ super().__init__(column)
205
+ self._column_ref = weakref.ref(column)
206
+ self._callback = weakref.WeakMethod(callback) if hasattr(callback, "__self__") and callback.__self__ is not None else callback
202
207
 
203
208
  def eventFilter(self, obj, event):
204
209
  """
@@ -207,9 +212,15 @@ class FocusEventFilter(QObject):
207
212
  :param obj: object
208
213
  :param event: event
209
214
  """
210
- if event.type() == QEvent.MouseButtonPress or event.type() == QEvent.FocusIn:
211
- widget = obj
212
- if widget is not None:
213
- self.callback(widget)
215
+ t = event.type()
216
+ if t in (QEvent.MouseButtonPress, QEvent.FocusIn):
217
+ col = self._column_ref()
218
+ if col is not None:
219
+ if isinstance(self._callback, weakref.WeakMethod):
220
+ cb = self._callback()
221
+ else:
222
+ cb = self._callback
223
+ if cb is not None:
224
+ cb(obj)
214
225
  return False
215
- return False
226
+ return False