]> jfr.im git - irc/weechat/qweechat.git/blob - qweechat/buffer.py
Fix set the title of the thread.
[irc/weechat/qweechat.git] / qweechat / buffer.py
1 # -*- coding: utf-8 -*-
2 #
3 # buffer.py - management of WeeChat buffers/nicklist
4 #
5 # Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
6 #
7 # This file is part of QWeeChat, a Qt remote GUI for WeeChat.
8 #
9 # QWeeChat is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # QWeeChat is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with QWeeChat. If not, see <http://www.gnu.org/licenses/>.
21 #
22 import traceback
23
24 from pkg_resources import resource_filename
25 from qweechat.chat import ChatTextEdit
26 from qweechat.input import InputLineEdit
27 import qweechat.weechat.color as color
28
29 from PySide6 import QtCore
30 from PySide6 import QtWidgets
31 from PySide6 import QtGui
32
33
34 class GenericListWidget(QtWidgets.QListWidget):
35 """Generic QListWidget with dynamic size."""
36
37 def __init__(self, *args):
38 super().__init__(*args)
39 self.setMaximumWidth(100)
40 self.setTextElideMode(QtCore.Qt.ElideNone)
41 self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
42 self.setFocusPolicy(QtCore.Qt.NoFocus)
43 pal = self.palette()
44 pal.setColor(QtGui.QPalette.Highlight, QtGui.QColor('#ddddff'))
45 pal.setColor(QtGui.QPalette.HighlightedText, QtGui.QColor('black'))
46 self.setPalette(pal)
47
48 def auto_resize(self):
49 size = self.sizeHintForColumn(0)
50 if size > 0:
51 size += 4
52 self.setMaximumWidth(size)
53
54 def clear(self, *args):
55 """Re-implement clear to set dynamic size after clear."""
56 QtWidgets.QListWidget.clear(*(self,) + args)
57 self.auto_resize()
58
59 def addItem(self, *args):
60 """Re-implement addItem to set dynamic size after add."""
61 QtWidgets.QListWidget.addItem(*(self,) + args)
62 self.auto_resize()
63
64 def insertItem(self, *args):
65 """Re-implement insertItem to set dynamic size after insert."""
66 QtWidgets.QListWidget.insertItem(*(self,) + args)
67 self.auto_resize()
68
69
70 class BufferListWidget(GenericListWidget):
71 """Widget with list of buffers."""
72
73 def __init__(self, *args):
74 super().__init__(*args)
75
76 def switch_prev_buffer(self):
77 if self.currentRow() > 0:
78 self.setCurrentRow(self.currentRow() - 1)
79 else:
80 self.setCurrentRow(self.count() - 1)
81
82 def switch_next_buffer(self):
83 if self.currentRow() < self.count() - 1:
84 self.setCurrentRow(self.currentRow() + 1)
85 else:
86 self.setCurrentRow(0)
87
88
89 class BufferWidget(QtWidgets.QWidget):
90 """
91 Widget with (from top to bottom):
92 title, chat + nicklist (optional) + prompt/input.
93 """
94
95 def __init__(self, display_nicklist=False):
96 super().__init__()
97
98 # title
99 self.title = QtWidgets.QLineEdit()
100 self.title.setFocusPolicy(QtCore.Qt.NoFocus)
101
102 # splitter with chat + nicklist
103 self.chat_nicklist = QtWidgets.QSplitter()
104 self.chat_nicklist.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
105 QtWidgets.QSizePolicy.Expanding)
106 self.chat = ChatTextEdit(debug=False)
107 self.chat_nicklist.addWidget(self.chat)
108 self.nicklist = GenericListWidget()
109 if not display_nicklist:
110 self.nicklist.setVisible(False)
111 self.chat_nicklist.addWidget(self.nicklist)
112
113 # prompt + input
114 self.hbox_edit = QtWidgets.QHBoxLayout()
115 self.hbox_edit.setContentsMargins(0, 0, 0, 0)
116 self.hbox_edit.setSpacing(0)
117 self.input = InputLineEdit(self.chat)
118 self.hbox_edit.addWidget(self.input)
119 prompt_input = QtWidgets.QWidget()
120 prompt_input.setLayout(self.hbox_edit)
121
122 # vbox with title + chat/nicklist + prompt/input
123 vbox = QtWidgets.QVBoxLayout()
124 vbox.setContentsMargins(0, 0, 0, 0)
125 vbox.setSpacing(0)
126 vbox.addWidget(self.title)
127 vbox.addWidget(self.chat_nicklist)
128 vbox.addWidget(prompt_input)
129
130 self.setLayout(vbox)
131
132 def set_title(self, title):
133 """Set buffer title."""
134 self.title.clear()
135 if title is not None:
136 self.title.setText(title)
137
138 def set_prompt(self, prompt):
139 """Set prompt."""
140 if self.hbox_edit.count() > 1:
141 self.hbox_edit.takeAt(0)
142 if prompt is not None:
143 label = QtWidgets.QLabel(prompt)
144 label.setContentsMargins(0, 0, 5, 0)
145 self.hbox_edit.insertWidget(0, label)
146
147
148 class Buffer(QtCore.QObject):
149 """A WeeChat buffer."""
150
151 bufferInput = QtCore.Signal(str, str)
152
153 def __init__(self, data={}):
154 QtCore.QObject.__init__(self)
155 self.data = data
156 self.nicklist = {}
157 self.widget = BufferWidget(display_nicklist=self.data.get('nicklist',
158 0))
159 self.update_title()
160 self.update_prompt()
161 self.widget.input.textSent.connect(self.input_text_sent)
162
163 def pointer(self):
164 """Return pointer on buffer."""
165 return self.data.get('__path', [''])[0]
166
167 def update_title(self):
168 """Update title."""
169 try:
170 self.widget.set_title(
171 color.remove(self.data['title']))
172 except Exception as e: # noqa: E722
173 # TODO: Debug print the exception to be fixed.
174 # traceback.print_exc()
175 self.widget.set_title(None)
176
177 def update_prompt(self):
178 """Update prompt."""
179 try:
180 self.widget.set_prompt(self.data['local_variables']['nick'])
181 except Exception as e: # noqa: E722
182 self.widget.set_prompt(None)
183
184 def input_text_sent(self, text):
185 """Called when text has to be sent to buffer."""
186 if self.data:
187 self.bufferInput.emit(self.data['full_name'], text)
188
189 def nicklist_add_item(self, parent, group, prefix, name, visible):
190 """Add a group/nick in nicklist."""
191 if group:
192 self.nicklist[name] = {
193 'visible': visible,
194 'nicks': []
195 }
196 else:
197 self.nicklist[parent]['nicks'].append({
198 'prefix': prefix,
199 'name': name,
200 'visible': visible,
201 })
202
203 def nicklist_remove_item(self, parent, group, name):
204 """Remove a group/nick from nicklist."""
205 if group:
206 if name in self.nicklist:
207 del self.nicklist[name]
208 else:
209 if parent in self.nicklist:
210 self.nicklist[parent]['nicks'] = [
211 nick for nick in self.nicklist[parent]['nicks']
212 if nick['name'] != name
213 ]
214
215 def nicklist_update_item(self, parent, group, prefix, name, visible):
216 """Update a group/nick in nicklist."""
217 if group:
218 if name in self.nicklist:
219 self.nicklist[name]['visible'] = visible
220 else:
221 if parent in self.nicklist:
222 for nick in self.nicklist[parent]['nicks']:
223 if nick['name'] == name:
224 nick['prefix'] = prefix
225 nick['visible'] = visible
226 break
227
228 def nicklist_refresh(self):
229 """Refresh nicklist."""
230 self.widget.nicklist.clear()
231 for group in sorted(self.nicklist):
232 for nick in sorted(self.nicklist[group]['nicks'],
233 key=lambda n: n['name']):
234 prefix_color = {
235 '': '',
236 ' ': '',
237 '+': 'yellow',
238 }
239 color = prefix_color.get(nick['prefix'], 'green')
240 if color:
241 icon = QtGui.QIcon(
242 resource_filename(__name__,
243 'data/icons/bullet_%s_8x8.png' %
244 color))
245 else:
246 pixmap = QtGui.QPixmap(8, 8)
247 pixmap.fill()
248 icon = QtGui.QIcon(pixmap)
249 item = QtWidgets.QListWidgetItem(icon, nick['name'])
250 self.widget.nicklist.addItem(item)
251 self.widget.nicklist.setVisible(True)