pygpt-net 2.6.20__py3-none-any.whl → 2.6.22__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. pygpt_net/CHANGELOG.txt +13 -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/agent/agent.py +130 -2
  7. pygpt_net/controller/agent/experts.py +93 -96
  8. pygpt_net/controller/agent/llama.py +2 -1
  9. pygpt_net/controller/assistant/assistant.py +18 -1
  10. pygpt_net/controller/assistant/batch.py +2 -3
  11. pygpt_net/controller/assistant/editor.py +2 -2
  12. pygpt_net/controller/assistant/files.py +2 -3
  13. pygpt_net/controller/assistant/store.py +2 -2
  14. pygpt_net/controller/attachment/attachment.py +17 -1
  15. pygpt_net/controller/audio/audio.py +2 -2
  16. pygpt_net/controller/camera/camera.py +15 -7
  17. pygpt_net/controller/chat/chat.py +2 -2
  18. pygpt_net/controller/chat/common.py +50 -33
  19. pygpt_net/controller/chat/image.py +67 -77
  20. pygpt_net/controller/chat/input.py +94 -166
  21. pygpt_net/controller/chat/output.py +83 -140
  22. pygpt_net/controller/chat/response.py +83 -102
  23. pygpt_net/controller/chat/text.py +116 -149
  24. pygpt_net/controller/ctx/common.py +2 -1
  25. pygpt_net/controller/ctx/ctx.py +87 -6
  26. pygpt_net/controller/files/files.py +13 -1
  27. pygpt_net/controller/idx/idx.py +26 -2
  28. pygpt_net/controller/idx/indexer.py +85 -76
  29. pygpt_net/controller/kernel/reply.py +53 -66
  30. pygpt_net/controller/kernel/stack.py +16 -16
  31. pygpt_net/controller/lang/lang.py +52 -34
  32. pygpt_net/controller/model/importer.py +3 -2
  33. pygpt_net/controller/model/model.py +62 -3
  34. pygpt_net/controller/notepad/notepad.py +86 -84
  35. pygpt_net/controller/plugins/settings.py +3 -4
  36. pygpt_net/controller/settings/editor.py +4 -4
  37. pygpt_net/controller/settings/profile.py +105 -124
  38. pygpt_net/controller/theme/menu.py +154 -57
  39. pygpt_net/controller/theme/nodes.py +51 -44
  40. pygpt_net/controller/theme/theme.py +33 -9
  41. pygpt_net/controller/tools/tools.py +2 -2
  42. pygpt_net/controller/ui/tabs.py +2 -3
  43. pygpt_net/controller/ui/ui.py +16 -2
  44. pygpt_net/core/agents/observer/evaluation.py +3 -3
  45. pygpt_net/core/agents/provider.py +25 -3
  46. pygpt_net/core/agents/runner.py +4 -1
  47. pygpt_net/core/agents/runners/llama_workflow.py +19 -7
  48. pygpt_net/core/agents/runners/loop.py +3 -1
  49. pygpt_net/core/agents/runners/openai_workflow.py +17 -3
  50. pygpt_net/core/agents/tools.py +4 -1
  51. pygpt_net/core/bridge/context.py +34 -37
  52. pygpt_net/core/ctx/container.py +13 -12
  53. pygpt_net/core/ctx/ctx.py +1 -1
  54. pygpt_net/core/ctx/output.py +7 -4
  55. pygpt_net/core/db/database.py +2 -2
  56. pygpt_net/core/debug/console/console.py +2 -2
  57. pygpt_net/core/debug/debug.py +12 -1
  58. pygpt_net/core/dispatcher/dispatcher.py +24 -1
  59. pygpt_net/core/events/app.py +7 -7
  60. pygpt_net/core/events/control.py +26 -26
  61. pygpt_net/core/events/event.py +6 -3
  62. pygpt_net/core/events/kernel.py +2 -2
  63. pygpt_net/core/events/render.py +13 -13
  64. pygpt_net/core/experts/experts.py +76 -82
  65. pygpt_net/core/experts/worker.py +12 -12
  66. pygpt_net/core/filesystem/actions.py +1 -2
  67. pygpt_net/core/models/models.py +5 -1
  68. pygpt_net/core/models/ollama.py +14 -5
  69. pygpt_net/core/render/plain/helpers.py +2 -5
  70. pygpt_net/core/render/plain/renderer.py +26 -30
  71. pygpt_net/core/render/web/body.py +1 -1
  72. pygpt_net/core/render/web/helpers.py +2 -2
  73. pygpt_net/core/render/web/renderer.py +4 -4
  74. pygpt_net/core/settings/settings.py +43 -13
  75. pygpt_net/core/tabs/tabs.py +20 -13
  76. pygpt_net/core/types/__init__.py +2 -1
  77. pygpt_net/core/types/agent.py +4 -4
  78. pygpt_net/core/types/base.py +19 -0
  79. pygpt_net/core/types/console.py +6 -6
  80. pygpt_net/core/types/mode.py +8 -8
  81. pygpt_net/core/types/multimodal.py +3 -3
  82. pygpt_net/core/types/openai.py +2 -1
  83. pygpt_net/data/config/config.json +5 -5
  84. pygpt_net/data/config/models.json +19 -3
  85. pygpt_net/data/config/settings.json +14 -14
  86. pygpt_net/data/locale/locale.de.ini +4 -1
  87. pygpt_net/data/locale/locale.en.ini +6 -3
  88. pygpt_net/data/locale/locale.es.ini +4 -1
  89. pygpt_net/data/locale/locale.fr.ini +4 -1
  90. pygpt_net/data/locale/locale.it.ini +4 -1
  91. pygpt_net/data/locale/locale.pl.ini +5 -4
  92. pygpt_net/data/locale/locale.uk.ini +4 -1
  93. pygpt_net/data/locale/locale.zh.ini +4 -1
  94. pygpt_net/item/ctx.py +256 -240
  95. pygpt_net/item/model.py +59 -116
  96. pygpt_net/item/preset.py +122 -105
  97. pygpt_net/plugin/twitter/plugin.py +2 -2
  98. pygpt_net/provider/agents/llama_index/workflow/planner.py +3 -3
  99. pygpt_net/provider/agents/openai/agent.py +4 -12
  100. pygpt_net/provider/agents/openai/agent_b2b.py +10 -15
  101. pygpt_net/provider/agents/openai/agent_planner.py +4 -4
  102. pygpt_net/provider/agents/openai/agent_with_experts.py +3 -7
  103. pygpt_net/provider/agents/openai/agent_with_experts_feedback.py +4 -8
  104. pygpt_net/provider/agents/openai/agent_with_feedback.py +4 -8
  105. pygpt_net/provider/agents/openai/bot_researcher.py +2 -18
  106. pygpt_net/provider/agents/openai/bots/__init__.py +0 -0
  107. pygpt_net/provider/agents/openai/bots/research_bot/__init__.py +0 -0
  108. pygpt_net/provider/agents/openai/bots/research_bot/agents/__init__.py +0 -0
  109. pygpt_net/provider/agents/openai/bots/research_bot/agents/planner_agent.py +1 -1
  110. pygpt_net/provider/agents/openai/bots/research_bot/agents/search_agent.py +1 -0
  111. pygpt_net/provider/agents/openai/bots/research_bot/agents/writer_agent.py +1 -1
  112. pygpt_net/provider/agents/openai/bots/research_bot/manager.py +1 -10
  113. pygpt_net/provider/agents/openai/evolve.py +5 -9
  114. pygpt_net/provider/agents/openai/supervisor.py +4 -8
  115. pygpt_net/provider/core/config/patch.py +10 -3
  116. pygpt_net/provider/core/ctx/db_sqlite/utils.py +43 -43
  117. pygpt_net/provider/core/model/patch.py +11 -1
  118. pygpt_net/provider/core/preset/json_file.py +47 -49
  119. pygpt_net/provider/gpt/agents/experts.py +2 -2
  120. pygpt_net/tools/audio_transcriber/ui/dialogs.py +44 -54
  121. pygpt_net/tools/code_interpreter/body.py +1 -2
  122. pygpt_net/tools/code_interpreter/tool.py +7 -4
  123. pygpt_net/tools/code_interpreter/ui/html.py +1 -3
  124. pygpt_net/tools/code_interpreter/ui/widgets.py +2 -3
  125. pygpt_net/tools/html_canvas/ui/widgets.py +1 -3
  126. pygpt_net/tools/image_viewer/ui/dialogs.py +40 -37
  127. pygpt_net/tools/indexer/ui/widgets.py +2 -4
  128. pygpt_net/tools/media_player/tool.py +2 -5
  129. pygpt_net/tools/media_player/ui/widgets.py +60 -36
  130. pygpt_net/tools/text_editor/ui/widgets.py +18 -19
  131. pygpt_net/tools/translator/ui/widgets.py +39 -35
  132. pygpt_net/ui/base/context_menu.py +9 -4
  133. pygpt_net/ui/dialog/db.py +1 -3
  134. pygpt_net/ui/dialog/models.py +1 -3
  135. pygpt_net/ui/dialog/models_importer.py +2 -4
  136. pygpt_net/ui/dialogs.py +34 -30
  137. pygpt_net/ui/layout/chat/attachments.py +72 -84
  138. pygpt_net/ui/layout/chat/attachments_ctx.py +40 -44
  139. pygpt_net/ui/layout/chat/attachments_uploaded.py +36 -39
  140. pygpt_net/ui/layout/chat/calendar.py +100 -70
  141. pygpt_net/ui/layout/chat/chat.py +23 -17
  142. pygpt_net/ui/layout/chat/input.py +95 -118
  143. pygpt_net/ui/layout/chat/output.py +100 -162
  144. pygpt_net/ui/layout/chat/painter.py +89 -61
  145. pygpt_net/ui/layout/ctx/ctx_list.py +43 -52
  146. pygpt_net/ui/layout/status.py +23 -14
  147. pygpt_net/ui/layout/toolbox/agent.py +27 -38
  148. pygpt_net/ui/layout/toolbox/agent_llama.py +42 -45
  149. pygpt_net/ui/layout/toolbox/assistants.py +42 -38
  150. pygpt_net/ui/layout/toolbox/computer_env.py +32 -23
  151. pygpt_net/ui/layout/toolbox/footer.py +13 -16
  152. pygpt_net/ui/layout/toolbox/image.py +18 -21
  153. pygpt_net/ui/layout/toolbox/indexes.py +46 -89
  154. pygpt_net/ui/layout/toolbox/mode.py +20 -7
  155. pygpt_net/ui/layout/toolbox/model.py +12 -10
  156. pygpt_net/ui/layout/toolbox/presets.py +68 -52
  157. pygpt_net/ui/layout/toolbox/prompt.py +31 -58
  158. pygpt_net/ui/layout/toolbox/toolbox.py +25 -21
  159. pygpt_net/ui/layout/toolbox/vision.py +20 -22
  160. pygpt_net/ui/main.py +2 -4
  161. pygpt_net/ui/menu/about.py +64 -84
  162. pygpt_net/ui/menu/audio.py +87 -63
  163. pygpt_net/ui/menu/config.py +121 -127
  164. pygpt_net/ui/menu/debug.py +69 -76
  165. pygpt_net/ui/menu/file.py +32 -35
  166. pygpt_net/ui/menu/menu.py +2 -3
  167. pygpt_net/ui/menu/plugins.py +69 -33
  168. pygpt_net/ui/menu/theme.py +45 -46
  169. pygpt_net/ui/menu/tools.py +56 -60
  170. pygpt_net/ui/menu/video.py +20 -25
  171. pygpt_net/ui/tray.py +1 -2
  172. pygpt_net/ui/widget/audio/bar.py +1 -3
  173. pygpt_net/ui/widget/audio/input_button.py +3 -4
  174. pygpt_net/ui/widget/calendar/select.py +1 -2
  175. pygpt_net/ui/widget/dialog/base.py +12 -9
  176. pygpt_net/ui/widget/dialog/editor_file.py +20 -23
  177. pygpt_net/ui/widget/dialog/find.py +25 -24
  178. pygpt_net/ui/widget/dialog/profile.py +57 -53
  179. pygpt_net/ui/widget/draw/painter.py +62 -93
  180. pygpt_net/ui/widget/element/button.py +42 -30
  181. pygpt_net/ui/widget/element/checkbox.py +23 -15
  182. pygpt_net/ui/widget/element/group.py +6 -5
  183. pygpt_net/ui/widget/element/labels.py +1 -2
  184. pygpt_net/ui/widget/filesystem/explorer.py +93 -102
  185. pygpt_net/ui/widget/image/display.py +1 -2
  186. pygpt_net/ui/widget/lists/assistant.py +1 -2
  187. pygpt_net/ui/widget/lists/attachment.py +1 -2
  188. pygpt_net/ui/widget/lists/attachment_ctx.py +1 -2
  189. pygpt_net/ui/widget/lists/context.py +2 -4
  190. pygpt_net/ui/widget/lists/index.py +1 -2
  191. pygpt_net/ui/widget/lists/model.py +1 -2
  192. pygpt_net/ui/widget/lists/model_editor.py +1 -2
  193. pygpt_net/ui/widget/lists/model_importer.py +1 -2
  194. pygpt_net/ui/widget/lists/preset.py +1 -2
  195. pygpt_net/ui/widget/lists/preset_plugins.py +1 -2
  196. pygpt_net/ui/widget/lists/profile.py +1 -2
  197. pygpt_net/ui/widget/lists/uploaded.py +1 -2
  198. pygpt_net/ui/widget/option/checkbox.py +2 -4
  199. pygpt_net/ui/widget/option/checkbox_list.py +1 -4
  200. pygpt_net/ui/widget/option/cmd.py +1 -4
  201. pygpt_net/ui/widget/option/dictionary.py +25 -28
  202. pygpt_net/ui/widget/option/input.py +1 -3
  203. pygpt_net/ui/widget/tabs/Input.py +16 -12
  204. pygpt_net/ui/widget/tabs/body.py +5 -3
  205. pygpt_net/ui/widget/tabs/layout.py +36 -25
  206. pygpt_net/ui/widget/tabs/output.py +96 -74
  207. pygpt_net/ui/widget/textarea/calendar_note.py +1 -2
  208. pygpt_net/ui/widget/textarea/editor.py +41 -73
  209. pygpt_net/ui/widget/textarea/find.py +11 -10
  210. pygpt_net/ui/widget/textarea/html.py +3 -6
  211. pygpt_net/ui/widget/textarea/input.py +63 -64
  212. pygpt_net/ui/widget/textarea/notepad.py +54 -38
  213. pygpt_net/ui/widget/textarea/output.py +65 -54
  214. pygpt_net/ui/widget/textarea/search_input.py +5 -4
  215. pygpt_net/ui/widget/textarea/web.py +2 -4
  216. pygpt_net/ui/widget/vision/camera.py +2 -31
  217. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/METADATA +25 -154
  218. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/RECORD +218 -217
  219. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/LICENSE +0 -0
  220. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/WHEEL +0 -0
  221. {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/entry_points.txt +0 -0
@@ -6,12 +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.08.15 03:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6 import QtCore
13
13
  from PySide6.QtGui import QStandardItemModel, Qt, QIcon
14
- from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QPushButton, QSplitter, QWidget, QSizePolicy
14
+ from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QPushButton, QWidget, QSizePolicy
15
15
 
16
16
  from pygpt_net.core.types import (
17
17
  MODE_AGENT,
@@ -19,9 +19,9 @@ from pygpt_net.core.types import (
19
19
  )
20
20
  from pygpt_net.ui.widget.element.labels import HelpLabel, TitleLabel
21
21
  from pygpt_net.ui.widget.lists.preset import PresetList
22
+
22
23
  from pygpt_net.ui.layout.toolbox.footer import Footer
23
24
  from pygpt_net.utils import trans
24
- import pygpt_net.icons_rc
25
25
 
26
26
  class Presets:
27
27
  def __init__(self, window=None):
@@ -34,11 +34,11 @@ class Presets:
34
34
  self.footer = Footer(window)
35
35
  self.id = 'preset.presets'
36
36
 
37
- def setup(self) -> QSplitter:
37
+ def setup(self) -> QWidget:
38
38
  """
39
39
  Setup presets
40
40
 
41
- :return: QSplitter
41
+ :return: QWidget
42
42
  """
43
43
  presets = self.setup_presets()
44
44
 
@@ -55,41 +55,43 @@ class Presets:
55
55
 
56
56
  :return: QVBoxLayout
57
57
  """
58
- self.window.ui.nodes['preset.presets.new'] = QPushButton(QIcon(":/icons/add.svg"), "")
59
- self.window.ui.nodes['preset.presets.new'].clicked.connect(
60
- lambda: self.window.controller.presets.editor.edit()
58
+ nodes = self.window.ui.nodes
59
+
60
+ nodes['preset.presets.new'] = QPushButton(QIcon(":/icons/add.svg"), "")
61
+ nodes['preset.presets.new'].clicked.connect(
62
+ lambda _=False: self.window.controller.presets.editor.edit()
61
63
  )
62
64
 
63
- self.window.ui.nodes['preset.presets.label'] = TitleLabel(trans("toolbox.presets.label"))
64
- self.window.ui.nodes['preset.agents.label'] = TitleLabel(trans("toolbox.agents.label"))
65
- self.window.ui.nodes['preset.experts.label'] = TitleLabel(trans("toolbox.experts.label"))
66
- self.window.ui.nodes['preset.presets.label'].setVisible(False)
67
- self.window.ui.nodes['preset.agents.label'].setVisible(False)
68
- self.window.ui.nodes['preset.experts.label'].setVisible(False)
65
+ nodes['preset.presets.label'] = TitleLabel(trans("toolbox.presets.label"))
66
+ nodes['preset.agents.label'] = TitleLabel(trans("toolbox.agents.label"))
67
+ nodes['preset.experts.label'] = TitleLabel(trans("toolbox.experts.label"))
68
+ nodes['preset.presets.label'].setVisible(False)
69
+ nodes['preset.agents.label'].setVisible(False)
70
+ nodes['preset.experts.label'].setVisible(False)
69
71
 
70
72
  header = QHBoxLayout()
71
- header.addWidget(self.window.ui.nodes['preset.presets.label'])
72
- header.addWidget(self.window.ui.nodes['preset.agents.label'])
73
- header.addWidget(self.window.ui.nodes['preset.experts.label'])
74
- header.addWidget(self.window.ui.nodes['preset.presets.new'], alignment=Qt.AlignRight)
73
+ header.addWidget(nodes['preset.presets.label'])
74
+ header.addWidget(nodes['preset.agents.label'])
75
+ header.addWidget(nodes['preset.experts.label'])
76
+ header.addWidget(nodes['preset.presets.new'], alignment=Qt.AlignRight)
75
77
  header.setContentsMargins(5, 0, 0, 0)
76
78
 
77
- self.window.ui.nodes[self.id] = PresetList(self.window, self.id)
78
- self.window.ui.nodes[self.id].selection_locked = self.window.controller.presets.preset_change_locked
79
- self.window.ui.nodes[self.id].setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
79
+ nodes[self.id] = PresetList(self.window, self.id)
80
+ nodes[self.id].selection_locked = self.window.controller.presets.preset_change_locked
81
+ nodes[self.id].setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
80
82
 
81
- self.window.ui.nodes['tip.toolbox.presets'] = HelpLabel(trans('tip.toolbox.presets'), self.window)
82
- self.window.ui.nodes['tip.toolbox.presets'].setAlignment(Qt.AlignCenter)
83
+ nodes['tip.toolbox.presets'] = HelpLabel(trans('tip.toolbox.presets'), self.window)
84
+ nodes['tip.toolbox.presets'].setAlignment(Qt.AlignCenter)
83
85
 
84
86
  layout = QVBoxLayout()
85
87
  layout.addStretch()
86
88
  layout.addLayout(header)
87
- layout.addWidget(self.window.ui.nodes[self.id], 1)
88
- layout.addWidget(self.window.ui.nodes['tip.toolbox.presets'])
89
+ layout.addWidget(nodes[self.id], 1)
90
+ layout.addWidget(nodes['tip.toolbox.presets'])
89
91
  layout.setContentsMargins(2, 5, 5, 5)
90
92
 
91
93
  self.window.ui.models[self.id] = self.create_model(self.window)
92
- self.window.ui.nodes[self.id].setModel(self.window.ui.models[self.id])
94
+ nodes[self.id].setModel(self.window.ui.models[self.id])
93
95
 
94
96
  return layout
95
97
 
@@ -108,38 +110,52 @@ class Presets:
108
110
  :param data: Data to update
109
111
  """
110
112
  mode = self.window.core.config.get('mode')
111
- view = self.window.ui.nodes[self.id]
112
- model = self.window.ui.models[self.id]
113
+ nodes = self.window.ui.nodes
114
+ models = self.window.ui.models
115
+
116
+ view = nodes[self.id]
117
+ model = models.get(self.id)
113
118
 
114
119
  view.backup_selection()
115
120
 
116
121
  if model is None:
117
122
  model = self.create_model(self.window)
118
- self.window.ui.models[self.id] = model
123
+ models[self.id] = model
119
124
  view.setModel(model)
120
125
 
121
- rc = model.rowCount()
122
- if rc:
123
- model.removeRows(0, rc)
124
-
125
- count = len(data)
126
- if count:
127
- model.setRowCount(count)
128
- count_experts = self.window.core.experts.count_experts
129
- for i, (key, item) in enumerate(data.items()):
130
- name = item.name
131
- if mode == MODE_EXPERT and not key.startswith("current.") and item.enabled:
132
- name = "[x] " + name
133
- elif mode == MODE_AGENT:
134
- num_experts = count_experts(key)
135
- if num_experts > 0:
136
- name = f"{name} ({num_experts} experts)"
137
-
138
- prompt = str(item.prompt)
139
- tooltip = prompt if len(prompt) <= 80 else prompt[:80] + '...'
140
-
141
- index = model.index(i, 0)
142
- model.setData(index, name, QtCore.Qt.DisplayRole)
143
- model.setData(index, tooltip, QtCore.Qt.ToolTipRole)
126
+ view.setUpdatesEnabled(False)
127
+ try:
128
+ if not data:
129
+ model.setRowCount(0)
130
+ else:
131
+ count = len(data)
132
+ model.setRowCount(count)
133
+
134
+ is_expert_mode = (mode == MODE_EXPERT)
135
+ is_agent_mode = (mode == MODE_AGENT)
136
+ count_experts = self.window.core.experts.count_experts if is_agent_mode else None
137
+ startswith_current = "current."
138
+
139
+ index_fn = model.index
140
+ set_item_data = model.setItemData
141
+ display_role = QtCore.Qt.DisplayRole
142
+ tooltip_role = QtCore.Qt.ToolTipRole
143
+
144
+ for i, (key, item) in enumerate(data.items()):
145
+ name = item.name
146
+ if is_expert_mode and item.enabled and not key.startswith(startswith_current):
147
+ name = "[x] " + name
148
+ elif is_agent_mode:
149
+ num_experts = count_experts(key)
150
+ if num_experts > 0:
151
+ name = f"{name} ({num_experts} experts)"
152
+
153
+ prompt = str(item.prompt)
154
+ tooltip = prompt if len(prompt) <= 80 else f"{prompt[:80]}..."
155
+
156
+ idx = index_fn(i, 0)
157
+ set_item_data(idx, {display_role: name, tooltip_role: tooltip})
158
+ finally:
159
+ view.setUpdatesEnabled(True)
144
160
 
145
161
  view.restore_selection()
@@ -6,18 +6,16 @@
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.22 15:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import Qt, QIcon
13
- from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QPushButton, QWidget, QCheckBox, QSizePolicy
13
+ from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QWidget, QSizePolicy
14
14
 
15
- from pygpt_net.ui.widget.anims.toggles import AnimToggle
16
15
  from pygpt_net.ui.widget.element.labels import HelpLabel, TitleLabel
17
16
  from pygpt_net.ui.widget.option.prompt import PromptTextarea
18
17
  from pygpt_net.ui.widget.option.toggle_label import ToggleLabel
19
18
  from pygpt_net.utils import trans
20
- import pygpt_net.icons_rc
21
19
 
22
20
  class Prompt:
23
21
  def __init__(self, window=None):
@@ -34,67 +32,42 @@ class Prompt:
34
32
 
35
33
  :return: QWidget
36
34
  """
37
- # cmd enable/disable
38
- self.window.ui.nodes['cmd.enabled'] = ToggleLabel(trans('cmd.enabled'),
39
- label_position="left",
40
- icon = ":/icons/build.svg",
41
- parent=self.window
42
- )
43
- self.window.ui.nodes['cmd.enabled'].box.stateChanged.connect(
44
- lambda: self.window.controller.chat.common.toggle_cmd(self.window.ui.nodes['cmd.enabled'].box.isChecked())
45
- )
46
- self.window.ui.nodes['cmd.enabled'].box.setToolTip(trans('cmd.tip'))
47
- self.window.ui.nodes['cmd.enabled'].box.setIcon(QIcon(":/icons/add.svg"))
35
+ w = self.window
36
+ nodes = w.ui.nodes
48
37
 
49
- # label
50
- self.window.ui.nodes['toolbox.prompt.label'] = TitleLabel(trans("toolbox.prompt"))
38
+ nodes['toolbox.prompt.label'] = TitleLabel(trans("toolbox.prompt"))
51
39
 
52
- header_layout = QHBoxLayout()
53
- header_layout.addWidget(self.window.ui.nodes['toolbox.prompt.label'])
54
- header_layout.addStretch(1)
55
- header_layout.addWidget(self.window.ui.nodes['cmd.enabled'])
56
- header_layout.setContentsMargins(5, 0, 10, 0)
40
+ nodes['cmd.enabled'] = ToggleLabel(
41
+ trans('cmd.enabled'),
42
+ label_position="left",
43
+ icon=":/icons/build.svg",
44
+ parent=w
45
+ )
46
+ box = nodes['cmd.enabled'].box
47
+ box.toggled.connect(w.controller.chat.common.toggle_cmd)
48
+ box.setToolTip(trans('cmd.tip'))
49
+ box.setIcon(QIcon(":/icons/add.svg"))
57
50
 
58
51
  header_widget = QWidget()
59
- header_widget.setLayout(header_layout)
60
-
61
- # clear
62
- """
63
- self.window.ui.nodes['preset.clear'] = QPushButton(QIcon(":/icons/close.svg"),"")
64
- self.window.ui.nodes['preset.clear'].clicked.connect(
65
- lambda: self.window.controller.presets.clear())
66
-
67
- # use
68
- self.window.ui.nodes['preset.use'] = QPushButton(trans('preset.use'))
69
- self.window.ui.nodes['preset.use'].clicked.connect(
70
- lambda: self.window.controller.presets.use())
71
- self.window.ui.nodes['preset.use'].setVisible(False)
72
-
52
+ header_layout = QHBoxLayout(header_widget)
53
+ header_layout.addWidget(nodes['toolbox.prompt.label'])
54
+ header_layout.addStretch(1)
55
+ header_layout.addWidget(nodes['cmd.enabled'])
56
+ header_layout.setContentsMargins(5, 0, 10, 0)
73
57
 
74
- # cols
75
- header = QHBoxLayout()
76
- header.addWidget(header_widget)
77
- #header.addStretch(1)
78
- #header.addWidget(self.window.ui.nodes['preset.use'], alignment=Qt.AlignRight)
79
- #header.addWidget(self.window.ui.nodes['preset.clear'], alignment=Qt.AlignRight)
80
- """
58
+ option = w.controller.presets.editor.get_option('prompt')
59
+ nodes['preset.prompt'] = PromptTextarea(w, 'preset', 'prompt', option)
60
+ nodes['preset.prompt'].setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
81
61
 
82
- # prompt
83
- option = self.window.controller.presets.editor.get_option('prompt')
84
- self.window.ui.nodes['preset.prompt'] = PromptTextarea(self.window, 'preset', 'prompt', option)
85
- self.window.ui.nodes['preset.prompt'].setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
86
- self.window.ui.nodes['tip.toolbox.prompt'] = HelpLabel(trans('tip.toolbox.prompt'), self.window)
87
- self.window.ui.nodes['tip.toolbox.prompt'].setAlignment(Qt.AlignCenter)
62
+ nodes['tip.toolbox.prompt'] = HelpLabel(trans('tip.toolbox.prompt'), w)
63
+ nodes['tip.toolbox.prompt'].setAlignment(Qt.AlignCenter)
88
64
 
89
- # rows
90
- layout = QVBoxLayout()
65
+ layout_widget = QWidget()
66
+ layout = QVBoxLayout(layout_widget)
91
67
  layout.addWidget(header_widget)
92
- layout.addWidget(self.window.ui.nodes['preset.prompt'])
93
- layout.addWidget(self.window.ui.nodes['tip.toolbox.prompt'])
68
+ layout.addWidget(nodes['preset.prompt'])
69
+ layout.addWidget(nodes['tip.toolbox.prompt'])
94
70
  layout.setContentsMargins(2, 5, 5, 5)
95
71
 
96
- widget = QWidget()
97
- widget.setLayout(layout)
98
- widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
99
-
100
- return widget
72
+ layout_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
73
+ return layout_widget
@@ -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.17 03:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import Qt
@@ -46,34 +46,38 @@ class ToolboxMain:
46
46
  :return: QSplitter
47
47
  :rtype: QSplitter
48
48
  """
49
+ ui = self.window.ui
50
+ nodes = ui.nodes
51
+
49
52
  # mode / model
50
- self.window.ui.nodes['tip.toolbox.mode'] = HelpLabel(trans('tip.toolbox.mode'), self.window)
51
- self.window.ui.nodes['tip.toolbox.mode'].setAlignment(Qt.AlignCenter)
53
+ tip = HelpLabel(trans('tip.toolbox.mode'), self.window)
54
+ tip.setAlignment(Qt.AlignCenter)
55
+ nodes['tip.toolbox.mode'] = tip
52
56
 
53
57
  # presets / assistants
54
- self.window.ui.nodes['toolbox.mode.layout'] = QVBoxLayout()
55
- self.window.ui.nodes['toolbox.mode.layout'].addWidget(self.mode.setup()) # modes
56
- self.window.ui.nodes['toolbox.mode.layout'].addWidget(self.model.setup()) # models
57
- self.window.ui.nodes['toolbox.mode.layout'].addWidget(self.window.ui.nodes['tip.toolbox.mode'])
58
- self.window.ui.nodes['toolbox.mode.layout'].addWidget(self.presets.setup(), 1) # presets / agents
59
- self.window.ui.nodes['toolbox.mode.layout'].addWidget(self.assistants.setup(), 1) # assistants
60
- self.window.ui.nodes['toolbox.mode.layout'].setContentsMargins(0, 0, 0, 0)
58
+ toolbox_mode = QWidget(self.window)
59
+ layout = QVBoxLayout(toolbox_mode)
60
+ layout.addWidget(self.mode.setup()) # modes
61
+ layout.addWidget(self.model.setup()) # models
62
+ layout.addWidget(tip)
63
+ layout.addWidget(self.presets.setup(), 1) # presets / agents
64
+ layout.addWidget(self.assistants.setup(), 1) # assistants
65
+ layout.setContentsMargins(0, 0, 0, 0)
61
66
 
62
- self.window.ui.nodes['toolbox.mode'] = QWidget()
63
- self.window.ui.nodes['toolbox.mode'].setLayout(self.window.ui.nodes['toolbox.mode.layout'])
64
- self.window.ui.nodes['toolbox.mode'].setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
67
+ toolbox_mode.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
68
+ nodes['toolbox.mode'] = toolbox_mode
69
+ nodes['toolbox.mode.layout'] = layout
65
70
 
66
- bottom = QVBoxLayout()
71
+ bottom_widget = QWidget(self.window)
72
+ bottom = QVBoxLayout(bottom_widget)
67
73
  bottom.addWidget(self.prompt.setup())
68
74
  bottom.addWidget(self.footer.setup())
69
75
  bottom.setContentsMargins(0, 0, 0, 0)
70
76
 
71
- bottom_widget = QWidget()
72
- bottom_widget.setLayout(bottom)
73
-
74
77
  # rows
75
- self.window.ui.splitters['toolbox'] = QSplitter(Qt.Vertical)
76
- self.window.ui.splitters['toolbox'].addWidget(self.window.ui.nodes['toolbox.mode']) # mode/model
77
- self.window.ui.splitters['toolbox'].addWidget(bottom_widget) # system prompt, footer (names, temp, logo, etc.)
78
+ splitter = QSplitter(Qt.Vertical, self.window)
79
+ splitter.addWidget(toolbox_mode) # mode/model
80
+ splitter.addWidget(bottom_widget) # system prompt, footer (names, temp, logo, etc.)
81
+ ui.splitters['toolbox'] = splitter
78
82
 
79
- return self.window.ui.splitters['toolbox']
83
+ return splitter
@@ -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: 2023.12.25 21:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtWidgets import QVBoxLayout, QLabel, QHBoxLayout, QWidget, QCheckBox
@@ -29,33 +29,31 @@ class Vision:
29
29
 
30
30
  :return: QWidget
31
31
  """
32
- # enable/disable
33
- self.window.ui.nodes['vision.capture.enable'] = QCheckBox(trans("vision.capture.enable"))
34
- self.window.ui.nodes['vision.capture.enable'].stateChanged.connect(
35
- lambda: self.window.controller.camera.toggle(self.window.ui.nodes['vision.capture.enable'].isChecked()))
36
- self.window.ui.nodes['vision.capture.enable'].setToolTip(trans('vision.capture.enable.tooltip'))
32
+ nodes = self.window.ui.nodes
33
+ camera = self.window.controller.camera
37
34
 
38
- # auto
39
- self.window.ui.nodes['vision.capture.auto'] = QCheckBox(trans("vision.capture.auto"))
40
- self.window.ui.nodes['vision.capture.auto'].stateChanged.connect(
41
- lambda: self.window.controller.camera.toggle_auto(self.window.ui.nodes['vision.capture.auto'].isChecked()))
42
- self.window.ui.nodes['vision.capture.auto'].setToolTip(trans('vision.capture.auto.tooltip'))
35
+ nodes['vision.capture.options'] = QWidget()
36
+ options = nodes['vision.capture.options']
43
37
 
44
- self.window.ui.nodes['vision.capture.label'] = QLabel(trans('vision.capture.options.title'))
38
+ nodes['vision.capture.enable'] = QCheckBox(trans("vision.capture.enable"), parent=options)
39
+ nodes['vision.capture.enable'].toggled.connect(camera.toggle)
40
+ nodes['vision.capture.enable'].setToolTip(trans('vision.capture.enable.tooltip'))
41
+
42
+ nodes['vision.capture.auto'] = QCheckBox(trans("vision.capture.auto"), parent=options)
43
+ nodes['vision.capture.auto'].toggled.connect(camera.toggle_auto)
44
+ nodes['vision.capture.auto'].setToolTip(trans('vision.capture.auto.tooltip'))
45
+
46
+ nodes['vision.capture.label'] = QLabel(trans('vision.capture.options.title'), parent=options)
45
47
 
46
- # checkbox options
47
48
  cols = QHBoxLayout()
48
- cols.addWidget(self.window.ui.nodes['vision.capture.enable'])
49
- cols.addWidget(self.window.ui.nodes['vision.capture.auto'])
49
+ cols.addWidget(nodes['vision.capture.enable'])
50
+ cols.addWidget(nodes['vision.capture.auto'])
50
51
 
51
- # rows
52
52
  rows = QVBoxLayout()
53
- rows.addWidget(self.window.ui.nodes['vision.capture.label'])
53
+ rows.addWidget(nodes['vision.capture.label'])
54
54
  rows.addLayout(cols)
55
55
 
56
- # widget
57
- self.window.ui.nodes['vision.capture.options'] = QWidget()
58
- self.window.ui.nodes['vision.capture.options'].setLayout(rows)
59
- self.window.ui.nodes['vision.capture.options'].setContentsMargins(0, 0, 0, 0)
56
+ options.setLayout(rows)
57
+ options.setContentsMargins(0, 0, 0, 0)
60
58
 
61
- return self.window.ui.nodes['vision.capture.options']
59
+ return options
pygpt_net/ui/main.py CHANGED
@@ -6,15 +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.08.20 20:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
13
13
 
14
14
  from PySide6.QtCore import QTimer, Signal, Slot, QThreadPool, QEvent, Qt, QLoggingCategory, QEventLoop
15
15
  from PySide6.QtGui import QShortcut, QKeySequence
16
- from qasync import QApplication
17
- from PySide6.QtWidgets import QMainWindow
16
+ from PySide6.QtWidgets import QMainWindow, QApplication
18
17
  from qt_material import QtStyleTools
19
18
 
20
19
  from pygpt_net.core.events import BaseEvent, KernelEvent, ControlEvent
@@ -25,7 +24,6 @@ from pygpt_net.ui import UI
25
24
  from pygpt_net.ui.widget.textarea.web import ChatWebOutput
26
25
  from pygpt_net.utils import get_app_meta
27
26
 
28
-
29
27
  class MainWindow(QMainWindow, QtStyleTools):
30
28
 
31
29
  # states
@@ -6,13 +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.01.16 01:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QAction, QIcon
13
13
 
14
14
  from pygpt_net.utils import trans
15
- import pygpt_net.icons_rc
16
15
 
17
16
 
18
17
  class About:
@@ -26,92 +25,73 @@ class About:
26
25
 
27
26
  def setup(self):
28
27
  """Setup about menu"""
29
- self.window.ui.menu['info.about'] = QAction(QIcon(":/icons/info.svg"), trans("menu.info.about"),
30
- self.window)
31
- self.window.ui.menu['info.about'].setMenuRole(QAction.MenuRole.NoRole)
32
- self.window.ui.menu['info.changelog'] = QAction(QIcon(":/icons/history.svg"), trans("menu.info.changelog"),
33
- self.window)
34
- self.window.ui.menu['info.updates'] = QAction(QIcon(":/icons/updater.svg"), trans("menu.info.updates"),
35
- self.window)
36
- self.window.ui.menu['info.report'] = QAction(QIcon(":/icons/public_filled.svg"), trans("menu.info.report"),
37
- self.window)
38
- self.window.ui.menu['info.website'] = QAction(QIcon(":/icons/public_filled.svg"), trans("menu.info.website"),
39
- self.window)
40
- self.window.ui.menu['info.docs'] = QAction(QIcon(":/icons/public_filled.svg"), trans("menu.info.docs"),
41
- self.window)
42
- self.window.ui.menu['info.pypi'] = QAction(QIcon(":/icons/public_filled.svg"), trans("menu.info.pypi"),
43
- self.window)
44
- self.window.ui.menu['info.snap'] = QAction(QIcon(":/icons/public_filled.svg"), trans("menu.info.snap"),
45
- self.window)
46
- self.window.ui.menu['info.ms_store'] = QAction(QIcon(":/icons/public_filled.svg"), trans("menu.info.ms_store"),
47
- self.window)
48
- self.window.ui.menu['info.github'] = QAction(QIcon(":/icons/public_filled.svg"), trans("menu.info.github"),
49
- self.window)
28
+ w = self.window
29
+ m = w.ui.menu
50
30
 
51
- self.window.ui.menu['info.discord'] = QAction(QIcon(":/icons/public_filled.svg"), trans("menu.info.discord"),
52
- self.window)
31
+ icon_info = QIcon(":/icons/info.svg")
32
+ icon_history = QIcon(":/icons/history.svg")
33
+ icon_updater = QIcon(":/icons/updater.svg")
34
+ icon_public = QIcon(":/icons/public_filled.svg")
35
+ icon_favorite = QIcon(":/icons/favorite.svg")
53
36
 
54
- self.window.ui.menu['info.license'] = QAction(QIcon(":/icons/info.svg"), trans("menu.info.license"),
55
- self.window)
37
+ m['info.about'] = QAction(icon_info, trans("menu.info.about"), w)
38
+ m['info.about'].setMenuRole(QAction.MenuRole.NoRole)
39
+ m['info.changelog'] = QAction(icon_history, trans("menu.info.changelog"), w)
40
+ m['info.updates'] = QAction(icon_updater, trans("menu.info.updates"), w)
41
+ m['info.report'] = QAction(icon_public, trans("menu.info.report"), w)
42
+ m['info.website'] = QAction(icon_public, trans("menu.info.website"), w)
43
+ m['info.docs'] = QAction(icon_public, trans("menu.info.docs"), w)
44
+ m['info.pypi'] = QAction(icon_public, trans("menu.info.pypi"), w)
45
+ m['info.snap'] = QAction(icon_public, trans("menu.info.snap"), w)
46
+ m['info.ms_store'] = QAction(icon_public, trans("menu.info.ms_store"), w)
47
+ m['info.github'] = QAction(icon_public, trans("menu.info.github"), w)
48
+ m['info.discord'] = QAction(icon_public, trans("menu.info.discord"), w)
49
+ m['info.license'] = QAction(icon_info, trans("menu.info.license"), w)
56
50
 
57
- self.window.ui.menu['donate.coffee'] = QAction(QIcon(":/icons/favorite.svg"), "Buy me a coffee",
58
- self.window)
59
- self.window.ui.menu['donate.coffee'].setMenuRole(QAction.MenuRole.NoRole)
60
- self.window.ui.menu['donate.paypal'] = QAction(QIcon(":/icons/favorite.svg"), "PayPal",
61
- self.window)
62
- self.window.ui.menu['donate.github'] = QAction(QIcon(":/icons/favorite.svg"), "GitHub Sponsors", self.window)
51
+ m['donate.coffee'] = QAction(icon_favorite, "Buy me a coffee", w)
52
+ m['donate.coffee'].setMenuRole(QAction.MenuRole.NoRole)
53
+ m['donate.paypal'] = QAction(icon_favorite, "PayPal", w)
54
+ m['donate.github'] = QAction(icon_favorite, "GitHub Sponsors", w)
63
55
 
64
- self.window.ui.menu['donate.coffee'].triggered.connect(
65
- lambda: self.window.controller.dialogs.info.donate('coffee'))
66
- self.window.ui.menu['donate.paypal'].triggered.connect(
67
- lambda: self.window.controller.dialogs.info.donate('paypal'))
68
- self.window.ui.menu['donate.github'].triggered.connect(
69
- lambda: self.window.controller.dialogs.info.donate('github'))
56
+ dlg_info = w.controller.dialogs.info
57
+ launcher = w.controller.launcher
70
58
 
71
- self.window.ui.menu['info.about'].triggered.connect(
72
- lambda: self.window.controller.dialogs.info.toggle('about'))
73
- self.window.ui.menu['info.changelog'].triggered.connect(
74
- lambda: self.window.controller.dialogs.info.toggle('changelog'))
75
- self.window.ui.menu['info.updates'].triggered.connect(
76
- lambda: self.window.controller.launcher.check_updates())
77
- self.window.ui.menu['info.report'].triggered.connect(
78
- lambda: self.window.controller.dialogs.info.goto_report())
79
- self.window.ui.menu['info.website'].triggered.connect(
80
- lambda: self.window.controller.dialogs.info.goto_website())
81
- self.window.ui.menu['info.docs'].triggered.connect(
82
- lambda: self.window.controller.dialogs.info.goto_docs())
83
- self.window.ui.menu['info.pypi'].triggered.connect(
84
- lambda: self.window.controller.dialogs.info.goto_pypi())
85
- self.window.ui.menu['info.snap'].triggered.connect(
86
- lambda: self.window.controller.dialogs.info.goto_snap())
87
- self.window.ui.menu['info.ms_store'].triggered.connect(
88
- lambda: self.window.controller.dialogs.info.goto_ms_store())
89
- self.window.ui.menu['info.github'].triggered.connect(
90
- lambda: self.window.controller.dialogs.info.goto_github())
91
- self.window.ui.menu['info.discord'].triggered.connect(
92
- lambda: self.window.controller.dialogs.info.goto_discord())
93
- self.window.ui.menu['info.license'].triggered.connect(
94
- lambda: self.window.controller.dialogs.info.toggle(
95
- 'license',
96
- width=500,
97
- height=480,
98
- ))
59
+ m['donate.coffee'].triggered.connect(lambda checked=False, i=dlg_info: i.donate('coffee'))
60
+ m['donate.paypal'].triggered.connect(lambda checked=False, i=dlg_info: i.donate('paypal'))
61
+ m['donate.github'].triggered.connect(lambda checked=False, i=dlg_info: i.donate('github'))
99
62
 
100
- self.window.ui.menu['menu.about'] = self.window.menuBar().addMenu(trans("menu.info"))
101
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.about'])
102
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.changelog'])
103
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.updates'])
104
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.report'])
105
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.docs'])
106
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.website'])
107
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.github'])
108
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.pypi'])
109
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.snap'])
110
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.ms_store'])
111
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.discord'])
112
- self.window.ui.menu['menu.about'].addAction(self.window.ui.menu['info.license'])
63
+ m['info.about'].triggered.connect(lambda checked=False, i=dlg_info: i.toggle('about'))
64
+ m['info.changelog'].triggered.connect(lambda checked=False, i=dlg_info: i.toggle('changelog'))
65
+ m['info.updates'].triggered.connect(lambda checked=False, l=launcher: l.check_updates())
66
+ m['info.report'].triggered.connect(lambda checked=False, i=dlg_info: i.goto_report())
67
+ m['info.website'].triggered.connect(lambda checked=False, i=dlg_info: i.goto_website())
68
+ m['info.docs'].triggered.connect(lambda checked=False, i=dlg_info: i.goto_docs())
69
+ m['info.pypi'].triggered.connect(lambda checked=False, i=dlg_info: i.goto_pypi())
70
+ m['info.snap'].triggered.connect(lambda checked=False, i=dlg_info: i.goto_snap())
71
+ m['info.ms_store'].triggered.connect(lambda checked=False, i=dlg_info: i.goto_ms_store())
72
+ m['info.github'].triggered.connect(lambda checked=False, i=dlg_info: i.goto_github())
73
+ m['info.discord'].triggered.connect(lambda checked=False, i=dlg_info: i.goto_discord())
74
+ m['info.license'].triggered.connect(lambda checked=False, i=dlg_info: i.toggle('license', width=500, height=480))
113
75
 
114
- self.window.ui.menu['menu.donate'] = self.window.ui.menu['menu.about'].addMenu(trans("menu.info.donate"))
115
- self.window.ui.menu['menu.donate'].addAction(self.window.ui.menu['donate.coffee'])
116
- self.window.ui.menu['menu.donate'].addAction(self.window.ui.menu['donate.paypal'])
117
- self.window.ui.menu['menu.donate'].addAction(self.window.ui.menu['donate.github'])
76
+ m['menu.about'] = w.menuBar().addMenu(trans("menu.info"))
77
+ m['menu.about'].addActions([
78
+ m['info.about'],
79
+ m['info.changelog'],
80
+ m['info.updates'],
81
+ m['info.report'],
82
+ m['info.docs'],
83
+ m['info.website'],
84
+ m['info.github'],
85
+ m['info.pypi'],
86
+ m['info.snap'],
87
+ m['info.ms_store'],
88
+ m['info.discord'],
89
+ m['info.license'],
90
+ ])
91
+
92
+ m['menu.donate'] = m['menu.about'].addMenu(trans("menu.info.donate"))
93
+ m['menu.donate'].addActions([
94
+ m['donate.coffee'],
95
+ m['donate.paypal'],
96
+ m['donate.github'],
97
+ ])