pygpt-net 2.4.30__py3-none-any.whl → 2.4.35__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 (135) hide show
  1. CHANGELOG.md +32 -0
  2. README.md +2105 -1892
  3. pygpt_net/CHANGELOG.txt +32 -0
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/controller/access/__init__.py +5 -5
  6. pygpt_net/controller/access/control.py +3 -2
  7. pygpt_net/controller/attachment.py +68 -1
  8. pygpt_net/controller/audio/__init__.py +34 -6
  9. pygpt_net/controller/chat/__init__.py +3 -1
  10. pygpt_net/controller/chat/attachment.py +263 -38
  11. pygpt_net/controller/chat/audio.py +99 -0
  12. pygpt_net/controller/chat/input.py +10 -3
  13. pygpt_net/controller/chat/output.py +4 -1
  14. pygpt_net/controller/chat/text.py +7 -3
  15. pygpt_net/controller/dialogs/confirm.py +17 -1
  16. pygpt_net/controller/lang/custom.py +3 -1
  17. pygpt_net/controller/mode.py +2 -1
  18. pygpt_net/controller/painter/capture.py +2 -2
  19. pygpt_net/controller/presets/editor.py +15 -2
  20. pygpt_net/controller/ui/__init__.py +4 -1
  21. pygpt_net/core/access/voice.py +2 -2
  22. pygpt_net/core/agents/legacy.py +3 -1
  23. pygpt_net/core/attachments/__init__.py +14 -9
  24. pygpt_net/core/attachments/context.py +226 -44
  25. pygpt_net/core/{audio.py → audio/__init__.py} +1 -1
  26. pygpt_net/core/audio/context.py +34 -0
  27. pygpt_net/core/bridge/context.py +29 -1
  28. pygpt_net/core/ctx/__init__.py +4 -1
  29. pygpt_net/core/db/__init__.py +4 -2
  30. pygpt_net/core/debug/attachments.py +3 -1
  31. pygpt_net/core/debug/context.py +5 -1
  32. pygpt_net/core/debug/presets.py +3 -1
  33. pygpt_net/core/events/event.py +2 -1
  34. pygpt_net/core/experts/__init__.py +3 -1
  35. pygpt_net/core/idx/chat.py +28 -6
  36. pygpt_net/core/idx/indexing.py +123 -15
  37. pygpt_net/core/modes.py +3 -1
  38. pygpt_net/core/presets.py +13 -2
  39. pygpt_net/core/render/markdown/pid.py +2 -1
  40. pygpt_net/core/render/plain/pid.py +2 -1
  41. pygpt_net/core/render/web/body.py +34 -12
  42. pygpt_net/core/render/web/pid.py +2 -1
  43. pygpt_net/core/render/web/renderer.py +8 -3
  44. pygpt_net/core/tokens.py +4 -2
  45. pygpt_net/core/types/mode.py +2 -1
  46. pygpt_net/data/config/config.json +7 -5
  47. pygpt_net/data/config/models.json +190 -5
  48. pygpt_net/data/config/modes.json +11 -5
  49. pygpt_net/data/config/presets/current.audio.json +34 -0
  50. pygpt_net/data/config/settings.json +15 -1
  51. pygpt_net/data/css/web.css +70 -0
  52. pygpt_net/data/css/web.dark.css +4 -1
  53. pygpt_net/data/css/web.light.css +1 -1
  54. pygpt_net/data/locale/locale.de.ini +27 -14
  55. pygpt_net/data/locale/locale.en.ini +63 -47
  56. pygpt_net/data/locale/locale.es.ini +27 -14
  57. pygpt_net/data/locale/locale.fr.ini +29 -16
  58. pygpt_net/data/locale/locale.it.ini +27 -14
  59. pygpt_net/data/locale/locale.pl.ini +31 -18
  60. pygpt_net/data/locale/locale.uk.ini +27 -14
  61. pygpt_net/data/locale/locale.zh.ini +34 -21
  62. pygpt_net/data/locale/plugin.cmd_files.de.ini +4 -4
  63. pygpt_net/data/locale/plugin.cmd_files.en.ini +4 -4
  64. pygpt_net/data/locale/plugin.cmd_files.es.ini +4 -4
  65. pygpt_net/data/locale/plugin.cmd_files.fr.ini +4 -4
  66. pygpt_net/data/locale/plugin.cmd_files.it.ini +4 -4
  67. pygpt_net/data/locale/plugin.cmd_files.pl.ini +4 -4
  68. pygpt_net/data/locale/plugin.cmd_files.uk.ini +4 -4
  69. pygpt_net/data/locale/plugin.cmd_files.zh.ini +4 -4
  70. pygpt_net/data/locale/plugin.cmd_web.de.ini +5 -5
  71. pygpt_net/data/locale/plugin.cmd_web.en.ini +5 -5
  72. pygpt_net/data/locale/plugin.cmd_web.es.ini +5 -5
  73. pygpt_net/data/locale/plugin.cmd_web.fr.ini +5 -5
  74. pygpt_net/data/locale/plugin.cmd_web.it.ini +5 -5
  75. pygpt_net/data/locale/plugin.cmd_web.pl.ini +5 -5
  76. pygpt_net/data/locale/plugin.cmd_web.uk.ini +5 -5
  77. pygpt_net/data/locale/plugin.cmd_web.zh.ini +5 -5
  78. pygpt_net/data/locale/plugin.idx_llama_index.de.ini +12 -12
  79. pygpt_net/data/locale/plugin.idx_llama_index.en.ini +12 -12
  80. pygpt_net/data/locale/plugin.idx_llama_index.es.ini +12 -12
  81. pygpt_net/data/locale/plugin.idx_llama_index.fr.ini +12 -12
  82. pygpt_net/data/locale/plugin.idx_llama_index.it.ini +12 -12
  83. pygpt_net/data/locale/plugin.idx_llama_index.pl.ini +12 -12
  84. pygpt_net/data/locale/plugin.idx_llama_index.uk.ini +12 -12
  85. pygpt_net/data/locale/plugin.idx_llama_index.zh.ini +12 -12
  86. pygpt_net/data/win32/USER-LICENSE.rtf +0 -0
  87. pygpt_net/data/win32/banner.bmp +0 -0
  88. pygpt_net/data/win32/banner_welcome.bmp +0 -0
  89. pygpt_net/item/attachment.py +9 -1
  90. pygpt_net/item/ctx.py +9 -1
  91. pygpt_net/item/preset.py +5 -1
  92. pygpt_net/launcher.py +3 -1
  93. pygpt_net/migrations/Version20241126170000.py +28 -0
  94. pygpt_net/migrations/__init__.py +3 -1
  95. pygpt_net/plugin/audio_input/__init__.py +11 -1
  96. pygpt_net/plugin/audio_input/worker.py +9 -1
  97. pygpt_net/plugin/audio_output/__init__.py +37 -7
  98. pygpt_net/plugin/audio_output/worker.py +38 -41
  99. pygpt_net/plugin/cmd_code_interpreter/runner.py +2 -2
  100. pygpt_net/plugin/cmd_mouse_control/__init__.py +4 -2
  101. pygpt_net/plugin/openai_dalle/__init__.py +3 -1
  102. pygpt_net/plugin/openai_vision/__init__.py +3 -1
  103. pygpt_net/provider/core/attachment/json_file.py +4 -1
  104. pygpt_net/provider/core/config/patch.py +22 -0
  105. pygpt_net/provider/core/ctx/db_sqlite/storage.py +14 -4
  106. pygpt_net/provider/core/ctx/db_sqlite/utils.py +19 -2
  107. pygpt_net/provider/core/model/patch.py +7 -1
  108. pygpt_net/provider/core/preset/json_file.py +5 -1
  109. pygpt_net/provider/gpt/__init__.py +14 -2
  110. pygpt_net/provider/gpt/audio.py +63 -0
  111. pygpt_net/provider/gpt/chat.py +76 -44
  112. pygpt_net/provider/gpt/utils.py +27 -0
  113. pygpt_net/provider/gpt/vision.py +37 -15
  114. pygpt_net/provider/loaders/base.py +10 -1
  115. pygpt_net/provider/loaders/web_yt.py +19 -1
  116. pygpt_net/tools/image_viewer/ui/dialogs.py +3 -1
  117. pygpt_net/ui/dialog/about.py +1 -1
  118. pygpt_net/ui/dialog/preset.py +3 -1
  119. pygpt_net/ui/dialog/url.py +29 -0
  120. pygpt_net/ui/dialogs.py +5 -1
  121. pygpt_net/ui/layout/chat/attachments.py +42 -6
  122. pygpt_net/ui/layout/chat/attachments_ctx.py +14 -4
  123. pygpt_net/ui/layout/chat/attachments_uploaded.py +8 -4
  124. pygpt_net/ui/widget/anims/toggles.py +2 -2
  125. pygpt_net/ui/widget/dialog/url.py +59 -0
  126. pygpt_net/ui/widget/lists/attachment.py +22 -17
  127. pygpt_net/ui/widget/lists/attachment_ctx.py +65 -3
  128. pygpt_net/ui/widget/option/checkbox.py +1 -3
  129. pygpt_net/ui/widget/option/toggle.py +1 -0
  130. pygpt_net/ui/widget/textarea/url.py +43 -0
  131. {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.35.dist-info}/METADATA +2107 -1894
  132. {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.35.dist-info}/RECORD +135 -124
  133. {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.35.dist-info}/LICENSE +0 -0
  134. {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.35.dist-info}/WHEEL +0 -0
  135. {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.35.dist-info}/entry_points.txt +0 -0
@@ -6,18 +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: 2024.11.23 00:00:00 #
9
+ # Updated Date: 2024.11.26 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
13
13
 
14
- from PySide6.QtGui import QStandardItemModel, Qt
14
+ from PySide6.QtGui import QStandardItemModel, Qt, QIcon
15
15
  from PySide6.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QCheckBox, QWidget
16
16
 
17
+ from pygpt_net.item.attachment import AttachmentItem
17
18
  from pygpt_net.ui.widget.element.labels import HelpLabel
18
19
  from pygpt_net.ui.widget.lists.attachment import AttachmentList
19
20
  from pygpt_net.utils import trans
20
21
 
22
+ import pygpt_net.icons_rc
21
23
 
22
24
  class Attachments:
23
25
  def __init__(self, window=None):
@@ -38,12 +40,21 @@ class Attachments:
38
40
  self.setup_attachments()
39
41
  self.setup_buttons()
40
42
 
43
+ empty_widget = QWidget()
44
+ self.window.ui.nodes['input.attachments.options.label'] = HelpLabel(trans("attachments.options.label"))
45
+
41
46
  # buttons layout
42
47
  buttons = QHBoxLayout()
43
48
  buttons.addWidget(self.window.ui.nodes['attachments.btn.add'])
49
+ buttons.addWidget(self.window.ui.nodes['attachments.btn.add_url'])
44
50
  buttons.addWidget(self.window.ui.nodes['attachments.btn.clear'])
51
+ buttons.addWidget(empty_widget)
52
+ buttons.addWidget(self.window.ui.nodes['input.attachments.options.label'])
53
+
54
+ buttons.addWidget(self.setup_auto_index())
45
55
  buttons.addWidget(self.setup_send_clear())
46
56
  buttons.addWidget(self.setup_capture_clear())
57
+ buttons.addStretch()
47
58
 
48
59
  self.window.ui.nodes['tip.input.attachments'] = HelpLabel(trans('tip.input.attachments'), self.window)
49
60
 
@@ -88,15 +99,34 @@ class Attachments:
88
99
 
89
100
  return widget
90
101
 
102
+ def setup_auto_index(self) -> QWidget:
103
+ """
104
+ Setup auto index checkbox
105
+
106
+ :return: QWidget
107
+ """
108
+ layout = QHBoxLayout()
109
+ layout.setContentsMargins(0, 0, 0, 0)
110
+ layout.setAlignment(Qt.AlignCenter)
111
+ layout.addWidget(self.window.ui.nodes['attachments.auto_index'])
112
+
113
+ widget = QWidget()
114
+ widget.setLayout(layout)
115
+
116
+ return widget
117
+
91
118
  def setup_buttons(self):
92
119
  """
93
120
  Setup buttons
94
121
  """
95
- self.window.ui.nodes['attachments.btn.add'] = QPushButton(trans('attachments.btn.add'))
96
- self.window.ui.nodes['attachments.btn.clear'] = QPushButton(trans('attachments.btn.clear'))
122
+ self.window.ui.nodes['attachments.btn.add'] = QPushButton(QIcon(":/icons/add.svg"), trans('attachments.btn.add'))
123
+ self.window.ui.nodes['attachments.btn.add_url'] = QPushButton(QIcon(":/icons/add.svg"), trans('attachments.btn.add_url'))
124
+ self.window.ui.nodes['attachments.btn.clear'] = QPushButton(QIcon(":/icons/close.svg"), trans('attachments.btn.clear'))
97
125
 
98
126
  self.window.ui.nodes['attachments.btn.add'].clicked.connect(
99
127
  lambda: self.window.controller.attachment.open_add())
128
+ self.window.ui.nodes['attachments.btn.add_url'].clicked.connect(
129
+ lambda: self.window.controller.attachment.open_add_url())
100
130
  self.window.ui.nodes['attachments.btn.clear'].clicked.connect(
101
131
  lambda: self.window.controller.attachment.clear(remove_local=True))
102
132
 
@@ -110,6 +140,11 @@ class Attachments:
110
140
  lambda: self.window.controller.attachment.toggle_capture_clear(
111
141
  self.window.ui.nodes['attachments.capture_clear'].isChecked()))
112
142
 
143
+ self.window.ui.nodes['attachments.auto_index'] = QCheckBox(trans('attachments.auto_index'))
144
+ self.window.ui.nodes['attachments.auto_index'].stateChanged.connect(
145
+ lambda: self.window.controller.attachment.toggle_auto_index(
146
+ self.window.ui.nodes['attachments.auto_index'].isChecked()))
147
+
113
148
  def setup_attachments(self):
114
149
  """
115
150
  Setup attachments list
@@ -144,8 +179,9 @@ class Attachments:
144
179
  for id in data:
145
180
  path = data[id].path
146
181
  size = ""
147
- if path and os.path.exists(path):
148
- size = self.window.core.filesystem.sizeof_fmt(os.path.getsize(path))
182
+ if data[id].type == AttachmentItem.TYPE_FILE:
183
+ if path and os.path.exists(path):
184
+ size = self.window.core.filesystem.sizeof_fmt(os.path.getsize(path))
149
185
  ctx_str = ""
150
186
  if data[id].ctx:
151
187
  ctx_str = "YES"
@@ -6,19 +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: 2024.11.23 00:00:00 #
9
+ # Updated Date: 2024.11.26 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
13
13
 
14
14
  from PySide6 import QtCore
15
- from PySide6.QtGui import QStandardItemModel, Qt
15
+ from PySide6.QtGui import QStandardItemModel, Qt, QIcon
16
16
  from PySide6.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QWidget, QRadioButton
17
17
 
18
18
  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
22
23
 
23
24
  class AttachmentsCtx:
24
25
  def __init__(self, window=None):
@@ -90,7 +91,7 @@ class AttachmentsCtx:
90
91
  self.window.ui.nodes[self.id] = AttachmentCtxList(self.window)
91
92
 
92
93
  # buttons
93
- self.window.ui.nodes['attachments_ctx.btn.clear'] = QPushButton(trans('attachments_uploaded.btn.clear'))
94
+ self.window.ui.nodes['attachments_ctx.btn.clear'] = QPushButton(QIcon(":/icons/close.svg"), trans('attachments_uploaded.btn.clear'))
94
95
  self.window.ui.nodes['attachments_ctx.btn.clear'].clicked.connect(
95
96
  lambda: self.window.controller.chat.attachment.clear()
96
97
  )
@@ -105,11 +106,12 @@ class AttachmentsCtx:
105
106
  :param parent: parent widget
106
107
  :return: QStandardItemModel
107
108
  """
108
- model = QStandardItemModel(0, 4, parent)
109
+ model = QStandardItemModel(0, 5, parent)
109
110
  model.setHeaderData(0, Qt.Horizontal, trans('attachments.header.name'))
110
111
  model.setHeaderData(1, Qt.Horizontal, trans('attachments.header.path'))
111
112
  model.setHeaderData(2, Qt.Horizontal, trans('attachments.header.size'))
112
113
  model.setHeaderData(3, Qt.Horizontal, trans('attachments.header.length'))
114
+ model.setHeaderData(4, Qt.Horizontal, trans('attachments.header.idx'))
113
115
  return model
114
116
 
115
117
  def update(self, data):
@@ -121,6 +123,7 @@ class AttachmentsCtx:
121
123
  self.window.ui.models[self.id].removeRows(0, self.window.ui.models[self.id].rowCount())
122
124
  i = 0
123
125
  for item in data:
126
+ indexed = False
124
127
  name = "No name"
125
128
  if 'name' in item:
126
129
  name = item['name']
@@ -136,6 +139,12 @@ class AttachmentsCtx:
136
139
  length = str(item['length'])
137
140
  if 'tokens' in item:
138
141
  length += ' / ~' + str(item['tokens'])
142
+ if 'indexed' in item and item['indexed']:
143
+ indexed = True
144
+
145
+ idx_str = ""
146
+ if indexed:
147
+ idx_str = trans("attachments.ctx.indexed")
139
148
 
140
149
  if os.path.exists(path):
141
150
  size = self.window.core.filesystem.sizeof_fmt(os.path.getsize(path))
@@ -149,4 +158,5 @@ class AttachmentsCtx:
149
158
  self.window.ui.models[self.id].setData(self.window.ui.models[self.id].index(i, 1), path)
150
159
  self.window.ui.models[self.id].setData(self.window.ui.models[self.id].index(i, 2), size)
151
160
  self.window.ui.models[self.id].setData(self.window.ui.models[self.id].index(i, 3), length)
161
+ self.window.ui.models[self.id].setData(self.window.ui.models[self.id].index(i, 4), idx_str)
152
162
  i += 1
@@ -12,7 +12,7 @@
12
12
  import os
13
13
 
14
14
  from PySide6 import QtCore
15
- from PySide6.QtGui import QStandardItemModel, Qt
15
+ from PySide6.QtGui import QStandardItemModel, Qt, QIcon
16
16
  from PySide6.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QCheckBox, QLabel, QWidget
17
17
 
18
18
  from pygpt_net.ui.widget.element.button import SyncButton
@@ -20,6 +20,7 @@ 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
23
24
 
24
25
  class AttachmentsUploaded:
25
26
  def __init__(self, window=None):
@@ -38,10 +39,11 @@ class AttachmentsUploaded:
38
39
  :return: QVBoxLayout
39
40
  """
40
41
  self.setup_attachments()
42
+ empty_widget = QWidget()
41
43
 
42
- self.window.ui.nodes['attachments_uploaded.sync.tip'] = QLabel(trans('attachments_uploaded.sync.tip'))
44
+ self.window.ui.nodes['attachments_uploaded.sync.tip'] = HelpLabel(trans('attachments_uploaded.sync.tip'))
45
+ self.window.ui.nodes['attachments_uploaded.sync.tip'].setWordWrap(False)
43
46
  self.window.ui.nodes['attachments_uploaded.sync.tip'].setAlignment(Qt.AlignCenter)
44
- empty_widget = QWidget()
45
47
 
46
48
  self.window.ui.nodes['tip.input.attachments.uploaded'] = HelpLabel(trans('tip.input.attachments.uploaded'),
47
49
  self.window)
@@ -52,6 +54,8 @@ class AttachmentsUploaded:
52
54
  buttons_layout.addWidget(self.window.ui.nodes['attachments_uploaded.btn.clear'])
53
55
  buttons_layout.addWidget(empty_widget)
54
56
  buttons_layout.addWidget(self.window.ui.nodes['attachments_uploaded.sync.tip'])
57
+ buttons_layout.addStretch()
58
+
55
59
 
56
60
  # layout
57
61
  layout = QVBoxLayout()
@@ -70,7 +74,7 @@ class AttachmentsUploaded:
70
74
 
71
75
  # buttons
72
76
  self.window.ui.nodes['attachments_uploaded.btn.sync'] = SyncButton(trans('attachments_uploaded.btn.sync'), self.window)
73
- self.window.ui.nodes['attachments_uploaded.btn.clear'] = QPushButton(trans('attachments_uploaded.btn.clear'))
77
+ self.window.ui.nodes['attachments_uploaded.btn.clear'] = QPushButton(QIcon(":/icons/close.svg"), trans('attachments_uploaded.btn.clear'))
74
78
  self.window.ui.nodes['attachments_uploaded.btn.clear'].clicked.connect(
75
79
  lambda: self.window.controller.assistant.files.clear()
76
80
  )
@@ -26,8 +26,9 @@ class AnimToggle(QCheckBox):
26
26
  _light_grey_pen = QPen(Qt.lightGray)
27
27
 
28
28
  def __init__(self, title="", parent=None):
29
- super().__init__(parent)
29
+ super().__init__()
30
30
  self.setText(title)
31
+ self.option = None
31
32
 
32
33
  # Initialize the colors based on the current palette
33
34
  self.updateColors()
@@ -103,7 +104,6 @@ class AnimToggle(QCheckBox):
103
104
  self.animations_group.start()
104
105
 
105
106
  def paintEvent(self, e: QPaintEvent):
106
-
107
107
  contRect = self.contentsRect()
108
108
  handleRadius = round(0.24 * contRect.height())
109
109
 
@@ -0,0 +1,59 @@
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: 2024.11.26 02:00:00 #
10
+ # ================================================== #
11
+
12
+ from PySide6.QtWidgets import QDialog, QLabel, QHBoxLayout, QVBoxLayout, QPushButton
13
+
14
+ from pygpt_net.ui.widget.element.labels import HelpLabel
15
+ from pygpt_net.utils import trans
16
+ from pygpt_net.ui.widget.textarea.url import UrlInput
17
+
18
+
19
+ class UrlDialog(QDialog):
20
+ def __init__(self, window=None, id=None):
21
+ """
22
+ Url dialog
23
+
24
+ :param window: main window
25
+ :param id: info window id
26
+ """
27
+ super(UrlDialog, self).__init__(window)
28
+ self.window = window
29
+ self.id = id
30
+ self.current = None
31
+ self.input = UrlInput(window, id)
32
+ self.input.setMinimumWidth(400)
33
+
34
+ self.window.ui.nodes['dialog.url.btn.update'] = QPushButton(trans('dialog.url.update'))
35
+ self.window.ui.nodes['dialog.url.btn.update'].clicked.connect(
36
+ lambda: self.window.controller.dialogs.confirm.accept_url(
37
+ self.id,
38
+ self.window.ui.dialog['url'].current,
39
+ self.input.text()),
40
+ )
41
+
42
+ self.window.ui.nodes['dialog.url.btn.dismiss'] = QPushButton(trans('dialog.url.dismiss'))
43
+ self.window.ui.nodes['dialog.url.btn.dismiss'].clicked.connect(
44
+ lambda: self.window.controller.dialogs.confirm.dismiss_url())
45
+
46
+ bottom = QHBoxLayout()
47
+ bottom.addWidget(self.window.ui.nodes['dialog.url.btn.dismiss'])
48
+ bottom.addWidget(self.window.ui.nodes['dialog.url.btn.update'])
49
+
50
+ self.window.ui.nodes['dialog.url.label'] = QLabel(trans("dialog.url.title"))
51
+ self.window.ui.nodes['dialog.url.tip'] = HelpLabel(trans("dialog.url.tip"))
52
+
53
+ layout = QVBoxLayout()
54
+ layout.addWidget(self.window.ui.nodes['dialog.url.label'])
55
+ layout.addWidget(self.input)
56
+ layout.addWidget(self.window.ui.nodes['dialog.url.tip'])
57
+ layout.addLayout(bottom)
58
+
59
+ self.setLayout(layout)
@@ -6,13 +6,14 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.11.23 00:00:00 #
9
+ # Updated Date: 2024.11.26 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt
13
13
  from PySide6.QtGui import QAction, QIcon, QResizeEvent, QImage
14
14
  from PySide6.QtWidgets import QMenu, QApplication, QHeaderView
15
15
 
16
+ from pygpt_net.item.attachment import AttachmentItem
16
17
  from pygpt_net.ui.widget.lists.base import BaseList
17
18
  from pygpt_net.utils import trans
18
19
  import pygpt_net.icons_rc
@@ -91,9 +92,12 @@ class AttachmentList(BaseList):
91
92
  idx = item.row()
92
93
  preview_actions = []
93
94
  path = None
95
+ attachment = None
94
96
 
95
97
  if idx >= 0:
96
- path = self.window.controller.attachment.get_path_by_idx(mode, idx)
98
+ attachment = self.window.controller.attachment.get_by_idx(mode, idx)
99
+ if attachment:
100
+ path = attachment.path
97
101
  preview_actions = []
98
102
  if self.window.core.filesystem.actions.has_preview(path):
99
103
  preview_actions = self.window.core.filesystem.actions.get_preview(self, path)
@@ -116,21 +120,22 @@ class AttachmentList(BaseList):
116
120
  lambda: self.action_delete(event))
117
121
 
118
122
  menu = QMenu(self)
119
- if idx >= 0 and preview_actions:
120
- for action in preview_actions:
121
- menu.addAction(action)
122
- menu.addAction(actions['open'])
123
- menu.addAction(actions['open_dir'])
124
-
125
- if idx >= 0:
126
- if self.window.core.filesystem.actions.has_use(path):
127
- use_actions = self.window.core.filesystem.actions.get_use(self, path)
128
- use_menu = QMenu(trans('action.use'), self)
129
- for action in use_actions:
130
- use_menu.addAction(action)
131
- menu.addMenu(use_menu)
132
-
133
- menu.addAction(actions['rename'])
123
+ if attachment and attachment.type == AttachmentItem.TYPE_FILE:
124
+ if idx >= 0 and preview_actions:
125
+ for action in preview_actions:
126
+ menu.addAction(action)
127
+
128
+ menu.addAction(actions['open'])
129
+ menu.addAction(actions['open_dir'])
130
+ if idx >= 0:
131
+ if self.window.core.filesystem.actions.has_use(path):
132
+ use_actions = self.window.core.filesystem.actions.get_use(self, path)
133
+ use_menu = QMenu(trans('action.use'), self)
134
+ for action in use_actions:
135
+ use_menu.addAction(action)
136
+ menu.addMenu(use_menu)
137
+
138
+ menu.addAction(actions['rename'])
134
139
  menu.addAction(actions['delete'])
135
140
 
136
141
  if idx >= 0:
@@ -85,18 +85,47 @@ class AttachmentCtxList(BaseList):
85
85
  """
86
86
  actions = {}
87
87
 
88
+ item = self.indexAt(event.pos())
89
+ idx = item.row()
90
+
91
+ has_file = False
92
+ has_src = False
93
+ has_dest = False
94
+
95
+ if idx >= 0:
96
+ has_file = self.window.controller.chat.attachment.has_file_by_idx(idx)
97
+ has_src = self.window.controller.chat.attachment.has_src_by_idx(idx)
98
+ has_dest = self.window.controller.chat.attachment.has_dest_by_idx(idx)
99
+
100
+ actions['open'] = QAction(QIcon(":/icons/view.svg"), trans('action.open'), self)
101
+ actions['open'].triggered.connect(
102
+ lambda: self.action_open(event)
103
+ )
104
+ actions['open_dir_src'] = QAction(QIcon(":/icons/folder.svg"), trans('action.open_dir_src'), self)
105
+ actions['open_dir_src'].triggered.connect(
106
+ lambda: self.action_open_dir_src(event)
107
+ )
108
+ actions['open_dir_dest'] = QAction(QIcon(":/icons/folder.svg"), trans('action.open_dir_storage'), self)
109
+ actions['open_dir_dest'].triggered.connect(
110
+ lambda: self.action_open_dir_dest(event)
111
+ )
112
+
88
113
  actions['delete'] = QAction(QIcon(":/icons/delete.svg"), trans('action.delete'), self)
89
114
  actions['delete'].triggered.connect(
90
115
  lambda: self.action_delete(event)
91
116
  )
92
117
 
93
118
  menu = QMenu(self)
119
+ if has_file:
120
+ menu.addAction(actions['open'])
121
+ if has_src:
122
+ menu.addAction(actions['open_dir_src'])
123
+ if has_dest:
124
+ menu.addAction(actions['open_dir_dest'])
94
125
  menu.addAction(actions['delete'])
95
126
 
96
- item = self.indexAt(event.pos())
97
- idx = item.row()
98
127
  if idx >= 0:
99
- self.window.controller.assistant.files.select(item.row())
128
+ self.window.controller.chat.attachment.select(item.row())
100
129
  menu.exec_(event.globalPos())
101
130
 
102
131
  def action_delete(self, event):
@@ -109,3 +138,36 @@ class AttachmentCtxList(BaseList):
109
138
  idx = item.row()
110
139
  if idx >= 0:
111
140
  self.window.controller.chat.attachment.delete_by_idx(idx)
141
+
142
+ def action_open(self, event):
143
+ """
144
+ Open action handler
145
+
146
+ :param event: mouse event
147
+ """
148
+ item = self.indexAt(event.pos())
149
+ idx = item.row()
150
+ if idx >= 0:
151
+ self.window.controller.chat.attachment.open_by_idx(idx)
152
+
153
+ def action_open_dir_src(self, event):
154
+ """
155
+ Open source directory action handler
156
+
157
+ :param event: mouse event
158
+ """
159
+ item = self.indexAt(event.pos())
160
+ idx = item.row()
161
+ if idx >= 0:
162
+ self.window.controller.chat.attachment.open_dir_src_by_idx(idx)
163
+
164
+ def action_open_dir_dest(self, event):
165
+ """
166
+ Open destination directory action handler
167
+
168
+ :param event: mouse event
169
+ """
170
+ item = self.indexAt(event.pos())
171
+ idx = item.row()
172
+ if idx >= 0:
173
+ self.window.controller.chat.attachment.open_dir_dest_by_idx(idx)
@@ -8,6 +8,7 @@
8
8
  # Created By : Marcin Szczygliński #
9
9
  # Updated Date: 2024.11.24 22:00:00 #
10
10
  # ================================================== #
11
+
11
12
  from PySide6.QtGui import QIcon
12
13
  from PySide6.QtWidgets import QCheckBox, QHBoxLayout, QWidget, QLabel
13
14
 
@@ -67,10 +68,7 @@ class OptionCheckbox(QWidget):
67
68
  self.box.isChecked()
68
69
  )
69
70
  )
70
-
71
71
  self.label = QLabel(self.title)
72
- self.box = AnimToggle()
73
-
74
72
  self.layout = QHBoxLayout()
75
73
  self.layout.addWidget(self.box)
76
74
 
@@ -47,6 +47,7 @@ class OptionCheckbox(QWidget):
47
47
  self.box = AnimToggle(self.title, self.window)
48
48
  if self.value is not None:
49
49
  self.box.setChecked(self.value)
50
+
50
51
  self.box.stateChanged.connect(
51
52
  lambda: self.window.controller.config.checkbox.on_update(
52
53
  self.parent_id,
@@ -0,0 +1,43 @@
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: 2024.11.26 02:00:00 #
10
+ # ================================================== #
11
+
12
+ from PySide6 import QtCore
13
+ from PySide6.QtWidgets import QLineEdit
14
+
15
+
16
+ class UrlInput(QLineEdit):
17
+ def __init__(self, window=None, id=None):
18
+ """
19
+ Url dialog input
20
+
21
+ :param window: main window
22
+ :param id: info window id
23
+ """
24
+ super(UrlInput, self).__init__(window)
25
+
26
+ self.window = window
27
+ self.id = id
28
+
29
+ def keyPressEvent(self, event):
30
+ """
31
+ Key press event
32
+
33
+ :param event: key event
34
+ """
35
+ super(UrlInput, self).keyPressEvent(event)
36
+
37
+ # save on Enter
38
+ if event.key() == QtCore.Qt.Key_Return or event.key() == QtCore.Qt.Key_Enter:
39
+ self.window.controller.dialogs.confirm.accept_url(
40
+ self.window.ui.dialog['url'].id,
41
+ self.window.ui.dialog['url'].current,
42
+ self.text(),
43
+ )