]>
Commit | Line | Data |
---|---|---|
7dcf23b1 SH |
1 | # -*- coding: utf-8 -*- |
2 | # | |
e836cfb0 SH |
3 | # buffer.py - management of WeeChat buffers/nicklist |
4 | # | |
8335009d | 5 | # Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org> |
7dcf23b1 SH |
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 | # | |
eedb06f0 | 22 | import traceback |
7dcf23b1 | 23 | |
77df9d06 | 24 | from pkg_resources import resource_filename |
0ee7d2e9 AR |
25 | from qweechat.chat import ChatTextEdit |
26 | from qweechat.input import InputLineEdit | |
27 | import qweechat.weechat.color as color | |
7dcf23b1 | 28 | |
1f27a20e AR |
29 | from PySide6 import QtCore |
30 | from PySide6 import QtWidgets | |
31 | from PySide6 import QtGui | |
356719e0 | 32 | |
7dcf23b1 | 33 | |
1f27a20e | 34 | class GenericListWidget(QtWidgets.QListWidget): |
dc15599c | 35 | """Generic QListWidget with dynamic size.""" |
7dcf23b1 SH |
36 | |
37 | def __init__(self, *args): | |
1f27a20e | 38 | super().__init__(*args) |
dc15599c SH |
39 | self.setMaximumWidth(100) |
40 | self.setTextElideMode(QtCore.Qt.ElideNone) | |
7dcf23b1 | 41 | self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) |
7dcf23b1 SH |
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 | ||
02cba1c1 SH |
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.""" | |
1f27a20e | 56 | QtWidgets.QListWidget.clear(*(self,) + args) |
02cba1c1 SH |
57 | self.auto_resize() |
58 | ||
dc15599c SH |
59 | def addItem(self, *args): |
60 | """Re-implement addItem to set dynamic size after add.""" | |
1f27a20e | 61 | QtWidgets.QListWidget.addItem(*(self,) + args) |
02cba1c1 SH |
62 | self.auto_resize() |
63 | ||
64 | def insertItem(self, *args): | |
65 | """Re-implement insertItem to set dynamic size after insert.""" | |
1f27a20e | 66 | QtWidgets.QListWidget.insertItem(*(self,) + args) |
02cba1c1 | 67 | self.auto_resize() |
dc15599c SH |
68 | |
69 | ||
70 | class BufferListWidget(GenericListWidget): | |
71 | """Widget with list of buffers.""" | |
72 | ||
73 | def __init__(self, *args): | |
1f27a20e | 74 | super().__init__(*args) |
7dcf23b1 SH |
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 | ||
1f27a20e | 89 | class BufferWidget(QtWidgets.QWidget): |
77df9d06 SH |
90 | """ |
91 | Widget with (from top to bottom): | |
92 | title, chat + nicklist (optional) + prompt/input. | |
93 | """ | |
7dcf23b1 SH |
94 | |
95 | def __init__(self, display_nicklist=False): | |
1f27a20e | 96 | super().__init__() |
7dcf23b1 SH |
97 | |
98 | # title | |
1f27a20e | 99 | self.title = QtWidgets.QLineEdit() |
02cba1c1 | 100 | self.title.setFocusPolicy(QtCore.Qt.NoFocus) |
7dcf23b1 SH |
101 | |
102 | # splitter with chat + nicklist | |
1f27a20e AR |
103 | self.chat_nicklist = QtWidgets.QSplitter() |
104 | self.chat_nicklist.setSizePolicy(QtWidgets.QSizePolicy.Expanding, | |
105 | QtWidgets.QSizePolicy.Expanding) | |
3a5ec0c1 | 106 | self.chat = ChatTextEdit(debug=False) |
7dcf23b1 | 107 | self.chat_nicklist.addWidget(self.chat) |
dc15599c | 108 | self.nicklist = GenericListWidget() |
7dcf23b1 SH |
109 | if not display_nicklist: |
110 | self.nicklist.setVisible(False) | |
111 | self.chat_nicklist.addWidget(self.nicklist) | |
112 | ||
113 | # prompt + input | |
1f27a20e | 114 | self.hbox_edit = QtWidgets.QHBoxLayout() |
c728febd SH |
115 | self.hbox_edit.setContentsMargins(0, 0, 0, 0) |
116 | self.hbox_edit.setSpacing(0) | |
7dcf23b1 | 117 | self.input = InputLineEdit(self.chat) |
c728febd | 118 | self.hbox_edit.addWidget(self.input) |
1f27a20e | 119 | prompt_input = QtWidgets.QWidget() |
c728febd | 120 | prompt_input.setLayout(self.hbox_edit) |
7dcf23b1 SH |
121 | |
122 | # vbox with title + chat/nicklist + prompt/input | |
1f27a20e | 123 | vbox = QtWidgets.QVBoxLayout() |
7dcf23b1 SH |
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() | |
baa01601 | 135 | if title is not None: |
7dcf23b1 SH |
136 | self.title.setText(title) |
137 | ||
c728febd SH |
138 | def set_prompt(self, prompt): |
139 | """Set prompt.""" | |
140 | if self.hbox_edit.count() > 1: | |
141 | self.hbox_edit.takeAt(0) | |
baa01601 | 142 | if prompt is not None: |
1f27a20e | 143 | label = QtWidgets.QLabel(prompt) |
c728febd SH |
144 | label.setContentsMargins(0, 0, 5, 0) |
145 | self.hbox_edit.insertWidget(0, label) | |
146 | ||
7dcf23b1 SH |
147 | |
148 | class Buffer(QtCore.QObject): | |
149 | """A WeeChat buffer.""" | |
150 | ||
1f27a20e | 151 | bufferInput = QtCore.Signal(str, str) |
7dcf23b1 SH |
152 | |
153 | def __init__(self, data={}): | |
154 | QtCore.QObject.__init__(self) | |
155 | self.data = data | |
2a0b6adc | 156 | self.nicklist = {} |
77df9d06 SH |
157 | self.widget = BufferWidget(display_nicklist=self.data.get('nicklist', |
158 | 0)) | |
c728febd SH |
159 | self.update_title() |
160 | self.update_prompt() | |
7dcf23b1 SH |
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 | ||
c728febd SH |
167 | def update_title(self): |
168 | """Update title.""" | |
169 | try: | |
77df9d06 | 170 | self.widget.set_title( |
eedb06f0 AR |
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() | |
c728febd SH |
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']) | |
eedb06f0 | 181 | except Exception as e: # noqa: E722 |
c728febd SH |
182 | self.widget.set_prompt(None) |
183 | ||
7dcf23b1 SH |
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 | ||
2a0b6adc SH |
189 | def nicklist_add_item(self, parent, group, prefix, name, visible): |
190 | """Add a group/nick in nicklist.""" | |
191 | if group: | |
77df9d06 SH |
192 | self.nicklist[name] = { |
193 | 'visible': visible, | |
194 | 'nicks': [] | |
195 | } | |
02cba1c1 | 196 | else: |
890d4fa2 SH |
197 | self.nicklist[parent]['nicks'].append({ |
198 | 'prefix': prefix, | |
199 | 'name': name, | |
200 | 'visible': visible, | |
201 | }) | |
2a0b6adc SH |
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: | |
77df9d06 SH |
210 | self.nicklist[parent]['nicks'] = [ |
211 | nick for nick in self.nicklist[parent]['nicks'] | |
212 | if nick['name'] != name | |
213 | ] | |
2a0b6adc SH |
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.""" | |
02cba1c1 | 230 | self.widget.nicklist.clear() |
2a0b6adc | 231 | for group in sorted(self.nicklist): |
77df9d06 SH |
232 | for nick in sorted(self.nicklist[group]['nicks'], |
233 | key=lambda n: n['name']): | |
890d4fa2 SH |
234 | prefix_color = { |
235 | '': '', | |
236 | ' ': '', | |
237 | '+': 'yellow', | |
238 | } | |
2a0b6adc SH |
239 | color = prefix_color.get(nick['prefix'], 'green') |
240 | if color: | |
77df9d06 SH |
241 | icon = QtGui.QIcon( |
242 | resource_filename(__name__, | |
243 | 'data/icons/bullet_%s_8x8.png' % | |
244 | color)) | |
2a0b6adc SH |
245 | else: |
246 | pixmap = QtGui.QPixmap(8, 8) | |
247 | pixmap.fill() | |
248 | icon = QtGui.QIcon(pixmap) | |
1f27a20e | 249 | item = QtWidgets.QListWidgetItem(icon, nick['name']) |
2a0b6adc SH |
250 | self.widget.nicklist.addItem(item) |
251 | self.widget.nicklist.setVisible(True) |