pygpt-net 2.4.37__py3-none-any.whl → 2.4.39__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.
- CHANGELOG.md +11 -0
- README.md +24 -5
- pygpt_net/CHANGELOG.txt +11 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/__init__.py +3 -1
- pygpt_net/controller/calendar/__init__.py +3 -1
- pygpt_net/controller/chat/render.py +8 -5
- pygpt_net/controller/config/placeholder.py +29 -0
- pygpt_net/controller/ctx/__init__.py +32 -24
- pygpt_net/controller/ctx/common.py +3 -2
- pygpt_net/controller/dialogs/confirm.py +2 -2
- pygpt_net/controller/lang/custom.py +2 -7
- pygpt_net/controller/lang/mapping.py +2 -2
- pygpt_net/controller/layout.py +2 -2
- pygpt_net/controller/notepad.py +8 -5
- pygpt_net/controller/settings/editor.py +6 -0
- pygpt_net/controller/theme/__init__.py +33 -8
- pygpt_net/controller/theme/common.py +22 -1
- pygpt_net/controller/theme/markdown.py +26 -14
- pygpt_net/controller/theme/menu.py +26 -5
- pygpt_net/controller/ui/tabs.py +201 -58
- pygpt_net/core/attachments/context.py +14 -12
- pygpt_net/core/audio/__init__.py +59 -1
- pygpt_net/core/ctx/__init__.py +11 -1
- pygpt_net/core/ctx/container.py +16 -9
- pygpt_net/core/ctx/output.py +86 -67
- pygpt_net/core/debug/tabs.py +3 -2
- pygpt_net/core/filesystem/__init__.py +5 -19
- pygpt_net/core/filesystem/url.py +7 -3
- pygpt_net/core/render/base.py +14 -3
- pygpt_net/core/render/markdown/renderer.py +3 -1
- pygpt_net/core/render/plain/renderer.py +3 -3
- pygpt_net/core/render/web/body.py +39 -17
- pygpt_net/core/render/web/renderer.py +7 -5
- pygpt_net/core/tabs/__init__.py +180 -71
- pygpt_net/core/tabs/tab.py +13 -4
- pygpt_net/data/config/config.json +14 -4
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/modes.json +3 -3
- pygpt_net/data/config/settings.json +55 -10
- pygpt_net/data/config/settings_section.json +3 -0
- pygpt_net/data/css/style.light.css +1 -0
- pygpt_net/data/css/{web.css → web-blocks.css} +144 -133
- pygpt_net/data/css/web-chatgpt.css +342 -0
- pygpt_net/data/css/web-chatgpt.dark.css +64 -0
- pygpt_net/data/css/web-chatgpt.light.css +75 -0
- pygpt_net/data/css/web-chatgpt_wide.css +342 -0
- pygpt_net/data/css/web-chatgpt_wide.dark.css +64 -0
- pygpt_net/data/css/web-chatgpt_wide.light.css +75 -0
- pygpt_net/data/locale/locale.de.ini +12 -0
- pygpt_net/data/locale/locale.en.ini +14 -1
- pygpt_net/data/locale/locale.es.ini +12 -0
- pygpt_net/data/locale/locale.fr.ini +12 -0
- pygpt_net/data/locale/locale.it.ini +12 -0
- pygpt_net/data/locale/locale.pl.ini +12 -0
- pygpt_net/data/locale/locale.uk.ini +12 -0
- pygpt_net/data/locale/locale.zh.ini +12 -0
- pygpt_net/plugin/audio_input/simple.py +21 -5
- pygpt_net/provider/core/config/patch.py +22 -1
- pygpt_net/provider/core/ctx/base.py +4 -1
- pygpt_net/provider/core/ctx/db_sqlite/__init__.py +10 -1
- pygpt_net/provider/core/ctx/db_sqlite/storage.py +22 -1
- pygpt_net/ui/layout/chat/input.py +10 -18
- pygpt_net/ui/layout/chat/output.py +26 -44
- pygpt_net/ui/layout/toolbox/footer.py +18 -2
- pygpt_net/ui/menu/config.py +7 -11
- pygpt_net/ui/menu/theme.py +9 -2
- pygpt_net/ui/widget/lists/context.py +1 -0
- pygpt_net/ui/widget/tabs/layout.py +195 -0
- pygpt_net/ui/widget/tabs/output.py +124 -35
- pygpt_net/ui/widget/textarea/html.py +11 -1
- pygpt_net/ui/widget/textarea/output.py +10 -1
- pygpt_net/ui/widget/textarea/search_input.py +4 -1
- pygpt_net/ui/widget/textarea/web.py +49 -9
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.dist-info}/METADATA +25 -6
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.dist-info}/RECORD +81 -74
- /pygpt_net/data/css/{web.dark.css → web-blocks.dark.css} +0 -0
- /pygpt_net/data/css/{web.light.css → web-blocks.light.css} +0 -0
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.dist-info}/LICENSE +0 -0
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.dist-info}/WHEEL +0 -0
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.39.dist-info}/entry_points.txt +0 -0
pygpt_net/ui/menu/theme.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: 2024.
|
9
|
+
# Updated Date: 2024.12.07 21:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtGui import QAction, QIcon
|
@@ -28,10 +28,14 @@ class Theme:
|
|
28
28
|
def setup(self):
|
29
29
|
"""Setup theme menu"""
|
30
30
|
self.window.ui.menu['theme'] = {}
|
31
|
+
self.window.ui.menu['theme_style'] = {}
|
31
32
|
self.window.ui.menu['theme_syntax'] = {}
|
32
33
|
self.window.ui.menu['theme.layout.density'] = {}
|
33
34
|
self.window.ui.menu['menu.theme'] = QMenu(trans("menu.theme"), self.window)
|
34
35
|
|
36
|
+
# styles
|
37
|
+
self.window.ui.menu['theme.style'] = QMenu(trans("menu.theme.style"), self.window)
|
38
|
+
|
35
39
|
# color themes
|
36
40
|
self.window.ui.menu['theme.dark'] = QMenu(trans("menu.theme.dark"), self.window)
|
37
41
|
self.window.ui.menu['theme.light'] = QMenu(trans("menu.theme.light"), self.window)
|
@@ -40,12 +44,14 @@ class Theme:
|
|
40
44
|
# layout density
|
41
45
|
self.window.ui.menu['theme.density'] = QMenu(trans("menu.theme.density"), self.window)
|
42
46
|
|
47
|
+
"""
|
43
48
|
# blocks
|
44
49
|
self.window.ui.menu['theme.blocks'] = QAction(trans("menu.theme.blocks"), self.window, checkable=True)
|
45
50
|
self.window.ui.menu['theme.blocks'].triggered.connect(
|
46
51
|
lambda: self.window.controller.theme.toggle_option('render.blocks'))
|
47
52
|
self.window.ui.menu['theme.blocks'].setCheckable(True)
|
48
53
|
self.window.ui.menu['theme.blocks'].setChecked(self.window.core.config.get('render.blocks'))
|
54
|
+
"""
|
49
55
|
|
50
56
|
# tooltips
|
51
57
|
self.window.ui.menu['theme.tooltips'] = QAction(trans("menu.theme.tooltips"), self.window, checkable=True)
|
@@ -62,10 +68,11 @@ class Theme:
|
|
62
68
|
self.window.ui.menu['theme.settings'].triggered.connect(
|
63
69
|
lambda: self.window.controller.settings.open_section('layout'))
|
64
70
|
|
71
|
+
self.window.ui.menu['menu.theme'].addMenu(self.window.ui.menu['theme.style'])
|
65
72
|
self.window.ui.menu['menu.theme'].addMenu(self.window.ui.menu['theme.dark'])
|
66
73
|
self.window.ui.menu['menu.theme'].addMenu(self.window.ui.menu['theme.light'])
|
67
74
|
self.window.ui.menu['menu.theme'].addMenu(self.window.ui.menu['theme.syntax'])
|
68
75
|
self.window.ui.menu['menu.theme'].addMenu(self.window.ui.menu['theme.density'])
|
69
|
-
self.window.ui.menu['menu.theme'].addAction(self.window.ui.menu['theme.blocks'])
|
76
|
+
# self.window.ui.menu['menu.theme'].addAction(self.window.ui.menu['theme.blocks'])
|
70
77
|
self.window.ui.menu['menu.theme'].addAction(self.window.ui.menu['theme.tooltips'])
|
71
78
|
self.window.ui.menu['menu.theme'].addAction(self.window.ui.menu['theme.settings'])
|
@@ -0,0 +1,195 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# ================================================== #
|
4
|
+
# This file is a part of PYGPT package #
|
5
|
+
# Website: https://pygpt.net #
|
6
|
+
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
|
+
# MIT License #
|
8
|
+
# Created By : Marcin Szczygliński #
|
9
|
+
# Updated Date: 2024.12.09 03:00:00 #
|
10
|
+
# ================================================== #
|
11
|
+
|
12
|
+
from PySide6.QtCore import Qt, QObject, QEvent
|
13
|
+
from PySide6.QtWidgets import QTabWidget, QWidget, QVBoxLayout, QSplitter, QSizePolicy
|
14
|
+
|
15
|
+
from pygpt_net.ui.widget.tabs.output import OutputTabs
|
16
|
+
|
17
|
+
|
18
|
+
class OutputColumn(QWidget):
|
19
|
+
def __init__(self, window=None):
|
20
|
+
"""
|
21
|
+
Output column
|
22
|
+
|
23
|
+
:param window: window instance
|
24
|
+
"""
|
25
|
+
super(OutputColumn, self).__init__(window)
|
26
|
+
self.window = window
|
27
|
+
self.idx = -1
|
28
|
+
self.tabs = OutputTabs(self.window, column=self)
|
29
|
+
self.layout = QVBoxLayout()
|
30
|
+
self.layout.addWidget(self.tabs)
|
31
|
+
self.layout.setContentsMargins(0, 0, 0, 0)
|
32
|
+
self.setLayout(self.layout)
|
33
|
+
self.filter = FocusEventFilter(self, self.on_focus)
|
34
|
+
self.installEventFilter(self.filter)
|
35
|
+
self.setFocusPolicy(Qt.StrongFocus)
|
36
|
+
|
37
|
+
def on_focus(self, widget):
|
38
|
+
"""
|
39
|
+
On widget clicked
|
40
|
+
|
41
|
+
:param widget: widget
|
42
|
+
"""
|
43
|
+
self.window.controller.ui.tabs.on_column_focus(self.idx)
|
44
|
+
widget.setFocus()
|
45
|
+
|
46
|
+
def set_idx(self, idx: int):
|
47
|
+
"""
|
48
|
+
Set index
|
49
|
+
|
50
|
+
:param idx: int
|
51
|
+
"""
|
52
|
+
self.idx = idx
|
53
|
+
|
54
|
+
def get_idx(self) -> int:
|
55
|
+
"""
|
56
|
+
Get index
|
57
|
+
|
58
|
+
:return: int
|
59
|
+
"""
|
60
|
+
return self.idx
|
61
|
+
|
62
|
+
def set_tabs(self, tabs: QTabWidget):
|
63
|
+
"""
|
64
|
+
Set tabs widget
|
65
|
+
|
66
|
+
:param tabs: QTabWidget
|
67
|
+
"""
|
68
|
+
self.tabs = tabs
|
69
|
+
|
70
|
+
def get_tabs(self) -> OutputTabs:
|
71
|
+
"""
|
72
|
+
Get tabs
|
73
|
+
|
74
|
+
:return: OutputTabs
|
75
|
+
"""
|
76
|
+
return self.tabs
|
77
|
+
|
78
|
+
|
79
|
+
class OutputLayout(QWidget):
|
80
|
+
def __init__(self, window=None):
|
81
|
+
"""
|
82
|
+
Output layout
|
83
|
+
|
84
|
+
:param window: window instance
|
85
|
+
"""
|
86
|
+
super(OutputLayout, self).__init__(window)
|
87
|
+
self.window = window
|
88
|
+
self.columns = []
|
89
|
+
|
90
|
+
column1 = OutputColumn(self.window)
|
91
|
+
column2 = OutputColumn(self.window)
|
92
|
+
self.add_column(column1)
|
93
|
+
self.add_column(column2)
|
94
|
+
|
95
|
+
self.splitter = QSplitter(Qt.Horizontal)
|
96
|
+
self.splitter.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
97
|
+
for column in self.columns:
|
98
|
+
self.splitter.addWidget(column)
|
99
|
+
|
100
|
+
self.window.ui.splitters['columns'] = self.splitter
|
101
|
+
|
102
|
+
self.layout = QVBoxLayout()
|
103
|
+
self.layout.addWidget(self.splitter, stretch=1)
|
104
|
+
self.layout.setContentsMargins(0, 0, 0, 0)
|
105
|
+
self.setLayout(self.layout)
|
106
|
+
|
107
|
+
def get_next_idx(self) -> int:
|
108
|
+
"""
|
109
|
+
Get next index
|
110
|
+
|
111
|
+
:return: int
|
112
|
+
"""
|
113
|
+
return len(self.columns)
|
114
|
+
|
115
|
+
def add_column(self, column: OutputColumn):
|
116
|
+
"""
|
117
|
+
Add column
|
118
|
+
|
119
|
+
:param column: OutputColumn
|
120
|
+
"""
|
121
|
+
idx = self.get_next_idx()
|
122
|
+
column.set_idx(idx)
|
123
|
+
self.columns.append(column)
|
124
|
+
|
125
|
+
def get_tabs_by_idx(self, idx: int) -> OutputTabs:
|
126
|
+
"""
|
127
|
+
Get tabs by column index
|
128
|
+
|
129
|
+
:param idx: int
|
130
|
+
:return: OutputTabs
|
131
|
+
"""
|
132
|
+
for column in self.columns:
|
133
|
+
if column.idx == idx:
|
134
|
+
return column.tabs
|
135
|
+
return None
|
136
|
+
|
137
|
+
def get_active_tabs(self) -> OutputTabs:
|
138
|
+
"""
|
139
|
+
Get active tabs
|
140
|
+
|
141
|
+
:return: OutputTabs
|
142
|
+
"""
|
143
|
+
current = self.window.controller.ui.tabs.get_current_column_idx()
|
144
|
+
for column in self.columns:
|
145
|
+
if column.idx == current:
|
146
|
+
return column.tabs
|
147
|
+
|
148
|
+
def get_column_by_idx(self, idx: int) -> OutputColumn:
|
149
|
+
"""
|
150
|
+
Get column by index
|
151
|
+
|
152
|
+
:param idx: int
|
153
|
+
:return: OutputColumn
|
154
|
+
"""
|
155
|
+
for column in self.columns:
|
156
|
+
if column.idx == idx:
|
157
|
+
return column
|
158
|
+
return None
|
159
|
+
|
160
|
+
def get_active_column(self) -> OutputColumn:
|
161
|
+
"""
|
162
|
+
Get active column
|
163
|
+
|
164
|
+
:return: OutputColumn
|
165
|
+
"""
|
166
|
+
current = self.window.controller.ui.tabs.get_current_column_idx()
|
167
|
+
for column in self.columns:
|
168
|
+
if column.idx == current:
|
169
|
+
return column
|
170
|
+
|
171
|
+
class FocusEventFilter(QObject):
|
172
|
+
def __init__(self, column, callback):
|
173
|
+
"""
|
174
|
+
Column event filter
|
175
|
+
|
176
|
+
:param column: parent column
|
177
|
+
:param callback: callback
|
178
|
+
"""
|
179
|
+
super().__init__()
|
180
|
+
self.column = column
|
181
|
+
self.callback = callback
|
182
|
+
|
183
|
+
def eventFilter(self, obj, event):
|
184
|
+
"""
|
185
|
+
Click event filter
|
186
|
+
|
187
|
+
:param obj: object
|
188
|
+
:param event: event
|
189
|
+
"""
|
190
|
+
if event.type() == QEvent.MouseButtonPress or event.type() == QEvent.FocusIn:
|
191
|
+
widget = obj
|
192
|
+
if widget is not None:
|
193
|
+
self.callback(widget)
|
194
|
+
return False
|
195
|
+
return False
|
@@ -6,10 +6,10 @@
|
|
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.
|
9
|
+
# Updated Date: 2024.12.09 03:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
|
-
from PySide6.QtWidgets import QTabWidget, QMenu
|
12
|
+
from PySide6.QtWidgets import QTabWidget, QMenu, QPushButton
|
13
13
|
from PySide6.QtCore import Qt, Slot
|
14
14
|
from PySide6.QtGui import QAction, QIcon
|
15
15
|
|
@@ -19,16 +19,59 @@ import pygpt_net.icons_rc
|
|
19
19
|
|
20
20
|
|
21
21
|
class OutputTabs(QTabWidget):
|
22
|
-
def __init__(self, window=None):
|
22
|
+
def __init__(self, window=None, column=None):
|
23
23
|
super(OutputTabs, self).__init__(window)
|
24
24
|
self.window = window
|
25
|
+
self.column = column
|
25
26
|
self.setMinimumHeight(1)
|
26
27
|
self.owner = None
|
27
28
|
self.setMovable(True)
|
29
|
+
self.init()
|
30
|
+
|
31
|
+
def init(self):
|
32
|
+
"""Initialize"""
|
33
|
+
# create the [+] button
|
34
|
+
add_button = QPushButton(QIcon(":/icons/add.svg"), "")
|
35
|
+
add_button.setFixedSize(30, 25)
|
36
|
+
add_button.setFlat(True)
|
37
|
+
add_button.clicked.connect(
|
38
|
+
lambda: self.window.controller.ui.tabs.new_tab(self.column.get_idx())
|
39
|
+
)
|
40
|
+
add_button.setObjectName('tab-add')
|
41
|
+
add_button.setProperty('tabAdd', True)
|
42
|
+
add_button.setToolTip(trans('action.tab.add.chat'))
|
43
|
+
|
44
|
+
# add the button to the top right corner of the tab bar
|
45
|
+
self.setCornerWidget(add_button, corner=Qt.TopRightCorner)
|
46
|
+
|
47
|
+
# connect signals
|
48
|
+
self.currentChanged.connect(
|
49
|
+
lambda: self.window.controller.ui.tabs.on_tab_changed(self.currentIndex(), self.column.get_idx())
|
50
|
+
)
|
51
|
+
self.tabBarClicked.connect(
|
52
|
+
lambda: self.window.controller.ui.tabs.on_tab_clicked(self.currentIndex(), self.column.get_idx())
|
53
|
+
)
|
54
|
+
self.tabBarDoubleClicked.connect(
|
55
|
+
lambda: self.window.controller.ui.tabs.on_tab_dbl_clicked(self.currentIndex(), self.column.get_idx())
|
56
|
+
)
|
57
|
+
self.tabCloseRequested.connect(
|
58
|
+
lambda: self.window.controller.ui.tabs.on_tab_closed(self.currentIndex(), self.column.get_idx())
|
59
|
+
)
|
60
|
+
self.tabBar().tabMoved.connect(
|
61
|
+
lambda: self.window.controller.ui.tabs.on_tab_moved(self.currentIndex(), self.column.get_idx())
|
62
|
+
)
|
63
|
+
|
64
|
+
def get_column(self):
|
65
|
+
"""
|
66
|
+
Get column
|
67
|
+
|
68
|
+
:return: OutputColumn
|
69
|
+
"""
|
70
|
+
return self.column
|
28
71
|
|
29
72
|
def setOwner(self, owner: Tab):
|
30
73
|
"""
|
31
|
-
Set
|
74
|
+
Set internal tab instance
|
32
75
|
|
33
76
|
:param owner: parent tab instance
|
34
77
|
"""
|
@@ -42,56 +85,67 @@ class OutputTabs(QTabWidget):
|
|
42
85
|
"""
|
43
86
|
if event.button() == Qt.RightButton:
|
44
87
|
idx = self.tabBar().tabAt(event.pos())
|
45
|
-
|
88
|
+
column_idx = self.column.get_idx()
|
89
|
+
tab = self.window.core.tabs.get_tab_by_index(idx, column_idx)
|
46
90
|
if tab is not None:
|
47
91
|
if tab.type == Tab.TAB_NOTEPAD:
|
48
|
-
self.show_notepad_menu(idx, event.globalPos()) # notepad
|
92
|
+
self.show_notepad_menu(idx, column_idx, event.globalPos()) # notepad
|
49
93
|
elif tab.type == Tab.TAB_CHAT:
|
50
|
-
self.show_chat_menu(idx, event.globalPos()) # chat
|
94
|
+
self.show_chat_menu(idx, column_idx, event.globalPos()) # chat
|
51
95
|
elif tab.type == Tab.TAB_FILES:
|
52
|
-
self.show_files_menu(idx, event.globalPos()) # files
|
96
|
+
self.show_files_menu(idx, column_idx, event.globalPos()) # files
|
53
97
|
else:
|
54
|
-
self.show_default_menu(idx, event.globalPos()) # default
|
98
|
+
self.show_default_menu(idx, column_idx, event.globalPos()) # default
|
55
99
|
super(OutputTabs, self).mousePressEvent(event)
|
56
100
|
|
57
|
-
def get_common_actions(self, index):
|
101
|
+
def get_common_actions(self, index: int, column_idx: int):
|
58
102
|
"""
|
59
103
|
Get common actions
|
60
104
|
|
61
105
|
:param index: index
|
106
|
+
:param column_idx: column index
|
62
107
|
:return: dict
|
63
108
|
"""
|
64
109
|
actions = {}
|
65
110
|
actions['add_chat'] = QAction(QIcon(":/icons/add.svg"), trans('action.tab.add.chat'), self)
|
66
111
|
actions['add_chat'].triggered.connect(
|
67
|
-
lambda: self.add_tab(index, Tab.TAB_CHAT)
|
112
|
+
lambda: self.add_tab(index, column_idx, Tab.TAB_CHAT)
|
68
113
|
)
|
69
114
|
actions['add_notepad'] = QAction(QIcon(":/icons/add.svg"), trans('action.tab.add.notepad'), self)
|
70
115
|
actions['add_notepad'].triggered.connect(
|
71
|
-
lambda: self.add_tab(index, Tab.TAB_NOTEPAD)
|
116
|
+
lambda: self.add_tab(index, column_idx, Tab.TAB_NOTEPAD)
|
72
117
|
)
|
73
118
|
actions['edit'] = QAction(QIcon(":/icons/edit.svg"), trans('action.rename'), self)
|
74
119
|
actions['edit'].triggered.connect(
|
75
|
-
lambda: self.rename_tab(index)
|
120
|
+
lambda: self.rename_tab(index, column_idx)
|
121
|
+
)
|
122
|
+
actions['move_right'] = QAction(QIcon(":/icons/forward"), trans('action.tab.move.right'), self)
|
123
|
+
actions['move_right'].triggered.connect(
|
124
|
+
lambda: self.window.controller.ui.tabs.move_tab(index, column_idx, 1)
|
125
|
+
)
|
126
|
+
actions['move_left'] = QAction(QIcon(":/icons/back"), trans('action.tab.move.left'), self)
|
127
|
+
actions['move_left'].triggered.connect(
|
128
|
+
lambda: self.window.controller.ui.tabs.move_tab(index, column_idx, 0)
|
76
129
|
)
|
77
130
|
return actions
|
78
131
|
|
79
|
-
def show_notepad_menu(self, index, global_pos):
|
132
|
+
def show_notepad_menu(self, index: int, column_idx: int, global_pos):
|
80
133
|
"""
|
81
134
|
Show notepad menu
|
82
135
|
|
83
136
|
:param index: index
|
137
|
+
:param column_idx: column index
|
84
138
|
:param global_pos: global position
|
85
139
|
"""
|
86
140
|
context_menu = QMenu()
|
87
|
-
actions = self.get_common_actions(index)
|
141
|
+
actions = self.get_common_actions(index, column_idx)
|
88
142
|
actions['close'] = QAction(QIcon(":/icons/close.svg"), trans('action.tab.close'), self)
|
89
143
|
actions['close'].triggered.connect(
|
90
|
-
lambda: self.close_tab(index)
|
144
|
+
lambda: self.close_tab(index, column_idx)
|
91
145
|
)
|
92
146
|
actions['close_all'] = QAction(QIcon(":/icons/close.svg"), trans('action.tab.close_all.notepad'), self)
|
93
147
|
actions['close_all'].triggered.connect(
|
94
|
-
lambda: self.close_all(Tab.TAB_NOTEPAD)
|
148
|
+
lambda: self.close_all(Tab.TAB_NOTEPAD, column_idx)
|
95
149
|
)
|
96
150
|
context_menu.addAction(actions['add_chat'])
|
97
151
|
context_menu.addAction(actions['add_notepad'])
|
@@ -100,24 +154,32 @@ class OutputTabs(QTabWidget):
|
|
100
154
|
|
101
155
|
if self.window.core.tabs.count_by_type(Tab.TAB_NOTEPAD) > 1:
|
102
156
|
context_menu.addAction(actions['close_all'])
|
157
|
+
|
158
|
+
# move
|
159
|
+
if column_idx != 0:
|
160
|
+
context_menu.addAction(actions['move_left'])
|
161
|
+
if column_idx != 1:
|
162
|
+
context_menu.addAction(actions['move_right'])
|
163
|
+
|
103
164
|
context_menu.exec(global_pos)
|
104
165
|
|
105
|
-
def show_chat_menu(self, index, global_pos):
|
166
|
+
def show_chat_menu(self, index: int, column_idx: int, global_pos):
|
106
167
|
"""
|
107
168
|
Show chat menu
|
108
169
|
|
109
170
|
:param index: index
|
171
|
+
:param column_idx: column index
|
110
172
|
:param global_pos: global position
|
111
173
|
"""
|
112
174
|
context_menu = QMenu()
|
113
|
-
actions = self.get_common_actions(index)
|
175
|
+
actions = self.get_common_actions(index, column_idx)
|
114
176
|
actions['close'] = QAction(QIcon(":/icons/close.svg"), trans('action.tab.close'), self)
|
115
177
|
actions['close'].triggered.connect(
|
116
|
-
lambda: self.close_tab(index)
|
178
|
+
lambda: self.close_tab(index, column_idx)
|
117
179
|
)
|
118
180
|
actions['close_all'] = QAction(QIcon(":/icons/close.svg"), trans('action.tab.close_all.chat'), self)
|
119
181
|
actions['close_all'].triggered.connect(
|
120
|
-
lambda: self.close_all(Tab.TAB_CHAT)
|
182
|
+
lambda: self.close_all(Tab.TAB_CHAT, column_idx)
|
121
183
|
)
|
122
184
|
context_menu.addAction(actions['add_chat'])
|
123
185
|
context_menu.addAction(actions['add_notepad'])
|
@@ -126,21 +188,26 @@ class OutputTabs(QTabWidget):
|
|
126
188
|
# at least one chat tab must be open
|
127
189
|
if self.window.core.tabs.count_by_type(Tab.TAB_CHAT) > 1:
|
128
190
|
context_menu.addAction(actions['close'])
|
129
|
-
|
130
|
-
if self.window.core.tabs.count_by_type(Tab.TAB_CHAT) > 1:
|
131
191
|
context_menu.addAction(actions['close_all'])
|
132
192
|
|
193
|
+
# move
|
194
|
+
if column_idx != 0:
|
195
|
+
context_menu.addAction(actions['move_left'])
|
196
|
+
if column_idx != 1:
|
197
|
+
context_menu.addAction(actions['move_right'])
|
198
|
+
|
133
199
|
context_menu.exec(global_pos)
|
134
200
|
|
135
|
-
def show_files_menu(self, index, global_pos):
|
201
|
+
def show_files_menu(self, index: int, column_idx: int, global_pos):
|
136
202
|
"""
|
137
203
|
Show files menu
|
138
204
|
|
139
205
|
:param index: index
|
206
|
+
:param column_idx: column index
|
140
207
|
:param global_pos: global position
|
141
208
|
"""
|
142
209
|
context_menu = QMenu()
|
143
|
-
actions = self.get_common_actions(index)
|
210
|
+
actions = self.get_common_actions(index, column_idx)
|
144
211
|
actions['refresh'] = QAction(QIcon(":/icons/reload.svg"), trans('action.refresh'), self)
|
145
212
|
actions['refresh'].triggered.connect(
|
146
213
|
lambda: self.window.controller.files.update_explorer()
|
@@ -149,51 +216,73 @@ class OutputTabs(QTabWidget):
|
|
149
216
|
context_menu.addAction(actions['add_notepad'])
|
150
217
|
context_menu.addAction(actions['refresh'])
|
151
218
|
context_menu.addAction(actions['edit'])
|
219
|
+
|
220
|
+
# move
|
221
|
+
if column_idx != 0:
|
222
|
+
context_menu.addAction(actions['move_left'])
|
223
|
+
if column_idx != 1:
|
224
|
+
context_menu.addAction(actions['move_right'])
|
225
|
+
|
152
226
|
context_menu.exec(global_pos)
|
153
227
|
|
154
|
-
def show_default_menu(self, index, global_pos):
|
228
|
+
def show_default_menu(self, index: int, column_idx: int, global_pos):
|
155
229
|
"""
|
156
230
|
Show default menu
|
157
231
|
|
158
232
|
:param index: index
|
233
|
+
:param column_idx: column index
|
159
234
|
:param global_pos: global position
|
160
235
|
"""
|
161
236
|
context_menu = QMenu()
|
162
|
-
actions = self.get_common_actions(index)
|
237
|
+
actions = self.get_common_actions(index, column_idx)
|
163
238
|
context_menu.addAction(actions['add_chat'])
|
164
239
|
context_menu.addAction(actions['add_notepad'])
|
165
240
|
context_menu.addAction(actions['edit'])
|
241
|
+
|
242
|
+
# move
|
243
|
+
if column_idx != 0:
|
244
|
+
context_menu.addAction(actions['move_left'])
|
245
|
+
if column_idx != 1:
|
246
|
+
context_menu.addAction(actions['move_right'])
|
247
|
+
|
166
248
|
context_menu.exec(global_pos)
|
167
249
|
|
168
250
|
@Slot()
|
169
|
-
def rename_tab(self, index):
|
251
|
+
def rename_tab(self, index: int, column_idx: int):
|
170
252
|
"""
|
171
253
|
Rename tab
|
254
|
+
|
172
255
|
:param index: index
|
256
|
+
:param column_idx: column index
|
173
257
|
"""
|
174
|
-
self.window.controller.ui.tabs.rename(index)
|
258
|
+
self.window.controller.ui.tabs.rename(index, column_idx)
|
175
259
|
|
176
260
|
@Slot()
|
177
|
-
def close_tab(self, index):
|
261
|
+
def close_tab(self, index: int, column_idx: int):
|
178
262
|
"""
|
179
263
|
Close tab
|
264
|
+
|
180
265
|
:param index: index
|
266
|
+
:param column_idx: column index
|
181
267
|
"""
|
182
|
-
self.window.controller.ui.tabs.close(index)
|
268
|
+
self.window.controller.ui.tabs.close(index, column_idx)
|
183
269
|
|
184
270
|
@Slot()
|
185
|
-
def close_all(self, type):
|
271
|
+
def close_all(self, type, column_idx: int):
|
186
272
|
"""
|
187
273
|
Close all tabs
|
274
|
+
|
188
275
|
:param type: type
|
276
|
+
:param column_idx: column index
|
189
277
|
"""
|
190
|
-
self.window.controller.ui.tabs.close_all(type)
|
278
|
+
self.window.controller.ui.tabs.close_all(type, column_idx)
|
191
279
|
|
192
280
|
@Slot()
|
193
|
-
def add_tab(self, index, type):
|
281
|
+
def add_tab(self, index: int, column_idx: int, type):
|
194
282
|
"""
|
195
283
|
Add tab
|
196
284
|
:param index: index
|
285
|
+
:param column_idx: column index
|
197
286
|
:param type: type
|
198
287
|
"""
|
199
|
-
self.window.controller.ui.tabs.append(type, index)
|
288
|
+
self.window.controller.ui.tabs.append(type, index, column_idx)
|
@@ -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.
|
9
|
+
# Updated Date: 2024.12.09 00:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import re
|
@@ -42,6 +42,15 @@ class HtmlOutput(QWebEngineView):
|
|
42
42
|
self.plain = ""
|
43
43
|
self.html_content = ""
|
44
44
|
self.meta = None
|
45
|
+
self.tab = None
|
46
|
+
|
47
|
+
def set_tab(self, tab):
|
48
|
+
"""
|
49
|
+
Set tab
|
50
|
+
|
51
|
+
:param tab: Tab
|
52
|
+
"""
|
53
|
+
self.tab = tab
|
45
54
|
|
46
55
|
def set_meta(self, meta: CtxMeta):
|
47
56
|
"""
|
@@ -163,6 +172,7 @@ class HtmlOutput(QWebEngineView):
|
|
163
172
|
if success:
|
164
173
|
event = RenderEvent(RenderEvent.ON_PAGE_LOAD, {
|
165
174
|
"meta": self.meta,
|
175
|
+
"tab": self.tab,
|
166
176
|
})
|
167
177
|
self.window.dispatch(event)
|
168
178
|
|
@@ -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.
|
9
|
+
# Updated Date: 2024.12.09 00:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtCore import Qt
|
@@ -38,6 +38,15 @@ class ChatOutput(QTextBrowser):
|
|
38
38
|
self.setOpenLinks(False)
|
39
39
|
self.anchorClicked.connect(self.open_external_link)
|
40
40
|
self.setWordWrapMode(QTextOption.WordWrap)
|
41
|
+
self.tab = None
|
42
|
+
|
43
|
+
def set_tab(self, tab):
|
44
|
+
"""
|
45
|
+
Set tab
|
46
|
+
|
47
|
+
:param tab: Tab
|
48
|
+
"""
|
49
|
+
self.tab = tab
|
41
50
|
|
42
51
|
def open_external_link(self, url):
|
43
52
|
"""
|
@@ -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.
|
9
|
+
# Updated Date: 2024.12.07 21:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtGui import QAction, QIcon
|
@@ -32,6 +32,9 @@ class CtxSearchInput(QLineEdit):
|
|
32
32
|
self.clear_action.triggered.connect(self.clear_search_string)
|
33
33
|
self.addAction(self.clear_action, QLineEdit.TrailingPosition)
|
34
34
|
self.clear_action.setVisible(False)
|
35
|
+
action = QAction(self)
|
36
|
+
action.setIcon(QIcon(":/icons/search.svg"))
|
37
|
+
self.addAction(action, QLineEdit.LeadingPosition)
|
35
38
|
|
36
39
|
self.textChanged.connect(self.on_text_changed)
|
37
40
|
|