pygpt-net 2.4.55__py3-none-any.whl → 2.4.56__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 (67) hide show
  1. CHANGELOG.md +5 -0
  2. README.md +6 -1
  3. pygpt_net/CHANGELOG.txt +5 -0
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/controller/access/__init__.py +1 -3
  6. pygpt_net/controller/access/voice.py +20 -7
  7. pygpt_net/controller/{attachment.py → attachment/__init__.py} +0 -0
  8. pygpt_net/controller/{camera.py → camera/__init__.py} +1 -1
  9. pygpt_net/controller/{files.py → files/__init__.py} +0 -0
  10. pygpt_net/controller/{finder.py → finder/__init__.py} +0 -0
  11. pygpt_net/controller/{launcher.py → launcher/__init__.py} +0 -0
  12. pygpt_net/controller/{layout.py → layout/__init__.py} +0 -0
  13. pygpt_net/controller/{notepad.py → notepad/__init__.py} +0 -0
  14. pygpt_net/controller/settings/editor.py +4 -0
  15. pygpt_net/core/access/shortcuts.py +48 -29
  16. pygpt_net/core/{camera.py → camera/__init__.py} +5 -4
  17. pygpt_net/core/{command.py → command/__init__.py} +4 -3
  18. pygpt_net/core/{dispatcher.py → dispatcher/__init__.py} +0 -0
  19. pygpt_net/core/{history.py → history/__init__.py} +0 -2
  20. pygpt_net/core/{image.py → image/__init__.py} +0 -0
  21. pygpt_net/core/{info.py → info/__init__.py} +0 -0
  22. pygpt_net/core/{locale.py → locale/__init__.py} +0 -0
  23. pygpt_net/core/{notepad.py → notepad/__init__.py} +0 -0
  24. pygpt_net/core/{platforms.py → platforms/__init__.py} +0 -0
  25. pygpt_net/core/{plugins.py → plugins/__init__.py} +0 -0
  26. pygpt_net/core/{settings.py → settings/__init__.py} +0 -0
  27. pygpt_net/core/tabs/__init__.py +8 -6
  28. pygpt_net/core/{tokens.py → tokens/__init__.py} +0 -0
  29. pygpt_net/data/config/config.json +9 -9
  30. pygpt_net/data/config/models.json +3 -3
  31. pygpt_net/data/config/modes.json +3 -3
  32. pygpt_net/launcher.py +3 -2
  33. pygpt_net/plugin/audio_input/simple.py +2 -3
  34. pygpt_net/plugin/audio_input/worker.py +1 -1
  35. pygpt_net/provider/core/config/patch.py +13 -1
  36. pygpt_net/tools/code_interpreter/__init__.py +2 -1
  37. pygpt_net/tools/code_interpreter/ui/dialogs.py +10 -1
  38. pygpt_net/tools/code_interpreter/ui/widgets.py +56 -1
  39. pygpt_net/tools/html_canvas/__init__.py +2 -1
  40. pygpt_net/tools/html_canvas/ui/dialogs.py +10 -1
  41. pygpt_net/tools/html_canvas/ui/widgets.py +33 -1
  42. pygpt_net/ui/__init__.py +1 -1
  43. pygpt_net/ui/layout/chat/calendar.py +5 -2
  44. pygpt_net/ui/layout/chat/explorer.py +4 -2
  45. pygpt_net/ui/layout/chat/painter.py +4 -2
  46. pygpt_net/ui/main.py +63 -2
  47. pygpt_net/ui/widget/calendar/select.py +29 -1
  48. pygpt_net/ui/widget/draw/painter.py +25 -1
  49. pygpt_net/ui/widget/filesystem/explorer.py +24 -1
  50. pygpt_net/ui/widget/tabs/body.py +54 -4
  51. pygpt_net/ui/widget/textarea/calendar_note.py +26 -2
  52. pygpt_net/ui/widget/textarea/html.py +21 -2
  53. pygpt_net/ui/widget/textarea/notepad.py +37 -3
  54. pygpt_net/ui/widget/textarea/web.py +4 -2
  55. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.56.dist-info}/METADATA +7 -2
  56. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.56.dist-info}/RECORD +67 -67
  57. /pygpt_net/controller/{command.py → command/__init__.py} +0 -0
  58. /pygpt_net/controller/{mode.py → mode/__init__.py} +0 -0
  59. /pygpt_net/core/{installer.py → installer/__init__.py} +0 -0
  60. /pygpt_net/core/{models.py → models/__init__.py} +0 -0
  61. /pygpt_net/core/{modes.py → modes/__init__.py} +0 -0
  62. /pygpt_net/core/{presets.py → presets/__init__.py} +0 -0
  63. /pygpt_net/core/{profile.py → profile/__init__.py} +0 -0
  64. /pygpt_net/core/{worker.py → worker/__init__.py} +0 -0
  65. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.56.dist-info}/LICENSE +0 -0
  66. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.56.dist-info}/WHEEL +0 -0
  67. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.56.dist-info}/entry_points.txt +0 -0
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.12.12 01:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6 import QtCore
@@ -42,6 +42,15 @@ class ToolWidget:
42
42
  self.label_output = None # output label
43
43
  self.label_history = None # history label
44
44
 
45
+ def set_tab(self, tab):
46
+ """
47
+ Set tab
48
+
49
+ :param tab: Tab
50
+ """
51
+ self.output.set_tab(tab)
52
+ self.input.set_tab(tab)
53
+
45
54
  def setup(self, all: bool = True) -> QVBoxLayout:
46
55
  """
47
56
  Setup widget body
@@ -297,6 +306,29 @@ class PythonInput(QTextEdit):
297
306
  lambda: self.tool.update_input()
298
307
  )
299
308
  self.setFocus()
309
+ self.tab = None
310
+ self.installEventFilter(self)
311
+
312
+ def set_tab(self, tab):
313
+ """
314
+ Set tab
315
+
316
+ :param tab: Tab
317
+ """
318
+ self.tab = tab
319
+
320
+ def eventFilter(self, source, event):
321
+ """
322
+ Focus event filter
323
+
324
+ :param source: source
325
+ :param event: event
326
+ """
327
+ if event.type() == event.Type.FocusIn:
328
+ if self.tab is not None:
329
+ col_idx = self.tab.column_idx
330
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
331
+ return super().eventFilter(source, event)
300
332
 
301
333
  def update_stylesheet(self, data: str):
302
334
  """
@@ -364,6 +396,29 @@ class PythonOutput(BaseCodeEditor):
364
396
  self.setProperty('class', 'interpreter-output')
365
397
  self.default_stylesheet = ""
366
398
  self.setStyleSheet(self.default_stylesheet)
399
+ self.tab = None
400
+ self.installEventFilter(self)
401
+
402
+ def set_tab(self, tab):
403
+ """
404
+ Set tab
405
+
406
+ :param tab: Tab
407
+ """
408
+ self.tab = tab
409
+
410
+ def eventFilter(self, source, event):
411
+ """
412
+ Focus event filter
413
+
414
+ :param source: source
415
+ :param event: event
416
+ """
417
+ if event.type() == event.Type.FocusIn:
418
+ if self.tab is not None:
419
+ col_idx = self.tab.column_idx
420
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
421
+ return super().eventFilter(source, event)
367
422
 
368
423
  def clear_content(self):
369
424
  """Clear content"""
@@ -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 22:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -295,6 +295,7 @@ class HtmlCanvas(BaseTool):
295
295
  layout = canvas.widget.setup()
296
296
  widget = QWidget()
297
297
  widget.setLayout(layout)
298
+ canvas.set_tab(tab)
298
299
  self.load_output()
299
300
  return widget
300
301
 
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.12.09 23:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import re
@@ -15,6 +15,7 @@ from PySide6.QtCore import Qt
15
15
  from PySide6.QtGui import QAction, QIcon
16
16
  from PySide6.QtWidgets import QMenuBar, QVBoxLayout
17
17
 
18
+ from pygpt_net.core.tabs.tab import Tab
18
19
  from pygpt_net.ui.widget.dialog.base import BaseDialog
19
20
  from pygpt_net.utils import trans
20
21
 
@@ -71,6 +72,14 @@ class Tool:
71
72
  self.menu["file"].addAction(self.actions["file.clear"])
72
73
  return self.menu_bar
73
74
 
75
+ def set_tab(self, tab: Tab):
76
+ """
77
+ Set tab
78
+
79
+ :param tab: Tab
80
+ """
81
+ self.widget.set_tab(tab)
82
+
74
83
  def setup(self):
75
84
  """Setup canvas dialog"""
76
85
  self.layout = self.widget.setup()
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.12.09 23:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt, Slot, QUrl, QObject, Signal
@@ -34,6 +34,15 @@ class ToolWidget:
34
34
  self.edit = None # canvas edit
35
35
  self.btn_edit = None # edit checkbox
36
36
 
37
+ def set_tab(self, tab):
38
+ """
39
+ Set tab
40
+
41
+ :param tab: Tab
42
+ """
43
+ self.output.set_tab(tab)
44
+ self.edit.set_tab(tab)
45
+
37
46
  def setup(self) -> QVBoxLayout:
38
47
  """
39
48
  Setup widget body
@@ -128,6 +137,29 @@ class CanvasEdit(BaseCodeEditor):
128
137
  self.setProperty('class', 'interpreter-output')
129
138
  self.default_stylesheet = ""
130
139
  self.setStyleSheet(self.default_stylesheet)
140
+ self.tab = None
141
+ self.installEventFilter(self)
142
+
143
+ def set_tab(self, tab):
144
+ """
145
+ Set tab
146
+
147
+ :param tab: Tab
148
+ """
149
+ self.tab = tab
150
+
151
+ def eventFilter(self, source, event):
152
+ """
153
+ Focus event filter
154
+
155
+ :param source: source
156
+ :param event: event
157
+ """
158
+ if event.type() == event.Type.FocusIn:
159
+ if self.tab is not None:
160
+ col_idx = self.tab.column_idx
161
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
162
+ return super().eventFilter(source, event)
131
163
 
132
164
 
133
165
  class ToolSignals(QObject):
pygpt_net/ui/__init__.py CHANGED
@@ -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.01.17 13:00:00 #
9
+ # Updated Date: 2025.01.19 03:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -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.05 23:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt
@@ -44,7 +44,10 @@ class Calendar:
44
44
  :return: QWidget
45
45
  """
46
46
  self.init()
47
- return self.window.core.tabs.from_widget(self.setup_calendar())
47
+ body = self.window.core.tabs.from_widget(self.setup_calendar())
48
+ body.append(self.window.ui.calendar['note'])
49
+ body.append(self.window.ui.calendar['select'])
50
+ return body
48
51
 
49
52
  def setup_filters(self) -> QWidget:
50
53
  """
@@ -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.05 23:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.ui.widget.tabs.body import TabBody
@@ -36,4 +36,6 @@ class Explorer:
36
36
  self.window.ui.nodes['output_files'] = FileExplorer(self.window, path, index_data)
37
37
 
38
38
  # build tab body
39
- return self.window.core.tabs.from_widget(self.window.ui.nodes['output_files'])
39
+ body = self.window.core.tabs.from_widget(self.window.ui.nodes['output_files'])
40
+ body.append(self.window.ui.nodes['output_files'])
41
+ return body
@@ -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.05 23:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QPixmap, QIcon
@@ -83,7 +83,9 @@ class Painter:
83
83
  """
84
84
  # build tab body
85
85
  self.init()
86
- return self.window.core.tabs.from_layout(self.setup_painter())
86
+ body = self.window.core.tabs.from_layout(self.setup_painter())
87
+ body.append(self.window.ui.painter)
88
+ return body
87
89
 
88
90
  def setup_painter(self) -> QVBoxLayout:
89
91
  """
pygpt_net/ui/main.py CHANGED
@@ -6,16 +6,19 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.12.09 23:00:00 #
9
+ # Updated Date: 2025.01.19 03:00:00 #
10
10
  # ================================================== #
11
11
 
12
+ import copy
12
13
  import os
13
14
 
15
+ from PySide6 import QtWidgets
14
16
  from PySide6.QtCore import QTimer, Signal, Slot, QThreadPool, QEvent, Qt, QLoggingCategory
17
+ from PySide6.QtGui import QShortcut, QKeySequence
15
18
  from PySide6.QtWidgets import QApplication, QMainWindow
16
19
  from qt_material import QtStyleTools
17
20
 
18
- from pygpt_net.core.events import BaseEvent, KernelEvent
21
+ from pygpt_net.core.events import BaseEvent, KernelEvent, ControlEvent
19
22
  from pygpt_net.container import Container
20
23
  from pygpt_net.controller import Controller
21
24
  from pygpt_net.tools import Tools
@@ -85,6 +88,9 @@ class MainWindow(QMainWindow, QtStyleTools):
85
88
  self.ui = UI(self)
86
89
  self.ui.init()
87
90
 
91
+ # global shortcuts
92
+ self.shortcuts = []
93
+
88
94
  # setup signals
89
95
  self.statusChanged.connect(self.update_status)
90
96
  self.stateChanged.connect(self.update_state)
@@ -338,3 +344,58 @@ class MainWindow(QMainWindow, QtStyleTools):
338
344
  self.showNormal()
339
345
  self.activateWindow()
340
346
  self.ui.tray_menu['restore'].setVisible(False)
347
+
348
+ def setup_global_shortcuts(self):
349
+ """Setup global shortcuts"""
350
+ if not hasattr(self, 'core') or not hasattr(self.core, 'config'):
351
+ return
352
+
353
+ # unregister existing shortcuts
354
+ if hasattr(self, 'shortcuts'):
355
+ for shortcut in self.shortcuts:
356
+ # disconnect signals
357
+ shortcut.activated.disconnect()
358
+ # disable the shortcut to prevent it from handling events
359
+ shortcut.setEnabled(False)
360
+ # remove the parent to break the QObject tree
361
+ shortcut.setParent(None)
362
+ # schedule the shortcut for deletion
363
+ shortcut.deleteLater()
364
+ # clear the list of shortcuts
365
+ self.shortcuts.clear()
366
+ # process events to delete shortcuts immediately
367
+ QtWidgets.QApplication.processEvents()
368
+ else:
369
+ self.shortcuts = []
370
+
371
+ # Handle the Escape key
372
+ escape_shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self)
373
+ escape_shortcut.setContext(Qt.ApplicationShortcut)
374
+ escape_shortcut.activated.connect(self.controller.access.on_escape)
375
+ self.shortcuts.append(escape_shortcut)
376
+
377
+ config = copy.deepcopy(self.core.config.get("access.shortcuts"))
378
+ for shortcut_conf in config:
379
+ print(shortcut_conf)
380
+ key = shortcut_conf.get('key', '')
381
+ key_modifier = shortcut_conf.get('key_modifier', '')
382
+ action_name = shortcut_conf.get('action')
383
+
384
+ if not key or not action_name:
385
+ continue
386
+
387
+ key_sequence_parts = []
388
+ if key_modifier and key_modifier != '---':
389
+ if key_modifier == "Control":
390
+ key_modifier = "Ctrl"
391
+ key_sequence_parts.append(key_modifier)
392
+ key_sequence_parts.append(key)
393
+ key_sequence_str = '+'.join(key_sequence_parts)
394
+ key_sequence = QKeySequence(key_sequence_str)
395
+
396
+ shortcut = QShortcut(key_sequence, self)
397
+ shortcut.setContext(Qt.ApplicationShortcut)
398
+ shortcut.activated.connect(
399
+ lambda checked=False, action=action_name: self.dispatch(ControlEvent(action))
400
+ )
401
+ self.shortcuts.append(shortcut)
@@ -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.08.29 04:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import QRect, QDate
13
13
  from PySide6.QtGui import QColor, QBrush, QFont, Qt, QAction, QContextMenuEvent, QIcon, QPixmap, QPen
14
14
  from PySide6.QtWidgets import QCalendarWidget, QMenu
15
15
 
16
+ from pygpt_net.core.tabs.tab import Tab
16
17
  from pygpt_net.utils import trans
17
18
  import pygpt_net.icons_rc
18
19
 
@@ -44,6 +45,29 @@ class CalendarSelect(QCalendarWidget):
44
45
  self.setContextMenuPolicy(Qt.CustomContextMenu)
45
46
  self.customContextMenuRequested.connect(self.open_context_menu)
46
47
  self.setProperty('class', 'calendar')
48
+ self.tab = None
49
+ self.installEventFilter(self)
50
+
51
+ def set_tab(self, tab: Tab):
52
+ """
53
+ Set tab
54
+
55
+ :param tab: Tab
56
+ """
57
+ self.tab = tab
58
+
59
+ def eventFilter(self, source, event):
60
+ """
61
+ Focus event filter
62
+
63
+ :param source: source
64
+ :param event: event
65
+ """
66
+ if event.type() == event.Type.FocusIn:
67
+ if self.tab is not None:
68
+ col_idx = self.tab.column_idx
69
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
70
+ return super().eventFilter(source, event)
47
71
 
48
72
  def page_changed(self, year, month):
49
73
  """
@@ -172,6 +196,10 @@ class CalendarSelect(QCalendarWidget):
172
196
  # if date in self.counters['ctx']:
173
197
  self.window.controller.calendar.on_ctx_select(year, month, day)
174
198
 
199
+ if self.tab is not None:
200
+ col_idx = self.tab.column_idx
201
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
202
+
175
203
  def add_ctx(self, date: QDate, num: int):
176
204
  """
177
205
  Add ctx counter to counter list
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.04.12 08:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import datetime
@@ -15,6 +15,7 @@ from PySide6.QtCore import Qt, QPoint
15
15
  from PySide6.QtGui import QImage, QPainter, QPen, QAction, QIcon, QKeySequence
16
16
  from PySide6.QtWidgets import QMenu, QWidget, QFileDialog, QMessageBox, QApplication
17
17
 
18
+ from pygpt_net.core.tabs.tab import Tab
18
19
  from pygpt_net.utils import trans
19
20
  import pygpt_net.icons_rc
20
21
 
@@ -35,6 +36,16 @@ class PainterWidget(QWidget):
35
36
  self.undoLimit = 10
36
37
  self.setFocusPolicy(Qt.StrongFocus)
37
38
  self.setFocus()
39
+ self.installEventFilter(self)
40
+ self.tab = None
41
+
42
+ def set_tab(self, tab: Tab):
43
+ """
44
+ Set tab
45
+
46
+ :param tab: Tab
47
+ """
48
+ self.tab = tab
38
49
 
39
50
  def handle_paste(self):
40
51
  """Handle clipboard paste"""
@@ -353,3 +364,16 @@ class PainterWidget(QWidget):
353
364
  painter = QPainter(new)
354
365
  painter.drawImage(QPoint(0, 0), self.image)
355
366
  self.image = new
367
+
368
+ def eventFilter(self, source, event):
369
+ """
370
+ Focus event filter
371
+
372
+ :param source: source
373
+ :param event: event
374
+ """
375
+ if event.type() == event.Type.FocusIn:
376
+ if self.tab is not None:
377
+ col_idx = self.tab.column_idx
378
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
379
+ return super().eventFilter(source, event)
@@ -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.12 04:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import datetime
@@ -118,6 +118,29 @@ class FileExplorer(QWidget):
118
118
  vertical-align: middle;
119
119
  }
120
120
  """)
121
+ self.tab = None
122
+ self.installEventFilter(self)
123
+
124
+ def eventFilter(self, source, event):
125
+ """
126
+ Focus event filter
127
+
128
+ :param source: source
129
+ :param event: event
130
+ """
131
+ if event.type() == event.Type.FocusIn:
132
+ if self.tab is not None:
133
+ col_idx = self.tab.column_idx
134
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
135
+ return super().eventFilter(source, event)
136
+
137
+ def set_tab(self, tab: Tab):
138
+ """
139
+ Set tab
140
+
141
+ :param tab: Tab
142
+ """
143
+ self.tab = tab
121
144
 
122
145
  def setOwner(self, owner: Tab):
123
146
  """
@@ -6,18 +6,48 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.12.09 23:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
- from PySide6.QtWidgets import QTabWidget
12
+ from PySide6.QtCore import QEvent
13
+ from PySide6.QtWidgets import QTabWidget, QWidget
13
14
 
14
15
  from pygpt_net.core.tabs.tab import Tab
15
16
 
16
17
 
17
18
  class TabBody(QTabWidget):
18
- def __init__(self):
19
+ def __init__(self, window=None):
19
20
  super(TabBody, self).__init__()
21
+ self.window = window
20
22
  self.owner = None
23
+ self.body = []
24
+ self.installEventFilter(self)
25
+
26
+ def append(self, body: QWidget):
27
+ """
28
+ Append tab body (parent widget)
29
+
30
+ :param body: tab body widget
31
+ """
32
+ self.body.append(body)
33
+
34
+ def get_body(self):
35
+ """
36
+ Get tab body (parent widget)
37
+
38
+ :return: tab body widget
39
+ """
40
+ return self.body
41
+
42
+ def attach_tab(self, tab: Tab):
43
+ """
44
+ Attach tab to body
45
+
46
+ :param tab: tab instance
47
+ """
48
+ for body in self.body:
49
+ if hasattr(body, 'set_tab'):
50
+ body.set_tab(tab)
21
51
 
22
52
  def setOwner(self, owner: Tab):
23
53
  """
@@ -26,6 +56,7 @@ class TabBody(QTabWidget):
26
56
  :param owner: parent tab instance
27
57
  """
28
58
  self.owner = owner
59
+ self.attach_tab(owner)
29
60
 
30
61
  def getOwner(self) -> Tab:
31
62
  """
@@ -33,4 +64,23 @@ class TabBody(QTabWidget):
33
64
 
34
65
  :return: parent tab instance
35
66
  """
36
- return self.owner
67
+ return self.owner
68
+
69
+ def eventFilter(self, source, event):
70
+ """
71
+ Focus event filter
72
+
73
+ :param source: source
74
+ :param event: event
75
+ """
76
+ if (event.type() == QEvent.ChildAdded and
77
+ source is self and
78
+ event.child().isWidgetType()):
79
+ self._glwidget = event.child()
80
+ self._glwidget.installEventFilter(self)
81
+ elif (event.type() == event.Type.MouseButtonPress):
82
+ # handle column focus
83
+ if self.owner is not None:
84
+ col_idx = self.owner.column_idx
85
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
86
+ return super().eventFilter(source, event)
@@ -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.04.11 16:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt
13
13
  from PySide6.QtGui import QAction, QIcon, QKeySequence
14
14
  from PySide6.QtWidgets import QTextEdit
15
15
 
16
+ from pygpt_net.core.tabs.tab import Tab
16
17
  from pygpt_net.core.text.finder import Finder
17
18
  from pygpt_net.utils import trans
18
19
  import pygpt_net.icons_rc
@@ -21,7 +22,7 @@ import pygpt_net.icons_rc
21
22
  class CalendarNote(QTextEdit):
22
23
  def __init__(self, window=None):
23
24
  """
24
- Notepad
25
+ Calendar note widget
25
26
 
26
27
  :param window: main window
27
28
  """
@@ -34,6 +35,29 @@ class CalendarNote(QTextEdit):
34
35
  self.textChanged.connect(self.text_changed)
35
36
  self.max_font_size = 42
36
37
  self.min_font_size = 8
38
+ self.tab = None
39
+ self.installEventFilter(self)
40
+
41
+ def eventFilter(self, source, event):
42
+ """
43
+ Focus event filter
44
+
45
+ :param source: source
46
+ :param event: event
47
+ """
48
+ if event.type() == event.Type.FocusIn:
49
+ if self.tab is not None:
50
+ col_idx = self.tab.column_idx
51
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
52
+ return super().eventFilter(source, event)
53
+
54
+ def set_tab(self, tab: Tab):
55
+ """
56
+ Set tab
57
+
58
+ :param tab: Tab
59
+ """
60
+ self.tab = tab
37
61
 
38
62
  def text_changed(self):
39
63
  """On parent textarea text changed"""
@@ -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: 2024.12.09 00:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import re
13
13
 
14
- from PySide6.QtCore import Qt, QObject, Signal, Slot
14
+ from PySide6.QtCore import Qt, QObject, Signal, Slot, QEvent
15
15
  from PySide6.QtWebChannel import QWebChannel
16
16
  from PySide6.QtWebEngineCore import QWebEngineSettings, QWebEnginePage
17
17
  from PySide6.QtWebEngineWidgets import QWebEngineView
@@ -43,6 +43,7 @@ class HtmlOutput(QWebEngineView):
43
43
  self.html_content = ""
44
44
  self.meta = None
45
45
  self.tab = None
46
+ self.installEventFilter(self)
46
47
 
47
48
  def set_tab(self, tab):
48
49
  """
@@ -213,6 +214,24 @@ class HtmlOutput(QWebEngineView):
213
214
  super(HtmlOutput, self).focusInEvent(e)
214
215
  self.window.controller.finder.focus_in(self.finder)
215
216
 
217
+ def eventFilter(self, source, event):
218
+ """
219
+ Focus event filter
220
+
221
+ :param source: source
222
+ :param event: event
223
+ """
224
+ if (event.type() == QEvent.ChildAdded and
225
+ source is self and
226
+ event.child().isWidgetType()):
227
+ self._glwidget = event.child()
228
+ self._glwidget.installEventFilter(self)
229
+ elif (event.type() == event.Type.MouseButtonPress):
230
+ if self.tab:
231
+ col_idx = self.tab.column_idx
232
+ self.window.controller.ui.tabs.on_column_focus(col_idx)
233
+ return super().eventFilter(source, event)
234
+
216
235
 
217
236
  class CustomWebEnginePage(QWebEnginePage):
218
237
  """Custom WebEnginePage to handle web events"""