pygpt-net 2.6.21__py3-none-any.whl → 2.6.23__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 (160) hide show
  1. pygpt_net/CHANGELOG.txt +12 -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/llama.py +3 -0
  7. pygpt_net/controller/assistant/batch.py +2 -3
  8. pygpt_net/controller/assistant/editor.py +2 -2
  9. pygpt_net/controller/assistant/files.py +2 -3
  10. pygpt_net/controller/assistant/store.py +2 -2
  11. pygpt_net/controller/audio/audio.py +2 -2
  12. pygpt_net/controller/chat/response.py +4 -0
  13. pygpt_net/controller/ctx/ctx.py +2 -1
  14. pygpt_net/controller/files/files.py +24 -55
  15. pygpt_net/controller/idx/indexer.py +85 -76
  16. pygpt_net/controller/lang/lang.py +52 -34
  17. pygpt_net/controller/model/importer.py +2 -2
  18. pygpt_net/controller/notepad/notepad.py +86 -84
  19. pygpt_net/controller/plugins/settings.py +3 -4
  20. pygpt_net/controller/settings/profile.py +105 -124
  21. pygpt_net/controller/theme/menu.py +154 -57
  22. pygpt_net/controller/theme/nodes.py +51 -44
  23. pygpt_net/controller/theme/theme.py +33 -9
  24. pygpt_net/controller/tools/tools.py +2 -2
  25. pygpt_net/controller/ui/tabs.py +2 -3
  26. pygpt_net/core/agents/observer/evaluation.py +2 -2
  27. pygpt_net/core/agents/runners/loop.py +1 -0
  28. pygpt_net/core/bridge/bridge.py +2 -0
  29. pygpt_net/core/ctx/container.py +13 -12
  30. pygpt_net/core/ctx/output.py +7 -4
  31. pygpt_net/core/debug/console/console.py +2 -2
  32. pygpt_net/core/filesystem/actions.py +1 -2
  33. pygpt_net/core/filesystem/opener.py +261 -0
  34. pygpt_net/core/filesystem/url.py +13 -10
  35. pygpt_net/core/platforms/platforms.py +5 -4
  36. pygpt_net/core/render/plain/helpers.py +2 -5
  37. pygpt_net/core/render/plain/renderer.py +26 -30
  38. pygpt_net/core/render/web/body.py +1 -1
  39. pygpt_net/core/settings/settings.py +43 -13
  40. pygpt_net/core/tabs/tabs.py +20 -13
  41. pygpt_net/data/config/config.json +4 -4
  42. pygpt_net/data/config/models.json +3 -3
  43. pygpt_net/data/css/web-blocks.dark.css +7 -1
  44. pygpt_net/data/css/web-blocks.light.css +5 -2
  45. pygpt_net/data/css/web-chatgpt.dark.css +7 -1
  46. pygpt_net/data/css/web-chatgpt.light.css +3 -0
  47. pygpt_net/data/css/web-chatgpt_wide.dark.css +7 -1
  48. pygpt_net/data/css/web-chatgpt_wide.light.css +3 -0
  49. pygpt_net/data/locale/locale.de.ini +5 -1
  50. pygpt_net/data/locale/locale.en.ini +5 -1
  51. pygpt_net/data/locale/locale.es.ini +5 -1
  52. pygpt_net/data/locale/locale.fr.ini +5 -1
  53. pygpt_net/data/locale/locale.it.ini +5 -1
  54. pygpt_net/data/locale/locale.pl.ini +6 -4
  55. pygpt_net/data/locale/locale.uk.ini +5 -1
  56. pygpt_net/data/locale/locale.zh.ini +5 -1
  57. pygpt_net/plugin/twitter/plugin.py +2 -2
  58. pygpt_net/provider/core/config/patch.py +12 -1
  59. pygpt_net/tools/audio_transcriber/ui/dialogs.py +44 -54
  60. pygpt_net/tools/code_interpreter/body.py +1 -2
  61. pygpt_net/tools/code_interpreter/tool.py +7 -4
  62. pygpt_net/tools/code_interpreter/ui/html.py +1 -3
  63. pygpt_net/tools/code_interpreter/ui/widgets.py +2 -3
  64. pygpt_net/tools/html_canvas/ui/widgets.py +1 -3
  65. pygpt_net/tools/image_viewer/ui/dialogs.py +40 -37
  66. pygpt_net/tools/indexer/ui/widgets.py +2 -4
  67. pygpt_net/tools/media_player/tool.py +2 -5
  68. pygpt_net/tools/media_player/ui/widgets.py +60 -36
  69. pygpt_net/tools/text_editor/ui/widgets.py +18 -19
  70. pygpt_net/tools/translator/ui/widgets.py +39 -35
  71. pygpt_net/ui/base/context_menu.py +9 -4
  72. pygpt_net/ui/dialog/db.py +1 -3
  73. pygpt_net/ui/dialog/models.py +1 -3
  74. pygpt_net/ui/dialog/models_importer.py +2 -4
  75. pygpt_net/ui/dialogs.py +34 -30
  76. pygpt_net/ui/layout/chat/attachments.py +72 -84
  77. pygpt_net/ui/layout/chat/attachments_ctx.py +40 -44
  78. pygpt_net/ui/layout/chat/attachments_uploaded.py +36 -39
  79. pygpt_net/ui/layout/chat/calendar.py +100 -70
  80. pygpt_net/ui/layout/chat/chat.py +23 -17
  81. pygpt_net/ui/layout/chat/input.py +95 -118
  82. pygpt_net/ui/layout/chat/output.py +100 -162
  83. pygpt_net/ui/layout/chat/painter.py +89 -61
  84. pygpt_net/ui/layout/ctx/ctx_list.py +43 -52
  85. pygpt_net/ui/layout/status.py +23 -14
  86. pygpt_net/ui/layout/toolbox/agent.py +27 -38
  87. pygpt_net/ui/layout/toolbox/agent_llama.py +41 -45
  88. pygpt_net/ui/layout/toolbox/assistants.py +42 -38
  89. pygpt_net/ui/layout/toolbox/computer_env.py +32 -23
  90. pygpt_net/ui/layout/toolbox/footer.py +13 -16
  91. pygpt_net/ui/layout/toolbox/image.py +18 -21
  92. pygpt_net/ui/layout/toolbox/indexes.py +46 -89
  93. pygpt_net/ui/layout/toolbox/mode.py +20 -7
  94. pygpt_net/ui/layout/toolbox/model.py +12 -10
  95. pygpt_net/ui/layout/toolbox/presets.py +68 -52
  96. pygpt_net/ui/layout/toolbox/prompt.py +31 -58
  97. pygpt_net/ui/layout/toolbox/toolbox.py +25 -21
  98. pygpt_net/ui/layout/toolbox/vision.py +20 -22
  99. pygpt_net/ui/main.py +2 -4
  100. pygpt_net/ui/menu/about.py +64 -84
  101. pygpt_net/ui/menu/audio.py +87 -63
  102. pygpt_net/ui/menu/config.py +121 -127
  103. pygpt_net/ui/menu/debug.py +69 -76
  104. pygpt_net/ui/menu/file.py +32 -35
  105. pygpt_net/ui/menu/menu.py +2 -3
  106. pygpt_net/ui/menu/plugins.py +69 -33
  107. pygpt_net/ui/menu/theme.py +45 -46
  108. pygpt_net/ui/menu/tools.py +56 -60
  109. pygpt_net/ui/menu/video.py +20 -25
  110. pygpt_net/ui/tray.py +1 -2
  111. pygpt_net/ui/widget/audio/bar.py +1 -3
  112. pygpt_net/ui/widget/audio/input_button.py +3 -4
  113. pygpt_net/ui/widget/calendar/select.py +1 -2
  114. pygpt_net/ui/widget/dialog/base.py +12 -9
  115. pygpt_net/ui/widget/dialog/editor_file.py +20 -23
  116. pygpt_net/ui/widget/dialog/find.py +25 -24
  117. pygpt_net/ui/widget/dialog/profile.py +57 -53
  118. pygpt_net/ui/widget/draw/painter.py +62 -93
  119. pygpt_net/ui/widget/element/button.py +42 -30
  120. pygpt_net/ui/widget/element/checkbox.py +23 -15
  121. pygpt_net/ui/widget/element/group.py +6 -5
  122. pygpt_net/ui/widget/element/labels.py +1 -2
  123. pygpt_net/ui/widget/filesystem/explorer.py +93 -102
  124. pygpt_net/ui/widget/image/display.py +1 -2
  125. pygpt_net/ui/widget/lists/assistant.py +1 -2
  126. pygpt_net/ui/widget/lists/attachment.py +1 -2
  127. pygpt_net/ui/widget/lists/attachment_ctx.py +1 -2
  128. pygpt_net/ui/widget/lists/context.py +2 -4
  129. pygpt_net/ui/widget/lists/index.py +1 -2
  130. pygpt_net/ui/widget/lists/model.py +1 -2
  131. pygpt_net/ui/widget/lists/model_editor.py +1 -2
  132. pygpt_net/ui/widget/lists/model_importer.py +1 -2
  133. pygpt_net/ui/widget/lists/preset.py +1 -2
  134. pygpt_net/ui/widget/lists/preset_plugins.py +1 -2
  135. pygpt_net/ui/widget/lists/profile.py +1 -2
  136. pygpt_net/ui/widget/lists/uploaded.py +1 -2
  137. pygpt_net/ui/widget/option/checkbox.py +2 -4
  138. pygpt_net/ui/widget/option/checkbox_list.py +1 -4
  139. pygpt_net/ui/widget/option/cmd.py +1 -4
  140. pygpt_net/ui/widget/option/dictionary.py +25 -28
  141. pygpt_net/ui/widget/option/input.py +1 -3
  142. pygpt_net/ui/widget/tabs/Input.py +16 -12
  143. pygpt_net/ui/widget/tabs/body.py +5 -3
  144. pygpt_net/ui/widget/tabs/layout.py +41 -28
  145. pygpt_net/ui/widget/tabs/output.py +442 -85
  146. pygpt_net/ui/widget/textarea/calendar_note.py +1 -2
  147. pygpt_net/ui/widget/textarea/editor.py +41 -73
  148. pygpt_net/ui/widget/textarea/find.py +11 -10
  149. pygpt_net/ui/widget/textarea/html.py +3 -6
  150. pygpt_net/ui/widget/textarea/input.py +134 -69
  151. pygpt_net/ui/widget/textarea/notepad.py +54 -38
  152. pygpt_net/ui/widget/textarea/output.py +65 -54
  153. pygpt_net/ui/widget/textarea/search_input.py +5 -4
  154. pygpt_net/ui/widget/textarea/web.py +2 -4
  155. pygpt_net/ui/widget/vision/camera.py +2 -31
  156. {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.23.dist-info}/METADATA +38 -174
  157. {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.23.dist-info}/RECORD +160 -159
  158. {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.23.dist-info}/LICENSE +0 -0
  159. {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.23.dist-info}/WHEEL +0 -0
  160. {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.23.dist-info}/entry_points.txt +0 -0
@@ -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
+ ])
@@ -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.14 18:00:00 #
9
+ # Updated Date: 2025.08.24 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QAction, QIcon
@@ -25,65 +25,89 @@ class Audio:
25
25
 
26
26
  def setup(self):
27
27
  """Setup audio menu"""
28
- self.window.ui.menu['audio.output'] = QAction(
29
- trans("menu.audio.output"),
30
- self.window,
31
- checkable=True,
32
- )
33
- self.window.ui.menu['audio.input'] = QAction(
34
- trans("menu.audio.input"),
35
- self.window,
36
- checkable=True,
37
- )
38
- self.window.ui.menu['audio.control.plugin'] = QAction(
39
- trans("menu.audio.control.plugin"),
40
- self.window,
41
- checkable=True,
42
- )
43
- self.window.ui.menu['audio.control.global'] = QAction(
44
- trans("menu.audio.control.global"),
45
- self.window,
46
- checkable=True,
47
- )
48
- self.window.ui.menu['audio.cache.clear'] = QAction(
49
- QIcon(":/icons/delete.svg"),
50
- trans("menu.audio.cache.clear"),
51
- self.window,
52
- checkable=False,
53
- )
54
-
55
- self.window.ui.menu['audio.stop'] = QAction(
56
- QIcon(":/icons/mute.svg"),
57
- trans("menu.audio.stop"),
58
- self.window,
59
- checkable=False,
60
- )
61
-
62
- self.window.ui.menu['audio.output'].triggered.connect(
63
- lambda: self.window.controller.plugins.toggle('audio_output')
64
- )
65
- self.window.ui.menu['audio.input'].triggered.connect(
66
- lambda: self.window.controller.plugins.toggle('audio_input')
67
- )
68
- self.window.ui.menu['audio.control.plugin'].triggered.connect(
69
- lambda: self.window.controller.plugins.toggle('voice_control')
70
- )
71
- self.window.ui.menu['audio.control.global'].triggered.connect(
72
- lambda: self.window.controller.access.voice.toggle_voice_control()
73
- )
74
- self.window.ui.menu['audio.cache.clear'].triggered.connect(
75
- lambda: self.window.controller.audio.clear_cache()
76
- )
77
- self.window.ui.menu['audio.stop'].triggered.connect(
78
- lambda: self.window.controller.audio.stop_audio()
79
- )
80
-
81
- self.window.ui.menu['menu.audio'] = self.window.menuBar().addMenu(trans("menu.audio"))
82
- self.window.ui.menu['menu.audio'].addAction(self.window.ui.menu['audio.input'])
83
- self.window.ui.menu['menu.audio'].addAction(self.window.ui.menu['audio.output'])
84
- self.window.ui.menu['menu.audio'].addSeparator()
85
- self.window.ui.menu['menu.audio'].addAction(self.window.ui.menu['audio.control.plugin'])
86
- self.window.ui.menu['menu.audio'].addAction(self.window.ui.menu['audio.control.global'])
87
- self.window.ui.menu['menu.audio'].addSeparator()
88
- self.window.ui.menu['menu.audio'].addAction(self.window.ui.menu['audio.cache.clear'])
89
- self.window.ui.menu['menu.audio'].addAction(self.window.ui.menu['audio.stop'])
28
+ w = self.window
29
+ m = w.ui.menu
30
+
31
+ title = trans("menu.audio")
32
+ txt_output = trans("menu.audio.output")
33
+ txt_input = trans("menu.audio.input")
34
+ txt_ctrl_plugin = trans("menu.audio.control.plugin")
35
+ txt_ctrl_global = trans("menu.audio.control.global")
36
+ txt_cache_clear = trans("menu.audio.cache.clear")
37
+ txt_stop = trans("menu.audio.stop")
38
+
39
+ icon_cache = QIcon(":/icons/delete.svg")
40
+ icon_stop = QIcon(":/icons/mute.svg")
41
+
42
+ plugins_toggle = w.controller.plugins.toggle
43
+ voice_toggle = w.controller.access.voice.toggle_voice_control
44
+ audio_clear = w.controller.audio.clear_cache
45
+ audio_stop = w.controller.audio.stop_audio
46
+
47
+ menu = m.get('menu.audio')
48
+ is_new_menu = menu is None
49
+ if is_new_menu:
50
+ menu = w.menuBar().addMenu(title)
51
+ m['menu.audio'] = menu
52
+ else:
53
+ menu.setTitle(title)
54
+
55
+ act_output = m.get('audio.output')
56
+ if act_output is None:
57
+ act_output = QAction(txt_output, w, checkable=True)
58
+ m['audio.output'] = act_output
59
+ act_output.triggered.connect(lambda _=False: plugins_toggle('audio_output'))
60
+ else:
61
+ act_output.setText(txt_output)
62
+
63
+ act_input = m.get('audio.input')
64
+ if act_input is None:
65
+ act_input = QAction(txt_input, w, checkable=True)
66
+ m['audio.input'] = act_input
67
+ act_input.triggered.connect(lambda _=False: plugins_toggle('audio_input'))
68
+ else:
69
+ act_input.setText(txt_input)
70
+
71
+ act_ctrl_plugin = m.get('audio.control.plugin')
72
+ if act_ctrl_plugin is None:
73
+ act_ctrl_plugin = QAction(txt_ctrl_plugin, w, checkable=True)
74
+ m['audio.control.plugin'] = act_ctrl_plugin
75
+ act_ctrl_plugin.triggered.connect(lambda _=False: plugins_toggle('voice_control'))
76
+ else:
77
+ act_ctrl_plugin.setText(txt_ctrl_plugin)
78
+
79
+ act_ctrl_global = m.get('audio.control.global')
80
+ if act_ctrl_global is None:
81
+ act_ctrl_global = QAction(txt_ctrl_global, w, checkable=True)
82
+ m['audio.control.global'] = act_ctrl_global
83
+ act_ctrl_global.triggered.connect(lambda _=False: voice_toggle())
84
+ else:
85
+ act_ctrl_global.setText(txt_ctrl_global)
86
+
87
+ act_cache_clear = m.get('audio.cache.clear')
88
+ if act_cache_clear is None:
89
+ act_cache_clear = QAction(icon_cache, txt_cache_clear, w, checkable=False)
90
+ m['audio.cache.clear'] = act_cache_clear
91
+ act_cache_clear.triggered.connect(lambda _=False: audio_clear())
92
+ else:
93
+ act_cache_clear.setText(txt_cache_clear)
94
+ act_cache_clear.setIcon(icon_cache)
95
+
96
+ act_stop = m.get('audio.stop')
97
+ if act_stop is None:
98
+ act_stop = QAction(icon_stop, txt_stop, w, checkable=False)
99
+ m['audio.stop'] = act_stop
100
+ act_stop.triggered.connect(lambda _=False: audio_stop())
101
+ else:
102
+ act_stop.setText(txt_stop)
103
+ act_stop.setIcon(icon_stop)
104
+
105
+ if is_new_menu:
106
+ menu.addAction(act_input)
107
+ menu.addAction(act_output)
108
+ menu.addSeparator()
109
+ menu.addAction(act_ctrl_plugin)
110
+ menu.addAction(act_ctrl_global)
111
+ menu.addSeparator()
112
+ menu.addAction(act_cache_clear)
113
+ menu.addAction(act_stop)
@@ -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
  import os
@@ -15,7 +15,6 @@ from PySide6.QtGui import QAction, QIcon
15
15
  from PySide6.QtWidgets import QMenu
16
16
 
17
17
  from pygpt_net.utils import trans
18
- import pygpt_net.icons_rc
19
18
 
20
19
  from .lang import Lang
21
20
  from .theme import Theme
@@ -34,137 +33,132 @@ class Config:
34
33
 
35
34
  def setup(self):
36
35
  """Setup config menu"""
37
- self.window.ui.menu['config.settings'] = QAction(QIcon(":/icons/settings_filled.svg"),
38
- trans("menu.config.settings"), self.window)
39
- self.window.ui.menu['config.settings'].setMenuRole(QAction.MenuRole.NoRole)
40
-
41
- self.window.ui.menu['config.models'] = QMenu(trans("menu.config.models"), self.window)
42
-
43
- self.window.ui.menu['config.access'] = QAction(QIcon(":/icons/accessibility.svg"),
44
- trans("menu.config.access"), self.window)
45
- self.window.ui.menu['config.access'].setMenuRole(QAction.MenuRole.NoRole)
46
-
47
- # models
48
- self.window.ui.menu['config.models.edit'] = QAction(QIcon(":/icons/settings_filled.svg"),
49
- trans("menu.config.models.edit"), self.window)
50
- self.window.ui.menu['config.models.edit'].triggered.connect(
51
- lambda: self.window.controller.model.editor.toggle_editor())
52
- self.window.ui.menu['config.models.import.provider'] = QAction(QIcon(":/icons/reload.svg"),
53
- trans("menu.config.models.import.provider"),
54
- self.window)
55
- self.window.ui.menu['config.models.import.provider'].triggered.connect(
56
- lambda: self.window.controller.model.importer.toggle_editor())
57
-
58
- self.window.ui.menu['config.models'].addAction(self.window.ui.menu['config.models.edit'])
59
- self.window.ui.menu['config.models'].addAction(self.window.ui.menu['config.models.import.provider'])
60
-
61
-
62
- css_dir = os.path.join(self.window.core.config.path, 'css')
63
- css_files = os.listdir(css_dir)
64
- css_files = [f for f in css_files if not f.endswith('.backup')] # remove .backup files
65
- css_files = sorted(css_files) # sort by name
66
-
67
- json_files = []
68
- json_files.append("attachments.json")
69
- json_files.append("assistants.json")
70
- json_files.append("config.json")
71
- json_files.append("models.json")
72
- json_files.append("plugin_presets.json")
73
-
74
- # -------------------------------------------- #
75
-
76
- # create submenu for css files
77
- self.window.ui.menu['config.edit.css'] = QMenu(trans("menu.config.edit.css"), self.window)
36
+ w = self.window
37
+ m = w.ui.menu
38
+ tr = trans
39
+
40
+ icon_settings = QIcon(":/icons/settings_filled.svg")
41
+ icon_access = QIcon(":/icons/accessibility.svg")
42
+ icon_reload = QIcon(":/icons/reload.svg")
43
+ icon_edit = QIcon(":/icons/edit.svg")
44
+ icon_undo = QIcon(":/icons/undo.svg")
45
+ icon_add = QIcon(":/icons/add.svg")
46
+ icon_folder = QIcon(":/icons/folder_filled.svg")
47
+ icon_save = QIcon(":/icons/save.svg")
48
+
49
+ m['config.settings'] = QAction(icon_settings, tr("menu.config.settings"), w)
50
+ m['config.settings'].setMenuRole(QAction.MenuRole.NoRole)
51
+
52
+ m['config.models'] = QMenu(tr("menu.config.models"), w)
53
+
54
+ m['config.access'] = QAction(icon_access, tr("menu.config.access"), w)
55
+ m['config.access'].setMenuRole(QAction.MenuRole.NoRole)
56
+
57
+ m['config.models.edit'] = QAction(icon_settings, tr("menu.config.models.edit"), w)
58
+ m['config.models.edit'].triggered.connect(
59
+ lambda: w.controller.model.editor.toggle_editor()
60
+ )
61
+ m['config.models.import.provider'] = QAction(icon_reload, tr("menu.config.models.import.provider"), w)
62
+ m['config.models.import.provider'].triggered.connect(
63
+ lambda: w.controller.model.importer.toggle_editor()
64
+ )
65
+
66
+ m['config.models'].addAction(m['config.models.edit'])
67
+ m['config.models'].addAction(m['config.models.import.provider'])
68
+
69
+ css_dir = os.path.join(w.core.config.path, 'css')
70
+ css_files = sorted(f for f in os.listdir(css_dir) if not f.endswith('.backup'))
71
+
72
+ json_files = (
73
+ "attachments.json",
74
+ "assistants.json",
75
+ "config.json",
76
+ "models.json",
77
+ "plugin_presets.json",
78
+ )
79
+
80
+ m['config.edit.css'] = QMenu(tr("menu.config.edit.css"), w)
81
+ css_menu = m['config.edit.css']
78
82
 
79
83
  for css_file in css_files:
80
- name = css_file.split("/")[-1]
81
- self.window.ui.menu['config.edit.css.' + name] = QAction(QIcon(":/icons/edit.svg"),
82
- name, self.window)
83
- self.window.ui.menu['config.edit.css.' + name].triggered.connect(
84
- lambda checked=True, file=css_file: self.window.controller.settings.toggle_file_editor(file))
85
- self.window.ui.menu['config.edit.css'].addAction(self.window.ui.menu['config.edit.css.' + name])
86
-
87
- # restore css files
88
- self.window.ui.menu['config.edit.css'].addSeparator()
89
- self.window.ui.menu['config.edit.css.restore'] = QAction(QIcon(":/icons/undo.svg"),
90
- trans('menu.config.edit.css.restore'), self.window)
91
- self.window.ui.menu['config.edit.css.restore'].triggered.connect(
92
- lambda checked=True: self.window.controller.layout.restore_default_css(force=False))
93
- self.window.ui.menu['config.edit.css'].addAction(self.window.ui.menu['config.edit.css.restore'])
94
-
95
- # -------------------------------------------- #
96
-
97
- # create submenu for JSON files
98
- self.window.ui.menu['config.edit.json'] = QMenu(trans("menu.config.edit.json"), self.window)
84
+ name = os.path.basename(css_file)
85
+ key = 'config.edit.css.' + name
86
+ m[key] = QAction(icon_edit, name, w)
87
+ m[key].triggered.connect(
88
+ lambda checked=True, file=css_file: w.controller.settings.toggle_file_editor(file)
89
+ )
90
+ css_menu.addAction(m[key])
91
+
92
+ css_menu.addSeparator()
93
+ m['config.edit.css.restore'] = QAction(icon_undo, tr('menu.config.edit.css.restore'), w)
94
+ m['config.edit.css.restore'].triggered.connect(
95
+ lambda checked=True: w.controller.layout.restore_default_css(force=False)
96
+ )
97
+ css_menu.addAction(m['config.edit.css.restore'])
98
+
99
+ m['config.edit.json'] = QMenu(tr("menu.config.edit.json"), w)
100
+ json_menu = m['config.edit.json']
99
101
 
100
102
  for json_file in json_files:
101
103
  name = json_file
102
- self.window.ui.menu['config.edit.json.' + name] = QAction(QIcon(":/icons/edit.svg"),
103
- name, self.window)
104
- self.window.ui.menu['config.edit.json.' + name].triggered.connect(
105
- lambda checked=True, file=json_file: self.window.controller.settings.toggle_file_editor(file))
106
- self.window.ui.menu['config.edit.json'].addAction(self.window.ui.menu['config.edit.json.' + name])
107
-
108
- # -------------------------------------------- #
109
-
110
- # create submenu for profiles
111
- self.window.ui.menu['config.profiles'] = {}
112
- self.window.ui.menu['config.profile'] = QMenu(trans("menu.config.profile"), self.window)
113
-
114
- # add new
115
- self.window.ui.menu['config.profile.new'] = QAction(
116
- QIcon(":/icons/add.svg"), trans("menu.config.profile.new"), self.window, checkable=False)
117
- self.window.ui.menu['config.profile.new'].triggered.connect(
118
- lambda: self.window.controller.settings.profile.new())
119
- self.window.ui.menu['config.profile.new'].setMenuRole(QAction.MenuRole.NoRole)
120
- self.window.ui.menu['config.profile'].addAction(self.window.ui.menu['config.profile.new'])
121
-
122
- # edit
123
- self.window.ui.menu['config.profile.edit'] = QAction(
124
- QIcon(":/icons/edit.svg"), trans("menu.config.profile.edit"), self.window, checkable=False)
125
- self.window.ui.menu['config.profile.edit'].triggered.connect(
126
- lambda: self.window.controller.settings.profile.toggle_editor())
127
- self.window.ui.menu['config.profile.edit'].setMenuRole(QAction.MenuRole.NoRole)
128
- self.window.ui.menu['config.profile'].addAction(self.window.ui.menu['config.profile.edit'])
129
- self.window.ui.menu['config.profile'].addSeparator()
130
-
131
- # -------------------------------------------- #
132
-
133
- self.window.ui.menu['config.open_dir'] = QAction(QIcon(":/icons/folder_filled.svg"),
134
- trans("menu.config.open_dir"), self.window)
135
- self.window.ui.menu['config.change_dir'] = QAction(QIcon(":/icons/settings_filled.svg"),
136
- trans("menu.config.change_dir"), self.window)
137
- self.window.ui.menu['config.save'] = QAction(QIcon(":/icons/save.svg"),
138
- trans("menu.config.save"), self.window)
139
-
140
- self.window.ui.menu['config.settings'].triggered.connect(
141
- lambda: self.window.controller.settings.toggle_editor('settings'))
142
-
143
- self.window.ui.menu['config.access'].triggered.connect(
144
- lambda: self.window.controller.settings.open_section('access'))
145
-
146
- self.window.ui.menu['config.open_dir'].triggered.connect(
147
- lambda: self.window.controller.settings.open_config_dir())
148
-
149
- self.window.ui.menu['config.change_dir'].triggered.connect(
150
- lambda: self.window.controller.settings.workdir.change())
151
-
152
- self.window.ui.menu['config.save'].triggered.connect(
153
- lambda: self.window.controller.settings.save_all())
104
+ key = 'config.edit.json.' + name
105
+ m[key] = QAction(icon_edit, name, w)
106
+ m[key].triggered.connect(
107
+ lambda checked=True, file=json_file: w.controller.settings.toggle_file_editor(file)
108
+ )
109
+ json_menu.addAction(m[key])
110
+
111
+ m['config.profiles'] = {}
112
+ m['config.profile'] = QMenu(tr("menu.config.profile"), w)
113
+
114
+ m['config.profile.new'] = QAction(icon_add, tr("menu.config.profile.new"), w, checkable=False)
115
+ m['config.profile.new'].triggered.connect(
116
+ lambda: w.controller.settings.profile.new()
117
+ )
118
+ m['config.profile.new'].setMenuRole(QAction.MenuRole.NoRole)
119
+ m['config.profile'].addAction(m['config.profile.new'])
120
+
121
+ m['config.profile.edit'] = QAction(icon_edit, tr("menu.config.profile.edit"), w, checkable=False)
122
+ m['config.profile.edit'].triggered.connect(
123
+ lambda: w.controller.settings.profile.toggle_editor()
124
+ )
125
+ m['config.profile.edit'].setMenuRole(QAction.MenuRole.NoRole)
126
+ m['config.profile'].addAction(m['config.profile.edit'])
127
+ m['config.profile'].addSeparator()
128
+
129
+ m['config.open_dir'] = QAction(icon_folder, tr("menu.config.open_dir"), w)
130
+ m['config.change_dir'] = QAction(icon_settings, tr("menu.config.change_dir"), w)
131
+ m['config.save'] = QAction(icon_save, tr("menu.config.save"), w)
132
+
133
+ m['config.settings'].triggered.connect(
134
+ lambda: w.controller.settings.toggle_editor('settings')
135
+ )
136
+ m['config.access'].triggered.connect(
137
+ lambda: w.controller.settings.open_section('access')
138
+ )
139
+ m['config.open_dir'].triggered.connect(
140
+ lambda: w.controller.settings.open_config_dir()
141
+ )
142
+ m['config.change_dir'].triggered.connect(
143
+ lambda: w.controller.settings.workdir.change()
144
+ )
145
+ m['config.save'].triggered.connect(
146
+ lambda: w.controller.settings.save_all()
147
+ )
154
148
 
155
149
  self.lang.setup()
156
150
  self.theme.setup()
157
151
 
158
- self.window.ui.menu['menu.config'] = self.window.menuBar().addMenu(trans("menu.config"))
159
- self.window.ui.menu['menu.config'].addAction(self.window.ui.menu['config.settings'])
160
- self.window.ui.menu['menu.config'].addMenu(self.window.ui.menu['config.models'])
161
- self.window.ui.menu['menu.config'].addAction(self.window.ui.menu['config.access'])
162
-
163
- self.window.ui.menu['menu.config'].addMenu(self.window.ui.menu['menu.theme'])
164
- self.window.ui.menu['menu.config'].addMenu(self.window.ui.menu['menu.lang'])
165
- self.window.ui.menu['menu.config'].addMenu(self.window.ui.menu['config.edit.css'])
166
- self.window.ui.menu['menu.config'].addMenu(self.window.ui.menu['config.edit.json'])
167
- self.window.ui.menu['menu.config'].addMenu(self.window.ui.menu['config.profile'])
168
- self.window.ui.menu['menu.config'].addAction(self.window.ui.menu['config.open_dir'])
169
- self.window.ui.menu['menu.config'].addAction(self.window.ui.menu['config.change_dir'])
170
- self.window.ui.menu['menu.config'].addAction(self.window.ui.menu['config.save'])
152
+ m['menu.config'] = w.menuBar().addMenu(tr("menu.config"))
153
+ menu = m['menu.config']
154
+ menu.addAction(m['config.settings'])
155
+ menu.addMenu(m['config.models'])
156
+ menu.addAction(m['config.access'])
157
+ menu.addMenu(m['menu.theme'])
158
+ menu.addMenu(m['menu.lang'])
159
+ menu.addMenu(m['config.edit.css'])
160
+ menu.addMenu(m['config.edit.json'])
161
+ menu.addMenu(m['config.profile'])
162
+ menu.addAction(m['config.open_dir'])
163
+ menu.addAction(m['config.change_dir'])
164
+ menu.addAction(m['config.save'])